FastAPI Application Skill Overview Expert guidance for building FastAPI backend applications with route decorators, dependency injection, CORS configuration, and Pydantic v2 validation. Supports ERP endpoints for students, fees, attendance, and authentication. When This Skill Applies This skill triggers when users request: - App Setup : "Create FastAPI app", "Initialize FastAPI", "Lifespan events" - Routes : "Student endpoint", "API route", "GET/POST handler", "APIRouter" - Dependencies : "DB dependency", "Auth dependency", "Depends()", "JWT auth" - CORS : "CORS enable frontend", "Cross-origi…

)\n\n# Create schema\nclass StudentCreate(StudentBase):\n password: str = Field(..., min_length=8)\n class_id: Optional[str] = None\n\n# Update schema (partial updates)\nclass StudentUpdate(BaseModel):\n model_config = ConfigDict(from_attributes=True)\n\n name: Optional[str] = Field(None, min_length=2, max_length=100)\n email: Optional[EmailStr] = None\n phone: Optional[str] = None\n class_id: Optional[str] = None\n\n# Response schema\nclass StudentResponse(StudentBase):\n id: str\n class_id: Optional[str] = None\n created_at: datetime\n updated_at: datetime\n\n# Pagination response\nclass PaginatedResponse(BaseModel):\n model_config = ConfigDict(from_attributes=True)\n\n data: list[StudentResponse]\n meta: dict = {\n \"total\": 0,\n \"page\": 1,\n \"page_size\": 100,\n \"total_pages\": 1\n }\n```\n\n```python\n# schemas/fees.py\nfrom pydantic import BaseModel, Field\nfrom datetime import datetime\nfrom typing import Optional\nfrom enum import Enum\n\nclass FeeStatus(str, Enum):\n PENDING = \"pending\"\n PAID = \"paid\"\n OVERDUE = \"overdue\"\n WAIVED = \"waived\"\n\nclass FeeBase(BaseModel):\n student_id: str\n amount: float = Field(..., gt=0)\n description: str = Field(..., max_length=500)\n due_date: datetime\n\nclass FeeCreate(FeeBase):\n pass\n\nclass FeeUpdate(BaseModel):\n status: Optional[FeeStatus] = None\n paid_date: Optional[datetime] = None\n notes: Optional[str] = None\n\nclass FeeResponse(FeeBase):\n id: str\n status: FeeStatus\n paid_date: Optional[datetime] = None\n created_at: datetime\n```\n\n**Requirements:**\n- Use Pydantic v2 ConfigDict instead of Config class\n- Field validation with min/max, patterns, gt/lt\n- EmailStr for email validation\n- Enum for status fields\n- Optional fields with defaults\n- From_attributes for ORM compatibility\n\n## Output Requirements\n\n### Code Files\n\n1. **Main Application**:\n - `main.py` - FastAPI app initialization\n - `config.py` - Settings and environment variables\n\n2. **Routers**:\n - `routers/__init__.py`\n - `routers/students.py`\n - `routers/fees.py`\n - `routers/attendance.py`\n - `routers/auth.py`\n\n3. **Dependencies**:\n - `dependencies/__init__.py`\n - `dependencies/database.py`\n - `dependencies/auth.py`\n\n4. **Models and Schemas**:\n - `models/__init__.py`\n - `models/student.py`\n - `schemas/__init__.py`\n - `schemas/student.py`\n - `schemas/fees.py`\n\n### Integration Requirements\n\n- **@api-client**: JSON response formatting for frontend\n- **@auth-integration**: JWT validation\n- **@react-component**: Error response schemas\n\n### Documentation\n\n- **PHR**: Create Prompt History Record for auth/DB decisions\n- **ADR**: Document auth strategy (JWT vs session), DB choice (async SQLAlchemy)\n- **Comments**: Document endpoint purposes and validation rules\n\n## Workflow\n\n1. **Initialize App**\n - Create FastAPI instance with lifespan\n - Configure CORS middleware\n - Set up logging\n\n2. **Setup Database**\n - Create async SQLAlchemy engine\n - Define session dependency\n - Create database models\n\n3. **Create Dependencies**\n - Auth dependency with JWT\n - Role-based access\n - DB session management\n\n4. **Define Schemas**\n - Pydantic v2 models for requests/responses\n - Validation rules\n - Response formatting\n\n5. **Build Routes**\n - Create APIRouter for each domain\n - Implement CRUD operations\n - Add pagination and filtering\n\n6. **Test and Document**\n - Verify Swagger docs\n - Test authentication\n - Validate error responses\n\n## Quality Checklist\n\nBefore completing any FastAPI implementation:\n\n- [ ] **Pydantic v2 Validation**: ConfigDict, Field validators\n- [ ] **SQLAlchemy Async**: Use async sessions, avoid blocking calls\n- [ ] **Rate Limiting**: Implement slowapi or similar for endpoints\n- [ ] **Swagger Docs Auto**: /docs shows all endpoints\n- [ ] **Error Handling**: Proper HTTPException with status codes\n- [ ] **Auth Protected**: All endpoints with dependencies\n- [ ] **Pagination**: skip/limit for list endpoints\n- [ ] **Type Hints**: All functions fully typed\n- [ ] **Environment Config**: Secrets in environment variables\n- [ ] **CORS Config**: Allow frontend origins with credentials\n\n## Common Patterns\n\n### Student Endpoint with Auth\n\n```python\n# routers/students.py\[email protected](\"/students/\", response_model=List[StudentResponse])\nasync def get_students(\n skip: int = Query(0, ge=0),\n limit: int = Query(100, ge=1, le=1000),\n class_id: Optional[str] = None,\n db: AsyncSession = Depends(get_db),\n current_user = Depends(get_current_user),\n):\n \"\"\"Get students with pagination and optional class filter\"\"\"\n query = select(StudentModel)\n\n if class_id:\n query = query.where(StudentModel.class_id == class_id)\n\n query = query.offset(skip).limit(limit).order_by(StudentModel.created_at.desc())\n\n result = await db.execute(query)\n return result.scalars().all()\n```\n\n### CORS Enable Frontend\n\n```python\n# main.py\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\n \"http://localhost:3000\", # Next.js dev\n \"http://localhost:5173\", # Vite dev\n \"https://yourdomain.com\", # Production\n ],\n allow_credentials=True,\n allow_methods=[\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\"],\n allow_headers=[\"Authorization\", \"Content-Type\"],\n)\n```\n\n### DB Dependency with Session\n\n```python\n# dependencies/database.py\nasync def get_db() -> AsyncSession:\n async with async_session_maker() as session:\n try:\n yield session\n await session.commit()\n except Exception:\n await session.rollback()\n raise\n finally:\n await session.close()\n```\n\n### JWT Auth Dependency\n\n```python\n# dependencies/auth.py\nfrom fastapi import Depends, HTTPException, status\nfrom fastapi.security import HTTPBearer\n\noauth2_scheme = HTTPBearer()\n\nasync def get_token_data(token: str = Depends(oauth2_scheme)):\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n return payload\n except JWTError:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Invalid token\"\n )\n```\n\n## Rate Limiting\n\n```python\n# dependencies/rate_limit.py\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\n\nlimiter = Limiter(key_func=get_remote_address)\n\ndef rate_limit(requests: int = 60, seconds: int = 60):\n def decorator(func):\n return limiter.limit(f\"{requests}/{seconds}\")(func)\n return decorator\n\n# Usage\[email protected](\"/students/\")\n@rate_limit(requests=100, seconds=60)\nasync def get_students():\n return {\"message\": \"Students list\"}\n```\n\n## Environment Configuration\n\n```python\n# config.py\nfrom pydantic_settings import BaseSettings\nfrom typing import List\n\nclass Settings(BaseSettings):\n APP_NAME: str = \"ERP API\"\n DEBUG: bool = False\n API_V1_PREFIX: str = \"/api/v1\"\n\n # Database\n DATABASE_URL: str = \"postgresql+asyncpg://user:password@localhost:5432/erp_db\"\n\n # JWT\n JWT_SECRET_KEY: str\n JWT_ALGORITHM: str = \"HS256\"\n ACCESS_TOKEN_EXPIRE_MINUTES: int = 30\n\n # CORS\n CORS_ORIGINS: List[str] = [\"http://localhost:3000\"]\n\n class Config:\n env_file = \".env\"\n env_file_encoding = \"utf-8\"\n\nsettings = Settings()\n```\n\n## Running the Application\n\n```bash\n# Install dependencies\npip install fastapi uvicorn[standard] sqlalchemy[asyncio] asyncpg\npip install python-jose[cryptography] passlib[bcrypt]\npip install slowapi pydantic-settings\n\n# Run development\nuvicorn main:app --reload --host 0.0.0.0 --port 8000\n\n# Run production\nuvicorn main:app --host 0.0.0.0 --port 8000 --workers 4\n```\n\n## References\n\n- FastAPI Documentation: https://fastapi.tiangolo.com\n- Pydantic v2: https://docs.pydantic.dev/latest/\n- SQLAlchemy Async: https://docs.sqlalchemy.org/en/20/orm/extensions/asyncio.html\n- JWT with FastAPI: https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/\n- SlowAPI Rate Limiting: https://pypi.org/project/slowapi/\n---","attachment_filenames":["skill-report.json"],"attachments":[{"filename":"skill-report.json","content":"{\n \"schema_version\": \"2.0\",\n \"meta\": {\n \"generated_at\": \"2026-01-21T16:50:52.362Z\",\n \"slug\": \"awais68-fastapi-app\",\n \"source_url\": \"https://github.com/Awais68/hackathon-2-phase-ii-full-stack-web-app/tree/main/.claude/skills/fastapi-app\",\n \"source_ref\": \"main\",\n \"model\": \"claude\",\n \"analysis_version\": \"3.0.0\",\n \"source_type\": \"community\",\n \"content_hash\": \"2c2548c4a912a53a8e8b3d20ca05cab41453fb361a62e9ead27c2be3fe03dd99\",\n \"tree_hash\": \"bcea66382507125eadb6abe89dc9c51c3cdae3203eb02360ea40bfcf624bf883\"\n },\n \"skill\": {\n \"name\": \"fastapi-app\",\n \"description\": \"Use when creating FastAPI backend applications - route handlers, dependencies, CORS config, or Pydantic models.\\nNOT when frontend logic, non-Python backends, or unrelated server-side code.\\nTriggers: \\\"FastAPI\\\", \\\"student endpoint\\\", \\\"API route\\\", \\\"dependency injection\\\", \\\"CORS\\\", \\\"Pydantic model\\\".\\n\",\n \"summary\": \"Expert guidance for building FastAPI backend applications with route decorators, dependency injection, CORS configuration, and Pydantic v2 validation for ERP systems.\",\n \"icon\": \"📦\",\n \"version\": \"1.0.0\",\n \"author\": \"Awais68\",\n \"license\": \"MIT\",\n \"tags\": [\n \"fastapi\",\n \"python\",\n \"backend\",\n \"api\",\n \"pydantic\"\n ],\n \"supported_tools\": [\n \"claude\",\n \"codex\",\n \"claude-code\"\n ],\n \"risk_factors\": [\n \"scripts\",\n \"filesystem\"\n ]\n },\n \"security_audit\": {\n \"risk_level\": \"low\",\n \"is_blocked\": false,\n \"safe_to_publish\": true,\n \"summary\": \"All static findings are false positives. The skill provides legitimate FastAPI development guidance. Pattern detections (C2 keywords, weak crypto, command execution) are misidentifications of standard code examples and documentation URLs in the SKILL.md file.\",\n \"risk_factor_evidence\": [\n {\n \"factor\": \"filesystem\",\n \"evidence\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 436,\n \"line_end\": 457\n }\n ]\n },\n {\n \"factor\": \"scripts\",\n \"evidence\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 28,\n \"line_end\": 94\n }\n ]\n }\n ],\n \"critical_findings\": [],\n \"high_findings\": [],\n \"medium_findings\": [],\n \"low_findings\": [\n {\n \"title\": \"Documentation references detected as patterns\",\n \"description\": \"Static scanner flagged documentation URLs (fastapi.tiangolo.com, docs.pydantic.dev) as network targets. These are legitimate documentation references in the SKILL.md References section.\",\n \"locations\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 666,\n \"line_end\": 670\n }\n ]\n }\n ],\n \"dangerous_patterns\": [],\n \"files_scanned\": 2,\n \"total_lines\": 1766,\n \"audit_model\": \"claude\",\n \"audited_at\": \"2026-01-21T16:50:52.362Z\"\n },\n \"content\": {\n \"user_title\": \"Build FastAPI Backend Applications\",\n \"value_statement\": \"FastAPI skills help developers create robust Python web APIs with automatic documentation, validation, and dependency injection. This skill provides expert guidance for building production-ready FastAPI applications with route handlers, CORS configuration, and Pydantic v2 models.\",\n \"seo_keywords\": [\n \"FastAPI\",\n \"Python API\",\n \"REST API\",\n \"Pydantic validation\",\n \"API development\",\n \"FastAPI routing\",\n \"dependency injection\",\n \"CORS configuration\",\n \"Claude\",\n \"Codex\",\n \"Claude Code\"\n ],\n \"actual_capabilities\": [\n \"Generate FastAPI application structure with lifespan context manager and logging\",\n \"Create APIRouter endpoints with CRUD operations for students, fees, and attendance\",\n \"Implement JWT authentication with role-based access control\",\n \"Configure CORS middleware for frontend origins and credentials\",\n \"Build Pydantic v2 models with Field validation and ORM compatibility\"\n ],\n \"limitations\": [\n \"Does not generate database migrations or schema changes\",\n \"Does not create frontend React or Vue components\",\n \"Does not set up deployment infrastructure like Docker or CI/CD\",\n \"Does not write unit tests or integration tests\"\n ],\n \"use_cases\": [\n {\n \"title\": \"Backend API Development\",\n \"description\": \"Create new FastAPI endpoints for student management, fee tracking, or attendance systems with proper authentication and validation.\",\n \"target_user\": \"Backend developers building ERP or educational platform APIs\"\n },\n {\n \"title\": \"API Security Implementation\",\n \"description\": \"Add JWT authentication, role-based access control, and secure CORS configuration to existing FastAPI applications.\",\n \"target_user\": \"Developers implementing authentication and authorization\"\n },\n {\n \"title\": \"Data Validation Setup\",\n \"description\": \"Define Pydantic v2 models with field validation, email patterns, and ORM compatibility for API request and response schemas.\",\n \"target_user\": \"API designers setting up data validation layers\"\n }\n ],\n \"prompt_templates\": [\n {\n \"title\": \"Create FastAPI App Structure\",\n \"prompt\": \"Create a FastAPI application with lifespan events, CORS middleware allowing localhost:3000 and localhost:5173, and include routers for /api/v1/auth, /api/v1/students, and /api/v1/fees with proper tags and dependencies.\",\n \"scenario\": \"Initializing a new FastAPI backend project\"\n },\n {\n \"title\": \"Build CRUD Endpoints\",\n \"prompt\": \"Generate APIRouter with GET, POST, PUT, and DELETE endpoints for a student resource. Include pagination with skip/limit, response models using Pydantic, and dependency injection for database session and current user authentication.\",\n \"scenario\": \"Building RESTful CRUD operations for a resource\"\n },\n {\n \"title\": \"Add JWT Authentication\",\n \"prompt\": \"Create dependencies for JWT authentication including create_access_token function, get_current_user dependency with HTTPBearer, and get_admin_user for role-based access control. Use HS256 algorithm and environment variables for secrets.\",\n \"scenario\": \"Implementing authentication and authorization\"\n },\n {\n \"title\": \"Define Pydantic Schemas\",\n \"prompt\": \"Create Pydantic v2 models for a student entity including StudentBase, StudentCreate, StudentUpdate, and StudentResponse. Include Field validators for name length, EmailStr for email, and ConfigDict for ORM compatibility.\",\n \"scenario\": \"Defining data validation and serialization schemas\"\n }\n ],\n \"output_examples\": [\n {\n \"input\": \"Create a FastAPI app with student endpoints\",\n \"output\": [\n \"Generated main.py with FastAPI initialization, CORS configuration, and lifespan events\",\n \"Created routers/students.py with CRUD endpoints and authentication dependencies\",\n \"Added dependencies/database.py for async SQLAlchemy session management\",\n \"Generated Pydantic schemas in schemas/student.py with validation rules\"\n ]\n },\n {\n \"input\": \"Add JWT authentication to the API\",\n \"output\": [\n \"Created dependencies/auth.py with JWT token creation and validation\",\n \"Implemented get_current_user dependency using HTTPBearer scheme\",\n \"Added role-based access control with get_admin_user dependency\",\n \"Configured environment variable loading for JWT_SECRET_KEY\"\n ]\n }\n ],\n \"best_practices\": [\n \"Use async SQLAlchemy sessions with context managers to prevent connection leaks\",\n \"Always return appropriate HTTP status codes (200, 201, 204, 400, 401, 403, 404) for API responses\",\n \"Store secrets in environment variables using os.getenv() with sensible defaults for development\"\n ],\n \"anti_patterns\": [\n \"Do not hardcode secrets or passwords directly in source code files\",\n \"Do not use synchronous database calls in async FastAPI route handlers\",\n \"Do not disable Pydantic validation or omit response models in endpoints\"\n ],\n \"faq\": [\n {\n \"question\": \"What FastAPI features does this skill support?\",\n \"answer\": \"This skill supports FastAPI app initialization, APIRouter for modular routes, dependency injection with Depends(), CORS middleware configuration, Pydantic v2 models, and async SQLAlchemy integration.\"\n },\n {\n \"question\": \"Does this skill generate authentication code?\",\n \"answer\": \"Yes, it generates JWT authentication using python-jose with HS256 algorithm, including token creation, validation dependencies, and role-based access control decorators.\"\n },\n {\n \"question\": \"Can this skill create database models?\",\n \"answer\": \"The skill provides guidance on SQLAlchemy async engine setup and session management. For database models, it generates Pydantic schemas for request/response validation rather than ORM model definitions.\"\n },\n {\n \"question\": \"What validation does Pydantic v2 support?\",\n \"answer\": \"Pydantic v2 supports Field validators for min/max length, EmailStr for email validation, pattern matching with regex, gt/lt for numeric values, and ConfigDict for ORM compatibility.\"\n },\n {\n \"question\": \"How does CORS configuration work?\",\n \"answer\": \"The skill configures CORSMiddleware with allow_origins for specific frontend URLs, allow_credentials for cookies/auth headers, and allow_methods/allow_headers for cross-origin requests.\"\n },\n {\n \"question\": \"Does this skill handle deployment or Docker?\",\n \"answer\": \"No, this skill focuses on application code generation. For deployment, it provides basic uvicorn run commands but does not generate Dockerfiles, docker-compose, or CI/CD configurations.\"\n }\n ]\n },\n \"file_structure\": [\n {\n \"name\": \"SKILL.md\",\n \"type\": \"file\",\n \"path\": \"SKILL.md\",\n \"lines\": 671\n }\n ]\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":10163,"content_sha256":"ba033065c30c423a65429485d7577508a43e3163b6a4177f702f0d115f78bd75"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"FastAPI Application Skill","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"Expert guidance for building FastAPI backend applications with route decorators, dependency injection, CORS configuration, and Pydantic v2 validation. Supports ERP endpoints for students, fees, attendance, and authentication.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When This Skill Applies","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill triggers when users request:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"App Setup","type":"text","marks":[{"type":"strong"}]},{"text":": \"Create FastAPI app\", \"Initialize FastAPI\", \"Lifespan events\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Routes","type":"text","marks":[{"type":"strong"}]},{"text":": \"Student endpoint\", \"API route\", \"GET/POST handler\", \"APIRouter\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dependencies","type":"text","marks":[{"type":"strong"}]},{"text":": \"DB dependency\", \"Auth dependency\", \"Depends()\", \"JWT auth\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CORS","type":"text","marks":[{"type":"strong"}]},{"text":": \"CORS enable frontend\", \"Cross-origin config\", \"credentials\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Models","type":"text","marks":[{"type":"strong"}]},{"text":": \"Pydantic model\", \"Student schema\", \"Fee validation\"","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Rules","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. Init: FastAPI App and Lifespan","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# main.py\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom routers import students, fees, attendance, auth\nfrom dependencies.database import get_db\nfrom dependencies.auth import get_current_user\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n # Startup\n logger.info(\"Starting up FastAPI application...\")\n yield\n # Shutdown\n logger.info(\"Shutting down FastAPI application...\")\n\napp = FastAPI(\n title=\"ERP API\",\n description=\"Educational Resource Planning API\",\n version=\"1.0.0\",\n lifespan=lifespan,\n docs_url=\"/docs\",\n redoc_url=\"/redoc\",\n)\n\n# CORS Configuration\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"http://localhost:3000\", \"http://localhost:5173\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n# Include routers with prefix and tags\napp.include_router(\n auth.router,\n prefix=\"/api/v1/auth\",\n tags=[\"Authentication\"],\n)\n\napp.include_router(\n students.router,\n prefix=\"/api/v1/students\",\n tags=[\"Students\"],\n dependencies=[Depends(get_current_user)],\n)\n\napp.include_router(\n fees.router,\n prefix=\"/api/v1/fees\",\n tags=[\"Fees\"],\n dependencies=[Depends(get_current_user)],\n)\n\napp.include_router(\n attendance.router,\n prefix=\"/api/v1/attendance\",\n tags=[\"Attendance\"],\n dependencies=[Depends(get_current_user)],\n)","type":"text"}]},{"type":"paragraph","content":[{"text":"Requirements:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use FastAPI() with lifespan context manager","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configure CORS for frontend origins","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Include routers with APIRouter","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set up logging for production","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enable Swagger docs at /docs","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. Routes: APIRouter with Tags and Responses","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# routers/students.py\nfrom fastapi import APIRouter, Depends, HTTPException, status\nfrom sqlalchemy.ext.asyncio import AsyncSession\nfrom typing import List, Optional\nfrom pydantic import BaseModel, EmailStr, Field\n\nfrom dependencies.database import get_db\nfrom dependencies.auth import get_current_user, get_admin_user\nfrom models.student import Student as StudentModel\nfrom schemas.student import StudentCreate, StudentUpdate, StudentResponse\n\nrouter = APIRouter()\n\[email protected](\"/\", response_model=List[StudentResponse])\nasync def get_students(\n skip: int = 0,\n limit: int = 100,\n db: AsyncSession = Depends(get_db),\n current_user = Depends(get_current_user),\n):\n \"\"\"Get all students with pagination\"\"\"\n students = await db.execute(\n select(StudentModel)\n .offset(skip)\n .limit(limit)\n )\n return students.scalars().all()\n\[email protected](\"/{student_id}\", response_model=StudentResponse)\nasync def get_student(\n student_id: str,\n db: AsyncSession = Depends(get_db),\n current_user = Depends(get_current_user),\n):\n \"\"\"Get a single student by ID\"\"\"\n student = await db.execute(\n select(StudentModel).where(StudentModel.id == student_id)\n )\n student = student.scalar_one_or_none()\n\n if not student:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"Student not found\"\n )\n return student\n\[email protected](\"/\", response_model=StudentResponse, status_code=status.HTTP_201_CREATED)\nasync def create_student(\n student_data: StudentCreate,\n db: AsyncSession = Depends(get_db),\n current_user = Depends(get_admin_user),\n):\n \"\"\"Create a new student\"\"\"\n # Check if email exists\n existing = await db.execute(\n select(StudentModel).where(StudentModel.email == student_data.email)\n )\n if existing.scalar_one_or_none():\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=\"Email already registered\"\n )\n\n student = StudentModel(**student_data.model_dump())\n db.add(student)\n await db.commit()\n await db.refresh(student)\n return student\n\[email protected](\"/{student_id}\", response_model=StudentResponse)\nasync def update_student(\n student_id: str,\n student_data: StudentUpdate,\n db: AsyncSession = Depends(get_db),\n current_user = Depends(get_admin_user),\n):\n \"\"\"Update a student\"\"\"\n student = await db.execute(\n select(StudentModel).where(StudentModel.id == student_id)\n )\n student = student.scalar_one_or_none()\n\n if not student:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"Student not found\"\n )\n\n update_data = student_data.model_dump(exclude_unset=True)\n for field, value in update_data.items():\n setattr(student, field, value)\n\n await db.commit()\n await db.refresh(student)\n return student\n\[email protected](\"/{student_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_student(\n student_id: str,\n db: AsyncSession = Depends(get_db),\n current_user = Depends(get_admin_user),\n):\n \"\"\"Delete a student\"\"\"\n student = await db.execute(\n select(StudentModel).where(StudentModel.id == student_id)\n )\n student = student.scalar_one_or_none()\n\n if not student:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"Student not found\"\n )\n\n await db.delete(student)\n await db.commit()","type":"text"}]},{"type":"paragraph","content":[{"text":"Requirements:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use APIRouter with prefix and tags","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Response models with Pydantic schemas","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Proper HTTP status codes (200, 201, 204, 404, 400)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dependencies for auth and DB","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pagination with skip/limit","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. Dependencies: Auth and DB Sessions","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# dependencies/database.py\nfrom sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker\nfrom databases import Database\nimport os\n\nDATABASE_URL = os.getenv(\n \"DATABASE_URL\",\n \"postgresql+asyncpg://user:password@localhost:5432/erp_db\"\n)\n\nengine = create_async_engine(DATABASE_URL, echo=True)\nasync_session_maker = async_sessionmaker(\n engine,\n class_=AsyncSession,\n expire_on_commit=False,\n)\n\nasync def get_db() -> AsyncSession:\n async with async_session_maker() as session:\n try:\n yield session\n await session.commit()\n except Exception:\n await session.rollback()\n raise\n finally:\n await session.close()\n\nasync def init_db():\n \"\"\"Initialize database tables\"\"\"\n async with engine.begin() as conn:\n await conn.run_sync(Base.metadata.create_all)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# dependencies/auth.py\nfrom fastapi import Depends, HTTPException, status\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\nfrom jose import JWTError, jwt\nfrom datetime import datetime, timedelta\nfrom typing import Optional\nimport os\n\nSECRET_KEY = os.getenv(\"JWT_SECRET_KEY\", \"your-secret-key\")\nALGORITHM = \"HS256\"\nACCESS_TOKEN_EXPIRE_MINUTES = 30\n\nsecurity = HTTPBearer()\n\ndef create_access_token(data: dict, expires_delta: Optional[timedelta] = None):\n to_encode = data.copy()\n if expires_delta:\n expire = datetime.utcnow() + expires_delta\n else:\n expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)\n to_encode.update({\"exp\": expire})\n encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)\n return encoded_jwt\n\nasync def get_current_user(\n credentials: HTTPAuthorizationCredentials = Depends(security),\n):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n\n try:\n payload = jwt.decode(\n credentials.credentials,\n SECRET_KEY,\n algorithms=[ALGORITHM]\n )\n user_id: str = payload.get(\"sub\")\n if user_id is None:\n raise credentials_exception\n except JWTError:\n raise credentials_exception\n\n return {\"user_id\": user_id, \"role\": payload.get(\"role\")}\n\nasync def get_admin_user(current_user = Depends(get_current_user)):\n if current_user.get(\"role\") not in [\"admin\", \"teacher\"]:\n raise HTTPException(\n status_code=status.HTTP_403_FORBIDDEN,\n detail=\"Admin access required\"\n )\n return current_user","type":"text"}]},{"type":"paragraph","content":[{"text":"Requirements:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Async SQLAlchemy sessions with context manager","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"JWT token creation and validation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"HTTPBearer for token extraction","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Role-based access control","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Environment variables for secrets","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"4. Pydantic v2 Models","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# schemas/student.py\nfrom pydantic import BaseModel, EmailStr, Field, ConfigDict\nfrom datetime import datetime\nfrom typing import Optional\nfrom enum import Enum\n\nclass StudentRole(str, Enum):\n STUDENT = \"student\"\n TEACHER = \"teacher\"\n ADMIN = \"admin\"\n\n# Base model with config\nclass StudentBase(BaseModel):\n model_config = ConfigDict(from_attributes=True)\n\n name: str = Field(..., min_length=2, max_length=100)\n email: EmailStr\n phone: Optional[str] = Field(None, pattern=r'^\\+?[\\d\\s-]+

