Skip to content

feat: migra pipelines de dados do Prefect 0 para o Prefect 3 - #1553

Merged
Winzen merged 6 commits into
mainfrom
feat/prefect3-flows-migration
Jun 11, 2026
Merged

feat: migra pipelines de dados do Prefect 0 para o Prefect 3#1553
Winzen merged 6 commits into
mainfrom
feat/prefect3-flows-migration

Conversation

@folhesgabriel

@folhesgabriel folhesgabriel commented May 21, 2026

Copy link
Copy Markdown
Collaborator

Migração Prefect 0 → Prefect 3

Migração completa da infraestrutura e dos flows de orquestração de dados da Base dos Dados do Prefect 0.15 para o Prefect 3, rodando em Kubernetes (GKE). Este PR vai direto para main e substitui integralmente a stack de orquestração em produção.


Commits

`feat: configura imagem Docker, CI/CD e tooling de deploy para Prefect 3`

Docker image (`Dockerfile.prefect3` + `entrypoint.sh`):

  • Python 3.12 via `uv`; pacotes instalados no Python do sistema para que o Prefect engine (`/usr/local/bin/python`) os encontre em runtime sem ajuste de `PYTHONPATH`
  • `entrypoint.sh` decodifica `BASEDOSDADOS_CREDENTIALS_STAGING/PROD` e `DBT_SERVICE_ACCOUNT` (base64) em `/credentials-{dev,prod}/*.json` antes de iniciar o flow — um único secret K8s serve tanto a lib `basedosdados` quanto o dbt
  • `dbt_packages` instalados no build em `/app/dbt_packages`; `dbt_project.yml` define `packages-install-path` para o mesmo caminho, independente do `cwd` em runtime

Dependências (`pyproject.toml` / `uv.lock`): atualizadas para Python 3.12 — `PyYAML >=6.0.1`, `lxml >=4.9.4`, `grpcio >=1.59.0`, `shapely >=2.0.2`, `pymssql >=2.3.0`, `google-auth >=2.23.0`

CI/CD (`.github/workflows/`):

  • `build-docker-prefect3.yaml` — build e push para GCR a cada alteração em `Dockerfile.prefect3`, `pyproject.toml`, `uv.lock` ou `entrypoint.sh`; atualiza a imagem default dos dois work pools via API do Prefect
  • `cd-prefect3.yaml` — registra todos os flows no pool `basedosdados` (prod) a cada push em `main`
  • `cd-prefect3-staging.yaml` — registra flows alterados no pool `basedosdados-dev` em PRs com a label `deploy-flow`

Deploy script (`.github/scripts/deploy_flows.py`): descobre flows importando dinamicamente cada `datasets/*/flows.py`; pula arquivos Prefect 0 automaticamente (`ImportError` em `from prefect import Parameter`); aceita `--pool`, `--branch` e `--files` para deploys pontuais.


`refactor: divide utils.py em módulos especializados para Prefect 3`

O `utils.py` original (1 033 linhas, API Prefect 0) é substituído por cinco módulos com responsabilidade única:

Módulo Conteúdo
`utils/vault.py` `get_vault_client`, `get_vault_secret`, `get_credentials_from_secret`
`utils/gcs.py` `DBTArtifactUploader`, `dump_header`, `get_credentials_from_env`
`utils/tasks.py` `@tasks` Prefect 3: `rename_flow_run_dataset_table`, `upload_to_gcs`, `run_dbt`, `download_data_to_gcs`
`utils/utils.py` `log()`, `is_running_in_prod()`, `to_partitions()`, `query_to_line()`
`utils/init.py` Limpo — removidos os `from pipelines.datasets.*.flows import *` que importavam flows Prefect 0 e quebravam qualquer import do módulo

Mudanças de comportamento relevantes:

  • `is_running_in_prod()` lê `prefect.runtime.flow_run.work_pool_name` em vez da env var `PREFECT__CLOUD__AUTH_TOKEN` do Prefect 0
  • `upload_to_gcs` recebe `bucket_name` explicitamente; `billing_project_id` é definido igual ao `bucket_name` para evitar 403 em buckets com requester-pays
  • `notify_discord_on_failure` usa a assinatura de hook do Prefect 3 (`flow, flow_run, state, ...`) e é projetado para ser parcializado com `functools.partial`

`feat: introduz camada register_* para atualização de cobertura temporal`

Substitui o meta-flow `update_temporal_coverage` do Prefect 0 por uma biblioteca Python tipada e testável que os flows chamam diretamente como `@tasks` do Prefect 3.

Arquitetura (`pipelines/utils/metadata/`):

