Microframework Python modular (FastAPI · Celery · SQLAlchemy · Typer): núcleo instalable para monolitos modulares y migrar apps legacy. Inspirado en Laravel/Spring.
Project description
milpa 🌽
milpa es un microframework de Python 3.14 para construir monolitos modulares, inspirado en la ergonomía de Laravel y la disciplina de capas de Spring. Junta cuatro piezas maduras detrás de una estructura opinada y un kernel reutilizable:
FastAPI para HTTP · Celery para tareas/crons · SQLAlchemy 2.0 para datos · Typer para la consola.
Pensado para dos cosas: arrancar servicios nuevos sin re-decidir la arquitectura cada vez, y migrar apps legacy de Laravel a Python conservando conceptos familiares (artisan, scheduler, mailables, soft-deletes, timestamps, Passport).
🚀 Quickstart
milpa se instala como cualquier paquete y trae el comando milpa new, que genera un proyecto
listo para correr (estilo laravel new / django-admin startproject):
# 1) instala el paquete (de forma aislada con uv, o como dependencia con pip)
uv tool install milpa-core # o: pipx install milpa-core · pip install milpa-core
# El paquete se llama `milpa-core` en PyPI (porque `milpa` choca con otro proyecto), pero el
# comando de consola y el import SIGUEN siendo `milpa`: `milpa new …` / `import milpa`.
# 2) crea un proyecto CON el demo de notas (auth, RBAC/ABAC, correos, patrones estilo milpa)
milpa new miapp --demo
cd miapp
# 3) instálalo y arráncalo
uv sync # instala milpa + deps + faker (dev)
uv run python jornal migrate run # crea las tablas (sqlite por default, zero-config)
uv run python jornal db seed # admin@demo.test + ana/beto + notas (todos: "password")
uv run python jornal serve # 👉 http://127.0.0.1:8000
Entra como admin@demo.test / password. La API con OpenAPI está en /docs. Sin --demo
obtienes un esqueleto limpio (un módulo Hello mínimo) para empezar de cero.
jornales el "artisan" de milpa (lo genera el scaffolder en la raíz del proyecto):serve,queue work,schedule work,make controller|model|module,migrate,db seed, … Ve todo conuv run python jornal list.
✨ Características
Todo es OPT-IN y auto-descubrible (no estorba si no lo usas):
- Patrones estilo milpa —
Events/Observers(1:N, transporte adaptativo: worker si hay broker, si no síncrono),Mediator(command bus 1:1, transport-neutral HTTP+CLI) yPipeline(modelo cebolla). Patrones ya probados que un arquitecto puede sugerir, no impuestos. - Background —
@job(on-demand,.dispatch()) y@cron_task(agendado, anti-overlap), separados a propósito (job ≠ cron). - API REST (estilo DRF) — versionado (
@Controller(version="v1")), rate limiting (@rate_limit), filtering DSL (FilterQueryModel) + paginación por cursor, y negociación de contenido (una ruta sirve JSON o HTML segúnAccept). - Auth — RBAC (roles) + ABAC (
Gate/@policy), JWT (API) + sesión cookie/CSRF (browser, estilo Sanctum); valida también tokens OAuth2 de Laravel Passport. - Errores que NUNCA fallan en silencio — todo error HTTP sale en RFC 9457
(
application/problem+json); el CLI rinde errores limpios (sin traceback crudo ni fuga de valores); mensajes accionables que apuntan al fix. - Datos estilo Spring Data —
Repository[Model, Id]tipado,@transactional, serializers Pydantic v2 (computed_field), soft-delete y timestamps automáticos; engine agnóstico del motor. - HTTP — controllers class-based (
@Controller/@Get/@Post), Jinja2 + HTMX/Alpine (sin Inertia) · i18n (YAML) · mail (Mailable+ drivers smtp/log/null + plantillas firmadas). - Frontend con Vite (estilo laravel-vite) — helpers
vite()/vite_asset()(HMR en dev, chunks hasheados en prod), microfrontends por vertical (surcos/: cada equipo su app Vite — React/Vue/Svelte/vanilla — servida same-origin, cero CORS), runtime-configwindow.__ENVsin rebuild y PWA sin boilerplate (manifest en runtime + Service Worker).
🎮 El demo (milpa new --demo)
--demo materializa un módulo de referencia corrible (usuarios + notas) que ejercita TODO el
stack y sirve de plantilla viva: auth dual (JWT API + sesión cookie/CSRF), RBAC + ABAC,
routing class-based, los patrones estilo milpa (eventos→correos automáticos, mediator,
pipeline, @job, @cron_task) y UI HTMX + Alpine + Pico.css. Corre sobre SQLite sin
levantar infraestructura.
- Web (HTMX):
http://127.0.0.1:8000comoadmin@demo.test/password. Crea/borra notas (HTMX), entra a Usuarios (solo roladmin→ RBAC); editas/borras solo tus notas (ABAC). - API (JWT):
POST /api/login→{access_token}; luegoAuthorization: Bearer <token>en/api/me,/api/notes(CRUD),/v1/reports/notesvs/v2/...(versionado). OpenAPI en/docs. - Microfrontends (Vite, OPT-IN): el demo trae dos surcos —
demo-spa(React + PWA con file-router) en/spaytablero(vanilla) en/tablero. Requieren Node ≥22.13 y pnpm 11:pnpm install && pnpm -r builden la raíz del proyecto, recarga y listo (en dev:pnpm --filter demo-spa deven paralelo ajornal serve). - Correos: el
.envtraeMAIL_DRIVER=log(los correos se imprimen en la terminal dejornal serve). Para verlos en un inbox web,docker compose up -dlevanta Mailpit (http://localhost:8025) y ponesMAIL_DRIVER=smtp.
Cada feature tiene su página en el manual y se demuestra ejecutable en el módulo Demo (contrastando la forma tradicional vs estilo milpa).
📦 API pública
La superficie estable vive en la fachada raíz — un import plano con lo que el demo y la guía enseñan (87 símbolos, web incluida):
from milpa import (
Controller, Get, Post, Put, Patch, Delete, # HTTP estilo Laravel
Fallback, api_version, rate_limit, view, # rutas, versionado, vistas
authenticated, Can, Roles, Scope, # auth: RBAC/ABAC y scopes Passport
job, cron_task, daily_at, hourly, # background: jobs y crons
Mail, Mailable, MailContent, # correo
Observer, dispatch, handles, send, # eventos (1:N) y mediator (1:1)
Pipeline, Pipe, # modelo cebolla
Repository, Factory, Seeder, transactional, # datos estilo Spring Data
console_command, settings, # consola y config tipada
)
La fachada es perezosa (PEP 562): import milpa a secas no instancia Celery, ni Settings,
ni el kernel web — cada símbolo se resuelve en su primer acceso. Las rutas profundas
(from milpa.Core.Http import Controller) siguen siendo válidas, y el paquete publica
py.typed (PEP 561): mypy y tu IDE reciben los tipos completos.
📖 Documentación
La guía completa estilo Laravel se publica en https://calcifux.github.io/milpa/: instalación, configuración, ciclo de vida HTTP, módulos, consola, correo, colas, cron, jobs, i18n, autenticación, base de datos (modelos, repositorios, filtrado/paginación), los patrones estilo milpa (eventos/observers, mediator, pipeline), la API REST (versionado, rate limiting, negociación de contenido, serializadores) y los errores RFC 9457.
🗂️ Estructura de un proyecto milpa
milpa new genera un proyecto donde TÚ trabajas en app/, y milpa (el framework, instalado
como paquete) aporta el kernel milpa.Core:
miapp/
app/
Modules/
Demo/ # con --demo: módulo de referencia (users/notes + TODOS los patrones)
Models/ # modelos SQLAlchemy (auto-discovery)
Dictionaries/ # constantes de dominio
Resources/ # assets/lang/views del proyecto
migrations/ # revisiones Alembic (motor-agnóstico)
jornal # consola (artisan) del proyecto
docker-compose.yml # SOLO infra de dev: redis + mailpit
.env # configuración (DATABASE_URL, MAIL_*, secretos, …)
pyproject.toml # depende de `milpa`
El kernel que aporta el paquete (milpa.Core) es genérico y reutilizable: Http (create_app +
@Controller + RateLimit), Database (Repository, @transactional, Filtering), Auth (RBAC+ABAC,
JWT/sesión, Passport), Events/Mediator/Pipeline, Jobs/Cron, Mail, Errors (RFC 9457),
Translate (i18n), Console (kernel Typer). No tocas el kernel: el framework descubre tus
modelos, diccionarios, recursos, comandos y crons por convención.
Agregar un módulo
uv run python jornal make module Facturacion
Crea app/Modules/Facturacion/ con Http/, Services/, Repositories/, Jobs/, Crons/,
Observers/, Handlers/, Pipes/, Policies/, Mail/, Resources/, Console/Commands/. La API
y el beat lo descubren solos; el import-linter garantiza que no se enrede con otros módulos
(cada módulo es un microservicio en potencia: se puede extraer sin desenredar imports cruzados).
✅ Calidad
milpa trae los guardrails de fábrica; en el proyecto generado corres:
uv run pytest # tests rápidos, SIN base de datos
uv run ruff check . # lint (ruff format . para formato)
uv run mypy # tipos (estricto)
uv run lint-imports # fronteras entre módulos
fakeres dependencia de dev (la usan factories/seeders parajornal db seed): viene en el grupo dev del proyecto, así queuv syncla trae; unpip install milpa-core"pelón" no la incluye.
🐘 Base de datos
El engine es agnóstico del motor; se elige con DATABASE_URL. Por default sqlite (zero-config,
viene en Python). Para otro motor instala su extra:
uv add "milpa-core[postgres]" # PostgreSQL (psycopg v3)
uv add "milpa-core[mysql]" # MySQL / MariaDB (pymysql)
uv add "milpa-core[oracle]" # Oracle (oracledb)
uv add "milpa-core[mssql]" # SQL Server (pyodbc)
Migrar desde Laravel
El kernel reproduce conceptos familiares para acortar la curva: artisan→jornal,
scheduler→@cron_task, mailables, soft-deletes (deleted_at), timestamps automáticos
(created_at/updated_at), y validación de tokens OAuth2 de Passport (coloca la llave pública
RS256 del legacy y apunta PASSPORT_PUBLIC_KEY_PATH a ella).
Licencia
MIT © @Calcifux (Carlos Guillermo Reyes Ramiro)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file milpa_core-0.6.0.tar.gz.
File metadata
- Download URL: milpa_core-0.6.0.tar.gz
- Upload date:
- Size: 216.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
00d4c0e1f23ef9724f6296b774bcccb50cced26d8ac91fccf484b8300d05a467
|
|
| MD5 |
a150fe6cc65a519ebe68e47e930e72f9
|
|
| BLAKE2b-256 |
ce1d39d4b900beedd092e0dc24f2912fe74c84df1d0bd8be4506cbf5d3db561d
|
File details
Details for the file milpa_core-0.6.0-py3-none-any.whl.
File metadata
- Download URL: milpa_core-0.6.0-py3-none-any.whl
- Upload date:
- Size: 290.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbb30dec4db2aabd23d73402f8edb1373c81e70cfc96bb28cd17898f03d0caf8
|
|
| MD5 |
3bb81023a03874d014b81566a9d48c42
|
|
| BLAKE2b-256 |
8515297dc09056099222ed1ab530c5d0ea53c2a8b0a69557dd2dc0b47be3174c
|