FastAPI Application Skill Overview Expert guidance for building FastAPI backend applications with route decorators, dependency injection, CORS configuration, and Pydantic v2 validation. Supports ERP endpoints for students, fees, attendance, and authentication. When This Skill Applies This skill triggers when users request: - App Setup : "Create FastAPI app", "Initialize FastAPI", "Lifespan events" - Routes : "Student endpoint", "API route", "GET/POST handler", "APIRouter" - Dependencies : "DB dependency", "Auth dependency", "Depends()", "JWT auth" - CORS : "CORS enable frontend", "Cross-origi…

)\n\n# Create schema\nclass StudentCreate(StudentBase):\n password: str = Field(..., min_length=8)\n class_id: Optional[str] = None\n\n# Update schema (partial updates)\nclass StudentUpdate(BaseModel):\n model_config = ConfigDict(from_attributes=True)\n\n name: Optional[str] = Field(None, min_length=2, max_length=100)\n email: Optional[EmailStr] = None\n phone: Optional[str] = None\n class_id: Optional[str] = None\n\n# Response schema\nclass StudentResponse(StudentBase):\n id: str\n class_id: Optional[str] = None\n created_at: datetime\n updated_at: datetime\n\n# Pagination response\nclass PaginatedResponse(BaseModel):\n model_config = ConfigDict(from_attributes=True)\n\n data: list[StudentResponse]\n meta: dict = {\n \"total\": 0,\n \"page\": 1,\n \"page_size\": 100,\n \"total_pages\": 1\n }","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# schemas/fees.py\nfrom pydantic import BaseModel, Field\nfrom datetime import datetime\nfrom typing import Optional\nfrom enum import Enum\n\nclass FeeStatus(str, Enum):\n PENDING = \"pending\"\n PAID = \"paid\"\n OVERDUE = \"overdue\"\n WAIVED = \"waived\"\n\nclass FeeBase(BaseModel):\n student_id: str\n amount: float = Field(..., gt=0)\n description: str = Field(..., max_length=500)\n due_date: datetime\n\nclass FeeCreate(FeeBase):\n pass\n\nclass FeeUpdate(BaseModel):\n status: Optional[FeeStatus] = None\n paid_date: Optional[datetime] = None\n notes: Optional[str] = None\n\nclass FeeResponse(FeeBase):\n id: str\n status: FeeStatus\n paid_date: Optional[datetime] = None\n created_at: datetime","type":"text"}]},{"type":"paragraph","content":[{"text":"Requirements:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use Pydantic v2 ConfigDict instead of Config class","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Field validation with min/max, patterns, gt/lt","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"EmailStr for email validation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enum for status fields","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Optional fields with defaults","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"From_attributes for ORM compatibility","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Requirements","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Code Files","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Main Application","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"main.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" - FastAPI app initialization","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"config.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Settings and environment variables","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Routers","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"routers/__init__.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"routers/students.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"routers/fees.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"routers/attendance.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"routers/auth.py","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dependencies","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"dependencies/__init__.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"dependencies/database.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"dependencies/auth.py","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Models and Schemas","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"models/__init__.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"models/student.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"schemas/__init__.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"schemas/student.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"schemas/fees.py","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Integration Requirements","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"@api-client","type":"text","marks":[{"type":"strong"}]},{"text":": JSON response formatting for frontend","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"@auth-integration","type":"text","marks":[{"type":"strong"}]},{"text":": JWT validation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"@react-component","type":"text","marks":[{"type":"strong"}]},{"text":": Error response schemas","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Documentation","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PHR","type":"text","marks":[{"type":"strong"}]},{"text":": Create Prompt History Record for auth/DB decisions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ADR","type":"text","marks":[{"type":"strong"}]},{"text":": Document auth strategy (JWT vs session), DB choice (async SQLAlchemy)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Comments","type":"text","marks":[{"type":"strong"}]},{"text":": Document endpoint purposes and validation rules","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Initialize App","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create FastAPI instance with lifespan","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configure CORS middleware","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set up logging","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Setup Database","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create async SQLAlchemy engine","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Define session dependency","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create database models","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create Dependencies","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Auth dependency with JWT","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Role-based access","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"DB session management","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Define Schemas","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pydantic v2 models for requests/responses","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Validation rules","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Response formatting","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Build Routes","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create APIRouter for each domain","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implement CRUD operations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Add pagination and filtering","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test and Document","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verify Swagger docs","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test authentication","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Validate error responses","type":"text"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quality Checklist","type":"text"}]},{"type":"paragraph","content":[{"text":"Before completing any FastAPI implementation:","type":"text"}]},{"type":"checkbox_list","attrs":{"id":null},"content":[{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Pydantic v2 Validation","type":"text","marks":[{"type":"strong"}]},{"text":": ConfigDict, Field validators","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"SQLAlchemy Async","type":"text","marks":[{"type":"strong"}]},{"text":": Use async sessions, avoid blocking calls","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Rate Limiting","type":"text","marks":[{"type":"strong"}]},{"text":": Implement slowapi or similar for endpoints","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Swagger Docs Auto","type":"text","marks":[{"type":"strong"}]},{"text":": /docs shows all endpoints","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Error Handling","type":"text","marks":[{"type":"strong"}]},{"text":": Proper HTTPException with status codes","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Auth Protected","type":"text","marks":[{"type":"strong"}]},{"text":": All endpoints with dependencies","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Pagination","type":"text","marks":[{"type":"strong"}]},{"text":": skip/limit for list endpoints","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Type Hints","type":"text","marks":[{"type":"strong"}]},{"text":": All functions fully typed","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Environment Config","type":"text","marks":[{"type":"strong"}]},{"text":": Secrets in environment variables","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"CORS Config","type":"text","marks":[{"type":"strong"}]},{"text":": Allow frontend origins with credentials","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Student Endpoint with Auth","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# routers/students.py\[email protected](\"/students/\", response_model=List[StudentResponse])\nasync def get_students(\n skip: int = Query(0, ge=0),\n limit: int = Query(100, ge=1, le=1000),\n class_id: Optional[str] = None,\n db: AsyncSession = Depends(get_db),\n current_user = Depends(get_current_user),\n):\n \"\"\"Get students with pagination and optional class filter\"\"\"\n query = select(StudentModel)\n\n if class_id:\n query = query.where(StudentModel.class_id == class_id)\n\n query = query.offset(skip).limit(limit).order_by(StudentModel.created_at.desc())\n\n result = await db.execute(query)\n return result.scalars().all()","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"CORS Enable Frontend","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# main.py\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\n \"http://localhost:3000\", # Next.js dev\n \"http://localhost:5173\", # Vite dev\n \"https://yourdomain.com\", # Production\n ],\n allow_credentials=True,\n allow_methods=[\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\"],\n allow_headers=[\"Authorization\", \"Content-Type\"],\n)","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"DB Dependency with Session","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# dependencies/database.py\nasync def get_db() -> AsyncSession:\n async with async_session_maker() as session:\n try:\n yield session\n await session.commit()\n except Exception:\n await session.rollback()\n raise\n finally:\n await session.close()","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"JWT Auth Dependency","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# dependencies/auth.py\nfrom fastapi import Depends, HTTPException, status\nfrom fastapi.security import HTTPBearer\n\noauth2_scheme = HTTPBearer()\n\nasync def get_token_data(token: str = Depends(oauth2_scheme)):\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n return payload\n except JWTError:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Invalid token\"\n )","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Rate Limiting","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# dependencies/rate_limit.py\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\n\nlimiter = Limiter(key_func=get_remote_address)\n\ndef rate_limit(requests: int = 60, seconds: int = 60):\n def decorator(func):\n return limiter.limit(f\"{requests}/{seconds}\")(func)\n return decorator\n\n# Usage\[email protected](\"/students/\")\n@rate_limit(requests=100, seconds=60)\nasync def get_students():\n return {\"message\": \"Students list\"}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Environment Configuration","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# config.py\nfrom pydantic_settings import BaseSettings\nfrom typing import List\n\nclass Settings(BaseSettings):\n APP_NAME: str = \"ERP API\"\n DEBUG: bool = False\n API_V1_PREFIX: str = \"/api/v1\"\n\n # Database\n DATABASE_URL: str = \"postgresql+asyncpg://user:password@localhost:5432/erp_db\"\n\n # JWT\n JWT_SECRET_KEY: str\n JWT_ALGORITHM: str = \"HS256\"\n ACCESS_TOKEN_EXPIRE_MINUTES: int = 30\n\n # CORS\n CORS_ORIGINS: List[str] = [\"http://localhost:3000\"]\n\n class Config:\n env_file = \".env\"\n env_file_encoding = \"utf-8\"\n\nsettings = Settings()","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Running the Application","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Install dependencies\npip install fastapi uvicorn[standard] sqlalchemy[asyncio] asyncpg\npip install python-jose[cryptography] passlib[bcrypt]\npip install slowapi pydantic-settings\n\n# Run development\nuvicorn main:app --reload --host 0.0.0.0 --port 8000\n\n# Run production\nuvicorn main:app --host 0.0.0.0 --port 8000 --workers 4","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"References","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"FastAPI Documentation: https://fastapi.tiangolo.com","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pydantic v2: https://docs.pydantic.dev/latest/","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SQLAlchemy Async: https://docs.sqlalchemy.org/en/20/orm/extensions/asyncio.html","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"JWT with FastAPI: https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SlowAPI Rate Limiting: https://pypi.org/project/slowapi/","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"fastapi-app","author":"@skillopedia","source":{"stars":336,"repo_name":"marketplace","origin_url":"https://github.com/aiskillstore/marketplace/blob/HEAD/skills/awais68/fastapi-app/SKILL.md","repo_owner":"aiskillstore","body_sha256":"aa10ad8e2d56bb8c8449292db8e0ea37c9efbc383bc6769445be267e6feddca9","cluster_key":"e8efc707f7c8ce1cb4c991759bb7396c03ff85af151854d2b59fa30dc258539e","clean_bundle":{"format":"clean-skill-bundle-v1","source":"aiskillstore/marketplace/skills/awais68/fastapi-app/SKILL.md","attachments":[{"id":"29ce7093-188e-5af6-ba73-7fe70bc3c69b","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/29ce7093-188e-5af6-ba73-7fe70bc3c69b/attachment.json","path":"skill-report.json","size":10163,"sha256":"ba033065c30c423a65429485d7577508a43e3163b6a4177f702f0d115f78bd75","contentType":"application/json; charset=utf-8"}],"bundle_sha256":"f71087e1cb4c8cc5b4f775cc5fe78f3b29be121e51b0e02c19c042e1075604f1","attachment_count":1,"text_attachments":1,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/awais68/fastapi-app/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"web-development","category_label":"Web"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"web-development","import_tag":"clean-skills-v1","description":"Use when creating FastAPI backend applications - route handlers, dependencies, CORS config, or Pydantic models.\nNOT when frontend logic, non-Python backends, or unrelated server-side code.\nTriggers: \"FastAPI\", \"student endpoint\", \"API route\", \"dependency injection\", \"CORS\", \"Pydantic model\".\n"}},"renderedAt":1782979499577}

FastAPI Application Skill Overview Expert guidance for building FastAPI backend applications with route decorators, dependency injection, CORS configuration, and Pydantic v2 validation. Supports ERP endpoints for students, fees, attendance, and authentication. When This Skill Applies This skill triggers when users request: - App Setup : "Create FastAPI app", "Initialize FastAPI", "Lifespan events" - Routes : "Student endpoint", "API route", "GET/POST handler", "APIRouter" - Dependencies : "DB dependency", "Auth dependency", "Depends()", "JWT auth" - CORS : "CORS enable frontend", "Cross-origi…