Runtime e deploy
Quando usar esta página
Use esta trilha quando você precisa operar o Atreides como serviço:
- validar contratos HTTP da API command-side;
- testar JWT e escopo por tenant;
- disparar workflows no Airflow;
- executar as etapas de treino como jobs separados;
- inspecionar health, readiness, métricas e DAG runs.
Para o desenvolvimento diário, prefira Quickstart.
Comandos principais
just db-initjust db-migrations-dry-runjust seed-local-model-definitionjust serve-httpComandos auxiliares:
just config-validate <manifest.json>just config-apply <manifest.json>just config-apply-manifestsjust db-init aplica as migrations ClickHouse pendentes e registra as versões em
schema_migrations. Use just db-migrations-dry-run para listar as versões que
seriam aplicadas antes de executar contra um ambiente. just seed-local-model-definition cria a definição determinística usada pelos exemplos
locais, e just serve-http sobe a API carregando .env pelo just.
Configurações por organização
O diretório versionado config/orgs/ é o ponto padrão para configurações por
organização aplicadas em CI/CD. Cada organização deve ter um subdiretório próprio
com um manifest.json no mesmo contrato usado por just config-apply:
config/orgs/<organization_slug>/manifest.jsonEnquanto não houver manifests reais, o diretório permanece versionado com
.gitkeep e just config-apply-manifests termina sem aplicar nada. Quando houver
manifests, o comando percorre os subdiretórios em ordem determinística e ativa as
revisions de configuração no ClickHouse usando DATABASE_URL.
Esses manifests são a configuração operacional dos ModelDefinitions que a
organização poderá disparar. Um ModelDefinition representa uma política de
forecast para uma população de séries: receita de projeção, horizonte, validação,
features, estratégias, métricas e promoção. Depois que as revisões são aplicadas,
os triggers de treino e predição escolhem uma definição por model_definition_id.
O fluxo atual não tem roteamento granular por série no runtime. O trigger não
envia uma lista de SeriesKeys. Ele envia organization_id,
model_definition_id e snapshot_id; a definição escolhida resolve sua
series_projection_recipe; e o workflow processa todas as séries que essa
receita produz a partir do snapshot.
Variáveis de ambiente mínimas
export DATABASE_URL=clickhouse://default@127.0.0.1:8123/atreidesexport JWT_SECRET=dev-jwt-secret-with-sufficient-lengthexport AIRFLOW_API_BASE_URL=http://127.0.0.1:8080export AIRFLOW_LOCAL_DEV_AUTO_AUTH=true
export MLFLOW_TRACKING_URI=http://127.0.0.1:5000export DEMAND_STORAGE_BACKEND=s3export DEMAND_INGESTION_BUCKET=atreides-demandexport ARTIFACT_STORE_BACKEND=s3export MODEL_ARTIFACT_BUCKET=atreides-artifactsexport S3_ENDPOINT_URL=http://127.0.0.1:9000export S3_REGION=us-east-1export S3_ACCESS_KEY_ID=minioadminexport S3_SECRET_ACCESS_KEY=minioadminexport S3_USE_SSL=false
# Opcional: habilita exportacao OTLP/HTTP de traces para um collector.export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318API HTTP:
- exige
DATABASE_URL; - exige
JWT_SECRET; - exige
AIRFLOW_API_BASE_URL; - aceita
AIRFLOW_API_VERSION, padrãov2; - aceita
AIRFLOW_MODEL_TRAINING_DAG_ID, padrãomodel_training; - aceita
AIRFLOW_BEARER_TOKENpara ambientes com token explícito; - aceita
AIRFLOW_LOCAL_DEV_AUTO_AUTH=trueapenas para dev local com Airflow standalone; - não executa treino, materialização nem retry.
Jobs do Airflow:
- exigem
DATABASE_URL; - exigem
MLFLOW_TRACKING_URI; - exigem
DEMAND_STORAGE_BACKEND; - em
filesystem, exigemDEMAND_STORAGE_ROOT; - em
s3, exigemDEMAND_INGESTION_BUCKET; - em artifact store
s3, exigemMODEL_ARTIFACT_BUCKET; - quando usar MinIO/S3 compatível local, configure também
S3_ENDPOINT_URL,S3_ACCESS_KEY_ID,S3_SECRET_ACCESS_KEYeS3_USE_SSL=false.
Airflow:
- carrega DAGs de
src/infra/dags; - precisa de
PYTHONPATH=srcou equivalente; - executa os entrypoints em
src/infra/jobs; - é o dono de retries e estado operacional do workflow.
Observabilidade
O processo HTTP expõe GET /metrics fora do namespace /v1, portanto sem JWT,
para scrape Prometheus. A resposta inclui métricas de runtime Python e as
métricas operacionais do Atreides emitidas pelo adapter OpenTelemetry:
| Métrica Prometheus | Uso |
|---|---|
forecast_engine_operation_started_total | contador de operações iniciadas |
forecast_engine_operation_completed_total | contador de operações concluídas com sucesso |
forecast_engine_operation_failed_total | contador de falhas por operação e tipo de erro |
forecast_engine_operation_active | gauge de operações em andamento no processo |
forecast_engine_operation_duration_seconds | histograma de duração por operação |
forecast_engine_operation_series | histograma de séries processadas por operação |
forecast_engine_model_version | histograma da versão de modelo tocada pela operação |
As labels de métrica ficam restritas a dimensões de baixa cardinalidade:
operation, outcome, workflow, error_type, http_method, http_route e
http_status_code. Identificadores como organization_id,
model_definition_id e snapshot_id entram nos logs e spans, mas não viram
labels Prometheus.
As operações instrumentadas hoje são:
http.request: request HTTP com método, rota FastAPI templated e status;training.workflow.submit: API HTTP criou snapshot e disparou a DAG de treino;prediction.workflow.submit: API HTTP criou snapshot e disparou a DAG de predição;training.candidates.execute: job de treino resolveu configuração, treinou candidatas e persistiu instâncias;prediction.forecast.execute: job batch executou forecasts e persistiuForecastRuns.
O runtime também cria spans OpenTelemetry para as execuções de treino e forecast.
Para exportar traces e métricas OTLP em produção, configure
OTEL_EXPORTER_OTLP_ENDPOINT no processo HTTP e nos jobs. Sem essa variável, o
HTTP continua expondo métricas via /metrics, mas os jobs de Airflow ficam
limitados a logs e spans/métricas locais no processo. Com OTLP habilitado, o
shutdown dos jobs força o flush dos exporters antes de fechar os recursos.
Fluxo HTTP manual
- Gere um token local:
just setup-local-auth 01956c73-9c1f-7fb7-94b1-a2c5bc65d901 local-operator- Dispare treino em
POST /v1/model-definitions/{model_definition_id}/training-jobsinformandoinput_pathesource_format. - A API cria o snapshot
processinge dispara a DAGmodel_training. - Acompanhe o run no Airflow pelo
run_idretornado. - Acompanhe os resultados duráveis em ClickHouse, MLflow, storage e nas projeções externas do ambiente.
Regras operacionais:
- toda rota
/v1/*exige JWT bearer; - o
organization_iddo token é a fonte de verdade do tenant; model_definition_idseleciona a política de forecast que será executada;- a execução cobre todas as séries projetadas por essa definição no snapshot;
- não há parâmetro HTTP para limitar treino a uma lista de séries individuais;
- preparação de snapshot e treino rodam em jobs chamados pelo Airflow, não no processo HTTP;
- retry e reexecução pertencem ao Airflow;
- o Atreides permanece write-side para snapshots, treino e promoção; consultas operacionais detalhadas vivem fora deste serviço.
Contrato OpenAPI
A especificação OpenAPI é gerada pelo código FastAPI em src/infra/http e é a
referência operacional do contrato HTTP. Com a API em execução, use:
GET /openapi.jsonpara consumir a especificação;GET /docspara a UI Swagger;GET /redocpara a UI ReDoc;GET /healthzpara readiness do processo e dependências configuradas.
O schema documenta o security scheme BearerAuth, os operationId estáveis das
rotas de comando, exemplos de payload e respostas de erro esperadas. Se um campo
do contrato HTTP mudar, atualize primeiro os DTOs, rotas e docstrings em
src/infra/http, depois sincronize esta documentação.
Seed customizado
Para o seed local padrão, prefira:
just seed-local-model-definitionSe precisar customizar ids ou seletor, rode o módulo diretamente:
PYTHONPATH=src uv run python -m infra.persistence.clickhouse.seed \ --database-url "$DATABASE_URL" \ --organization-id "<organization_id>" \ --model-definition-id "<model_definition_id>" \ --name "mvp-seasonal-naive"Checklist de runtime
- banco do Atreides atualizado com a migration mais recente;
- Airflow iniciado e carregando a DAG
model_training; - ao menos um
ModelDefinitionpersistido e configurado por organização atendida; - operadores sabem qual
model_definition_idcorresponde a cada população de séries; AIRFLOW_API_BASE_URLconfigurado no processo HTTP;- token de Airflow configurado por
AIRFLOW_BEARER_TOKENem runtime real ouAIRFLOW_LOCAL_DEV_AUTO_AUTH=trueem dev local; MLFLOW_TRACKING_URIválido para os jobs;- backend de demanda configurado para os jobs;
- backend de artefatos configurado para os jobs;
- S3 compatível configurado quando usar MinIO;
- JWT configurado para todo
/v1/*; /healthzrespondendo sem erro.
Onde continuar
- Configuração de model definition para montar payloads válidos.
- Airflow e jobs para entender DAG, tasks e retries.
- Storage e artefatos para snapshot canônico e artifact store.