This post previously published on my blog

Hi. I have been developing Flask applications as a side project for 5 years. After all these years, I found the right structure I need for me.

First Steps

Firstly, I'm always using virtualenv to isolate my projects. For example, we want to develop a poll app.



mkdir poll_app cd poll_app virtualenv . source bin/activate

Python Libraries I Always Use

I'm developing applications that require a database. So, I always use flask_script and flask_migrate libraries. I don't like Flask's CLI tool.

I create a python file called manage.py such as Django's in the root folder. For example;



from MYAPP.data.models import db from MYAPP import app from flask_script import Manager from flask_migrate import Migrate , MigrateCommand db . init_app ( app ) migrate = Migrate ( app , db ) manager = Manager ( app ) manager . add_command ( 'db' , MigrateCommand ) if __name__ == "__main__" : manager . run ()

I'm using like that;



python manage.py db init # --> init migrations python manage.py db migrate # --> migrate models python manage.py db upgrade # --> apply changes python manage.py db --help # --> :)

Main app file

I create a file app.py in the root folder when I create a new project and then it changes like that.



from MYAPP import app # To do: This place will change later config = { "development" : "config.Development" } if __name__ == "__main__" : app . config . from_object ( config [ "development" ]) app . run ()

Config File

I also create a file called config.py in the root folder.



class BaseConfig ( object ): """ Base config class. This fields will use by production and development server """ ORIGINS = [ "*" ] # for api calls SECRET_KEY = 'YOUR SECRET KEY' class Development ( BaseConfig ): """ Development config. We use Debug mode """ PORT = 5000 DEBUG = True TESTING = False ENV = 'dev' # Currently we only have development config. # If you have production, you will need to pass it to here. config = { 'development' : 'config.Development' } def configure_app ( app ): """ App configuration will be here. Parameters ---------- app : Flask app instance """ app . config . from_object ( config [ 'development' ])

Folder Structure

I create a folder in the root directory. Let's say folder name is om_core. I create two folders in the om_core.

Their name api and data. The api folder stores application logic and routes. For example, I created a folder called user.

This folder contains two files called init.py and controllers.py file. Our other api layers will be like that. The controller file should be like that;



from flask import Blueprint , jsonify , request from MYAPP.data.models import db , User user = Blueprint ( 'user' , __name__ ) @ user . route ( '/' , methods = [ 'GET' ]) def get_users (): return jsonify ({ "message" : "Hi user :)" }) @ user . route ( '/<int:id>' , methods = [ 'GET' ]) def users ( id ): return jsonify ({ "id" : id })

I always use blueprints.

The data folder stores models. For example, I created a file called models.py



from flask_sqlalchemy import SQLAlchemy from MYAPP import app # We didn't pass app instance here. db = SQLAlchemy () class User ( db . Model ): """ Model for user management """ id = db . Column ( db . Integer , primary_key = True ) email = db . Column ( db . String ( 100 ), unique = True ) password = db . Column ( db . String ( 100 )) name = db . Column ( db . String ( 100 )) surname = db . Column ( db . String ( 100 )) active = db . Column ( db . Boolean (), default = True ) created_at = db . Column ( db . DateTime , default = db . func . now ()) updated_at = db . Column ( db . DateTime , default = db . func . now ()) def __init__ ( self , email , password , name , surname , active , created_at , updated_at ): self . email = email self . password = password self . name = name self . surname = surname self . active = active self . created_at = created_at self . updated_at = updated_at

Let's get back to the om_core folder. I create a file called init.py to use API layers as endpoints.



from flask import Flask from flask_cors import CORS from config import BaseConfig from config import configure_app app = Flask ( __name__ ) from MYAPP.api.user.controllers import user """ Corst settings will be here. We maybe use this endpoint later. """ cors = CORS ( app , resources = { r'/api/*' : { 'origins' : BaseConfig . ORIGINS } }) configure_app ( app ) app . url_map . strict_slashes = False app . register_blueprint ( user , url_prefix = '/api/users' )

You don't need to use Flask-CORS if you don't want to allow request from different origins. I'm using it to allow requests from different origins.

Screenshot for My Project Structure

This is a screenshot for my project structure.

That's all. If you want to see this project on the GitHub: https://github.com/foss-dev/open-monitoring

Thanks for reading.