Przejdź do treści
Biblioteka skilli
Programowanie · Budowanie i kod

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.

Repozytorium
samuel ↗
Licencja
MIT
Ostatnia zmiana repozytorium
29.04.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
2
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
5
Przestarzałość

Brak sygnałów. Repozytorium zmienione 29.04.2026, bez odwołań do wycofanych modeli i API.

Licencja

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

  1. Overview
  2. Core Principles
  3. Guardrails
  4. Project Structure
  5. Application Setup
  6. Pydantic Schemas (v2)
  7. Route Definitions
  8. Dependency Injection
  9. Async Patterns
  10. Error Handling
Sekcje z nagłówków SKILL.md, w oryginale · 484 linii, 1 519 słów
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

RepozytoriumWynikLicencja
Ta strona · ar4mirez/samuel100MIT
ericrisco/rsc-harness100MIT
TerminalSkills/skills100Apache-2.0
itechmeat/llm-code100MIT
fastapi/fastapi100MIT
nimadorostkar/Claude-Skills-collection100MIT
claude-dev-suite/claude-dev-suite100MIT
G1Joshi/Agent-Skills100MIT
chrishuffman5/domain-expert100MIT

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.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.