I was recently asked to share my base python app template to start up a new project. Funny enough, I don’t really have one. While I have built a (IMHO) good base to quickly get a python app spun up, I normally cherry-pick bits and pieces from past projects. So I figure now is a good a time as any to create a reusable project base so that anyone can use it. For the impatient, here it is python-app-template. For those who want to stick around, let’s go one level deeper on what exactly it is.
Why? Link to heading
Python doesn’t have a large number of opinionated frameworks once you get outside of Django, which is both good and bad. To put it on the record, I have nothing against Django (I haven’t used it since version 1.4), I just much prefer the control you get with the micro frameworks (is that still a term?) like Flask or more recently FastAPI.
However, I also don’t like spending hours or more tinkering with config or dependencies whenever I want to build a new app. In the same vein of DHH’s Omakub, I have my batteries included base project that should just work for any new app I build.
This includes some patterns and libraries I tend to use whenever I spin up a new project.
What’s in the box? Link to heading
The highlights include:
- uv for dependency managment.
- mise for tasks and (optional) auto-shimming the venv.
- FastAPI for the web framework.
- SQLAlchemy 2.x with SQLModel, full asyncio support.
- Postgres for a database.
- Alembic for migrations.
- Environment specific config.
- Preconfigured Dockerfile for building the app.
- docker-compose for local dev.
- Black and ruff for linting.
- Import linter to avoid circular imports.
- pytest with full asyncio support.
- Testcontainers for a throwaway db in tests.
- integration and unit test isolation. integration tests use a real postgres database, and each test gets a fresh, empty db with all migrations setup (and it’s fast, via db copying, not re-running migrations every time).
Extras Link to heading
UnitOfWork and Repositories Link to heading
The Repository pattern is well established in the industry, and I have a lightweight version setup to abstract away the database interactions.
The Unit of Work pattern is less prominent, but something I have recently adopted, as it works nice with repositories. My hybrid version is not true to Martin Fowler’s original definition, in that it does not span multiple sessions or transactions, rather it’s a way to group together a set of database operations. It results in a more functional paradigm, creating the unit of work at an entry-point to the applicaiton (http request, cli command, ..), and passing that down to calls. This works very well with async code, as it now becomes explicit which database session you are working with.
Both of these are included, but can be easily remove if they’re not your thing.