| name | backend-api-testing |
| description | Expert skill for testing and debugging the FastAPI backend. Use when working with API endpoints, database operations, authentication, or middleware troubleshooting. Use when this capability is needed. |
| metadata | {"author":"ahmedarafa994"} |
Backend API Testing Skill
Overview
This skill provides expertise in testing, debugging, and developing the Chimera FastAPI backend, including API endpoints, database operations, authentication flows, and middleware configuration.
When to Use This Skill
- Testing API endpoints (CRUD operations, transformations, generation)
- Debugging authentication/authorization issues
- Investigating database connection or query problems
- Troubleshooting middleware (rate limiting, CORS, security headers)
- Running pytest test suites
- Analyzing backend logs and error traces
Technology Stack
Core Framework
- FastAPI 0.104+: Modern async Python web framework
- Pydantic V2: Data validation with new
pattern, min_length syntax
- SQLAlchemy: ORM for database operations
- SQLite: Default development database (with
check_same_thread considerations)
Key Dependencies
fastapi = "^0.104.0"
uvicorn = "^0.24.0"
pydantic = "^2.5.0"
sqlalchemy = "^2.0.23"
httpx = "^0.25.0"
pytest = "^7.4.3"
pytest-asyncio = "^0.21.1"
Project Structure
backend-api/
├── app/
│ ├── api/
│ │ └── v1/
│ │ ├── api.py # Router registration
│ │ └── endpoints/ # API route handlers
│ │ ├── auth.py # Authentication
│ │ ├── generate.py # Content generation
│ │ ├── transform.py # Prompt transformations
│ │ ├── aegis.py # Aegis campaigns
│ │ └── aegis_ws.py # WebSocket telemetry
│ ├── core/
│ │ ├── config.py # Configuration management
│ │ ├── security.py # API keys, CORS, headers
│ │ └── database.py # DB session management
│ ├── middleware/
│ │ ├── rate_limit.py # Rate limiting
│ │ ├── selection.py # Model/provider selection
│ │ └── validation.py # Input sanitization
│ ├── models/ # SQLAlchemy models
│ ├── schemas/ # Pydantic schemas
│ └── main.py # FastAPI application entry
├── tests/ # Test suites
└── logs/ # Application logs
Common Testing Commands
Run All Tests with Coverage
cd backend-api
poetry run pytest --cov=app --cov-report=html --cov-report=term-missing
open htmlcov/index.html
Run Specific Test Files
poetry run pytest tests/test_auth.py -v
poetry run pytest tests/test_api_endpoints.py -v
poetry run pytest tests/test_deepteam_security.py -m "security or owasp" -v
Run Backend Server (Development)
npm run dev:backend
cd backend-api
poetry run uvicorn app.main:app --reload --port 8001 --log-level debug
Health Checks
curl http://localhost:8001/health
open http://localhost:8001/docs
open http://localhost:8001/redoc
Common Issues and Solutions
1. Login Endpoint Hangs (httpx.ReadTimeout)
Symptom: /api/v1/auth/login returns 504 timeout
Root Cause: Database write lock in SQLite, often from SelectionMiddleware
Solutions:
engine = create_engine(
DATABASE_URL,
connect_args={"check_same_thread": False},
poolclass=StaticPool
)
if request.url.path.startswith("/api/v1/auth"):
return await call_next(request)
Debugging:
export LOG_LEVEL=DEBUG
poetry run uvicorn app.main:app --reload --log-level debug
2. Pydantic V2 Migration Errors
Symptom: AttributeError: 'BaseModel' has no attribute 'regex' or 'min_items'
Root Cause: Deprecated Pydantic V1 syntax used in V2
Fixes:
from pydantic import BaseModel
class MySchema(BaseModel):
email: str = Field(..., regex=r'^[\w\.-]+@[\w\.-]+\.\w+$')
tags: List[str] = Field(..., min_items=1)
from pydantic import BaseModel, Field
class MySchema(BaseModel):
email: str = Field(..., pattern=r'^[\w\.-]+@[\w\.-]+\.\w+$')
tags: List[str] = Field(..., min_length=1)
3. ImportError for API_KEY_NAME_MAP
Symptom: ImportError: cannot import name 'API_KEY_NAME_MAP' from 'app.core.config'
Root Cause: Missing or incorrectly named constant in config.py
Fix:
API_KEY_NAME_MAP = {
"google": "GOOGLE_API_KEY",
"openai": "OPENAI_API_KEY",
"anthropic": "ANTHROPIC_API_KEY",
"deepseek": "DEEPSEEK_API_KEY"
}
4. 404 Errors for New Endpoints
Symptom: 404 Not Found for newly created endpoints
Root Cause: Router not registered in api.py
Fix:
from app.api.v1.endpoints import (
auth, generate, transform, aegis, aegis_ws, sessions, techniques
)
api_router = APIRouter()
api_router.include_router(auth.router, prefix="/auth", tags=["auth"])
api_router.include_router(aegis.router, prefix="/aegis", tags=["aegis"])
api_router.include_router(aegis_ws.router, prefix="/ws/aegis", tags=["websockets"])
5. CORS Errors from Frontend
Symptom: Browser console shows CORS policy errors
Fix:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3001", "http://localhost:3001"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Testing Best Practices
1. Use Fixtures for Database Setup
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
@pytest.fixture
def test_db():
engine = create_engine("sqlite:///:memory:")
TestingSessionLocal = sessionmaker(bind=engine)
yield TestingSessionLocal()
2. Mock External API Calls
from unittest.mock import AsyncMock, patch
@pytest.mark.asyncio
async def test_generate_endpoint():
with patch("app.services.llm.call_api", new_callable=AsyncMock) as mock_call:
mock_call.return_value = {"content": "Test response"}
3. Test Authentication Flows
def test_login_success(client):
response = client.post("/api/v1/auth/login", json={
"email": "test@example.com",
"password": "secure_password"
})
assert response.status_code == 200
assert "access_token" in response.json()
4. Test Rate Limiting
def test_rate_limit_exceeded(client):
for _ in range(101):
response = client.get("/api/v1/generate")
assert response.status_code == 429
Debugging Techniques
1. Enable Debug Logging
import logging
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
2. Add Request/Response Logging Middleware
from starlette.middleware.base import BaseHTTPMiddleware
class LoggingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
logger.debug(f"Request: {request.method} {request.url}")
response = await call_next(request)
logger.debug(f"Response: {response.status_code}")
return response
3. Use Pytest Verbose Flags
poetry run pytest -vv --tb=short
poetry run pytest -s
poetry run pytest -x
4. Inspect Database State
def test_campaign_created(test_db):
campaign = test_db.query(Campaign).first()
assert campaign is not None
assert campaign.status == "pending"
Performance Optimization
1. Use Async Database Queries
from sqlalchemy.ext.asyncio import AsyncSession
async def get_campaigns(db: AsyncSession):
result = await db.execute(select(Campaign))
return result.scalars().all()
2. Implement Caching
from functools import lru_cache
@lru_cache(maxsize=128)
def get_model_config(provider: str, model: str):
pass
3. Connection Pooling
engine = create_engine(
DATABASE_URL,
pool_size=20,
max_overflow=10,
pool_pre_ping=True
)
OpenAPI Schema Validation
cd backend-api
poetry run python -c "from app.main import app; import json; print(json.dumps(app.openapi(), indent=2))" > openapi.json
npx @apidevtools/swagger-cli validate openapi.json
References
Converted and distributed by TomeVault — claim your Tome and manage your conversions.