Saltar a contenido

El proyecto por dentro

Qué es de quién

Lo importante de un proyecto de tai-api es saber qué ficheros son tuyos —se crean una vez y generate no los toca— y cuáles son del generador —se reescriben en cada generate, y editarlos es perder el cambio—.

api/                                    ← raíz del proyecto
├── .taiapiproject                      configuración del proyecto          tuyo (y de los comandos)
├── pyproject.toml                      dependencias del servicio           tuyo; tai-api gestiona sus paquetes
├── dockerfile, entrypoint.sh           la imagen                           tuyo (se crea una vez)
├── rbac/
│   ├── main.py                         los permisos del realm              TUYO
│   └── tables/main/__init__.py         constantes de permisos              generado
└── api/                                ← el paquete Python
    ├── config.py                       VERSION, ROOT_PATH, ALLOWED_ORIGINS TUYO
    ├── resources/                      respuestas, excepciones, handlers   tuyo (se copia una vez)
    ├── extensions/__init__.py          setup(app): lo propio del arranque  TUYO (lo creas tú)
    ├── __main__.py, __dev__.py         los puntos de entrada               generados
    ├── app/                            create_app(), salud, documentación  generado
    ├── database/<schema>/              el cliente de tai-sql               generado
    ├── diagrams/                       los diagramas ER                    generado
    └── routers/
        ├── __init__.py                 main_router                         generado
        ├── database/<schema>/<tabla>/  los endpoints                       generado
        ├── auth/                       login, dependencias, /rbac          generado
        └── custom/                     tus endpoints                       TUYO

Todo fichero generado abre con una marca:

# Generado por tai-api: este fichero lo reescribe `tai-api generate`.
  • Un fichero con la marca se reescribe siempre. Los endpoints, app/ y routers/auth/.
  • Un fichero sin la marca no se toca. Si editas __main__.py, __dev__.py o routers/__init__.py quitando la marca, generate avisa y lo deja como está, pero deja de actualizarlo. Lo tuyo va en extensions/ y routers/custom/.
  • Una carpeta que no reconoce, no la borra. Un router propio dentro de routers/database/<schema>/ sobrevive a generate, pero no se monta: generate avisa de que lo muevas a routers/custom/.
  • Lo que desaparece del schema, se retira. Una tabla eliminada se lleva su carpeta de endpoints; un schema eliminado del proyecto de tai-sql, sus routers y su cliente.

La relación con tai-sql

tai-api no guarda la ruta del proyecto de tai-sql: lo busca cada vez desde el directorio actual, hacia arriba por los padres y después hacia abajo por las subcarpetas. Y busca su propio .taiapiproject hacia arriba y en las subcarpetas inmediatas. Por eso lo cómodo es ejecutar desde el directorio que contiene a los dos:

mi-proyecto/
├── database/        ← .taisqlproject, schemas/
└── api/             ← .taiapiproject

Desde dentro de api/, tai-sql no encuentra un proyecto hermano. generate, auth, rbac (en modo Database) y set-mcp lo necesitan; init, install y dev, no.

Si la API queda más abajo —en un proyecto de tai-chat está en chatbot/api/—, desde la raíz no se encuentra. Se indica con --project-dir, que no cambia de directorio, así que tai-sql sigue viendo database/:

tai-api --project-dir chatbot/api generate
TAI_API_PROJECT_DIR=chatbot/api tai-api rbac push   # lo mismo, con la variable

Las dependencias

Hay dos pyproject.toml, igual que en tai-sql:

  • El de tai-api (lo que instalas con pip install 'tai-api[...]') es la herramienta.
  • El del proyecto es lo que necesita la API en producción. Lo escribe init, y generate, auth y set-mcp añaden o quitan solo los paquetes que gestiona tai-api —tai-keycloak, fastapi-mcp…— cuando cambia la configuración. Lo que añadas tú no se toca.

resources/ no se regenera

tai-api init copia resources/ —el envoltorio APIResponse, las excepciones y sus handlers, el montaje de MCP— una vez. Es la única parte que tai-api entrega y abandona: una versión nueva no la actualiza, y por eso ningún endpoint generado depende de algo que no estuviera ya.

Lo que sí hace generate es avisar cuando el resources/ del proyecto es de una revisión anterior (RESOURCES_REVISION en su __init__.py; sin la marca, la 1), con lo que ha cambiado desde entonces y la ruta de la copia nueva dentro del paquete. Ponerla al día es copiar los ficheros —o lo que interese de ellos, si los editaste— y subir la marca.

Revisión Qué trae
2 (tai-api 0.5.0) Las rutas que no existen (404) y los métodos no admitidos (405) salen con el formato de siempre; las restricciones de la base de datos se clasifican por su SQLSTATE —un duplicado de MySQL o un NOT NULL ya no son un 500—; un t.abort() de un trigger de tai-sql es un 422 BUSINESS_RULE_VIOLATION; lo que llega en el cuerpo de una petición inválida no se repite en la respuesta ni en el log