++++From a fresh clone to a running server — dependencies, database bootstrap, environment configuration, and the release gates that protect you.
2. Project Setup
Getting the Project Running
The project uses Poetry (opens in a new tab) for dependency management. Once you have it installed, getting everything in place is a single command:
poetry installThat installs the main dependencies along with the dev tools — ruff for linting, pytest and pytest-asyncio for tests, bandit for static security analysis, and pip-audit for CVE scanning. All of them are defined in pyproject.toml so there's no hidden setup.
Before starting the server, the database needs to be initialized. The migration runner handles this:
poetry run python scripts/init_db.pyscripts/init_db.py calls the async migration runner, which applies every registered migration in order. This means your local database always starts from the same baseline as CI and staging — repeatable by design.
Once that's done, spin up the server:
poetry run uvicorn app.server:app --port 3100 --reloadThe --reload flag enables hot reload for development. The entry point app/server.py calls create_app() from server/api/src/main.py, which wires up the database, services, middleware, and routes.
Configuring the Environment
The template ships with safe-for-development defaults, but every security-sensitive value is read from environment variables. Before running in production, these need to be set explicitly:
AUTH_SECRET=<64-char-random-secret>
AUTH_EXPIRES_MINUTES=60
AUTH_BASIC_EMAIL=admin@example.com
AUTH_BASIC_PASSWORD=<long-random-password>
AUTH_BASIC_NAME=Admin User
LOG_LEVEL=INFO
LOG_JSON=true
LOG_DIAGNOSE=falseThe AuthService reads all of these at initialization time:
# server/api/src/services/auth_service.py
self._jwt_secret = os.getenv("AUTH_SECRET", "default_secret")
self._jwt_exp_minutes = int(os.getenv("AUTH_EXPIRES_MINUTES", "1440"))The fallbacks ("default_secret", "admin123") are intentionally weak — they're meant to be obvious in development, not workable in production. If you ship with AUTH_SECRET=default_secret, the JWT tokens your server issues can be forged by anyone who reads this codebase.
The Hard-Coded Secret Problem
This is the most common setup mistake in FastAPI projects:
# What not to do
JWT_SECRET = "prod-secret"
DEFAULT_PASSWORD = "admin123"Putting secrets in source code means they end up in git history, CI logs, and anywhere the repo is cloned. Even if you rotate them later, the old values are permanent in the commit log. Reading from environment variables at runtime keeps secrets out of source control entirely and lets you manage them through your deployment platform's secret store.
Quality Gates That Should Be Mandatory
The template includes four tools that should run before every merge or deploy. Running pytest alone is not enough:
poetry run ruff check . # linting and formatting
poetry run python -m pytest # unit and integration tests
poetry run bandit -r server # static security analysis
poetry run pip-audit # CVE scan on all dependenciesruff catches code quality issues that tests won't. bandit looks for common Python security mistakes like subprocess shell injection or weak hash usage. pip-audit checks your entire dependency tree against known vulnerability databases. Together they cover the gaps that unit tests leave.
None of these are expensive. On this codebase each runs in seconds. The cost of skipping them occasionally is that a known vulnerability or injectable config ends up in production — and you find out after the fact.
Run them frequently during development, and automate them in CI so they're never optional.