agentsclimarketplace

Fastapi advanced

Skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack/plugins/devtools-pack/skills/fastapi-advanced

A curated pack of custom Claude Code skills for developers — installable as a Claude Code plugin marketplace.

Install
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill fastapi-advanced

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

When to activate: FastAPI advanced patterns, middleware, lifespan, OpenAPI customization, rate limiting, CORS, file uploads

SKILL.md

3.8 KB, 808 tokens by cl100k_base, as published. Nobody here has run it

Advanced FastAPI Patterns

Lifespan (startup/shutdown)

from contextlib import asynccontextmanager
from fastapi import FastAPI

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Startup
    await db_pool.start()
    await redis.connect()
    logger.info("Application started")
    
    yield  # app is running
    
    # Shutdown
    await db_pool.close()
    await redis.disconnect()
    logger.info("Application stopped")

app = FastAPI(lifespan=lifespan)

OpenAPI Customization

from fastapi.openapi.utils import get_openapi

def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    
    schema = get_openapi(
        title="My API",
        version="1.0.0",
        description="Production API documentation",
        routes=app.routes,
    )
    
    # Add security scheme
    schema["components"]["securitySchemes"] = {
        "BearerAuth": {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"}
    }
    schema["security"] = [{"BearerAuth": []}]
    
    app.openapi_schema = schema
    return schema

app.openapi = custom_openapi

File Uploads

from fastapi import UploadFile, File
import aiofiles

ALLOWED_TYPES = {"image/jpeg", "image/png", "application/pdf"}
MAX_FILE_SIZE = 10 * 1024 * 1024  # 10MB

@router.post("/upload")
async def upload_file(
    file: UploadFile = File(...),
    current_user: User = Depends(get_current_user),
) -> dict:
    # Validate content type
    if file.content_type not in ALLOWED_TYPES:
        raise HTTPException(400, f"File type {file.content_type} not allowed")
    
    # Stream to check size without loading all into memory
    contents = b""
    async for chunk in file:
        contents += chunk
        if len(contents) > MAX_FILE_SIZE:
            raise HTTPException(413, "File too large")
    
    # Save
    dest = Path(f"uploads/{uuid4()}_{file.filename}")
    async with aiofiles.open(dest, "wb") as out:
        await out.write(contents)
    
    return {"filename": file.filename, "size": len(contents), "path": str(dest)}

Middleware Stack

from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.middleware.gzip import GZipMiddleware

# Order matters: outermost first
app.add_middleware(GZipMiddleware, minimum_size=1000)
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.cors_origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["api.example.com", "localhost"])

Custom Exception Handling

from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException

@app.exception_handler(RequestValidationError)
async def validation_error_handler(request: Request, exc: RequestValidationError) -> JSONResponse:
    return JSONResponse(
        status_code=422,
        content={
            "error": "validation_error",
            "details": [
                {"field": ".".join(str(loc) for loc in err["loc"]), "message": err["msg"]}
                for err in exc.errors()
            ],
        },
    )

@app.exception_handler(StarletteHTTPException)
async def http_error_handler(request: Request, exc: StarletteHTTPException) -> JSONResponse:
    return JSONResponse(
        status_code=exc.status_code,
        content={"error": exc.detail},
    )

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.