🚀
2. Project Setup
++++
Engineering
Apr 2026×12 min read

From a fresh clone to a running server — dependencies, database bootstrap, environment configuration, and the release gates that protect you.

2. Project Setup

Driptanil Datta
Driptanil DattaSoftware Developer

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 install

That 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.py

scripts/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 --reload

The --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=false

The 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 dependencies

ruff 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.

Drip

Driptanil Datta

Software Developer

Building full-stack systems, one commit at a time. This blog is a centralized learning archive for developers.

Legal Notes
Disclaimer

The content provided on this blog is for educational and informational purposes only. While I strive for accuracy, all information is provided "as is" without any warranties of completeness, reliability, or accuracy. Any action you take upon the information found on this website is strictly at your own risk.

Copyright & IP

Certain technical content, interview questions, and datasets are curated from external educational sources to provide a centralized learning resource. Respect for original authorship is maintained; no copyright infringement is intended. All trademarks, logos, and brand names are the property of their respective owners.

System Operational

© 2026 Driptanil Datta. All rights reserved.