Skip to content

Generated files

Every file generated by bluefox init is documented here.

main.py

The application entry point. Uses the bluefox-core app factory:

from bluefox_core import BluefoxSettings, create_bluefox_app


def create_app() -> object:
    settings = BluefoxSettings()
    return create_bluefox_app(settings, welcome=True)


app = create_app()

welcome=True enables the interactive welcome page at / with system status badges and a message playground. Remove it when you're ready to use your own root route. The create_app factory is also used by bluefox-test to spin up the app during testing.

items/ (example module)

A starter module demonstrating the auto-discovery convention:

items/
  __init__.py
  api.py          # Router auto-mounted at /items
  models.py       # Item model auto-discovered

items/api.py:

from fastapi import APIRouter

router = APIRouter()


@router.get("/")
async def list_items():
    return {"items": []}

items/models.py:

from sqlalchemy import Column, Integer, String
from bluefox_core import BluefoxBase


class Item(BluefoxBase):
    __tablename__ = "items"

    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)

bluefox-core auto-discovers */api.py files and mounts their router at /{dirname}. Models in */models.py are auto-imported so they register in BluefoxBase.metadata. No manual imports needed.

models.py

Root-level models file. Auto-discovered by bluefox-core. Add models here or in module directories (e.g., items/models.py).

.env and .env.example

.env has dev defaults filled in (DEBUG=true, LOG_LEVEL=DEBUG, local Postgres URL). .env.example is the template for production with placeholder values.

Both contain all BluefoxSettings fields:

APP_NAME=myapp
ENVIRONMENT=development
DEBUG=true
LOG_LEVEL=DEBUG
SECRET_KEY=dev-secret-key
DATABASE_URL=postgresql://myuser:mypass@localhost:5432/myapp
REDIS_URL=

Makefile

Target Description
make dev Start Postgres + run migrations + app with --reload
make dev-down Stop all dev containers
make run Run the app directly (no Docker)
make migrate Apply pending migrations
make migrate-make name=... Generate a new migration
make test Run the test suite

Dockerfile

Multi-stage build optimized for uv:

  1. Build stage — installs dependencies with uv sync --frozen, copies source
  2. Runtime stage — slim Python image, non-root user, health check via curl

docker-compose.yml

Production compose file:

  • migrate service runs alembic upgrade head then exits
  • app service depends on migrate completing successfully
  • Both connect to dokploy-network: external: true
  • Health check hits /health every 30 seconds

docker-compose.dev.yml

Dev overrides that layer on top of the production compose:

  • Adds a local Postgres 17 container with health checks
  • Sets DATABASE_URL to point at the local database
  • Mounts source files and module directories for hot reload
  • Overrides the network to a local bridge (no external dokploy-network needed)

alembic.ini

Standard Alembic config with script_location = migrations. The sqlalchemy.url is intentionally not set here — it comes from DATABASE_URL via migrations/env.py.

migrations/env.py

One-line configuration using bluefox-core:

from alembic import context
from bluefox_core.migrations import configure_alembic

configure_alembic(context)

configure_alembic() reads DATABASE_URL, imports your models, and sets up both online and offline migration modes.

tests/conftest.py

Wires up all bluefox-test fixtures:

from bluefox_test import bluefox_test_setup
from bluefox_core import BluefoxBase

globals().update(bluefox_test_setup(base=BluefoxBase, app_factory="main:create_app"))

This gives you client, db_session, and factory fixtures. Models are auto-discovered by bluefox-core — no manual imports needed.

tests/test_health.py

A smoke test that verifies the /health endpoint:

import pytest


@pytest.mark.asyncio
async def test_health(client):
    response = await client.get("/health")
    assert response.status_code == 200
    data = response.json()
    assert data["status"] == "ok"