This project is a starter project for FastAPI projects. It helps start a standard FastAPI API from an OpenAPI contract.
The starter OpenAPI specification is available in openapi.yaml.
It defines:
GET /helloGET /healthGET /readyGET /liveGET /startup
The probe endpoints are suitable for Kubernetes health, readiness, liveness, and startup checks.
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
fastapi dev app/src/main.pyThe API will be available at http://localhost:8000.
pytestConfiguration lives in:
app/src/config/settings.py
It uses pydantic-settings to load values from environment variables and an
optional .env file.
Example:
APP_NAME="My API"
APP_VERSION="1.2.3"
ENVIRONMENT="dev"
APP_LOG_LEVEL=DEBUGUse configuration in application code through:
from config import get_settings
settings = get_settings()The FastAPI app reads its title, version, and description from this configuration.
Logging is configured in:
app/src/config/logging.py
main.py creates one application logger named fastapi_template. Application
modules should create child loggers through:
from config import get_logger
logger = get_logger(__name__)The log level is controlled with APP_LOG_LEVEL, which is convenient for Docker
or Kubernetes environment configuration:
environment:
APP_LOG_LEVEL: DEBUGWhen openapi.yaml changes, regenerate the FastAPI contract code:
python scripts/generate_contract.pyThis uses the official OpenAPI Generator python-fastapi server generator. It generates:
app/src/generated/generated/apis/<tag>_api.pyapp/src/generated/apis/<tag>_api.pyapp/src/generated/apis/<tag>_api_base.pyapp/src/generated/models/*.py
The handwritten controller implements the generated Base*Api classes.
The official python-fastapi generator discovers endpoint implementations by
importing modules inside its generated implementation package:
app/src/generated/impl/
The generator script creates this bridge file:
app/src/generated/impl/default_controller.py
It only imports the handwritten controller:
from controllers.default_controller import DefaultControllerThis import registers DefaultController as a subclass of the generated
BaseDefaultApi and BaseProbesApi classes. The generated routers then call
that implementation.
This keeps generated code separate from handwritten code:
- generated contract code stays under
app/src/generated - handwritten implementation stays under
app/src/controllers - generated files can be recreated from
openapi.yamlwithout overwriting the controller implementation