add brain
This commit is contained in:
160
.brain/.agent/skills/python-backend/SKILL.md
Normal file
160
.brain/.agent/skills/python-backend/SKILL.md
Normal file
@@ -0,0 +1,160 @@
|
||||
---
|
||||
name: python-backend
|
||||
description: >
|
||||
Python backend development expertise for FastAPI, security patterns, database operations,
|
||||
Upstash integrations, and code quality. Use when: (1) Building REST APIs with FastAPI,
|
||||
(2) Implementing JWT/OAuth2 authentication, (3) Setting up SQLAlchemy/async databases,
|
||||
(4) Integrating Redis/Upstash caching, (5) Refactoring AI-generated Python code (deslopification),
|
||||
(6) Designing API patterns, or (7) Optimizing backend performance.
|
||||
---
|
||||
|
||||
# python-backend
|
||||
|
||||
Production-ready Python backend patterns for FastAPI, SQLAlchemy, and Upstash.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Building REST APIs with FastAPI
|
||||
- Implementing JWT/OAuth2 authentication
|
||||
- Setting up SQLAlchemy async databases
|
||||
- Integrating Redis/Upstash caching and rate limiting
|
||||
- Refactoring AI-generated Python code
|
||||
- Designing API patterns and project structure
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Async-first** - Use async/await for I/O operations
|
||||
2. **Type everything** - Pydantic models for validation
|
||||
3. **Dependency injection** - Use FastAPI's Depends()
|
||||
4. **Fail fast** - Validate early, use HTTPException
|
||||
5. **Security by default** - Never trust user input
|
||||
|
||||
## Quick Patterns
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── auth/
|
||||
│ ├── router.py # endpoints
|
||||
│ ├── schemas.py # pydantic models
|
||||
│ ├── models.py # db models
|
||||
│ ├── service.py # business logic
|
||||
│ └── dependencies.py
|
||||
├── posts/
|
||||
│ └── ...
|
||||
├── config.py
|
||||
├── database.py
|
||||
└── main.py
|
||||
```
|
||||
|
||||
### Async Routes
|
||||
|
||||
```python
|
||||
# BAD - blocks event loop
|
||||
@router.get("/")
|
||||
async def bad():
|
||||
time.sleep(10) # Blocking!
|
||||
|
||||
# GOOD - runs in threadpool
|
||||
@router.get("/")
|
||||
def good():
|
||||
time.sleep(10) # OK in sync function
|
||||
|
||||
# BEST - non-blocking
|
||||
@router.get("/")
|
||||
async def best():
|
||||
await asyncio.sleep(10) # Non-blocking
|
||||
```
|
||||
|
||||
### Pydantic Validation
|
||||
|
||||
```python
|
||||
from pydantic import BaseModel, EmailStr, Field
|
||||
|
||||
class UserCreate(BaseModel):
|
||||
email: EmailStr
|
||||
username: str = Field(min_length=3, max_length=50, pattern="^[a-zA-Z0-9_]+$")
|
||||
age: int = Field(ge=18)
|
||||
```
|
||||
|
||||
### Dependency Injection
|
||||
|
||||
```python
|
||||
async def get_current_user(token: str = Depends(oauth2_scheme)) -> User:
|
||||
payload = decode_token(token)
|
||||
user = await get_user(payload["sub"])
|
||||
if not user:
|
||||
raise HTTPException(401, "User not found")
|
||||
return user
|
||||
|
||||
@router.get("/me")
|
||||
async def get_me(user: User = Depends(get_current_user)):
|
||||
return user
|
||||
```
|
||||
|
||||
### SQLAlchemy Async
|
||||
|
||||
```python
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||
|
||||
engine = create_async_engine(DATABASE_URL, pool_pre_ping=True)
|
||||
SessionLocal = async_sessionmaker(engine, expire_on_commit=False)
|
||||
|
||||
async def get_session() -> AsyncGenerator[AsyncSession, None]:
|
||||
async with SessionLocal() as session:
|
||||
yield session
|
||||
```
|
||||
|
||||
### Redis Caching
|
||||
|
||||
```python
|
||||
from upstash_redis import Redis
|
||||
|
||||
redis = Redis.from_env()
|
||||
|
||||
@app.get("/data/{id}")
|
||||
def get_data(id: str):
|
||||
cached = redis.get(f"data:{id}")
|
||||
if cached:
|
||||
return cached
|
||||
data = fetch_from_db(id)
|
||||
redis.setex(f"data:{id}", 600, data)
|
||||
return data
|
||||
```
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
```python
|
||||
from upstash_ratelimit import Ratelimit, SlidingWindow
|
||||
|
||||
ratelimit = Ratelimit(
|
||||
redis=Redis.from_env(),
|
||||
limiter=SlidingWindow(max_requests=10, window=60),
|
||||
)
|
||||
|
||||
@app.get("/api/resource")
|
||||
def protected(request: Request):
|
||||
result = ratelimit.limit(request.client.host)
|
||||
if not result.allowed:
|
||||
raise HTTPException(429, "Rate limit exceeded")
|
||||
return {"data": "..."}
|
||||
```
|
||||
|
||||
## Reference Documents
|
||||
|
||||
For detailed patterns, see:
|
||||
|
||||
| Document | Content |
|
||||
|----------|---------|
|
||||
| `references/fastapi_patterns.md` | Project structure, async, Pydantic, dependencies, testing |
|
||||
| `references/security_patterns.md` | JWT, OAuth2, password hashing, CORS, API keys |
|
||||
| `references/database_patterns.md` | SQLAlchemy async, transactions, eager loading, migrations |
|
||||
| `references/upstash_patterns.md` | Redis, rate limiting, QStash background jobs |
|
||||
|
||||
## Resources
|
||||
|
||||
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
|
||||
- [SQLAlchemy 2.0 Documentation](https://docs.sqlalchemy.org/)
|
||||
- [Upstash Documentation](https://upstash.com/docs)
|
||||
- [Pydantic Documentation](https://docs.pydantic.dev/)
|
||||
Reference in New Issue
Block a user