Skip to content

#219: Structure your FastAPI Application

With our API, the tests, and the models we get deeper and deeper into FastAPI. It is now a good moment to check what FastAPI suggests on how to structure our application before we start a more complex example.

A structure for bigger FastAPI applications

In the FastAPI documentation we can find this suggested structure for bigger applications:

.
├── app                  # "app" is a Python package
   ├── __init__.py      # this file makes "app" a "Python package"
   ├── main.py          # "main" module, e.g. import app.main
   ├── dependencies.py  # "dependencies" module, e.g. import app.dependencies
   └── routers          # "routers" is a "Python subpackage"
      ├── __init__.py  # makes "routers" a "Python subpackage"
      ├── items.py     # "items" submodule, e.g. import app.routers.items
      └── users.py     # "users" submodule, e.g. import app.routers.users
   └── internal         # "internal" is a "Python subpackage"
       ├── __init__.py  # makes "internal" a "Python subpackage"
       └── admin.py     # "admin" submodule, e.g. import app.internal.admin

While that looks good, it misses a place for our tests, models, and the code to access the database. That means we can start with it but quickly run into the problem of finding a space for those not covered parts.

Alternatives

If we search for alternatives on how to structure our FastAPI project, we can find a few good candidates.

While those two approaches work, I am not fully happy with either structure. I would like something like the structure for Flask, that I got from Talk Python Training. Unfortunately, there is not a complete structure in the 3 courses about FastAPI that covers everything at once. That said, nobody is stopping us from condensing the templates used there into a single one:

.
   main.py              # "main" module, e.g. import app.main
   requirements.txt     # the packages we need to run the API
├───bin                  # scripts to update database, maintenance, etc.
├───data                 # SQLAlchemy classes to connect to the database
├───db                   # *.sqlite file with data
├───infrastructure       # middleware (e.g. caching)
├───models               # Pydantic models
├───routers              # Routers to split API into multiple files
   └───part_a.py        # Endpoints for part a 
├───server               # configuration for web server
   ├───nginx            # nginx configuration
   └───scripts          # scripts to run on server
├───services             # external APIs
├───static               # content to directly serve to user
   ├───css              # *.css files
   ├───img              # images
   └───js               # *.js files
└────templates           # view templates
    └───PART_A           # templates that match routers/part_a

That looks a bit more like what I had in mind. Let us see how this will work out with a larger application.

Next

There are multiple ways to structure our FastAPI applications. While there is an official guideline on how to do that, it does not cover all the parts that we are going to need. For my next step I am using the combined structure and see how that works out. Next week we put that to a test by building a To-do application that can manage our tasks.