What generating a FastAPI app from requirements produces
Archiet's Blueprint Wizard structures your requirements into entities, user stories, and acceptance criteria, then generates a FastAPI codebase specific to your product:
app/
├── main.py # FastAPI entry point; middleware, exception handlers, CORS
├── database.py # Async SQLAlchemy engine + session factory
├── dependencies.py # get_current_user, get_db, require_workspace
├── config.py # reads os.getenv(); raises on missing DATABASE_URL or SQLite
├── routers/
│ ├── auth.py # POST /auth/register, /auth/login, /auth/logout, /auth/refresh
│ ├── users.py # GET /users/me; PATCH /users/me
│ ├── billing.py # Stripe webhook + subscription endpoints
│ └── {entity}.py # Full CRUD + list with pagination per entity
├── models/
│ ├── user.py # User, Role, Workspace, Invitation (SQLAlchemy async models)
│ └── {entity}.py # One model file per entity
├── schemas/
│ ├── auth.py # LoginRequest, RegisterRequest, TokenResponse
│ └── {entity}.py # CreateSchema, UpdateSchema, ResponseSchema per entity
├── services/
│ ├── auth_service.py # JWT cookie issuance; bcrypt via passlib
│ └── {entity}_service.py # Async service; all queries filter by workspace_id
└── alembic/
└── versions/ # One revision per schema change
FastAPI-specific patterns Archiet gets right
Async SQLAlchemy sessions via Depends(get_db). Every route that touches the database receives an AsyncSession via dependency injection. No synchronous ORM calls in an async context. The session pattern is consistent across every generated router:
@router.get("/orders", response_model=list[OrderResponse])
async def list_orders(
page: int = 1,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
result = await db.execute(
select(Order)
.where(Order.workspace_id == current_user.active_workspace_id)
.order_by(Order.created_at.desc())
.offset((page - 1) * 25)
.limit(25)
)
return result.scalars().all()
Pydantic v2 schemas for every request and response. Request bodies are validated before reaching the service layer. Response schemas control exactly what is serialized — no accidental password hash leaks, no internal field exposure.
Depends(get_current_user) on every protected route. No route is accidentally left unprotected. The dependency raises HTTPException(401) when the cookie is absent or invalid, HTTPException(403) when the user lacks the required role.
Multi-tenant row filtering at the service level. Every service function filters by workspace_id. The dependency injection pattern ensures workspace_id is always resolved from the authenticated user — never from a URL parameter that can be tampered with.
JWT in httpOnly cookies. Access and refresh tokens are issued as httpOnly; Secure; SameSite=Lax cookies. No localStorage.setItem anywhere in the generated codebase. The frontend sends cookies automatically; the backend reads them via request.cookies.
PostgreSQL + async SQLAlchemy. SQLite is not supported. The generated config.py raises RuntimeError if DATABASE_URL is absent or points to SQLite. Async SQLAlchemy requires PostgreSQL (asyncpg driver).
What is included beyond the FastAPI backend
- Next.js frontend — all screens from your screen manifest (auth flow, dashboard, settings, billing, entity CRUD, onboarding, forgot-password, verify-email)
- React Native / Expo mobile app — App Store compliance files included
- Docker — multi-stage Dockerfile +
docker-compose.yml(FastAPI + Uvicorn + PostgreSQL + Redis + Nginx) - GitHub Actions CI/CD — ruff lint → pytest (async) → build → deploy pipeline
- Architecture docs — ADRs for every material technical decision under
docs/decisions/ - Compliance docs — GDPR DPIA, HIPAA risk assessment, PCI scope statement (when compliance flags set in genome)
- Quality gate — ARCHVERIFY blocks delivery below 80/100 quality score
FastAPI vs Flask: which to pick
Both are supported by Archiet. The practical choice:
-
Choose FastAPI when: you need async performance (real-time features, high concurrency, streaming responses), you want native automatic OpenAPI docs (Swagger UI + ReDoc at
/docsand/redoc), your team uses Python type hints consistently, or you're building an API-first product where the OpenAPI spec is the primary contract. -
Choose Flask when: your team knows Flask and the extension ecosystem, you want synchronous request-per-thread behaviour, or you're building a server-rendered web application with a Next.js frontend and the async complexity is overhead rather than benefit.
Both generate identical frontend, mobile, and infrastructure files. The choice only affects the backend language.
FAQ
Does the generated FastAPI app use SQLAlchemy sync or async?
Async SQLAlchemy (with asyncpg driver) by default. Every database call in the generated service layer uses await db.execute(select(...)) patterns. Synchronous SQLAlchemy is not generated — it would block the FastAPI event loop.
Does Archiet generate FastAPI with Alembic migrations?
Yes. Every schema change has an Alembic migration file. The generated alembic/env.py reads DATABASE_URL from the environment and raises if absent. No Base.metadata.create_all() calls.
Does the generated app include automatic OpenAPI documentation?
FastAPI generates /docs (Swagger UI) and /redoc automatically from the route signatures and Pydantic schemas. Archiet also generates a standalone openapi.yaml file for integration with API gateway tools, testing frameworks, and client SDK generators.
What database is used?
PostgreSQL with the asyncpg async driver. SQLite is not supported — the generated code uses asyncpg-specific patterns that SQLite cannot run.
How long does generation take?
Typically 60-120 seconds for a complete blueprint.