TAI-API
TAI-API es un framework ágil para el desarrollo de APIs REST basado en FastAPI, diseñado para acelerar la creación de APIs robustas y escalables mediante generación automática de código. Forma parte del ecosistema TAI (Triple Alpha Innovation) y se integra perfectamente con tai-sql para ofrecer una solución completa desde la base de datos hasta los endpoints.
🚀 Características Principales
- Generación Automática de Endpoints CRUD: Crea endpoints completos automáticamente a partir de tu esquema de base de datos
- CLI Intuitivo: Comandos simples para inicializar, generar y gestionar tu API
- Soporte Multi-Schema: Gestiona múltiples esquemas de base de datos en un solo proyecto
- Autenticación Integrada: Soporte nativo para autenticación por base de datos o Keycloak
- Operaciones Avanzadas: Endpoints para agregaciones, conteos, existencia, y consultas complejas
- Relaciones Automáticas: Carga eager loading de relaciones con el parámetro
includes - Paginación y Filtrado: Soporte completo para paginación, ordenamiento y filtrado dinámico
- Model Context Protocol (MCP): Exposición de endpoints vía MCP para integración con herramientas AI
- Documentación OpenAPI: Documentación interactiva generada automáticamente con Swagger UI
- Type Safety: Validación de datos con Pydantic y tipado completo
📋 Requisitos
- Python >= 3.10
- Poetry (para gestión de dependencias)
- PostgreSQL (como base de datos)
- tai-sql >= 0.3.59
🔧 Instalación
pip install tai-api
O con Poetry:
poetry add tai-api
🎯 Inicio Rápido
1. Inicializar un Proyecto
tai-api init mi-proyecto --namespace api
Este comando:
- Crea la estructura de directorios del proyecto
- Configura Poetry y las dependencias necesarias
- Genera archivos de configuración
- Crea recursos Docker para desarrollo
- Establece el namespace de la aplicación (por defecto:
api)
2. Configurar la Base de Datos
Primero, inicializa la configuración de tai-sql:
tai-sql init
Define tu esquema de base de datos y realiza la introspección:
tai-sql introspect --schema public
3. Generar la API
tai-api generate --schema public
Este comando genera automáticamente:
- Modelos Pydantic para validación de datos
- CRUD asíncrono para operaciones de base de datos
- Routers de FastAPI con endpoints completos
- Archivos de inicialización con importaciones correctas
- Diagramas ER de la base de datos
4. Ejecutar en Modo Desarrollo
tai-api dev
Tu API estará disponible en http://localhost:8000 con:
- Documentación Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc - OpenAPI Schema:
http://localhost:8000/openapi.json
📚 Comandos del CLI
tai-api init
Inicializa un nuevo proyecto TAI-API.
tai-api init <nombre-proyecto> [OPTIONS]
Argumentos:
project: Nombre del proyecto a crear
Opciones:
-n, --namespace: Nombre del namespace/módulo Python (por defecto:api)
Ejemplo:
tai-api init ecommerce-api --namespace backend
Estructura Generada:
ecommerce-api/
├── backend/
│ ├── __init__.py
│ ├── __main__.py
│ ├── __dev__.py
│ ├── database/
│ │ └── public/
│ │ ├── crud/
│ │ └── models/
│ ├── diagrams/
│ ├── resources/
│ │ ├── __init__.py
│ │ ├── exceptions.py
│ │ ├── handlers.py
│ │ ├── mcp.py
│ │ └── responses.py
│ └── routers/
│ └── database/
├── docker/
│ ├── dockerfile
│ └── entrypoint.sh
└── pyproject.toml
tai-api generate
El comando más importante del CLI. Genera todos los recursos de la API basándose en el esquema de base de datos.
tai-api generate [OPTIONS]
Opciones:
-s, --schema <nombre>: Genera recursos para un esquema específico--all: Genera recursos para todos los esquemas descubiertos
Ejemplos:
# Generar para el esquema por defecto
tai-api generate
# Generar para un esquema específico
tai-api generate --schema public
# Generar para todos los esquemas
tai-api generate --all
¿Qué Genera?
Para cada tabla en el esquema, el comando generate crea:
-
Modelos Pydantic (
database/{schema}/models/)- DTOs para lectura (Read)
- DTOs para creación (Create)
- DTOs para actualización (Update)
-
CRUD Asíncrono (
database/{schema}/crud/)- Operaciones CRUD completas
- Métodos de agregación
- Soporte para transacciones
-
Routers de FastAPI (
routers/database/{schema}/)- Un archivo
router_{tabla}.pypor cada tabla - Un archivo
router_enums.pycon todos los enums - Archivo
__init__.pycon agregación de routers
- Un archivo
-
Diagramas ER (
diagrams/)- Representación visual del esquema
Tipos de Endpoints Generados
Para cada tabla, se generan automáticamente los siguientes endpoints:
🔍 Consulta y Búsqueda
| Endpoint | Método | Descripción |
|---|---|---|
/{tabla} |
GET | Lista todos los registros con filtrado, paginación y ordenamiento |
/{tabla}/{id} |
GET | Obtiene un registro específico por su clave primaria |
/{tabla}/count |
GET | Cuenta registros que coinciden con los filtros |
/{tabla}/exists |
GET | Verifica si existe al menos un registro con los filtros |
Ejemplo de uso:
# Listar usuarios con paginación
GET /usuario?limit=10&offset=0&order_by=created_at&order=DESC
# Buscar usuario por id
GET /usuario/123
# Contar usuarios activos
GET /usuario/count?active=true
# Verificar si existe un email
GET /usuario/exists?email=test@example.com
📊 Operaciones de Agregación
| Endpoint | Método | Descripción |
|---|---|---|
/{tabla}/{campo}/sum |
GET | Suma todos los valores de un campo numérico |
/{tabla}/{campo}/mean |
GET | Calcula el promedio de un campo numérico |
/{tabla}/{campo}/max |
GET | Obtiene el valor máximo de un campo |
/{tabla}/{campo}/min |
GET | Obtiene el valor mínimo de un campo |
/{tabla}/agg |
POST | Realiza múltiples agregaciones en una sola consulta |
Ejemplo de uso:
# Suma total de ventas
GET /venta/monto/sum
# Precio promedio de productos
GET /producto/precio/mean
# Agregaciones múltiples
POST /venta/agg
{
"aggregations": [
{"field": "monto", "operation": "sum"},
{"field": "monto", "operation": "mean"},
{"field": "cantidad", "operation": "max"}
]
}
✏️ Creación y Modificación
| Endpoint | Método | Descripción |
|---|---|---|
/{tabla} |
POST | Crea un nuevo registro |
/{tabla}/{id} |
PATCH | Actualiza parcialmente un registro específico |
/{tabla} |
PATCH | Actualiza múltiples registros que coincidan con filtros |
Ejemplo de uso:
# Crear nuevo usuario
POST /usuario
{
"nombre": "Juan Pérez",
"email": "juan@example.com",
"active": true
}
# Actualizar usuario específico
PATCH /usuario/123
{
"nombre": "Juan P. Actualizado"
}
# Actualizar múltiples usuarios
PATCH /usuario?active=false
{
"estado": "inactivo"
}
🗑️ Eliminación
| Endpoint | Método | Descripción |
|---|---|---|
/{tabla}/{id} |
DELETE | Elimina un registro específico por su clave primaria |
Ejemplo de uso:
DELETE /usuario/123
🔗 Relaciones y Carga Eager
Todos los endpoints de consulta soportan el parámetro includes para cargar relaciones asociadas en una sola consulta:
# Usuario con sus posts
GET /usuario/123?includes=posts
# Usuario con posts y comentarios de cada post
GET /usuario/123?includes=posts.comments
# Múltiples relaciones
GET /usuario/123?includes=posts,profile,roles
📋 Enumeraciones
Se genera un router especial router_enums.py con endpoints para obtener todos los valores de enumeraciones definidas:
# Listar todos los valores de un enum
GET /enums/estado-usuario
# Ejemplo de respuesta
{
"status": "success",
"data": ["active", "inactive", "pending", "blocked"],
"message": "Enumeración obtenida exitosamente"
}
Características de los Endpoints
Todos los endpoints generados incluyen:
- ✅ Validación automática de datos con Pydantic
- ✅ Manejo de errores centralizado con respuestas consistentes
- ✅ Documentación OpenAPI completa con ejemplos
- ✅ Type hints completos para autocompletado IDE
- ✅ Logging integrado con tai-alphi
- ✅ Filtrado dinámico por cualquier campo
- ✅ Ordenamiento por múltiples campos
- ✅ Paginación con limit/offset
- ✅ Metadatos de paginación en respuestas
- ✅ Soporte CORS configurable
- ✅ Compresión de respuestas (gzip)
Estructura de Respuestas
Todos los endpoints siguen el formato estándar APIResponse:
{
"status": "success",
"data": { /* datos del recurso */ },
"message": "Operación exitosa",
"errors": null,
"meta": {
"total": 100,
"limit": 10,
"offset": 0
}
}
En caso de error:
{
"status": "error",
"data": null,
"message": "Error en la operación",
"errors": [
{
"code": "VALIDATION_ERROR",
"message": "El email es inválido",
"field": "email",
"details": null
}
],
"meta": null
}
tai-api set-auth
Configura el sistema de autenticación para la API.
tai-api set-auth
Este comando inicia un asistente interactivo que te guía a través de las opciones de autenticación:
Opciones de Autenticación:
1. Database - Autenticación basada en Base de Datos
Configura autenticación usando una tabla de usuarios en tu base de datos.
El asistente solicita:
- Tabla de usuarios
- Campo de username/email
- Campo de password (se hashea automáticamente con bcrypt)
- Opción de manejo de sesiones concurrentes
- Campo de session_id (si aplica)
Genera:
- Router de autenticación (
/auth) - Endpoints de login/logout
- Gestión de tokens JWT
- Dependencias de seguridad
- Middleware de autenticación
Endpoints generados:
POST /auth/login # Autenticación
POST /auth/logout # Cierre de sesión
POST /auth/refresh # Renovar token
GET /auth/me # Usuario actual
2. Keycloak - Autenticación con Keycloak
Integra Keycloak como proveedor de identidad.
El asistente solicita:
- URL del servidor Keycloak
- Realm
- Client ID
- Client Secret
- Configuración de roles y permisos
Genera:
- Integración completa con Keycloak
- Validación de tokens
- Decoradores de permisos
- Mapeo de roles
- Row Level Security (RLS) basado en tokens
Decorador de permisos:
@router.get("/users")
async def get_users(
token: AccessToken = Depends(requires_permissions('read', 'users'))
):
# Solo usuarios con permiso 'read' en recurso 'users'
pass
Ejemplo de uso:
tai-api set-auth
# > Selecciona: 1 (Database) o 2 (Keycloak)
# > Sigue el asistente interactivo
tai-api dev
Inicia el servidor de desarrollo con hot-reload.
tai-api dev [OPTIONS]
Opciones:
-w, --auth: Ejecutar con autenticación habilitada
Ejemplos:
# Modo desarrollo sin autenticación
tai-api dev
# Modo desarrollo con autenticación
tai-api dev --auth
Características:
- Hot-reload automático al detectar cambios
- Logs detallados en consola
- Servidor en
http://localhost:8000 - Documentación en
http://localhost:8000/docs
tai-api set-mcp
Configura el servidor para exponer endpoints vía Model Context Protocol (MCP).
tai-api set-mcp
¿Qué hace?
- Instala la dependencia
fastapi-mcp - Configura el endpoint
/mcp - Actualiza la configuración del proyecto
- Regenera archivos principales
Uso del endpoint MCP:
GET /mcp
Expone los metadatos de la API en formato MCP para integración con herramientas de IA y automatización.
🏗️ Arquitectura del Proyecto
mi-proyecto/
├── api/ # Namespace principal
│ ├── __init__.py
│ ├── __main__.py # Entry point con autenticación
│ ├── __dev__.py # Entry point para desarrollo
│ │
│ ├── database/ # Capa de datos
│ │ └── public/ # Schema 'public'
│ │ ├── models/ # Modelos Pydantic
│ │ │ ├── __init__.py
│ │ │ └── modelo_*.py
│ │ └── crud/ # Operaciones CRUD
│ │ └── asyn/
│ │ └── __init__.py
│ │
│ ├── routers/ # Endpoints FastAPI
│ │ ├── __init__.py
│ │ └── database/
│ │ ├── __init__.py
│ │ └── public/ # Routers del schema
│ │ ├── __init__.py
│ │ ├── router_tabla1.py
│ │ ├── router_tabla2.py
│ │ └── router_enums.py
│ │
│ ├── resources/ # Recursos compartidos
│ │ ├── __init__.py
│ │ ├── exceptions.py # Excepciones personalizadas
│ │ ├── handlers.py # Manejadores de errores
│ │ ├── responses.py # Modelos de respuesta
│ │ └── mcp.py # Configuración MCP
│ │
│ └── diagrams/ # Diagramas ER generados
│
├── docker/ # Recursos Docker
│ ├── dockerfile
│ └── entrypoint.sh
│
└── pyproject.toml # Configuración Poetry
🔐 Autenticación y Seguridad
Autenticación Database
Cuando se configura autenticación por base de datos:
# Endpoints protegidos automáticamente
from api.auth import get_current_user
@router.get("/protected")
async def protected_route(
current_user = Depends(get_current_user)
):
return {"user": current_user.username}
Autenticación Keycloak
Con Keycloak, se aplica Row Level Security (RLS) automático:
from api.auth import requires_permissions
@router.get("/usuarios")
async def get_usuarios(
token: AccessToken = Depends(requires_permissions('read', 'usuarios'))
):
# RLS aplicado automáticamente según token
# Solo ve registros permitidos por sus permisos
pass
🎨 Personalización
Modificar Endpoints Generados
Los routers generados son completamente editables. Puedes:
- Agregar validaciones personalizadas
- Modificar la lógica de negocio
- Añadir nuevos endpoints
- Cambiar parámetros de búsqueda
# En router_usuario.py - puedes editar libremente
@usuario_router.post("/registro")
async def registro_personalizado(
data: UsuarioCreate,
api: PublicAsyncDBAPI = Depends(PublicAsyncDBAPI)
):
# Lógica personalizada
# Validar email único
existe = await api.usuario.exists(email=data.email)
if existe:
raise ValidationException("Email ya registrado")
# Crear usuario
return await api.usuario.create(data)
Agregar Middleware
# En __main__.py
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Configurar Base de Datos
La configuración de base de datos se gestiona a través de tai-sql:
# Definir conexión
tai-sql config set DATABASE_URL postgresql://user:pass@localhost/db
# Establecer schema por defecto
tai-sql set-default-schema public
🧪 Testing
Ejemplo de test para endpoints generados:
from fastapi.testclient import TestClient
from api import app
client = TestClient(app)
def test_get_usuarios():
response = client.get("/usuario?limit=10")
assert response.status_code == 200
data = response.json()
assert data["status"] == "success"
assert isinstance(data["data"], list)
assert data["meta"]["limit"] == 10
def test_create_usuario():
response = client.post("/usuario", json={
"nombre": "Test User",
"email": "test@example.com"
})
assert response.status_code == 200
data = response.json()
assert data["status"] == "success"
assert data["data"]["email"] == "test@example.com"
📖 Integración con TAI-SQL
TAI-API se integra profundamente con TAI-SQL:
# 1. Inicializar tai-sql
tai-sql init
# 2. Definir esquema de BD
# Edita los archivos en schemas/
# 3. Aplicar migraciones
tai-sql migrate
# 4. Introspección (opcional, para BD existente)
tai-sql introspect --schema public
# 5. Generar API
tai-api generate --schema public
🚢 Despliegue
Con Docker
# Dockerfile generado automáticamente
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install poetry
RUN poetry install --no-dev
CMD ["poetry", "run", "uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8000"]
Con Docker Compose
version: '3.8'
services:
api:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
Producción
# Instalar dependencias de producción
poetry install --no-dev
# Ejecutar con Gunicorn + Uvicorn workers
gunicorn api:app \
--workers 4 \
--worker-class uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:8000 \
--access-logfile - \
--error-logfile -
🤝 Contribución
Las contribuciones son bienvenidas. Por favor:
- Fork el repositorio
- Crea una rama para tu feature (
git checkout -b feature/amazing-feature) - Commit tus cambios (
git commit -m 'Add amazing feature') - Push a la rama (
git push origin feature/amazing-feature) - Abre un Pull Request
📝 Licencia
Este proyecto está bajo la Licencia MIT. Ver el archivo LICENSE para más detalles.
🔗 Enlaces
- Homepage: Triple Alpha Innovation
- Repositorio: GitHub - tai-api
- Issues: GitHub Issues
- TAI-SQL: Repositorio tai-sql
👥 Autores
- MateoSaezMata - msaez@triplealpha.in
- CatuxaRama - crama@triplealpha.in
🙏 Agradecimientos
- FastAPI por el excelente framework
- El equipo de Triple Alpha Innovation
- La comunidad de código abierto
Desarrollado con ❤️ por Triple Alpha Innovation
Release files for tai-api 0.4.15
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tai_api-0.4.15.tar.gz | 250.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tai_api-0.4.15-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 567.1 kB
Release files / tai_api-0.4.15.tar.gz
| Download URL | tai_api-0.4.15.tar.gz |
|---|---|
| Size | 250.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
abe84f35b8cada74ff821820e7dfb3b48dfb8ca78e02850d7b2f8b16cc47c483
|
|
BLAKE2b-256 checksum How to use checksums |
e5cc3fe903e86c8ce1d138462d920ae44cd8de7138ba5ebfea6b41ab9e0ac5bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.2 CPython/3.11.0 Linux/6.17.0-1022-azure
|
Release files / tai_api-0.4.15-py3-none-any.whl
| Download URL | tai_api-0.4.15-py3-none-any.whl |
|---|---|
| Size | 316.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
44093fdb5de2cac1e57218b0138d9fb1c6ac73525c228a3bdb749721c3611dbb
|
|
BLAKE2b-256 checksum How to use checksums |
5a407cf6218ac4d13a0d8c6b76095229e0c4588f486f059adc1253c9d6bdfdf8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.2 CPython/3.11.0 Linux/6.17.0-1022-azure
|