Cookiecutter template to create a new FastAPI project
This repository serves as a Cookiecutter template to create a new FastAPI project, featuring:
Start a new project:cookiecutter https://github.com/Gradiant/fastapi-cookiecutter-template.git
The following will be prompted:
chdir to where the template was created (inside “directory_name”) and start the server with python .
This template uses different modules of “routes” to declare the endpoints organized by context. For example, an API with “users” and “posts” CRUD endpoints would have one “routes/users.py” module, and other “routes/posts.py” module, where the endpoints for “users” and “posts” would be defined, respectively.
In each module, an APIRouter is defined. The template includes a router module routes/api.py, with a sample “/status” endpoint.
This router is then imported in routers.py and declared in the setup_routes() function, so the API can use it.
When including a router, a common prefix can be set to each router.
Additionally, each router can have a “tag” associated, which is used to group its endpoints together in the generated documentation.
The settings are managed using Pydantic BaseSettings classes, all of them contained in the settings.py module. The main features and advantages of using these classes are:
.env
, and is loaded relative to the working directory where the application was launched from. The name of the file can be changed with the environment variable ENV_FILE
.The bundled settings are documented in the sample.env file.
The proposed logging system consists of a single logger (using loguru as logging library) that should only be user for logging records triggered from request handling (this means anything that runs from a request handler - any function decorated to serve an endpoint).
All the requests are passed through the request middleware, that will append a unique identifier to the log records of that request, using context variables (using loguru contextualize).
If the template is used with advanced_responses=yes, the returned responses will embed the request id and elapsed request processing time (seconds) in headers, as “X-Request-ID” and “X-Process-Time” respectively.
Having the request id as a client can be useful to search later on all the log records for a certain request.
The logger behaviour supported by the template is to print out the log records with a certain format. Optionally, using the REQUEST_LOG_SERIALIZE setting, these records can be serialized and printed out as JSON objects, that could then be persisted, and even grouped by request using the request identifier that is part of each record “extra” data.
The proposed procedure to return errors to clients is by raising a custom exception that inherits from the bundled BaseAPIException.
This class includes an abstract method “response()” that must return a FastAPI Response when implemented in custom exception classes. An exception for returning Internal Server (500) errors is included.
Any exception inherited from BaseAPIException that is raised from any point during a request handling will be captured by the request middleware.
The “response()” method is called from the middleware to obtain the response that will finally be returned to the client. Unknown exceptions will be returned as Internal Server errors, using the bundled namesake exception.
If the template is used with advanced_docs=yes, a documentation.py module will be created.
In this module, the default logic to generate the API documentation is overriden to support self-hosting the Swagger/OpenAPI and ReDoc requirements (JS, CSS and Favicon files), so they get loaded from the local deployment instead of CDNs, as stated in the FastAPI documentation. Self-hosting these files requires to set a static path on the API_DOCS_STATIC_PATH setting; refer to the sample.env file.
The template includes a tests package, where tests for the application can be placed. Includes a sample test on the /status endpoint, using FastAPI TestClient.
The template tests can run without creating a template, by running the tools/test_template.sh script.