Leitura (← CVM)¶
A seção filings_cvm.ingestion analisa e interpreta arquivos recebidos/baixados da CVM de
volta para modelos tipados — a contraparte do Envio.
Veja também: Referência da API · Uso.
Como importar um leitor — pelo portal root¶
Os leitores são agrupados pelo root do portal de dados abertos
(dados.cvm.gov.br/dados/<ROOT>/…), e cada root é a superfície pública dos seus leitores:
from filings_cvm.ingestion.cia_aberta import FreCiaAbertaAuditorReader
from filings_cvm.ingestion.fidc import InfMensalFidcTabIReader
from filings_cvm.ingestion.fi import InformeDiarioReader
São 22 roots: adm_cart, adm_fii, agente_auton, agente_fiduc, auditor, cia_aberta,
cia_estrang, cia_incent, consultor_vlmob, coord_oferta, crowdfunding, emissor_cepac,
fi, fiagro, fidc, fie, fii, fip, intermed, invnr, oferta, securit.
⚠️ Mudança incompatível na 0.26.0.
from filings_cvm import <Leitor>efrom filings_cvm.ingestion import <Leitor>deixaram de funcionar — os 216 leitores não são mais reexportados num namespace plano. Importe do root que é dono do leitor (a página de cada dataset mostra o import correto). O agrupamento é o do próprio portal da CVM; um namespace único de 216 nomes não tinha divisão nenhuma e crescia a cada leitor novo.
Padrões implementados¶
- Informe Diário FIF —
InformeDiarioReader: lê o dump mensal de open-data (inf_diario_fi_AAAAMM) e devolve umDataFrametipado e validado por contrato. - CDA FIF —
CdaReader: lê o dump mensal (cda_fi_AAAAMM), consolida os blocos de ativosBLC_1…BLC_8e traz o patrimônio líquido do fundo junto de cada posição. - Lâmina carteira FIF —
LaminaCarteiraReader: lê o membrolamina_fi_carteira_AAAAMMdo dump da Lâmina e devolve a alocação de cada fundo por tipo de ativo (PR_PL_ATIVO, percentual sinalizado do patrimônio líquido). - Lâmina FIF —
LaminaReader: lê o membrolamina_fi_AAAAMMdo mesmo dump — a lâmina propriamente dita, uma linha por classe de fundo com as suas 78 colunas. - Cadastro de Fundos (CAD/FI) —
CadastroFiReader: lêcad_fi.csv, o retrato do estado atual do cadastro. Semdate_refe sem chave única — o CNPJ se repete entre regimes regulatórios. - Registro RCVM 175 —
RegistroFundoReader,RegistroClasseReader,RegistroSubclasseReader: lêem os três membros deregistro_fundo_classe.zip(hierarquiafundo → classe → subclasse), o cadastro atual onde estão os fundos vivos. - CAD/FI histórico — 19 readers
CadastroFiHist*Reader: o log de alterações de cada atributo mutável do cadastro legado (situação, denominação, taxas, gestor, …), um por membro decad_fi_hist.zip. - Informe Mensal FIDC — 17 readers
InfMensalFidcTab*Reader: as tabelas do informe mensal dos FIDC (inf_mensal_fidc_AAAAMM.zip, Tabelas I–X + sub-tabelas de X), um por membro. Inaugura o portal rootfidc/. Cada reader declara a sua política de retry por tabela (_RETRY_POLICY). - Informe Mensal FII — 3 readers
InfMensalFii*Reader(geral,ativo_passivo,complemento): o informe mensal dos fundos imobiliários. Inaugura o portal rootfii/. ⚠️ O dump é particionado por ano (inf_mensal_fii_AAAA.zip), apesar de mensal — odate_refseleciona o ano. - DFIN FII —
DfinFiiReader: o índice das demonstrações financeiras dos FII (dfin_fii_AAAA.csv, um CSV solto). Uma linha por documento entregue, com umLink_Downloadque o reader devolve como texto e não segue. Particionado por ano. - Informe Trimestral FII — 16 readers
InfTrimestralFii*Reader: as tabelas do informe trimestral dos FII (inf_trimestral_fii_AAAA.zip) — cadastro, ativos, imóveis/terrenos e suas transações, rentabilidade e resultado contábil/financeiro. ⚠️ Particionado por ano (odate_refseleciona o ano, não o trimestre). - Informe Anual FII — 12 readers
InfAnualFii*Reader: as tabelas do informe anual dos FII (inf_anual_fii_AAAA.zip) — cadastro, ativos, distribuição de cotistas, diretor e prestadores, processos, representante. ⚠️ Contém CPF (dado pessoal, texto exato) e umLink_Download_Anexonão seguido. Com ele o portal rootfii/fica completo (4/4). - Informes periódicos FIP —
InfTrimestralFipReader+InfQuadrimestralFipReader: os dois informes dos FIP (CSVs soltos, particionados por ano), que inauguram o portal rootfip/. O trimestral é o regime pré-RCVM 175 (2010–2023); o quadrimestral o substituiu no pós-175 (2024→). Quase idênticos — só muda o identificador do fundo (CNPJ_FUNDOvsTP_FUNDO_CLASSE+CNPJ_FUNDO_CLASSE). - Informe Mensal FIAGRO — 2 readers
InfMensalFiagroReader+InfMensalFiagroSubclasseReader: o informe mensal dos FIAGRO (inf_mensal_fiagro_AAAAMM.zip, membrosinf_mensal_fiagro+inf_mensal_fiagro_subclasse), que inauguram o portal rootfiagro/. Particionado por mês (série a partir de202505); nomenclatura pós-RCVM 175 (chaveCNPJ_Classe). -
FIE — 3 readers
BalanceteFieReader(ZIP mensal, pós-RCVM 175),BalancoFieReader(ZIP anual, descontinuado em 2020, pré-175) eMedidasMesFieReader(CSV mensal solto): os três datasets dos Fundos de Investimento Especialmente constituídos, que completam o portal rootfie/. Não háFIE/CAD.FIE/MEDIDASé irmão deFIE/DOC, então o seu reader mora no rootfie/. -
DFIN Securit (CRA/CRI) + Emissor CEPAC — 3 readers
DfinCraReader,DfinCriReader(índices das demonstrações financeiras dos CRA/CRI, CSV solto anual,Link_Downloadnão seguido) eCadastroEmissorCepacReader(retrato dos emissores de CEPAC — municípios — snapshot de URL fixa, semdate_ref). Inauguram os portal rootssecurit/eemissor_cepac/; primeira fatia da Wave 2 do #41. -
Informe Mensal OTS (Securitização) — 8 readers
InfMensalOts*Reader(geral, ativo/passivo, classe, direitos creditórios, desembolso, fluxo de caixa, derivativos, cedente/devedor): as seções do informe mensal das operações de securitização não-CRA/CRI. ⚠️ Particionado por ano apesar de mensal.cedente_devedor.CNPJguarda CPF (dado pessoal, não validado como CNPJ);Indice_Subordinacao_Data_Basenão é data. Segunda fatia da Wave 2 do #41. -
Informe Mensal CRA (Securitização) — 8 readers
InfMensalCra*Reader(as mesmas 8 seções do OTS): o informe mensal das operações de CRA (recebíveis do agronegócio). ⚠️ Particionado por ano apesar de mensal. ⚠️ Mesmos nomes de seção do OTS, mas nenhuma lista de colunas igual (CNPJ_Emissorano lugar deCNPJ_Securitizadoranos 8;direitos_creditorioscom 56 colunas contra 43) — por isso cada contract é gerado do header publicado e pinado a um fixture verbatim.cedente_devedor.CNPJguarda CPF (dado pessoal, não validado como CNPJ);Indice_Subordinacao_Data_Basenão é data. Terceira fatia da Wave 2 do #41. -
Informe Mensal CRI (Securitização) — 11 readers
InfMensalCri*Reader: o informe mensal das operações de CRI (recebíveis imobiliários). ⚠️ Particionado por ano apesar de mensal. Compartilha 7 nomes de seção com CRA/OTS mas não temdireitos_creditorios(a seção de recebíveis écreditos, 51 colunas) e acrescenta 4 membros (carteira,carteira_modificacao,creditos,responsavel) — contracts gerados do header e pinados a fixtures verbatim.cedente_devedor.CNPJpode guardar CPF;Indice_Subordinacao_Data_BaseeData_LTV(varchar no META) não são datas;carteira_modificacao/responsavelsão header-only. Quarta e última fatia da Wave 2 — fecha o portal rootsecurit/(4/4). -
Cadastro de Auditores (AUDITOR) — 2 readers
AuditorPfReader/AuditorPjReadersobre ocad_auditor.zip(auditores pessoa física + firmas de auditoria). Snapshot de URL fixa, semdate_ref(molde doCadastroFiReader). O membropfnão tem CPF (identifica porCD_CVM+nome);pj.CNPJchega mascarado. Contracts gerados do header e pinados a fixtures verbatim. Inaugura o portal rootauditor/e a primeira fatia da Wave 3 do #41 (snapshots CAD de prestadores de serviço). -
Cadastro de Agentes Fiduciários (AGENTE_FIDUC) — 2 readers
AgenteFiducPfReader/AgenteFiducPjReadersobre ocad_agente_fiduc.zip(agentes pessoa física -
firmas). Snapshot de URL fixa, sem
date_ref. O membropfnão tem CPF nemCD_CVM(identifica só pelo nome);pj.CNPJchega mascarado. ⚠️ Não é cópia do AUDITOR — são 3 colunas de data em vez de 1, semCD_CVM, e opjacrescentaPAIS/DDD_TEL/TEL; contracts gerados do header e pinados a fixtures verbatim. Segunda fatia da Wave 3 do #41. -
Cadastro de Agentes Autônomos (AGENTE_AUTON) — 2 readers
AgenteAutonPfReader/AgenteAutonPjReadersobre ocad_agente_auton.zip(agentes autônomos de investimento: pessoa física + firmas). Snapshot de URL fixa, semdate_ref. Opfnão tem CPF (identifica peloNOME, que pode vir em branco);pj.CNPJchega mascarado. ⚠️ Não é cópia dos irmãos — acrescentaMOTIVO_CANCEL/DENOM_COMERC/EMAIL/SITE_ADMINe usaDDD; contracts gerados do header e pinados a fixtures verbatim. Terceira fatia da Wave 3 do #41. -
Cadastro de Repres. de Inv. Não Residentes (INVNR) — 2 readers
InvnrRepresPfReader/InvnrRepresPjReadersobre ocad_invnr_repres.zip(representantes de investidores não residentes: pessoa física + firmas). Snapshot de URL fixa, semdate_ref. Opfnão tem CPF (identifica peloNOME);pj.CNPJchega mascarado. ⚠️ Não é cópia dos irmãos — acrescentaCONTROLE_ACIONARIO/DDD_FAX/FAX/VL_PATRIM_LIQ/DT_PATRIM_LIQ(4 colunas de data nopj) e usaDDD_TEL; contracts gerados do header e pinados a fixtures verbatim. Quarta fatia da Wave 3 do #41. -
Cadastro de Intermediários (INTERMED) — 2 readers
IntermedReader/IntermedRespReadersobre ocad_intermed.zip(intermediários de mercado + tabela de responsáveis). Snapshot de URL fixa, semdate_ref. ⚠️ Os dois membros NÃO sãopf/pj— são o registro (28 cols) e os responsáveis (8 cols), ambos chaveados peloCNPJdo intermediário; o membro de responsáveis tem dado pessoal (RESP/EMAIL_RESP) mas sem CPF.CEP/TEL/FAX/CD_CVMficamstrapesar denumericno META; contracts gerados do header e pinados a fixtures verbatim. Quinta fatia da Wave 3 do #41. -
Cadastro de Administradores de Carteira (ADM_CART) — 5 readers
AdmCartPfReader/AdmCartPjReader/AdmCartDiretorReader/AdmCartRespReader/AdmCartSociosReadersobre ocad_adm_cart.zip. Snapshot de URL fixa, semdate_ref. ⚠️ Primeiro root de 5 membros, e 3 deles não têm nenhuma coluna de data (diretor/resp/socios→_DATE_COLS = (), tudo texto). Opfnão tem CNPJ nem CPF (chave =ADMIN); os satélites têm dado pessoal mas sem CPF — o únicoCNPJé o do administrador. Um CNPJ malformado da fonte (00.010.354/1901-72) é devolvido como publicado. Contracts gerados do header e pinados a fixtures verbatim. Sexta fatia da Wave 3 do #41. -
Cadastro de Consultores de Valores Mobiliários (CONSULTOR_VLMOB) — 5 readers
ConsultorVlmobPfReader/ConsultorVlmobPjReader/ConsultorVlmobDiretorReader/ConsultorVlmobRespReader/ConsultorVlmobSociosReadersobre ocad_consultor_vlmob.zip. Snapshot de URL fixa, semdate_ref. Mesma forma do ADM_CART — 3 dos 5 membros sem nenhuma coluna de data. ⚠️ Não é cópia:pfchaveado porNOME(nãoADMIN), 7ª colunaSITE_ADMIN;pjcom 20 cols e só 3 date cols (semDT_PATRIM_LIQ). Todos os CNPJ 100% válidos. Contracts gerados do header e pinados a fixtures verbatim. Sétima fatia da Wave 3 do #41. -
Cadastro de Administradores de FII (ADM_FII) — 1 reader
CadastroAdmFiiReadersobre ocad_adm_fii.csv(CSV solto, não ZIP; 18 colunas). Snapshot de URL fixa, semdate_ref. 3 colunas de data (DT_REG/DT_CANCEL/DT_INI_SIT;MOTIVO_CANCELé texto, não data); chaveado porCNPJ(mascarado), sem coluna de CPF. Molde do Cadastro FI / Emissor CEPAC. Oitava e última fatia da Wave 3 do #41 — encerra a Wave 3. -
Cadastro de Companhias Estrangeiras (CIA_ESTRANG) — 1 reader
CadastroCiaEstrangReadersobre ocad_cia_estrang.csv(CSV solto, não ZIP; 49 colunas). Snapshot de URL fixa, semdate_ref. 7 colunas de data (MOTIVO_CANCELé texto); duas colunas de CNPJ (CNPJda companhia +CNPJ_AUDITOR);RESPtem nome de pessoa mas sem coluna de CPF. Contract gerado do header e pinado a fixture verbatim (49 cols = risco de transcrição). Molde do ADM_FII. Abre a Wave 4 do #41. -
Cadastro de Companhias Incentivadas (CIA_INCENT) — 1 reader
CadastroCiaIncentReadersobre ocad_cia_incent.csv(CSV solto, não ZIP; 47 colunas, ~3.570 linhas). Snapshot de URL fixa, semdate_ref. ⚠️ Não é cópia do CIA_ESTRANG (temST_CIA_INCENT_REG, não temPAIS_ORIGEM/CD_PAIS_*, usaMUN/UF). 7 colunas de data (DT_INI_CATEG100% vazia mas é data por contrato;MOTIVO_CANCELé texto); duas colunas de CNPJ (CNPJ+CNPJ_AUDITOR);RESPsem CPF. Contract gerado do header e pinado a fixture verbatim. Segunda fatia da Wave 4 do #41. -
Cadastro de Coordenadores de Oferta (COORD_OFERTA) — 2 readers
CoordOfertaReader(registro, 25 cols, 4 date cols) /CoordOfertaRespReader(responsáveis, 6 cols, 2 date cols) sobre ocad_coord_oferta.zip. Snapshot de URL fixa, semdate_ref. ⚠️ Os 2 membros não são splitpf/pj— são registro + responsáveis, ambos chaveados peloCNPJdo coordenador (molde do INTERMED);resptem dado pessoal mas sem CPF. ⚠️ A META é um.zip, não.txt(404), comsectionassimétricas. Contracts gerados dos headers e pinados. Terceira fatia da Wave 4 do #41 e o primeiro ZIP multi-membro dela. -
Cadastro de Plataformas de Crowdfunding (CROWDFUNDING) — 3 readers
CrowdfundingReader(registro, 17 cols, 2 date cols) /CrowdfundingAdmRespReader/CrowdfundingSociosReader(satélites, 2 cols cada) sobre ocad_crowdfunding.zip. Snapshot de URL fixa, semdate_ref. ⚠️ Os 2 satélites não têm nenhuma coluna de data (_DATE_COLS = ()) e têm dado pessoal mas sem CPF; todos chaveados peloCNPJda plataforma. ⚠️ O registro é mais enxuto que os irmãos (semDT_CANCEL/MOTIVO_CANCEL/CD_CVM; usaWEBSITEeDDD) — anti-cópia pinada por teste. ⚠️ A META é um.zipde 3 membros, comsectionassimétricas. Quarta fatia da Wave 4 do #41. -
Ofertas de Distribuição (OFERTA/DISTRIB) — 2 readers
OfertaDistribuicaoReader(histórico pré-RCVM 160, 76 cols, 9 date cols, ~48,9k linhas) /OfertaResolucao160Reader(RCVM 160, 71 cols, 3 date cols, ~13,9k linhas) sobre ooferta_distribuicao.zip. Snapshot de URL fixa, semdate_ref. ⚠️ Não é registro+satélite — são duas tabelas de regimes diferentes com colunas disjuntas (anti-cópia pinada). Colunas monetárias/contagem ficamstr(texto decimal exato →Decimala jusante); múltiplas colunas de CNPJ por membro. ⚠️Data_deliberacao_aprovou_ofertachega emDD/MM/YYYY→ ficastr(a coerção é ISO-only). ⚠️ A META é um.zipde 2 membros, comsectionsimétricas. Contracts gerados dos headers e pinados. Quinta fatia da Wave 4 do #41; fecha a issue #14. -
Cadastro de Companhias Abertas (CIA_ABERTA/CAD) — 1 reader
CadastroCiaAbertaReadersobre ocad_cia_aberta.csv(CSV solto, não ZIP; 47 cols, ~2.677 linhas). Snapshot de URL fixa, semdate_ref. ⚠️ Não é cópia do CIA_ESTRANG/ CIA_INCENT (chaveCNPJ_CIA, nãoCNPJ; acrescentaTP_MERC). 7 date cols (MOTIVO_CANCELé texto); duas colunas de CNPJ (CNPJ_CIA+CNPJ_AUDITOR);RESPsem CPF. Contract gerado do header e pinado. Abre o portal rootcia_aberta/— a última e maior raiz da Wave 4; os 7 datasetsDOC/+EVENTOS/virão como readers próprios.
Cada padrão de leitura ganha a sua própria página, com Descrição e Exemplos, no mesmo formato das páginas de Envio.
Forma de um leitor¶
Todo leitor implementa o port read() -> pd.DataFrame (o contrato compartilhado, privado, em
_internal/config/ports) e devolve um DataFrame cujas colunas são tipadas explicitamente — nunca pela
inferência do pandas. Leitores de open-data (CSV) declaram o seu próprio contrato de colunas e
não reaproveitam o schema Pydantic de submissão, pois consomem um artefato distinto do XML.
Consulte o catálogo completo de padrões (implementados e pendentes) no CLAUDE.md do repositório.
Colunas de proveniência¶
Todo DataFrame devolvido por um leitor carrega, ao lado das colunas de origem, seis colunas
de proveniência, para que a camada bronze de um datalake seja autodescritiva e rastreável:
| Coluna | Conteúdo |
|---|---|
url |
URL exata de onde o dado foi baixado. |
updated_at |
Timestamp de coleta (quando esta leitura buscou o dado), UTC, tz-aware. |
source_key |
Identificador do dataset (do contrato) — distingue leitores que compartilham a mesma url (ex.: os 19 membros de um mesmo ZIP). |
package_version |
Versão do pacote que produziu a linha (para re-ingestão após correção de bug). |
ingestion_run_id |
UUID gerado uma vez por read(), comum a todas as linhas daquela leitura. |
content_hash |
sha256 dos bytes do artefato baixado — detecta se a fonte mudou desde a última coleta. |
Os nomes vivem em FileContract.PROVENANCE_COLUMNS; o seam stamp_provenance as acrescenta
depois da validação de contrato (elas não fazem parte do artefato de origem). updated_at
permanece tz-aware — um destino SQL que precise de naive normaliza no carregamento do warehouse,
nunca aqui.
Política de retry — retry_policy e _RETRY_POLICY¶
Todo leitor aceita um retry_policy: RetryPolicy | None = None no construtor, repassado ao seam
de download como a sua agenda de novas tentativas / backoff. Cada leitor declara a sua própria
paciência por meio do atributo de classe _RETRY_POLICY, então a política fica junto do
dataset e é ajustável por leitor — sem tocar nos demais.
A resolução é em duas camadas:
- Argumento
retry_policyno construtor — se informado, vence para aquela instância. - Atributo de classe
_RETRY_POLICYdo próprio leitor — o padrão quando nada é passado. O padrão de fábrica é paciente (o portal da CVM aplica throttle sob carga): 5 tentativas, backoff exponencial limitado (~2, 4, 8, 10 s).
from filings_cvm import RetryPolicy
from filings_cvm.ingestion.fi import CdaReader
# 1. Padrão — o leitor usa a política do seu próprio módulo. Nada a passar:
df_ = CdaReader().read()
# 2. Sobrescrever numa chamada — o argumento vence o padrão do módulo:
cls_retry_policy = RetryPolicy(int_max_attempts=10, float_max_wait_s=30.0)
df_ = CdaReader(retry_policy=cls_retry_policy).read()
# 3. Inspecionar o padrão de um leitor sem construir:
CdaReader._RETRY_POLICY # → RetryPolicy(int_max_attempts=5, …)
Para tornar a diferença permanente para um dataset, ajuste o _RETRY_POLICY na classe daquele
leitor — o RetryPolicy é um value object imutável, então declarar um por leitor é seguro. O
padrão é estrutural: um teste percorre toda a API pública e falha se um leitor novo não
declarar o seu _RETRY_POLICY.
Artefato bruto — path_raw¶
Todo leitor aceita um path_raw: Path | None = None no construtor:
None(padrão) — o artefato é baixado num diretório temporário, lido e descartado na saída. Nada persiste, e a leitura devolve apenas oDataFrame. Atenção: isso não é uma leitura sem disco — o arquivo é gravado transitoriamente e é preciso um diretório temporário gravável.- Um caminho — o artefato bruto e intacto (
.zip,.csv,.html,.xlsx, …) é gravado ali e mantido, antes de qualquer parsing. O diretório é criado junto com os pais.
É o espelho, na leitura, do output_path dos serializadores de Envio:
None mantém tudo em memória, um caminho grava em disco.
Guardar o artefato bruto é o que torna a camada bronze de um datalake autoritativa: quando a fonte muda o contrato dos dados e a transformação quebra, os bytes exatos que causaram a falha continuam reproduzíveis em disco, em vez de perdidos num novo download de uma fonte já alterada.
Automação¶
Dois jobs semanais vigiam a camada de leitura. Ambos abrem/atualizam uma issue e nunca reprovam o CI — "a CVM caiu" e "o nosso contract está errado" não podem virar o mesmo check vermelho:
- Deriva de contrato — a CVM mudou um dataset depois que embarcamos o
seu
FileContract? Compara META + header real contra os contracts. Nenhum check de PR consegue pegar isso, porque a mudança acontece depois do merge. - Completude do portal — a CVM publicou um dataset que ainda não lemos? Enumera o portal via CKAN e lista o que falta.