Saltar a contenido

Configuración

La configuración de un proyecto vive en dos sitios, y cada uno tiene su motivo:

Dónde Qué Quién lo cambia
.taiapiproject Qué se genera y cómo: autenticación, sesión, cliente, frontend Los comandos, y tú a mano
<paquete>/config.py Cómo arranca la API: versión, prefijo de rutas, orígenes de CORS Tú
Variables de entorno Secretos y URLs de cada despliegue Quien despliega. Ver Variables de entorno

El .taiapiproject

Un JSON en la raíz del proyecto. Lo escribe tai-api init y lo actualizan auth, rbac push, generate y set-mcp, pero se puede editar a mano: una clave que no reconoce es un error (A002), no se ignora, para que una errata no pase por un valor por defecto.

{
  "name": "mi-api",
  "namespace": "api",
  "secret_key_name": "SECRET_KEY",
  "app_dir": ".",
  "generated_schemas": ["public"],
  "mcp": false,
  "auth": {
    "type": "keycloak",
    "config": { "realms": [ { "name": "main", "client_name": "api", "audience": "api" } ] },
    "session": { "transport": "cookie" }
  },
  "client": { "paradigm": "async", "max_depth": 5, "pool": { "pool_size": 10 } },
  "frontend": { "output_dir": "../app/src/lib/api", "base_path": "/api", "tanstack": true, "zod": true }
}
Clave Qué es Por defecto
name El nombre del proyecto; también el logger del cliente de tai-sql el de init
namespace El paquete Python de la API api
app_dir Dónde está el paquete, relativo al .taiapiproject .
secret_key_name La variable de entorno con la clave de firma y de cifrado. Se escribe en la autenticación generada: al cambiarlo, tai-api generate (tai-api dev no arranca hasta entonces) SECRET_KEY
generated_schemas Los schemas de tai-sql que generate regenera sin preguntar los que se generaron
mcp Exponer /mcp (lo pone set-mcp) false
auth La autenticación: ver abajo sin autenticación
client El cliente de tai-sql que viaja con la API lo que decida tai-sql
frontend El cliente TypeScript no se genera

current_version y mode existen por compatibilidad y no se usan.

auth

type es database o keycloak, y config lo propio de cada uno —ver Database y Keycloak—. Lo escribe tai-api auth init.

session es la política de sesión del navegador, igual en los dos modos. Solo se escribe lo que difiere del valor por defecto:

Clave Qué es Por defecto
transport body (el refresh token en la respuesta) o cookie (en una cookie httpOnly) body
access_minutes Lo que dura un access token 10
idle_hours La inactividad que cierra la sesión 8
absolute_hours Lo que dura una sesión como mucho, con actividad o sin ella 12

Las tres duraciones solo aplican con cookie, y idle_hours no puede superar a absolute_hours. Ver La sesión con cookie.

client

El cliente de tai-sql que generate escribe en <paquete>/database/<schema>/:

Clave Qué es Por defecto
paradigm async, o both para tener además el DAO síncrono (scripts, tareas). sync no: los endpoints son asíncronos async
max_depth Hasta dónde se anidan las relaciones en los DTOs 5
logger_name El logger del cliente name
pool pool_size, max_overflow, pool_timeout, pool_recycle, pool_pre_ping, ssl, sqlalchemy_logs lo que declare el datasource() del schema

frontend

Clave Qué es Por defecto
output_dir Dónde se escribe el cliente, relativo al .taiapiproject. Obligatorio —
base_path De dónde cuelga la API vista desde el navegador /api
tanstack Las opciones de TanStack Query true
zod Los esquemas de los formularios true
react El adaptador de React, con react-router false
svelte El adaptador de Svelte (Svelte 4 o 5, con SvelteKit o sin él) false

react y svelte solo se escriben en el .taiapiproject si se activan: así una versión de tai-api anterior a ellos sigue pudiendo leer el de un proyecto que no los usa. generate comprueba en el package.json del frontend que esté instalado lo que activan react, svelte y zod, y si no, falla sin escribir nada (A012): ese cliente no compilaría. Una clave que tai-api no conoce (de una versión posterior, o una errata) se ignora con un aviso.

El config.py

tai-api init lo copia una vez y es tuyo:

VERSION = "0.1.0"          # la versión que enseñan /docs y /health
ROOT_PATH = ""             # el prefijo si la API cuelga de una ruta: "/api"
ALLOWED_ORIGINS = ["*"]    # los orígenes de CORS

@asynccontextmanager
async def lifespan(app: FastAPI):
    yield                  # lo que se hace al arrancar y al parar

Con la sesión con cookie, ALLOWED_ORIGINS no puede ser *

La API no arranca: con credenciales, el comodín aceptaría peticiones desde cualquier sitio. Detrás del proxy /api del frontend todo es mismo origen, y la lista puede quedar vacía ([]). Si el frontend llama a la API desde otro origen, van los orígenes exactos (["https://app.cliente.com"]).

ROOT_PATH es el prefijo que el proxy le quita a la ruta: el proxy /api del frontend reenvía /api/pedido como /pedido, y la API tiene que saber que se la sirve bajo /api para que la cookie de sesión vaya a /api/auth y la documentación enlace bien. Detrás de ese proxy, "/api".