Web Module — Architecture & Deployment¶
The web/ module is the FastAPI-based REST API layer of the Autograder system. It handles HTTP requests, persists grading configurations and submissions to a database, and delegates actual grading to the core autograder pipeline via background tasks.
For endpoint reference, see API Documentation.
Architecture¶
The web module follows a clean layered architecture:
Client Request
↓
Endpoint (web/api/v1/) → Route handlers, request validation
↓
Schema (web/schemas/) → Pydantic models for request/response
↓
Repository (web/repositories/) → Data access layer (SQLAlchemy)
↓
Database (PostgreSQL/SQLite) → Persistence
↓ (async)
Service (web/service/) → Business logic, grading orchestration
↓
Autograder Pipeline → Core grading engine
↓
Sandbox Manager → Docker container execution
Key Design Decisions¶
- Async throughout: All database operations and grading use
async/awaitvia SQLAlchemy's async engine andasyncio - Background grading: Submissions are saved immediately, grading runs as an
asyncio.create_taskso the API responds without blocking - Repository pattern: Database access is abstracted behind repository classes, keeping endpoint handlers thin
- Stateless DCE: The Deliberate Code Execution feature bypasses the database entirely for fast, stateless code execution
Configuration¶
Environment Variables¶
| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
Database connection string | postgresql+asyncpg://...localhost:5432/autograder |
DATABASE_ECHO |
Log SQL queries | False |
DATABASE_POOL_SIZE |
Connection pool size (PostgreSQL only) | 10 |
DATABASE_MAX_OVERFLOW |
Max overflow connections | 20 |
DATABASE_POOL_TIMEOUT |
Connection timeout (seconds) | 30 |
DATABASE_POOL_RECYCLE |
Connection recycle time (seconds) | 3600 |
SANDBOX_POOL_SIZE |
Sandbox containers per language | 2 |
JSON_LOGS |
Use JSON logging format | false |
OPENAI_API_KEY |
OpenAI API key (for AI feedback mode) | — |
Database Setup¶
PostgreSQL (Recommended for Production)¶
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/autograder
Connection pool sizing guidelines:
| Environment | POOL_SIZE |
MAX_OVERFLOW |
|---|---|---|
| Development | 5 | 10 |
| Production (low traffic) | 10 | 20 |
| Production (high traffic) | 20 | 40 |
SQLite (Development Only)¶
DATABASE_URL=sqlite+aiosqlite:///./autograder.db
Note: SQLite lacks concurrent write support and connection pooling — not recommended for production.
Database Migrations¶
# Apply all pending migrations
make db-upgrade
# Create a new migration
make db-migrate MSG="description of change"
# Show current version
make db-current
# Rollback last migration
make db-downgrade
# Reset database (destructive)
make db-reset
Or using Alembic directly:
alembic upgrade head # Apply migrations
alembic revision --autogenerate -m "description" # Create migration
alembic downgrade -1 # Rollback
alembic current # Current version
Deployment¶
Docker Compose¶
docker-compose up -d
This starts PostgreSQL and the Autograder API with sandbox support.
Manual¶
# Development
uvicorn web.main:app --reload
# Production
uvicorn web.main:app --host 0.0.0.0 --port 8000
API docs available at http://localhost:8000/docs (Swagger) and http://localhost:8000/redoc (ReDoc).
Troubleshooting¶
Database Connection Issues¶
- PostgreSQL: Verify
DATABASE_URLincludes thepostgresql+asyncpg://prefix. Check the server is running (docker psorpg_isready). Ensure migrations are up to date (alembic current). - SQLite: Verify file path and directory permissions.
- Pool exhaustion: Reduce
DATABASE_POOL_SIZE/DATABASE_MAX_OVERFLOW, or increaseDATABASE_POOL_TIMEOUT. EnableDATABASE_ECHO=Truetemporarily to monitor pool activity.
Sandbox Issues¶
- Verify Docker is running:
docker ps - Build sandbox images:
make sandbox-build-all - Adjust pool size:
SANDBOX_POOL_SIZEenvironment variable
API Not Starting¶
- Check logs for startup errors
- Verify dependencies:
pip install -r requirements.txt - Ensure port 8000 is available