Stride
Framework estilo Django para FastAPI. Models, ViewSets, Auth, Admin — baterias incluídas.
Arquitetura
flowchart TB
subgraph "Client Layer"
WEB[Web/Mobile]
CLI[CLI Tools]
end
subgraph "Stride"
subgraph "API Layer"
RT[AutoRouter]
VS[ViewSets]
AUTH[Auth/JWT]
end
subgraph "Business Layer"
PERM[Permissions]
VALID[Validators]
SER[Serializers]
end
subgraph "Data Layer"
MOD[Models]
QS[QuerySets]
REL[Relations]
end
subgraph "Infrastructure"
MW[Middleware]
MSG[Messaging]
TASK[Workers]
end
end
subgraph "Storage"
DB[(PostgreSQL)]
CACHE[(Redis)]
MQ[Kafka]
end
WEB --> RT
CLI --> RT
RT --> VS --> PERM --> MOD --> DB
VS --> VALID
VS --> SER
MOD --> QS
MOD --> REL
MW --> AUTH
MSG --> MQ
TASK --> CACHE
style VS fill:#e3f2fd
style MOD fill:#c8e6c9
style AUTH fill:#fff3e0
Filosofia Plug-and-Play
Configure no Settings, tudo é auto-configurado:
class AppSettings(Settings):
# Auth - auto-configurado
user_model: str = "src.apps.users.models.User"
# Kafka - auto-configurado
kafka_enabled: bool = True
# Tasks - auto-configurado
task_enabled: bool = True
# Multi-tenancy - auto-configurado
tenancy_enabled: bool = True
Zero chamadas explícitas: Você NÃO precisa chamar configure_auth(), configure_kafka(), etc.
Instalação
pipx install stride
stride init my-api && cd my-api
stride run
# → http://localhost:8000/docs
Documentação
Começando
| Doc |
Descrição |
| Criar uma aplicação |
Guia completo: config, DB, ViewSet, APIView, serializers, paginação, WebSocket, SSE, validação |
| Quickstart |
Primeira API em 5 minutos |
| Settings |
Sistema de configuração plug-and-play |
| Models |
Modelos de banco de dados |
| ViewSets |
Endpoints CRUD |
Autenticação
Camada de Dados
Infraestrutura
Avançado
Referência
Estrutura do Projeto
my-api/
├── src/
│ ├── settings.py # Toda configuração aqui
│ ├── main.py # Entry point da app
│ └── apps/
│ ├── models.py # Imports de models (barrel)
│ └── items/
│ ├── models.py
│ ├── views.py
│ └── routes.py
├── migrations/
├── .env
└── pyproject.toml
Exemplo Mínimo
# src/settings.py
from strider.config import Settings, configure
class AppSettings(Settings):
app_name: str = "Minha API"
settings = configure(settings_class=AppSettings)
# src/apps/items/models.py
from strider import Model, Field
from sqlalchemy.orm import Mapped
class Item(Model):
__tablename__ = "items"
id: Mapped[int] = Field.pk()
name: Mapped[str] = Field.string(max_length=200)
# src/apps/items/views.py
from strider import ModelViewSet
from .models import Item
class ItemViewSet(ModelViewSet):
model = Item
# src/main.py
from strider import StrideApp, AutoRouter
from src.apps.items.routes import router as items_router
api = AutoRouter(prefix="/api/v1")
api.include_router(items_router)
app = StrideApp(routers=[api])
# src/settings.py
from strider.config import Settings, PydanticField, configure
class AppSettings(Settings):
# ══════════════════════════════════════════════════════════════════
# Aplicação
# ══════════════════════════════════════════════════════════════════
app_name: str = "Minha API"
app_version: str = "1.0.0"
# ══════════════════════════════════════════════════════════════════
# Auth (auto-configurado quando user_model definido)
# ══════════════════════════════════════════════════════════════════
user_model: str = "src.apps.users.models.User"
models_module: str = "src.apps"
auth_password_hasher: str = "argon2"
# ══════════════════════════════════════════════════════════════════
# Kafka (auto-configurado quando kafka_enabled=True)
# ══════════════════════════════════════════════════════════════════
kafka_enabled: bool = True
kafka_bootstrap_servers: str = "kafka:9092"
avro_default_namespace: str = "com.mycompany.events"
# ══════════════════════════════════════════════════════════════════
# Tasks (auto-configurado quando task_enabled=True)
# ══════════════════════════════════════════════════════════════════
task_enabled: bool = True
task_worker_concurrency: int = 8
# ══════════════════════════════════════════════════════════════════
# Multi-tenancy
# ══════════════════════════════════════════════════════════════════
tenancy_enabled: bool = True
tenancy_field: str = "workspace_id"
# ══════════════════════════════════════════════════════════════════
# Middleware
# ══════════════════════════════════════════════════════════════════
middleware: list[str] = [
"timing",
"request_id",
"tenant",
"auth",
"logging",
]
# ══════════════════════════════════════════════════════════════════
# Admin
# ══════════════════════════════════════════════════════════════════
admin_site_title: str = "Minha Empresa"
admin_primary_color: str = "#10B981"
# ══════════════════════════════════════════════════════════════════
# Campos customizados
# ══════════════════════════════════════════════════════════════════
stripe_api_key: str = PydanticField(default="", description="Stripe API Key")
# Configura TUDO automaticamente
settings = configure(settings_class=AppSettings)
FileField estilo Django para upload e acesso a arquivos com signed URLs:
# 1. Configure no .env
# STORAGE_BACKEND=gcs
# STORAGE_GCS_BUCKET_NAME=meu-bucket
# STORAGE_GCS_CREDENTIALS_FILE=config/gcp-sa.json
# STORAGE_GCS_USE_SIGNED_URLS=true
# 2. No model, use AdvancedField.file() - estilo Django
from strider import Model, Field
from strider.fields import AdvancedField
class Course(Model):
__tablename__ = "courses"
id: Mapped[int] = Field.pk()
# Coluna do banco (armazena path)
cover_url: Mapped[str | None] = Field.string(500, nullable=True)
# FileField nativo
cover = AdvancedField.file("cover_url", upload_to="courses/covers/")
# 3. Use como Django FileField
course.cover.name # "courses/covers/abc.jpg"
course.cover.url # "https://...?X-Goog-Signature=..." (signed URL)
course.cover.save("foto.jpg", content, "image/jpeg") # Upload
course.cover.delete() # Remove do storage
# 4. Em schemas, transforme com get_file_url()
from strider.storage import get_file_url
class CourseResponse(OutputSchema):
cover_url: str | None = None
@model_validator(mode="after")
def transform_urls(self):
if self.cover_url:
self.cover_url = get_file_url(self.cover_url)
return self
Ver: Storage para documentação completa.
Comandos Rápidos
stride init my-api # Criar projeto
stride init my-api --minimal # Projeto mínimo
stride makemigrations # Gerar migrations
stride migrate # Aplicar migrations
stride run # Iniciar servidor
core createsuperuser # Criar usuário admin
core kafka worker --all # Executar workers
Links