Arquivo Responsabilidade
`domain.py` Tipo union `CoverageSpec`: `AllBdpro
`dto.py` Data transfer objects imutáveis passados entre camadas
`client.py` Cliente GraphQL autenticado via Vault (JWT via `tokenAuth`); header obtido em tempo de execução
`policy.py` Funções puras: `compute_coverage_dates(spec, source_max_date)` — toda a lógica de cobertura temporal isolada e testável
`bq.py` Adapter `BigQueryReader` + wrappers `@task`; lê data máxima da fonte no BigQuery
`register.py` `register_source_poll_task`, `register_source_poll_by_size`, `update_temporal_coverage` (`@flow` substituto do meta-flow P0)

`utils_async.py` deletado — zero callers confirmados por grep. Equivalência tipo-8 verificada via testes: nova lógica de cobertura == output legado em todos os casos.


`feat: migra todos os datasets do Prefect 0 para o Prefect 3`

46 datasets migrados. Mudanças estruturais aplicadas em todos:

Prefect 0 Prefect 3
`with Flow(name=...) as flow` `@flow(name=...) def flow(...)`
`Parameter("x", default=v)` argumento tipado com default
`CronClock` em objeto `Schedule` `flow.deploy_schedules` (lista de dicts)
`with case(cond, True)` Python puro `if cond`
`max_retries=N, retry_delay=timedelta(...)` `retries=N, retry_delay_seconds=N`
`flow.storage`, `flow.run_config`, `flow.executor` removidos (gerenciados pelo worker K8s)
`schedules.py` por dataset removido (schedule vive no `flows.py`)

Tasks movidas de `datasets/` para `crawler/` para evitar o trigger do `datasets/init.py` que importava todos os flows Prefect 0 e quebrava o ambiente Prefect 3.

Flows deprecados removidos: `br_b3_cotacoes`, `br_mercadolivre_ofertas`, `br_mg_belohorizonte_smfa_iptu`, `br_ons_avaliacao_operacao`, `br_ons_estimativa_custos`, `cross_update`, `mundo_transfermarkt_competicoes`, `mundo_transfermarkt_competicoes_internacionais`, `world_sofascore_competicoes_futebol`

Datasets migrados: `br_anatel_banda_larga_fixa`, `br_anatel_telefonia_movel`, `br_anp_precos_combustiveis`, `br_ans_beneficiario`, `br_bcb_agencia`, `br_bcb_estban`, `br_bcb_sicor`, `br_bcb_taxa_cambio`, `br_bcb_taxa_selic`, `br_bd_indicadores`, `br_bd_siga_o_dinheiro`, `br_camara_dados_abertos` (26 tabelas), `br_cgu_beneficios_cidadao`, `br_cgu_cartao_pagamento`, `br_cgu_emendas_parlamentares`, `br_cgu_licitacao_contrato`, `br_cgu_pessoal_executivo_federal`, `br_cgu_servidores_executivo_federal`, `br_cnj_improbidade_administrativa`, `br_cvm_administradores_carteira`, `br_cvm_fi`, `br_cvm_oferta_publica_distribuicao`, `br_denatran_frota`, `br_fgv_igp`, `br_ibge_inpc`, `br_ibge_ipca`, `br_ibge_ipca15`, `br_ibge_pnadc`, `br_inmet_bdmep`, `br_me_caged`, `br_me_cnpj`, `br_me_comex_stat`, `br_me_rais`, `br_mp_pep`, `br_ms_cnes`, `br_ms_sia`, `br_ms_sih`, `br_ms_sinan`, `br_poder360_pesquisas`, `br_rf_cafir`, `br_rf_cno`, `br_rj_isp_estatisticas_seguranca`, `br_sfb_sicar`, `br_stf_corte_aberta`, `br_tse_eleicoes`, `fundacao_lemann`


`chore: ajusta workflows de CI/CD — desativa P0 e restringe P3 para main`

Workflows Prefect 0 desativados (trigger alterado para `workflow_dispatch`):

  • `cd.yaml` — deploy de flows para o Prefect 0 (prod)
  • `cd-staging.yaml` — deploy de flows para o Prefect 0 (staging)
  • `build-docker.yaml` — build da imagem Docker do Prefect 0

Workflows Prefect 3 corrigidos (triggers restritos a `main`):

  • `cd-prefect3.yaml` — dispara apenas em push para `main`
  • `build-docker-prefect3.yaml` — dispara apenas em push para `main`
  • `cd-prefect3-staging.yaml` — dispara apenas em PRs para `main`

Estado dos flows em prod

Status Flows
✅ Rodando no Prefect 3 160
⚠️ Bloqueado (OOM ou bug no crawler) 10
⚠️ Schedule desativado (falhas repetidas) 5
❌️ Sem flows.py (confirmar) 2

Detalhes em `docs/infraestrutura/prefect/migracao-prefect-3/` no repositório `basedosdados/manual-equipe-dados`.

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 287 files, which is 137 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 25d8eadc-0cfc-43cb-bc21-e47ec4754a8a

📥 Commits

Reviewing files that changed from the base of the PR and between baea805 and d389d15.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (287)
  • .github/scripts/deploy_flows.py
  • .github/workflows/build-docker-prefect3.yaml
  • .github/workflows/build-docker.yaml
  • .github/workflows/cd-prefect3-staging.yaml
  • .github/workflows/cd-prefect3.yaml
  • .github/workflows/cd-staging.yaml
  • .github/workflows/cd.yaml
  • .gitignore
  • dbt_project.yml
  • pipelines/constants.py
  • pipelines/crawler/anatel/banda_larga_fixa/flows.py
  • pipelines/crawler/anatel/banda_larga_fixa/tasks.py
  • pipelines/crawler/anatel/telefonia_movel/flows.py
  • pipelines/crawler/anatel/telefonia_movel/tasks.py
  • pipelines/crawler/anp_precos_combustiveis/__init__.py
  • pipelines/crawler/anp_precos_combustiveis/constants.py
  • pipelines/crawler/anp_precos_combustiveis/tasks.py
  • pipelines/crawler/anp_precos_combustiveis/utils.py
  • pipelines/crawler/ans_beneficiario/__init__.py
  • pipelines/crawler/ans_beneficiario/constants.py
  • pipelines/crawler/ans_beneficiario/tasks.py
  • pipelines/crawler/ans_beneficiario/utils.py
  • pipelines/crawler/bcb/flows.py
  • pipelines/crawler/bcb/tasks.py
  • pipelines/crawler/bcb_agencia/__init__.py
  • pipelines/crawler/bcb_agencia/constants.py
  • pipelines/crawler/bcb_agencia/tasks.py
  • pipelines/crawler/bcb_agencia/utils.py
  • pipelines/crawler/bcb_estban/__init__.py
  • pipelines/crawler/bcb_estban/constants.py
  • pipelines/crawler/bcb_estban/tasks.py
  • pipelines/crawler/bcb_estban/utils.py
  • pipelines/crawler/bcb_taxa_cambio/__init__.py
  • pipelines/crawler/bcb_taxa_cambio/constants.py
  • pipelines/crawler/bcb_taxa_cambio/tasks.py
  • pipelines/crawler/bcb_taxa_cambio/utils.py
  • pipelines/crawler/bd_indicadores/__init__.py
  • pipelines/crawler/bd_indicadores/tasks.py
  • pipelines/crawler/bd_indicadores/utils.py
  • pipelines/crawler/bd_siga_o_dinheiro/__init__.py
  • pipelines/crawler/bd_siga_o_dinheiro/tasks.py
  • pipelines/crawler/camara_dados_abertos/constants.py
  • pipelines/crawler/camara_dados_abertos/flows.py
  • pipelines/crawler/camara_dados_abertos/tasks.py
  • pipelines/crawler/cgu/flows.py
  • pipelines/crawler/cgu/tasks.py
  • pipelines/crawler/cgu_emendas_parlamentares/__init__.py
  • pipelines/crawler/cgu_emendas_parlamentares/constants.py
  • pipelines/crawler/cgu_emendas_parlamentares/tasks.py
  • pipelines/crawler/cgu_pessoal_executivo_federal/__init__.py
  • pipelines/crawler/cgu_pessoal_executivo_federal/tasks.py
  • pipelines/crawler/cnj_improbidade_administrativa/__init__.py
  • pipelines/crawler/cnj_improbidade_administrativa/constants.py
  • pipelines/crawler/cnj_improbidade_administrativa/tasks.py
  • pipelines/crawler/cnj_improbidade_administrativa/utils.py
  • pipelines/crawler/cvm/flows.py
  • pipelines/crawler/cvm/tasks.py
  • pipelines/crawler/cvm_administradores_carteira/__init__.py
  • pipelines/crawler/cvm_administradores_carteira/flows.py
  • pipelines/crawler/cvm_administradores_carteira/tasks.py
  • pipelines/crawler/cvm_oferta_publica_distribuicao/__init__.py
  • pipelines/crawler/cvm_oferta_publica_distribuicao/tasks.py
  • pipelines/crawler/datasus/flows.py
  • pipelines/crawler/datasus/tasks.py
  • pipelines/crawler/denatran_frota/__init__.py
  • pipelines/crawler/denatran_frota/constants.py
  • pipelines/crawler/denatran_frota/tasks.py
  • pipelines/crawler/denatran_frota/utils.py
  • pipelines/crawler/fgv_igp/__init__.py
  • pipelines/crawler/fgv_igp/constants.py
  • pipelines/crawler/fgv_igp/flows.py
  • pipelines/crawler/fgv_igp/tasks.py
  • pipelines/crawler/fgv_igp/utils.py
  • pipelines/crawler/ibge_inflacao/README.md
  • pipelines/crawler/ibge_inflacao/flows.py
  • pipelines/crawler/ibge_pnadc/__init__.py
  • pipelines/crawler/ibge_pnadc/constants.py
  • pipelines/crawler/ibge_pnadc/tasks.py
  • pipelines/crawler/ibge_pnadc/utils.py
  • pipelines/crawler/inmet_bdmep/__init__.py
  • pipelines/crawler/inmet_bdmep/constants.py
  • pipelines/crawler/inmet_bdmep/tasks.py
  • pipelines/crawler/inmet_bdmep/utils.py
  • pipelines/crawler/isp/flows.py
  • pipelines/crawler/isp/tasks.py
  • pipelines/crawler/me_caged/__init__.py
  • pipelines/crawler/me_caged/constants.py
  • pipelines/crawler/me_caged/tasks.py
  • pipelines/crawler/me_caged/utils.py
  • pipelines/crawler/me_cnpj/__init__.py
  • pipelines/crawler/me_cnpj/constants.py
  • pipelines/crawler/me_cnpj/flows.py
  • pipelines/crawler/me_cnpj/tasks.py
  • pipelines/crawler/me_cnpj/utils.py
  • pipelines/crawler/me_comex_stat/__init__.py
  • pipelines/crawler/me_comex_stat/constants.py
  • pipelines/crawler/me_comex_stat/tasks.py
  • pipelines/crawler/me_comex_stat/utils.py
  • pipelines/crawler/me_rais/__init__.py
  • pipelines/crawler/me_rais/constants.py
  • pipelines/crawler/me_rais/flows.py
  • pipelines/crawler/me_rais/tasks.py
  • pipelines/crawler/me_rais/utils.py
  • pipelines/crawler/mp_pep/__init__.py
  • pipelines/crawler/mp_pep/constants.py
  • pipelines/crawler/mp_pep/tasks.py
  • pipelines/crawler/mp_pep/utils.py
  • pipelines/crawler/poder360_pesquisas/__init__.py
  • pipelines/crawler/poder360_pesquisas/tasks.py
  • pipelines/crawler/rf/flows.py
  • pipelines/crawler/rf/tasks.py
  • pipelines/crawler/rf_cafir/__init__.py
  • pipelines/crawler/rf_cafir/constants.py
  • pipelines/crawler/rf_cafir/tasks.py
  • pipelines/crawler/rf_cafir/utils.py
  • pipelines/crawler/sfb_sicar/__init__.py
  • pipelines/crawler/sfb_sicar/constants.py
  • pipelines/crawler/sfb_sicar/tasks.py
  • pipelines/crawler/sfb_sicar/utils.py
  • pipelines/crawler/stf_corte_aberta/__init__.py
  • pipelines/crawler/stf_corte_aberta/constants.py
  • pipelines/crawler/stf_corte_aberta/tasks.py
  • pipelines/crawler/stf_corte_aberta/utils.py
  • pipelines/crawler/tse_eleicoes/flows.py
  • pipelines/crawler/tse_eleicoes/tasks.py
  • pipelines/crawler/world_sofascore_competicoes_futebol/constants.py
  • pipelines/crawler/world_sofascore_competicoes_futebol/flows.py
  • pipelines/crawler/world_sofascore_competicoes_futebol/tasks.py
  • pipelines/crawler/world_sofascore_competicoes_futebol/utils.py
  • pipelines/datasets/__init__.py
  • pipelines/datasets/br_anatel_banda_larga_fixa/__init__.py
  • pipelines/datasets/br_anatel_banda_larga_fixa/flows.py
  • pipelines/datasets/br_anatel_banda_larga_fixa/schedules.py
  • pipelines/datasets/br_anatel_telefonia_movel/flows.py
  • pipelines/datasets/br_anatel_telefonia_movel/schedules.py
  • pipelines/datasets/br_anp_precos_combustiveis/flows.py
  • pipelines/datasets/br_anp_precos_combustiveis/schedules.py
  • pipelines/datasets/br_ans_beneficiario/flows.py
  • pipelines/datasets/br_ans_beneficiario/schedules.py
  • pipelines/datasets/br_b3_cotacoes/constants.py
  • pipelines/datasets/br_b3_cotacoes/flows.py
  • pipelines/datasets/br_b3_cotacoes/schedules.py
  • pipelines/datasets/br_b3_cotacoes/tasks.py
  • pipelines/datasets/br_b3_cotacoes/utils.py
  • pipelines/datasets/br_bcb_agencia/flows.py
  • pipelines/datasets/br_bcb_agencia/schedules.py
  • pipelines/datasets/br_bcb_estban/flows.py
  • pipelines/datasets/br_bcb_estban/schedules.py
  • pipelines/datasets/br_bcb_sicor/flows.py
  • pipelines/datasets/br_bcb_sicor/schedules.py
  • pipelines/datasets/br_bcb_taxa_cambio/flows.py
  • pipelines/datasets/br_bcb_taxa_selic/flows.py
  • pipelines/datasets/br_bd_indicadores/flows.py
  • pipelines/datasets/br_bd_siga_o_dinheiro/flows.py
  • pipelines/datasets/br_bndes_operacoes_contratadas/README.md
  • pipelines/datasets/br_bndes_operacoes_contratadas/constants.py
  • pipelines/datasets/br_bndes_operacoes_contratadas/flows.py
  • pipelines/datasets/br_bndes_operacoes_contratadas/schedules.py
  • pipelines/datasets/br_bndes_operacoes_contratadas/tasks.py
  • pipelines/datasets/br_bndes_operacoes_contratadas/utils.py
  • pipelines/datasets/br_camara_dados_abertos/flows.py
  • pipelines/datasets/br_camara_dados_abertos/schedules.py
  • pipelines/datasets/br_cgu_beneficios_cidadao/flows.py
  • pipelines/datasets/br_cgu_beneficios_cidadao/schedules.py
  • pipelines/datasets/br_cgu_cartao_pagamento/flows.py
  • pipelines/datasets/br_cgu_cartao_pagamento/schedules.py
  • pipelines/datasets/br_cgu_emendas_parlamentares/flows.py
  • pipelines/datasets/br_cgu_emendas_parlamentares/schedules.py
  • pipelines/datasets/br_cgu_licitacao_contrato/flows.py
  • pipelines/datasets/br_cgu_licitacao_contrato/schedules.py
  • pipelines/datasets/br_cgu_pessoal_executivo_federal/flows.py
  • pipelines/datasets/br_cgu_pessoal_executivo_federal/schedules.py
  • pipelines/datasets/br_cgu_servidores_executivo_federal/flows.py
  • pipelines/datasets/br_cgu_servidores_executivo_federal/schedules.py
  • pipelines/datasets/br_cnj_improbidade_administrativa/flows.py
  • pipelines/datasets/br_cvm_administradores_carteira/flows.py
  • pipelines/datasets/br_cvm_administradores_carteira/schedules.py
  • pipelines/datasets/br_cvm_fi/flows.py
  • pipelines/datasets/br_cvm_fi/schedules.py
  • pipelines/datasets/br_cvm_oferta_publica_distribuicao/flows.py
  • pipelines/datasets/br_cvm_oferta_publica_distribuicao/schedules.py
  • pipelines/datasets/br_denatran_frota/flows.py
  • pipelines/datasets/br_denatran_frota/schedules.py
  • pipelines/datasets/br_fgv_igp/flows.py
  • pipelines/datasets/br_ibge_ipca/flows.py
  • pipelines/datasets/br_ibge_ipca15/flows.py
  • pipelines/datasets/br_ibge_pnadc/flows.py
  • pipelines/datasets/br_inmet_bdmep/README.md
  • pipelines/datasets/br_inmet_bdmep/flows.py
  • pipelines/datasets/br_inmet_bdmep/schedules.py
  • pipelines/datasets/br_inmet_bdmep/tasks.py
  • pipelines/datasets/br_me_caged/flows.py
  • pipelines/datasets/br_me_cnpj/flows.py
  • pipelines/datasets/br_me_cnpj/schedules.py
  • pipelines/datasets/br_me_comex_stat/flows.py
  • pipelines/datasets/br_me_comex_stat/schedules.py
  • pipelines/datasets/br_me_rais/flows.py
  • pipelines/datasets/br_mercadolivre_ofertas/__init__.py
  • pipelines/datasets/br_mercadolivre_ofertas/constants.py
  • pipelines/datasets/br_mercadolivre_ofertas/decorators.py
  • pipelines/datasets/br_mercadolivre_ofertas/flows.py
  • pipelines/datasets/br_mercadolivre_ofertas/schedules.py
  • pipelines/datasets/br_mercadolivre_ofertas/tasks.py
  • pipelines/datasets/br_mercadolivre_ofertas/utils.py
  • pipelines/datasets/br_mg_belohorizonte_smfa_iptu/__init__.py
  • pipelines/datasets/br_mg_belohorizonte_smfa_iptu/constants.py
  • pipelines/datasets/br_mg_belohorizonte_smfa_iptu/flows.py
  • pipelines/datasets/br_mg_belohorizonte_smfa_iptu/schedules.py
  • pipelines/datasets/br_mg_belohorizonte_smfa_iptu/tasks.py
  • pipelines/datasets/br_mg_belohorizonte_smfa_iptu/utils.py
  • pipelines/datasets/br_mp_pep/flows.py
  • pipelines/datasets/br_ms_cnes/flows.py
  • pipelines/datasets/br_ms_cnes/schedules.py
  • pipelines/datasets/br_ms_sia/flows.py
  • pipelines/datasets/br_ms_sia/schedules.py
  • pipelines/datasets/br_ms_sih/flows.py
  • pipelines/datasets/br_ms_sih/schedules.py
  • pipelines/datasets/br_ms_sinan/__init__.py
  • pipelines/datasets/br_ms_sinan/flows.py
  • pipelines/datasets/br_ms_sinan/schedules.py
  • pipelines/datasets/br_ons_avaliacao_operacao/__init__.py
  • pipelines/datasets/br_ons_avaliacao_operacao/constants.py
  • pipelines/datasets/br_ons_avaliacao_operacao/flows.py
  • pipelines/datasets/br_ons_avaliacao_operacao/schedules.py
  • pipelines/datasets/br_ons_avaliacao_operacao/tasks.py
  • pipelines/datasets/br_ons_avaliacao_operacao/utils.py
  • pipelines/datasets/br_ons_estimativa_custos/__init__.py
  • pipelines/datasets/br_ons_estimativa_custos/constants.py
  • pipelines/datasets/br_ons_estimativa_custos/flows.py
  • pipelines/datasets/br_ons_estimativa_custos/schedules.py
  • pipelines/datasets/br_ons_estimativa_custos/tasks.py
  • pipelines/datasets/br_ons_estimativa_custos/utils.py
  • pipelines/datasets/br_poder360_pesquisas/flows.py
  • pipelines/datasets/br_rf_cafir/flows.py
  • pipelines/datasets/br_rf_cno/flows.py
  • pipelines/datasets/br_rj_isp_estatisticas_seguranca/flows.py
  • pipelines/datasets/br_rj_isp_estatisticas_seguranca/schedules.py
  • pipelines/datasets/br_sfb_sicar/flows.py
  • pipelines/datasets/br_stf_corte_aberta/flows.py
  • pipelines/datasets/br_tse_eleicoes/flows.py
  • pipelines/datasets/cross_update/__init__.py
  • pipelines/datasets/cross_update/flows.py
  • pipelines/datasets/cross_update/schedules.py
  • pipelines/datasets/cross_update/tasks.py
  • pipelines/datasets/cross_update/utils.py
  • pipelines/datasets/fundacao_lemann/flows.py
  • pipelines/datasets/mundo_transfermarkt_competicoes/__init__.py
  • pipelines/datasets/mundo_transfermarkt_competicoes/constants.py
  • pipelines/datasets/mundo_transfermarkt_competicoes/decorators.py
  • pipelines/datasets/mundo_transfermarkt_competicoes/flows.py
  • pipelines/datasets/mundo_transfermarkt_competicoes/schedules.py
  • pipelines/datasets/mundo_transfermarkt_competicoes/tasks.py
  • pipelines/datasets/mundo_transfermarkt_competicoes/utils.py
  • pipelines/datasets/mundo_transfermarkt_competicoes_internacionais/__init__.py
  • pipelines/datasets/mundo_transfermarkt_competicoes_internacionais/constants.py
  • pipelines/datasets/mundo_transfermarkt_competicoes_internacionais/decorators.py
  • pipelines/datasets/mundo_transfermarkt_competicoes_internacionais/flows.py
  • pipelines/datasets/mundo_transfermarkt_competicoes_internacionais/schedules.py
  • pipelines/datasets/mundo_transfermarkt_competicoes_internacionais/tasks.py
  • pipelines/datasets/mundo_transfermarkt_competicoes_internacionais/utils.py
  • pipelines/datasets/world_sofascore_competicoes_futebol/__init__.py
  • pipelines/datasets/world_sofascore_competicoes_futebol/flows.py
  • pipelines/datasets/world_sofascore_competicoes_futebol/schedules.py
  • pipelines/utils/dump_to_gcs/flows.py
  • pipelines/utils/metadata/bq.py
  • pipelines/utils/metadata/client.py
  • pipelines/utils/metadata/constants.py
  • pipelines/utils/metadata/domain.py
  • pipelines/utils/metadata/dto.py
  • pipelines/utils/metadata/flows.py
  • pipelines/utils/metadata/policy.py
  • pipelines/utils/metadata/register.py
  • pipelines/utils/metadata/tasks.py
  • pipelines/utils/metadata/utils.py
  • pipelines/utils/metadata/utils_async.py
  • pipelines/utils/schema_validator.py
  • pipelines/utils/tasks.py
  • pipelines/utils/tests/metadata/conftest.py
  • pipelines/utils/tests/metadata/test_bq.py
  • pipelines/utils/tests/metadata/test_client.py
  • pipelines/utils/tests/metadata/test_domain.py
  • pipelines/utils/tests/metadata/test_dto.py
  • pipelines/utils/tests/metadata/test_policy.py
  • pipelines/utils/tests/metadata/test_register.py
  • pipelines/utils/tests/metadata/test_register_tasks.py
  • pipelines/utils/tests/test_check_if_data_is_outdated_by_size_task.py
  • pyproject.toml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR executes a comprehensive migration of the Prefect orchestration framework from 0.x/2.x to Prefect 3. Changes span dependency updates, utilities refactoring into focused modules, deployment infrastructure (Docker image, CI/CD workflows, deployment scripts), shared task updates, and individual flow migrations with renamed objects and inline scheduling.

Changes

Prefect 3 Migration

Layer / File(s) Summary
Dependency and Runtime Setup
pyproject.toml, Dockerfile.prefect3, entrypoint.sh, dbt_project.yml
Pinned dependencies updated to Prefect 3.x, dbt 1.8+, and Pydantic 2.0+. Container image based on prefecthq/prefect:3-python3.12 with Chrome, OCR, and dbt deps; startup entrypoint decodes base64 GCS credentials into dev/prod credential files.
Utilities Refactoring - Core Modules
pipelines/utils/__init__.py, pipelines/utils/vault.py, pipelines/utils/discord.py, pipelines/utils/gcs.py, pipelines/utils/utils.py
Monolithic utils.py split into single-responsibility modules: vault.py (Hashicorp client, secret reading), discord.py (webhook notifications with production gating), gcs.py (credentials, blob listing, header dumping, artifact uploading). Core utils.py retains logging, partition writing, dataframe cleaning; Prefect logger integration added.
Utilities Refactoring - Tasks and Metadata
pipelines/utils/tasks.py, pipelines/utils/execute_dbt_model/flows.py, pipelines/utils/metadata/tasks.py, pipelines/utils/metadata/utils.py
Shared Prefect 3 tasks refactored: get_credentials, rename_flow_run_dataset_table (async), upload_to_gcs, run_dbt (default "run/test", artifact upload in finally), download_data_to_gcs (simplified size-based policies); dbt/GCS flow task updated; metadata task retry config changed from max_retries/timedelta to retries/retry_delay_seconds.
Deployment Infrastructure
.github/scripts/deploy_flows.py, .github/workflows/build-docker-prefect3.yaml, .github/workflows/cd-prefect3.yaml, .github/workflows/cd-prefect3-staging.yaml, scripts/deploy_dbt_model_flow.py
Dynamic flow discovery and deployment script (deploy_flows.py) loads Python modules, extracts Prefect Flow objects, deploys via flow.from_source().deploy() with branch/pool selection and schedule handling. Docker build workflow computes image tags, pushes to GCR, updates Prefect 3 work pool config. Prod/staging CD workflows trigger on pipeline changes, invoking deploy script with API credentials.
Flow Migrations - BCB Datasets
pipelines/crawler/bcb_estban/{tasks.py,utils.py}, pipelines/datasets/br_bcb_estban/{flows.py,schedules.py}, pipelines/datasets/br_bcb_taxa_selic/flows.py
bcb_estban tasks updated with Prefect 3 retry params, safer empty-metadata handling, typed return types; utils import source switched to crawler path. Flows converted to @flow factories with inline deploy_schedules (cron + timezone), shared _run_* orchestration helpers, Discord failure notification, and force-run parameter for bypassing outdated checks. Flow object names changed to br_bcb_estban__* pattern; schedules.py removed.
Flow Migrations - IBGE Inflation Flows
pipelines/crawler/ibge_inflacao/{flows.py,utils.py}, pipelines/datasets/br_ibge_ipca/flows.py, pipelines/datasets/br_ibge_inpc/flows.py
Shared _run_ibge_inflacao orchestration helper factored out for IBGE flows; factory pattern _ipca_flow(table_id, cron) and _inpc_flow(...) generate per-table flows with inline schedule deployment. Task invocation method changed from .run() to .fn() in utils callsites. Flow object names changed to br_ibge_*__* double-underscore pattern.
Flow Migrations - Câmara and Test Flows
pipelines/datasets/br_camara_dados_abertos/flows.py, pipelines/test_prefect3.py
Câmara flow migrated for deputado table only (other tables removed from executable code, preserved as comments); implements URL check, download/delimiter conversion, dev/prod upload, dbt execution tasks within a single @flow. Simple test flow demonstrates Prefect 3 @task/@flow syntax.
Migration Documentation
Prefect 3 Guia de Migração de Flows.md, Prefect 3 Flows Migrados.md
Comprehensive guide covering utils refactoring, Prefect 0→3 construct mapping, canonical flow template, factory patterns, JWT/GraphQL metadata authentication, deployment commands, known pitfalls (task.fn vs task.run, import issues, env-var stalls). Tracking document lists migration criteria, flow status (deployed/tested dev/prod), and prioritized next-to-migrate list.

Sequence Diagrams

sequenceDiagram
  participant dev as Developer
  participant gh as GitHub
  participant deploy as deploy_flows.py
  participant prefect as Prefect API
  participant gcs as GCS/Storage

  gh->>gh: Push to main or feat/prefect3
  gh->>deploy: Trigger cd-prefect3 workflow
  deploy->>deploy: load_flows_from_file(path)
  deploy->>prefect: flow.from_source(repo, branch).deploy(pool_name, schedule)
  prefect->>gcs: Store flow definition
  prefect-->>deploy: deployment_id
  deploy-->>gh: Success/fail exit status
Loading
sequenceDiagram
  participant Flow as Prefect Flow
  participant Task as run_dbt task
  participant dbtRunner as dbtRunner
  participant GCS as GCS Artifacts

  Flow->>Task: run_dbt(dataset_id, model)
  Task->>Task: Validate dbt_command
  Task->>Task: Resolve model path
  Task->>dbtRunner: invoke(run_results_path, ...)
  dbtRunner-->>Task: InvocationResult
  Task->>GCS: Upload dbt artifacts (finally block)
  Task-->>Flow: Success or raise exception
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related issues

Suggested labels

check-metadata


🐰 Prefect 3 hops into the frame,
With tasks and flows in modern shape!
Utilities split, pipelines bright,
From zero-point-x to version-three-height! 🚀

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/prefect3-flows-migration

@folhesgabriel
folhesgabriel marked this pull request as draft May 21, 2026 17:48
@mergify

mergify Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

@folhesgabriel esse pull request tem conflitos 😩

@mergify mergify Bot added the conflict [PR] Conflito de merge a resolver label May 21, 2026
@folhesgabriel
folhesgabriel changed the base branch from main to feat/prefect3 May 21, 2026 17:48
Comment thread refatorar_backend.md Outdated
"""Cria/atualiza o `Update` ligado ao `RawDataSource`."""
```

