Flask Application Factory
Tags: python, beginners, tutorial, flask
Published: 2022-02-22 20:24:36

Welcome to Part 2 of my multi-part tutorial on building a React, Flask, and GraphQL application. Before we get started on building our models, I wanted to first talk about the structure of our application and the file system. As I’ve mentioned, it’s very important for a developer to stay organized – whether it’s in regards to our code, our components, or our file system. Since our project is going to be growing, we need to structure ourselves to allow us to scale accordingly. I’m going to briefly talk about Flask’s application factory and how to structure our file system to help keep our application able to scale. 

### LARGE APPLICATION STRUCTURE

Let’s say the project I’m working on is called _Findr_, an application that will help developers find other developers to collaborate with. Here is a basic example of how my projects are usually organized. 


![File Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6gzzcchrnajvmvggakjs.png)

For now, we will just be working in the backend section.  

### APPLICATION FACTORY

In the previous article, we created just a single file application. This is very useful if you just need to do some small task or need a quick backend server. That being said, in the single file application our app instance is created right away and we won’t be able to change any of our configurations. As our application starts to scale and our configurations need to change dynamically, we will want to use a _factory function_ to delay the creation of our application – this is especially useful for testing.


If you haven’t done so already, let’s create a file directory called _Findr_. Inside of that directory we will create another directory called _backend_. And finally within that, let’s create a file called `__init__.py`. That’s a double underscore, just to be clear! Python will recognize this as the file called when we instantiate the application. 

_Findr / backend / __init__.py:_ 


```python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import config  # we’ll discuss the config file next

db = SQLAlchemy( )

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)
    app.config.from_pyfile(“../config.py”)

    db.init_app(app)
    
    from .api import api as api_blueprint  # We will discuss blueprints shortly as well
    app.register_blueprint(api_blueprint, url_prefix=’/api/’)

    return app
```

Here, the `create_app( )` function is the application factory. It will take an argument of the name of the configuration type we are using (Development, Production, Testing, etc), which will be stored in a _config.py_ file we will create momentarily. We created an uninitialized extension, _SQLAlchemy_, outside of the factory, then when we call `init_app( )` on it later, it initializes it.

### CONFIGURATION FILE

Next, we will create our _config.py_ file. This will hold all of our information for the databases and any future configurations we may need, for example Flask Mail settings to connect your application to GMail, etc. 

_Findr / config.py_


```python
class Config:
   SQLALCHEMY_TRACK_MODIFICATIONS = False
 
   @staticmethod
   def init_app(app):
       pass
 
class DevelopmentConfig(Config):
   DEBUG=True
   SQLALCHEMY_DATABASE_URI = 'postgresql://<username>:<password>@localhost:5432/findr'
 
class TestingConfig(Config):
   DEBUG = True
   TESTING = True
   SQLALCHEMY_DATABASE_URI = os.environ.get(
       "TEST_DATABASE_URL")
 
 
config = {
   'development': DevelopmentConfig,
   'testing': TestingConfig,
 
   'default': DevelopmentConfig}
```

Let’s break this down. First, we build a class Config that holds data we want all of our subclasses to have. Also we wrote the class method `init_app( )` that we saw earlier in our application factory above. Then we have two subclasses: _DevelopmentConfig_ and _TestingConfig_ which demonstrate two different ways to access the _SQLAlchemy Database URI_ – we can write the string out directly, or call it from an environmental variable we may have set up. Finally, there is a dictionary called `config` that we also called in the application factory to let us know which configuration we want to use. We have different configurations since, for example, if we are testing our application, we may want to manipulate the database and don’t want it to interfere with our development or production databases. 

### FLASK BLUEPRINTS

Since we converted to an application factory, the way we initially handled views with `@app.route(‘/home’)` won’t do the job anymore. Now that our application is created at runtime, the app.route decorator exists only after `create_app( )` is invoked, which is too late. 

We can have many different Blueprints in our application, each with their own views, errors, etc. We could write each Blueprint in a single file or create some structure to allow us to scale if we need to. Let’s create our first Blueprint:

_Findr / backend / api / __init__.py:_



```python
from flask import Blueprint

api = Blueprint(‘api’, __name__)

from . import views, errors
```

First, we imported _Blueprint_ from flask. Then, much like we created our initial application, we created the api blueprint with the name of ‘api’. Finally, we imported the files that are to be associated with this particular blueprint that will be kept in the same directory as this blueprint. These will be files like the view functions and any error handling, etc. **_It is important that the import comes at the bottom so we can avoid circular dependencies in these files_**. 

We already registered the blueprint with our app back in the application factory where I had commented. So, the last thing we need to talk about in order to get our application up and running, is the _application script_. 

### APPLICATION SCRIPT

In the `app.py` file in the top-level directory is where the actual application instance is defined. In this file we will need to create the application, declare which configuration we are using, call Flask-Migrate so we can make our migrations to the application for the database, and create the custom context for the flask shell we will use to help debug our code and databases. 


```python
from backend import create_app, db
from flask_migrate import Migrate
 
# We still need to create our models
# The following code you can comment out 
# if you want to run the application now
# Otherwise wait until we build these models next
from backend.models import User
 
 
 
app = create_app('development')
migrate = Migrate(app, db)
 
 
 
@app.shell_context_processor
def make_shell_context():
   return dict(db=db, User = User)

```

Besides our models, we have a fully functional flask application using an application factory format! 

To review, we discussed:
- How to structure a large Flask application
- How to create the Application Factory function
- How to create our config.py file
- How to create a Flask Blueprint to hold our views, errors, etc
- How to create our application script to run all of our code


In the next part of this series, we will see how to build out our models, use SQLAlchemy to store them in the database, connect our Flask backend to GraphQL and write out our schema and resolver functions. See you there!