fastapi-scaff: generating a layered FastAPI project with API, services and models
This is a fastapi scaff. (fastapi脚手架,一键生成项目或api,让开发变得更简单)
At a glance
- What is it?
- fastapi-scaff is a command line generator that writes a FastAPI project skeleton with an api, services and models layering, optional Celery and Alembic support, and Docker files. It suits teams that want a house layout in one command, and it suits them less if their Python floor is below 3.11 or their structure is already decided.
- Who is it for?
- Adopt fastapi-scaff if your team keeps re-creating the same FastAPI skeleton and wants the api, services and models split with the core middleware, config, database and log directories already in place. Do not adopt it if you are on Python 3.10 or below, since the package requires 3.11, and read the generated project before editing it, because the scaffolding writes files you then own outright.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A generator for the project skeleton, not a FastAPI add-on
fastapi-scaff is a command line tool that creates FastAPI projects and adds endpoints to them. The project description says it plainly, in English and Chinese, that this is a fastapi scaffold, and the three jobs it lists are new project, add api, and tpl template.
What it generates is a full project tree, not a library to import. The generated layout is described as an ASM architecture, where A is api, S is services and M is models, with a core directory for configuration, database, logging and middleware, a utils directory, and main.py as the entry point. Alongside the application code the tree carries a config directory, a docs directory, a tests directory, requirements.txt, a runserver.py, and Docker files including a Dockerfile, a docker-build.sh and a docker-compose.yaml.
There is a second application package, app_celery, for asynchronous tasks, which only appears when you ask for it.
The package is published on pip as fastapi-scaff and requires Python 3.11 or later, both in the installation note and in the pyproject metadata, which lists the 3.11 classifier and requires-python of >=3.11. Licence is MIT. The last push to the repository was on 2026-10-01, and the repository has no GitHub releases, so versions are tracked differently, which is the subject of a later section.
The ASM layering and the request path it enforces
The interesting design decision in the tool is not the directory list, it is the fixed request flow. The documentation gives it as main.py, then core with its middleware, then api, then services, then models. A request is expected to travel in that order, and the generated code is arranged so that it does.
The division of labour follows from the names. The api layer holds the interface definitions, versioned under an api/v1 directory. The services layer holds the business logic. The models layer holds the data models. Core holds the cross-cutting concerns: conf for configuration, db for the database, log for logging, and the middleware that sits between the app and the routes.
That has an immediate consequence for anyone reviewing the output. A route handler in api should not contain business logic, because the business logic belongs in services, and a service should not know about the request object, because that belongs in api. The generator gives you the place for each thing, which is the main argument for using it over a bare FastAPI application.
The naming is described as finalized after multiple revisions, with the goal of being concise and easy to understand. That is a hint about the project's history, and also a warning: the layout is opinionated, and you will either accept it or edit it. Editing it is fine, but then you have diverged from what the add command and the tpl command expect to find.
Creating a project and adding an API to it
The command surface is small, and the help flag is the first thing to run.
pip install fastapi-scaff
fastapi-scaff -hCreating a project takes a name, and the template size is selected with the -t flag. Three sizes are documented: light, tiny and single, each with its own tree.
fastapi-scaff new <myproj>
fastapi-scaff new <myproj> -t light
fastapi-scaff new <myproj> -t tiny
fastapi-scaff new <myproj> -t singleAdding an endpoint to a project you already have is the second command, and it is run from the project root directory.
cd to project root dir
fastapi-scaff add <myapi>This split is the part of the tool that earns its keep. Creating a project is a one-time event, whereas adding an API happens every week, and if the generator can wire a new router, a version directory and the model layer consistently, that is more valuable than the initial tree. The documentation also states that modules can be enabled flexibly through parameters when creating a project with new, with database, loguru and redis given as the examples.
One caveat on the naming: the new and add commands take the project and the API name as arguments, and it is up to you to keep them consistent with the directory conventions the generated code already follows.
Celery, migrations and Docker arrive as opt-in flags
The heavier integrations are not on by default, and each has its own switch. Celery support is requested at creation time with a flag, or injected into an existing project with the tpl command and a project argument.
fastapi-scaff new <myproj> --celery
fastapi-scaff tpl celery -p <mycelery>Migration support works the same way, with a flag on new, and then two commands that run before the server starts: one to generate and one to upgrade.
fastapi-scaff new <myproj> --migration
python runmigration.py generate init
python runmigration.py upgradeDocker support is different in kind. The project files are simply present in the generated tree, namely a Dockerfile, a docker-build.sh that uses the default Dockerfile by default, and a docker-compose.yaml. The compose file that ships with the project shows the intended shape: an app service on port 8000, an APP_ENV environment variable set to prod, a volume mounted for logs, and a uvicorn command.
image: fastapi-scaff:v1.0.0
restart: unless-stopped
ports:
- "8000:8000"
environment:
APP_ENV: prod
command: "uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 5 --log-level info"The commented alternative in that file swaps uvicorn for gunicorn with config/gunicorn.conf.py, with a note that gunicorn has to be installed. Both options are documented in the same project run section, with links to the uvicorn and gunicorn documentation.
Running the generated project and its pinned dependencies
The run instructions are four steps: change into the project root, modify the configuration such as the database settings, install the requirements, and start the server.
pip install -r requirements.txt
python runserver.pyThe requirements file is fully pinned, and it doubles as a map of what the scaffold actually integrates. It lists fastapi at 0.142.2, uvicorn with the standard extra at 0.54.0, SQLAlchemy at 2.1.1 with aiosqlite at 0.22.1, alembic at 1.20.0, celery at 5.6.3, redis at 8.1.0, loguru at 0.7.3, PyJWT at 2.15.1, bcrypt at 5.0.0, PyYAML, python-dotenv and tzdata. The gunicorn line is present but commented out.
That list matches the feature descriptions in the documentation, which claim integrated api-key and jwt, integrated sqlalchemy, integrated migration, integrated celery and integrated docker. The auth story is JWT with bcrypt, the data story is SQLAlchemy with alembic migrations, the logging is loguru, and celery is wired to redis as the broker.
Pinning every dependency exactly is good for reproducibility and a cost when you upgrade. Because the versions are frozen in the generated file rather than expressed as ranges, an upgrade of fastapi or sqlalchemy is a manual edit in each generated project, and the scaffolder will not do it for you unless you regenerate.
The alternative: hand keeping the layout, and the tpl escape hatch
The realistic alternative to a generator is to keep a copy of the layout in a template repository of your own and copy it by hand, or to write a small internal script. The difference in approach comes down to what happens after the first week.
A hand maintained copy does not rot the same way, because your template repository is under your control and you can update it when the dependencies change. What it lacks is the second command. The add command is what keeps a generated project consistent over time, because it writes a new router, a version directory and the model layer in the shape the rest of the tree expects, which is the failure a hand copied template cannot prevent.
The tpl command is the part of fastapi-scaff that survives a house style. It integrates templates such as celery and docker into existing projects, which means a team whose layout is already decided can still use the tool for the module wiring without accepting the ASM tree. The documentation makes that distinction explicit, describing tpl as a way to easily integrate templates into existing projects.
There is also a third option, the one the scaffold is arguing against, which is to write the structure by hand once and then never look at it again. That works fine until the first new endpoint, and at that point the project has a conventions problem rather than a code problem.
Where the project is thin, and how it tracks versions
Several gaps are visible in the repository itself rather than in the design.
The documentation is largely Chinese, with the README in both languages and a pointer to a blog post for more documents. The project has no homepage and no GitHub releases. There is no changelog, no test suite description beyond a tests directory, and no CI badge in the README header.
Versioning is unusual and worth understanding before you rely on it. The setup.py file contains a BuildCommand and a PublishCommand, and the build command reads the version from a .history file at the repository root, taking the first line that starts with a hash marker, and rewrites the __version__ string in the package init file with it. The pyproject metadata then reads the version from that attribute. So the version of the published package comes from a file that also serves as a change history, and the two are kept in step by a custom command rather than by a tag.
The repository top level also contains files that go beyond the scaffold itself, including a Dockerfile-bullseye, a docker-swarm.yaml, and three Nomad related files named nomad-app.hcl, nomad-setup.sh and nomad-traefik.hcl, plus runcbeat.py and runcworker.py. Those suggest deployment variants the README does not document in detail, so a team deploying to Nomad or to a Swarm cluster would have to read the files rather than the instructions.
And the tool generates a project that is yours to maintain from the moment it is created. The scaffolding gives you a consistent starting point, not a maintained dependency.
Editorial conclusion
Adopt fastapi-scaff if your team keeps re-creating the same FastAPI skeleton and wants the api, services and models split with the core middleware, config, database and log directories already in place. Do not adopt it if you are on Python 3.10 or below, since the package requires 3.11, and read the generated project before editing it, because the scaffolding writes files you then own outright. Before you generate anything, run fastapi-scaff -h and pick the template size, since light, tiny and single produce materially different trees.
Frequently asked questions
How do I create a new FastAPI project with fastapi-scaff?
Install the package with pip install fastapi-scaff, then run fastapi-scaff new <myproj>. You can select a template size with the -t flag, with light, tiny and single documented, and the help flag fastapi-scaff -h lists the commands.
Which Python version does fastapi-scaff require?
The installation note says the package can be installed using pip with Python 3.11 or newer, and the pyproject metadata lists requires-python of >=3.11 with a 3.11 classifier.
How do I add an API endpoint to an existing project?
Change into the project root directory and run fastapi-scaff add <myapi>. The command is meant to be run from the project root so it can place the new router in the right versioned api directory.
How do I enable Celery and database migrations in fastapi-scaff?
Celery is enabled at creation with fastapi-scaff new <myproj> --celery, and migrations with fastapi-scaff new <myproj> --migration, after which you run python runmigration.py generate init and python runmigration.py upgrade before starting the server.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/atpuxiner-fastapi-scaff)Was this useful?