Cada método é nomeado pela entidade que toca. Quem ler o flow entende imediatamente qual campo no Django está sendo escrito.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ótimo

@Winzen
Winzen force-pushed the feat/prefect3-flows-migration branch from f9918fb to 6d4dbc2 Compare June 11, 2026 11:44
@mergify

mergify Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

@folhesgabriel esse pull request tem conflitos 😩

@Winzen
Winzen force-pushed the feat/prefect3-flows-migration branch from 6d4dbc2 to 63e091b Compare June 11, 2026 12:17
@Winzen Winzen changed the title Feat/prefect3 flows migration feat: migrate data pipelines from Prefect 0 to Prefect 3 Jun 11, 2026
@Winzen
Winzen force-pushed the feat/prefect3-flows-migration branch from 63e091b to a80f8e8 Compare June 11, 2026 16:46
@Winzen Winzen changed the title feat: migrate data pipelines from Prefect 0 to Prefect 3 feat: migra pipelines de dados do Prefect 0 para o Prefect 3 Jun 11, 2026
@Winzen
Winzen force-pushed the feat/prefect3-flows-migration branch from 1192297 to 7c9cb40 Compare June 11, 2026 20:10
@Winzen
Winzen marked this pull request as ready for review June 11, 2026 20:13
@Winzen
Winzen force-pushed the feat/prefect3-flows-migration branch from 1a258d1 to 6c2e749 Compare June 11, 2026 20:38
@Winzen Winzen removed the conflict [PR] Conflito de merge a resolver label Jun 11, 2026
@mergify

mergify Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

@folhesgabriel esse pull request tem conflitos 😩

@mergify mergify Bot added the conflict [PR] Conflito de merge a resolver label Jun 11, 2026
@Winzen
Winzen force-pushed the feat/prefect3-flows-migration branch from 6c2e749 to a15094c Compare June 11, 2026 20:42
@Winzen
Winzen changed the base branch from feat/prefect3 to main June 11, 2026 20:44
@mergify

mergify Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

@folhesgabriel esse pull request tem conflitos 😩

@Winzen
Winzen force-pushed the feat/prefect3-flows-migration branch from a15094c to 85068be Compare June 11, 2026 20:49
@Winzen Winzen removed the conflict [PR] Conflito de merge a resolver label Jun 11, 2026
@Winzen
Winzen force-pushed the feat/prefect3-flows-migration branch from ecd2ce0 to 5d2d54f Compare June 11, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[chore] Migração gradual Prefect 0.15 → 3.0: validação de infra e ajuste de recursos [chore] migração dos flows Prefect 0.15 → 3.x

4 participants