Your First Project
This guide walks through creating a complete project with authentication, demonstrating the key features Forge provides.
Creating the Project
Start by running the init command:
forge init
For this example, we’ll make the following choices:
Question |
Choice |
|---|---|
Project name |
|
Database |
PostgreSQL |
ORM |
SQLModel |
Enable migrations |
Yes |
Authentication |
Complete JWT Auth |
Redis |
Yes |
Celery |
Yes |
CORS |
Yes |
Dev tools |
Yes |
Testing |
Yes |
Docker |
Yes |
Understanding the Generated Code
Entry Point: main.py
The app/main.py file is the FastAPI application entry point. It handles:
Application lifecycle (startup/shutdown)
Database connection initialization
Redis connection (if enabled)
CORS middleware configuration
Router registration
Global exception handlers
The lifespan function manages resource initialization:
async def lifespan(_app: FastAPI):
# Startup: Initialize connections
await db_manager.initialize()
await redis_manager.initialize_async()
yield # Application runs here
# Shutdown: Close connections
await db_manager.close()
await redis_manager.close()
Configuration: Settings
The app/core/config/settings.py aggregates all configuration modules using lazy loading:
class Settings:
@cached_property
def app(self) -> AppSettings:
return AppSettings()
@cached_property
def database(self) -> DatabaseSettings:
return DatabaseSettings()
# ... other settings
Each settings module reads from environment variables defined in secret/.env.development.
Database Models
With Complete JWT Auth, Forge generates a User model in app/models/user.py:
class User(SQLModel, table=True):
__tablename__ = "users"
id: Optional[int] = Field(default=None, primary_key=True)
username: str = Field(unique=True, index=True)
email: str = Field(unique=True, index=True)
hashed_password: str
is_active: bool = Field(default=True)
is_verified: bool = Field(default=False) # Email verification
is_superuser: bool = Field(default=False)
created_at: datetime
updated_at: datetime
last_login_at: Optional[datetime]
Authentication Flow
The Complete JWT Auth includes:
Registration (
POST /api/v1/auth/register): Creates user, sends verification emailEmail Verification (
POST /api/v1/auth/verify-email): Verifies email with codeLogin (
POST /api/v1/auth/login): Returns access and refresh tokensToken Refresh (
POST /api/v1/auth/refresh): Gets new access tokenPassword Reset (
POST /api/v1/auth/forgot-password,POST /api/v1/auth/reset-password)Logout (
POST /api/v1/auth/logout,POST /api/v1/auth/logout-all)
Setting Up the Database
Configure Environment
Edit secret/.env.development with your database credentials:
DATABASE_URL=postgresql+asyncpg://postgres:password@localhost:5432/blog_api
Create the Database
Create the database in PostgreSQL:
createdb blog_api
Run Migrations
Generate and apply the initial migration:
# Generate migration
alembic revision --autogenerate -m "Initial migration"
# Apply migration
alembic upgrade head
Running the Application
Development Mode
uv run uvicorn app.main:app --reload
With Docker
For a complete environment including PostgreSQL and Redis:
docker-compose up -d
This starts:
Your FastAPI application
PostgreSQL database
Redis server
Celery worker and beat (if enabled)
Automatic database migrations
Testing the API
Register a User
curl -X POST http://localhost:8000/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "testuser",
"email": "test@example.com",
"password": "SecurePass123!"
}'
Login
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "SecurePass123!"
}'
Response includes access_token and refresh_token.
Access Protected Endpoint
curl http://localhost:8000/api/v1/users/me \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Running Tests
If you enabled testing, run the test suite:
uv run pytest
Tests use an in-memory SQLite database, so they don’t affect your development database.
Next Steps
Now that you have a working project:
Configuration: Customize your project settings
Database: Learn about database operations
Authentication: Understand the auth system in detail
Deployment: Deploy to production