title: How do I structure this medium sized flask application?
body: <p>Using the FLASK framework in Python, my application needs to:</p>
  
  <ol>
  <li>register and log in users (with either a sqlite or postgres database) </li>
  <li>access a specific google spreadsheet that the logged in user owns and output that data in a json format.
  <strong>I am required to have my own authorization &amp; authentication system</strong> </li>
  </ol>
  
  <p>I am having a lot of trouble figuring out how to even structure the application - what directories and sub-directories should I have? </p>
  
  <p>I have done A LOT of playing around (about 1 months worth). I am using a virtual environment but don't know how to test my code well either. In general, my code runs but I have no idea how they work together really.** I am completely new to flask.**</p>
  
  <p><strong>Structuring the app</strong>: </p>
  
  <p>|app</p>
  
  <p>|----run.py</p>
  
  <p>|----config.py</p>
  
  <p>|----database</p>
  
  <p>|---------database.db</p>
  
  <p>|----app</p>
  
  <p>|---------views.py</p>
  
  <p>|---------models.py</p>
  
  <p>|---------forms.py</p>
  
  <p>|---------extensions.py</p>
  
  <p>|----templates</p>
  
  <p>|---------....</p>
  
  <p>|----static</p>
  
  <p>|--------....</p>
  
  <p><strong>Authorization / Authentication</strong>: 
  <em>I have looked at Flask-Login, Flask-Auth, Flask-Security. I understand the general idea but do not know how to securely implement a complete authorization &amp; authentication system.</em> </p>
  
  <pre><code>app = Flask(__name__)
  app.config.from_object(config)
  login_manager = LoginManager()
  login_manager.init_app(app)
  
  def create_app():   
      db.init_app()
      db.app = app
      db.create_all()
      return app
  
  @app.route('/')
  def index():
       #needs to render the homepage template
  
  @app.route('/signup', methods = ['GET', 'POST'])
  def register():
      form = SignupForm()
      if request.method == 'GET':
          return render_template('signup.html', form=form)
      elif request.method == 'POST':
          if form.validate_on_submit():
              if User.query.filter_by(email=form.email.data).first():
                  return "email exists"
              else:
                  newuser = User(form.email.data, form.password.data)
                  db.session.add(newuser)
                  db.session.commit()
                  login_user(newuser)
  
              return "New User created"
      else:
          return "form didn't validate"
  
      return "Signup"
  
  @app.route('/login', methods = ['GET', 'POST'])
  def login():
      form = SignupForm()
  
      if request.method == 'GET':
          return render_template('login.html', form=form)
      elif request.method == 'POST':
          if form.validate_on_submit():
              user = User.query.filter_by(email=form.email.data).first()
              if user:
                  if user.password == form.password.data:
                      login_user(user)
                      return "you are logged in"
                  else:
                      return "wrong password"
              else:
                  return "user doesnt exist"
          else:
              return "form did not validate"
  
  @login_manager.user_loader
  def load_user(email):
      return User.query.filter_by(email = email).first()
  
  @app.route('/protected')
  @login_required
  def protected():
      return "protected area for logged in users only"
  
  if __name__ == '__main__':
      #app.create_app()
      app.run(port=5000, host='localhost')`
  </code></pre>
  
  <hr>
  
  <pre><code>from flask_security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin, login_required
  import os
  
  # Create app
  app = Flask(__name__)
  #app.config['DEBUG'] = True
  app.config['SECRET_KEY'] = '' 
  app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////'
  app.config['SECURITY_PASSWORD_HASH'] = 'sha512_crypt'
  app.config['SECURITY_PASSWORD_SALT'] = str(os.urandom(24))
  # Create database connection object
  db = SQLAlchemy(app)
  
  # Define models
  roles_users = db.Table('roles_users',
      db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
      db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
  
  class Role(db.Model, RoleMixin):
      id = db.Column(db.Integer(), primary_key=True) 
      name = db.Column(db.String(80), unique=True) 
      description = db.Column(db.String(255))
  
  class User(db.Model, UserMixin):
      id = db.Column(db.Integer, primary_key=True)
      email = db.Column(db.String(255), unique=True) 
      password = db.Column(db.String(255))
      active = db.Column(db.Boolean())
      confirmed_at = db.Column(db.DateTime())
      roles = db.relationship('Role', secondary=roles_users,  backref=db.backref('users', lazy='dynamic'))
  
  
  user_datastore = SQLAlchemyUserDatastore(db, User, Role)
  security = Security(app, user_datastore)
  
  # Create a user to test with
  @app.before_first_request 
  def create_user():
      db.create_all()
      user_datastore.create_user(email='', password='')
      db.session.commit()
  
  @app.route('/') 
  @login_required 
  def home():
      #password = encrypt_password('mypass')
      #print verify_and_update_password('mypass', password)
      return "hello"
  
  if __name__ == '__main__': 
      app.run(debug=True, use_reloader=False)
  </code></pre>
  
  <p>** I would really appreciate any guidance!**</p>