fastapi
/fastapi
Daje wytyczne i wzorce dla projektów FastAPI w pracy z AI: wzorce asynchroniczne, modele Pydantic, wstrzykiwanie zależności i zasady OpenAPI.
- Autor
- ar4mirez ↗
- Repozytorium
- samuel ↗
- Licencja
- MIT
- Ostatnia zmiana repozytorium
- 29.04.2026
Ocena i bezpieczeństwo
- Pliki w paczce
- 2
- Skrypty
- 0
- Komentarze HTML
- 0
- Adresy URL w SKILL.md
- 5
Brak sygnałów. Repozytorium zmienione 29.04.2026, bez odwołań do wycofanych modeli i API.
MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.
Co robi i kiedy
Daje wytyczne i wzorce dla projektów FastAPI w pracy z AI: wzorce asynchroniczne, modele Pydantic, wstrzykiwanie zależności i zasady OpenAPI.
Oryginalny opis (EN)
FastAPI framework guardrails, patterns, and best practices for AI-assisted development. Use when working with FastAPI projects, or when the user mentions FastAPI. Provides async patterns, Pydantic models, dependency injection, and OpenAPI guidelines.
Jak działa
- Overview
- Core Principles
- Guardrails
- Project Structure
- Application Setup
- Pydantic Schemas (v2)
- Route Definitions
- Dependency Injection
- Async Patterns
- Error Handling
Podgląd SKILL.md
---
name: fastapi
description: |
FastAPI framework guardrails, patterns, and best practices for AI-assisted development.
Use when working with FastAPI projects, or when the user mentions FastAPI.
Provides async patterns, Pydantic models, dependency injection, and OpenAPI guidelines.
license: MIT
metadata:
author: samuel
version: "1.0"
category: framework
language: python
extensions: ".py"
---
# FastAPI Framework Guide
> Applies to: FastAPI 0.100+, Pydantic v2, SQLAlchemy 2.0
> Language: Python 3.10+
> Type: Async API Framework
## Overview
FastAPI is a modern, high-performance web framework for building APIs with Python based on standard type hints. Built on Starlette (web) and Pydantic (validation).
**Use FastAPI when:**
- Building REST APIs or GraphQL backends
- Need native async/await support
- Want automatic OpenAPI documentation
- Need high performance (comparable to Node.js/Go)
- Want strong type validation with Pydantic
**Consider alternatives when:**
- Need full-stack with templates (consider Django)
- Building simple scripts (consider Flask)
- Need extensive admin interface (consider Django)
## Core Principles
1. **Type-First**: Use type hints everywhere; they drive validation and docs
2. **Async by Default**: Use `async def` for I/O-bound endpoints
3. **Dependency Injection**: Use `Depends()` for shared logic and resources
4. **Thin Endpoints**: Keep route handlers thin, business logic in services
5. **Schema Validation**: Use Pydantic models for all request/response data
## Guardrails
### Code Style
- Use `async def` for endpoints with I/O operations
- Use `def` (sync) only for CPU-bound operations without I/O
- Never use sync database calls in async context
- Always use type hints on function signatures
- Run `ruff check` and `mypy` before committing
### API Design
- Version your API: `/api/v1/...`
- Use plural nouns for resources: `/users`, `/products`
- Use HTTP methods correctly: GET (read), POST (create), PUT/PATCH (update), DELETE
- Return appropriate status codes (201 for creation, 204 for deletion)
- Always set `response_model` on endpoints
### Security
- Validate all inputs with Pydantic (automatic with FastAPI)
- Use `OAuth2PasswordBearer` for token auth
- Hash passwords with bcrypt (never store plaintext)
- Set CORS origins explicitly (never use `*` in production)
- Use `Depends()` for auth checks on every protected endpoint
### Error Handling
- Use custom exception classes inheriting from `HTTPException`
- Register global exception handlers for consistent responses
- Never expose internal errors to clients
- Always wrap database errors with context
## Project Structure
```
myproject/
├── pyproject.toml
├── alembic.ini
├── alembic/
│ ├── versions/
│ └── env.py
├── app/
│ ├── __init__.py
│ ├── main.py # Application entry point
│ ├── config.py # Settings (pydantic-settings)
│ ├── database.py # Async SQLAlchemy engine/session
│ ├── dependencies.py # Shared dependencies
│ ├── models/ # SQLAlchemy ORM models
│ │ ├── __init__.py
│ │ ├── base.py # DeclarativeBase, mixins
│ │ └── user.py
│ ├── schemas/ # Pydantic v2 schemas
│ │ ├── __init__.py
│ │ └── user.py
│ ├── api/ # API routes
│ │ ├── __init__.py
│ │ ├── deps.py # API-level dependencies (auth)
│ │ └── v1/
│ │ ├── __init__.py
│ │ ├── router.py # Aggregates all v1 routers
│ │ └── endpoints/
│ │ ├── users.py
│ │ └── products.py
│ ├── services/ # Business logic layer
│ │ ├── __init__.py
│ │ └── user.py
│ ├── repositories/ # Data access layer
│ │ ├── __init__.py
│ │ └── user.py
│ └── core/ # Cross-cutting utilities
│ ├── __init__.py
│ ├── security.py # JWT, password hashing
│ └── exceptions.py # Custom exception classes
├── tests/
│ ├── conftest.py # Fixtures (async client, db session)
│ ├── test_users.py
│ └── factories.py
└── docker-compose.yml
```
- `models/` = SQLAlchemy ORM (database shape)
- `schemas/` = Pydantic (API shape, validation)
- `services/` = Business logic (orchestration, rules)
- `repositories/` = Data access (queries, CRUD)
## Application Setup
### Main Application
```python
# app/main.py
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.api.v1.router import api_router
from app.config import settings
from app.database import engine
from app.models.base import Base
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Startup and shutdown events."""
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
yield
await engine.dispose()
app = FastAPI(
title=settings.PROJECT_NAME,
version=settings.VERSION,
openapi_url=f"{settings.API_V1_STR}/openapi.json",
lifespan=lifespan,
)
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(api_router, prefix=settings.API_V1_STR)
@app.get("/health")
async def health_check():
return {"status": "healthy"}
```
### Configuration
```python
# app/config.py
from functools import lru_cache
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=True,
)
PROJECT_NAME: str = "FastAPI App"
VERSION: str = "1.0.0"
DEBUG: bool = False
API_V1_STR: str = "/api/v1"
DATABASE_URL: str = "postgresql+asyncpg://user:pass@localhost/db"
SECRET_KEY: str
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
CORS_ORIGINS: list[str] = ["http://localhost:3000"]
@lru_cache
def get_settings() -> Settings:
return Settings()
settings = get_settings()
```
## Pydantic Schemas (v2)
```python
# app/schemas/user.py
from datetime import datetime
from uuid import UUID
from pydantic import BaseModel, ConfigDict, EmailStr, Field
class UserBase(BaseModel):
email: EmailStr
first_name: str | None = None
last_name: str | None = None
class UserCreate(UserBase):
password: str = Field(..., min_length=8, max_length=100)
class UserUpdate(BaseModel):
"""Partial update: all fields optional."""
email: EmailStr | None = None
first_name: str | None = None
last_name: str | None = None
password: str | None = Field(None, min_length=8, max_length=100)
class UserResponse(UserBase):
model_config = ConfigDict(from_attributes=True)
id: UUID
is_active: bool
created_at: datetime
class PaginatedResponse[T](BaseModel):
items: list[T]
total: int
page: int
size: int
pages: int
```
**Key Pydantic v2 patterns:**
- Use `ConfigDict(from_attributes=True)` instead of `class Config: orm_mode = True`
- Use `model_dump()` / `model_validate()` instead of `.dict()` / `.from_orm()`
- Use `Field(...)` for required fields with constraints
- Use `model_dump(exclude_unset=True)` for partial updates
## Route Definitions
### Router Setup
```python
# app/api/v1/router.py
from fastapi import APIRouter
from app.api.v1.endpoints import auth, users, products
api_router = APIRouter()
api_router.include_router(auth.router, prefix="/auth", tags=["auth"])
api_router.include_router(users.router, prefix="/users", tags=["users"])
api_router.include_router(products.router, prefix="/products", tags=["products"])
```
### Endpoint Pattern
```python
# app/api/v1/endpoints/users.py
from uuid import UUID
from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.api.deps import get_current_user
from app.database import get_db
from app.models.user import User
from app.schemas.user import UserResponse, PaginatedResponse
from app.services.user import UserService
router = APIRouter()
@router.get("", response_model=PaginatedResponse[UserResponse])
async def list_users(
page: int = Query(1, ge=1),
size: int = Query(20, ge=1, le=100),
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Get paginated list of users."""
service = UserService(db)
skip = (page - 1) * size
users, total = await service.get_multi(skip=skip, limit=size)
return PaginatedResponse(
items=[UserResponse.model_validate(u) for u in users],
total=total,
page=page,
size=size,
pages=(total + size - 1) // size,
)
@router.get("/{user_id}", response_model=UserResponse)
async def get_user(
user_id: UUID,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""Get user by ID."""
service = UserService(db)
user = await service.get(user_id)
return UserResponse.model_validate(user)
```
## Dependency Injection
```python
# app/database.py — Session dependency
async def get_db() -> AsyncSession:
async with AsyncSessionLocal() as session:
try:
yield session
await session.commit()
except Exception:
await session.rollback()
raise
finally:
await session.close()
# app/api/deps.py — Auth dependencies
from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/login")
async def get_current_user(
token: str = Depends(oauth2_scheme),
db: AsyncSession = Depends(get_db),
) -> User:
payload = verify_token(token)
user = await UserRepository(db).get(payload.sub)
if not user or not user.is_active:
raise HTTPException(status_code=403, detail="Inactive or missing user")
return user
async def get_current_superuser(
current_user: User = Depends(get_current_user),
) -> User:
if not current_user.is_superuser:
raise HTTPException(status_code=403, detail="Not enough permissions")
return current_user
```
**DI best practices:**
- Use `Depends()` for database sessions, auth, services
- Dependencies can depend on other dependencies (chain)
- Use `yield` dependencies for setup/teardown (e.g., DB sessions)
- Keep dependency functions small and focused
## Async Patterns
### Database (Async SQLAlchemy)
```python
# app/database.py
from sqlalchemy.ext.asyncio import (
AsyncSession, async_sessionmaker, create_async_engine,
)
engine = create_async_engine(
settings.DATABASE_URL,
echo=settings.DEBUG,
pool_pre_ping=True,
pool_size=5,
max_overflow=10,
)
AsyncSessionLocal = async_sessionmaker(
engine, class_=AsyncSession,
expire_on_commit=False,
)
```
### Key async rules
- Use `asyncpg` driver (not `psycopg2`) for PostgreSQL
- Use `selectinload()` for eager loading relationships (avoids N+1)
- Use `await session.flush()` to get IDs without committing
- Use `await session.refresh(obj)` after flush to load defaults
## Error Handling
```python
# app/core/exceptions.py
from fastapi import HTTPException, status
class AppException(HTTPException):
def __init__(self, detail: str, status_code: int = 500):
super().__init__(status_code=status_code, detail=detail)
class NotFoundException(AppException):
def __init__(self, detail: str = "Not found"):
super().__init__(detail=detail, status_code=status.HTTP_404_NOT_FOUND)
class ConflictException(AppException):
def __init__(self, detail: str = "Conflict"):
super().__init__(detail=detail, status_code=status.HTTP_409_CONFLICT)
class UnauthorizedException(AppException):
def __init__(self, detail: str = "Unauthorized"):
super().__init__(detail=detail, status_code=status.HTTP_401_UNAUTHORIZED)
class ForbiddenException(AppException):
def __init__(self, detail: str = "Forbidden"):
super().__init__(detail=detail, status_code=status.HTTP_403_FORBIDDEN)
```
Register a global handler in `main.py`:
```python
from fastapi.responses import JSONResponse
@app.exception_handler(AppException)
async def app_exception_handler(request, exc):
return JSONResponse(status_code=exc.status_code, content={"detail": exc.detail})
```
## Commands Reference
```bash
# Development
uvicorn app.main:app --reload --port 8000
# Production
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
# Database migrations
alembic init alembic
alembic revision --autogenerate -m "Initial migration"
alembic upgrade head
alembic downgrade -1
# Testing
pytest
pytest -v --cov=app --cov-report=html
pytest tests/test_users.py -k "test_register"
# Linting & type checking
ruff check app/
ruff check app/ --fix
mypy app/
```
## Best Practices Summary
### Do
- Use Pydantic for all request/response validation
- Use dependency injection for services and sessions
- Keep endpoints thin, logic in services
- Use `async def` for I/O operations
- Handle errors with custom exceptions
- Use type hints everywhere
- Write comprehensive async tests with `httpx.AsyncClient`
### Don't
- Put business logic in endpoints
- Use sync database calls in async context
- Expose internal ORM models directly as responses
- Skip input validation
- Ignore error handling
- Use global mutable state
## Advanced Topics
For detailed patterns, full code examples, and advanced usage, see:
- [references/patterns.md](references/patterns.md) -- Repository pattern, services, testing, security, middleware, background tasks, WebSocket
## External References
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
- [Pydantic v2 Documentation](https://docs.pydantic.dev/)
- [SQLAlchemy 2.0 Documentation](https://docs.sqlalchemy.org/en/20/)
- [Starlette Documentation](https://www.starlette.io/)
Pliki w paczce (2)
- SKILL.md 14 KB
- references/patterns.md 23 KB
Wersje
| Repozytorium | Wynik | Licencja |
|---|---|---|
| Ta strona · ar4mirez/samuel | 100 | MIT |
| ericrisco/rsc-harness | 100 | MIT |
| TerminalSkills/skills | 100 | Apache-2.0 |
| itechmeat/llm-code | 100 | MIT |
| fastapi/fastapi | 100 | MIT |
| nimadorostkar/Claude-Skills-collection | 100 | MIT |
| claude-dev-suite/claude-dev-suite | 100 | MIT |
| G1Joshi/Agent-Skills | 100 | MIT |
| chrishuffman5/domain-expert | 100 | MIT |
Identyczna treść występuje jeszcze w 1 innych folderach na GitHubie. Tu pokazujemy jedną, najlepiej ocenioną kopię.
Migawka bazy z 28.10.2026 · wersja paczki a7733566b0f4 (skrót SHA-256 całej paczki)
Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.
Podobne skille
- 100python-fastapi-ops
Stosuje wzorce frameworka FastAPI: endpointy API, wstrzykiwanie zależności, modele Pydantic, OpenAPI, Starlette, asynchroniczne REST API i uvicorn. - 100fastapi-patterns
Buduje produkcyjne aplikacje FastAPI z wstrzykiwaniem zależności, middleware, zadaniami w tle i uporządkowanym układem projektu, z wzorcami async, Pydantic, OpenAPI i testami. - 100fastapi-expert
Wspiera tworzenie wydajnych API w FastAPI z obsługą async, REST, OpenAPI i Pydantic. - 90FastAPI Patterns
Podaje wzorce tworzenia aplikacji FastAPI: endpointy, asynchroniczne trasy, wstrzykiwanie zależności, middleware, obsługa wyjątków i struktura projektu, z dobrymi praktykami async. - 100fastapi-pro
Podaje produkcyjne wzorce FastAPI dla Pythona 3.11+: endpointy async, SQLAlchemy 2.0 async, Pydantic V2, wstrzykiwanie zależności, JWT i testy. - 100fastapi-async-patterns
Buduje asynchroniczne API FastAPI z wstrzykiwaniem zależności i wzorcami serwisów, dla typowanych endpointów.