# Web Backend Agent Guide ## Overview FastAPI backend for BtToxin Pipeline - provides REST API for task submission, status monitoring, and result retrieval. ## Tech Stack - **Framework**: FastAPI - **Validation**: Pydantic + pydantic-settings - **Storage**: Redis (cache) + File system (persistence) - **Testing**: pytest - **ASGI Server**: Uvicorn ## Project Structure ``` web/backend/ ├── __init__.py # Package marker ├── main.py # FastAPI application entry point ├── config.py # Configuration and system constraints ├── models.py # Data models (TaskStatus, TaskMeta, etc.) └── storage.py # Redis + file hybrid storage ``` ## Development Commands ### Via pixi (recommended) ```bash # Start development server with hot reload pixi run api-dev # Run tests pixi run api-test ``` ### Direct commands ```bash # Start server uvicorn web.backend.main:app --reload --host 0.0.0.0 --port 8000 # Run tests pytest web/backend/ -v ``` ## API Endpoints ### Health Check ``` GET /api/health Response: {"status": "healthy"} ``` ### API Documentation When `DEBUG=true`: - Swagger UI: http://localhost:8000/api/docs - ReDoc: http://localhost:8000/api/redoc ## Data Models ### TaskStatus (Enum) ```python PENDING = "pending" # Waiting to be processed QUEUED = "queued" # In queue, waiting for slot RUNNING = "running" # Currently executing COMPLETED = "completed" # Successfully finished FAILED = "failed" # Execution failed ``` ### PipelineStage (Enum) ```python DIGGER = "digger" # Running BtToxin_Digger SHOTER = "shoter" # Running Shoter scoring PLOTS = "plots" # Generating heatmap plots BUNDLE = "bundle" # Bundling results ``` ### TaskMeta (Dataclass) Task metadata stored in Redis and `task_meta.json`: | Field | Type | Description | |-------|------|-------------| | task_id | str | Unique task identifier | | status | TaskStatus | Current execution status | | current_stage | PipelineStage | Current pipeline stage | | progress | int | Progress percentage (0-100) | | submission_time | str | ISO8601 timestamp | | start_time | str | ISO8601 timestamp | | completion_time | str | ISO8601 timestamp | | filename | str | Original uploaded filename | | file_size | int | File size in bytes | | lang | str | Report language (en/zh) | | error_message | str | Error description if failed | | token_hash | str | SHA256 hash for auth | ## Storage Strategy Hybrid Redis + file storage: - **Primary**: `/data/jobs//task_meta.json` (persistent) - **Cache**: Redis `task:{task_id}:meta` (fast access) - **Write order**: File first, then Redis - **Read order**: Redis first, file on cache miss ## Configuration Environment variables (see `config.py`): | Variable | Default | Description | |----------|---------|-------------| | REDIS_URL | redis://localhost:6379/0 | Redis connection | | JOBS_DIR | /data/jobs | Task storage directory | | TASK_TIMEOUT | 21600 | Task timeout (6 hours) | | MAX_ACTIVE_PIPELINES | 4 | Max concurrent tasks | | TASK_THREADS | 4 | Threads per task | | CORS_ORIGINS | * | Allowed CORS origins | | DEBUG | false | Enable debug mode | ## System Constraints Defined in `SystemConstraints` class: - Max upload size: 50 MB - Min free disk: 20 GB - Task timeout: 6 hours - Result retention: 30 days - Allowed extensions: .fna, .fa, .fasta ## Testing ```bash # Run all backend tests pixi run api-test # Run with verbose output pytest web/backend/ -v # Run specific test file pytest web/backend/test_storage.py -v ``` ## CORS Configuration CORS is configured to allow frontend access. Set `CORS_ORIGINS` environment variable for production: ```bash CORS_ORIGINS=https://example.com,https://app.example.com ```