Home

Awesome

<div align="center">

logo

Mentioned in Awesome <INSERT LIST NAME> License

</div>

Description

This is a simple FastAPI template that follows Flask's blueprint directory structure.

Features

Quickstart

Run in containers

Or, run locally

If you want to run the app locally, without using Docker, then:

Explore the endpoints

Housekeeping

Directory structure

This shows the folder structure of the default template.

fastapi-nano
├── svc                           # primary service folder
│   ├── apis                      # this houses all the API packages
│   │   ├── api_a                 # api_a package
│   │   │   ├── __init__.py       # empty init file to make the api_a folder a package
│   │   │   ├── mainmod.py        # main module of api_a package
│   │   │   └── submod.py         # submodule of api_a package
│   │   └── api_b                 # api_b package
│   │       ├── __init__.py       # empty init file to make the api_b folder a package
│   │       ├── mainmod.py        # main module of api_b package
│   │       └── submod.py         # submodule of api_b package
│   ├── core                      # this is where the configs live
│   │   ├── auth.py               # authentication with OAuth2
│   │   ├── config.py             # sample config file
│   │   └── __init__.py           # empty init file to make the config folder a package
│   ├── __init__.py               # empty init file to make the app folder a package
│   ├── main.py                   # main file where the fastAPI() class is called
│   ├── routes                    # this is where all the routes live
│   │   └── views.py              # file containing the endpoints for api_a and api_b
│   └── tests                     # test package
│       ├── __init__.py           # empty init file to make the tests folder a package
│       ├── test_api.py           # integration testing the API responses
│       └── test_functions.py     # unit testing the underlying functions
├── dockerfiles                   # directory containing all the dockerfiles
├── .env                          # env file containing app variables
├── Caddyfile                     # simple reverse-proxy with caddy
├── docker-compose.yml            # docker-compose file
├── pyproject.toml                # pep-518 compliant config file
└── uv.lock                       # pinned app and dev dependencies

In the above structure, api_a and api_b are the main packages where the code of the APIs live and they are exposed by the endpoints defined in the routes folder. Here, api_a and api_b have identical logic. These are dummy APIs that take an integer as input and return two random integers between zero and the input value. The purpose of including two identical APIs in the template is to demonstrate how you can decouple the logics of multiple APIs and then assemble their endpoints in the routes directory. The following snippets show the logic behind the dummy APIs.

This is a dummy submodule that houses a function called random_gen which generates a dictionary of random integers.

# This a dummy module
# This gets called in the module_main.py file
from __future__ import annotations
import random


def rand_gen(num: int) -> dict[str, int]:
    num = int(num)
    d = {
        "seed": num,
        "random_first": random.randint(0, num),
        "random_second": random.randint(0, num),
    }
    return d

The main_func in the primary module calls the rand_gen function from the submodule.

from __future__ import annotations
from svc.api_a.submod import rand_gen


def main_func(num: int) -> dict[str, int]:
    d = rand_gen(num)
    return d

The endpoint is exposed like this:

# svc/routes/views.py
from __future__ import annotations
#... codes regarding authentication ...

# endpoint for api_a (api_b looks identical)
@router.get("/api_a/{num}", tags=["api_a"])
async def view_a(num: int, auth: Depends =Depends(get_current_user)) -> dict[str, int]:
    return main_func_a(num)

So hitting the API with a random integer will give you a response like the following:

{
  "seed": 22,
  "random_first": 27,
  "random_second": 20
}

Further modifications

Resources

<div align="center"> ✨ 🍰 ✨ </div>