Migração para agrobr 2.0¶
O agrobr 2.0 torna explícitos erros e garantias que a série 1.x tratava de forma permissiva. Use este guia para atualizar integrações existentes. As versões dos contratos de cada dataset continuam independentes da versão da biblioteca, conforme a política SemVer.
Como testar a migração: um mock solto (patch(...), AsyncMock()) aceita qualquer argumento e esconde a chamada que a
2.0 recusa (§78). Crie os mocks com patch(..., autospec=True), ou
confira cada chamada com inspect.signature(funcao).bind(*args, **kwargs): os 2 levantam TypeError para argumento fora
da assinatura, como a 2.0. Nas funções que mantêm **kwargs (como as da
§78), a assinatura aceita qualquer nome, e só a execução recusa o
desconhecido: nelas, nem o autospec nem o bind acusam zarc.zoneamento(cultura=...), mapbiomas.cobertura(estado=...)
ou desmatamento.deter(data_inicio=...). Confira essas chamadas contra a tabela da
§85.
Servidor MCP e plugin do QGIS. Versões compatíveis com a 2.0: agrobr-mcp 0.2.0 ou posterior e agrobr-qgis 0.2.0 ou posterior (publicado depois da agrobr 2.0). As versões 0.1.x dos dois usam a API da 1.x: com elas, mantenha agrobr<2 até atualizar o servidor ou o plugin.
Resumo: o que quebra¶
Em ordem de risco. Cada linha aponta a seção com o detalhe.
Muda calado (a mesma chamada devolve outra coisa)
bcb.credito_ruralsemagregacaodevolve o agregado por UF (11 colunas), e não mais os registros do SICOR (21 colunas): para o recorte da 1.1.0, passeagregacao="registro"(§4).comtrade.comerciocompartner=Noneedatasets.comercio_internacionalcomparceiro=Nonedevolvem o agregado World, e não mais todos os parceiros publicados: para o recorte da 1.1.0, passe"all"ou"todos"(Comtrade). Otrade_mirrorexige um parceiro explícito:None, World,"all"e"todos"levantamInvalidParameterError.- A
safrado crédito rural sai "2023/24", e não "2023/2024": converta o que foi gravado comagrobr.normalize.dates.normalizar_safra(§76). - Os datasets devolvem as colunas na ordem do contrato, e a
datadoqueimadassai emdatetime64: leia as colunas pelo nome, não pela posição (§74). - Nomes de valor trocados:
nome_seriesai"ipa_agricola"(era"ipa_agropecuario"), eespeciesai"galinhas"(era"galinhas_poedeiras"). Os nomes antigos seguem aceitos na entrada, comFutureWarning, mas o filtro sobre a saída precisa trocar (§31, §26). conab.safras(produto, safra=X)semlevantamentolê X da publicação mais recente, com a revisão da CONAB: para o número original, passelevantamento(§27). Nos cereais de inverno, a safra do levantamento passa a ser a que termina no ano publicado, e a série histórica deles e do café sai com o ano publicado (§43).ibge.censo_agro_municipal_1985devolve 1 linha por casa do PDF, comvalorsó na casa confirmada: usevalor_lidoe filtre pelostatus(§81).- Os logs do agrobr não seguem mais a configuração do structlog da aplicação: saem pelo
loggingda biblioteca padrão, em JSON, e se controlam porlogging.getLogger("agrobr")(§73). municipiocasa o nome inteiro ou o código IBGE, e não mais um pedaço do nome, no SICAR, no MapBiomas, no PSR, no ZARC e na ANP: a mesma chamada pode trazer outro município, mais linhas ou menos (§86).- Colunas renomeadas na saída:
estado→ufno progresso da CONAB e no MapBiomas; colunas em português emposicionamento_fundos,oferta_demanda_globalecomercio_internacional;produtonormalizado noconab.brasil_total. Quem só exporta o frame recebe outro schema, sem erro (§87). - Colunas de data que eram texto saem em
datetime64(DERAL, IMEA, catálogo do INMET, ANTAQ e praças da ANTT): o filtro por textodd/mm/aaaacom o dia até 12 casa outra data, e o do DERAL pelo nome da aba ("Atual","02-10-23") pode voltar vazio, sem aviso (§89). - Inteiros por natureza saem em
Int64, texto no dtype padrão do pandas e o vazio com os tipos do cheio; 7 contratos da 1.1.0 sobem de versão major por isso (6 a 2.x ecomercio_internacionala 3.0) (§89). AGROBR_CACHE_DIRpassa a valer, etrue/yespassam a desligar o cache da ANEC e do Acervo Fundiário (§91).- O IBAMA guarda o CSV por 1 hora: dentro da hora, a mesma chamada devolve a coleta anterior (§94).
ibge produtos --pesquisa PAMconsulta a PAM, e não mais o LSPA (§92).- O catálogo de datasets e contratos, o
normalizee a ANEC devolvem cópias: alterar o objeto devolvido não muda mais a chamada seguinte (§95). mapbiomas.cobertura,mapbiomas.transicaoedatasets.uso_do_solosemcolecaoleem a coleção 11, e não mais a 10: a mesma chamada devolve outros números. Para o recorte da 1.1.0, passecolecao=10(§63).- Pela CONAB,
area_colhidasai nula emconab.safrase noestimativa_safra, edata_publicacaoé a data do boletim, e não mais o dia da consulta (§3). acervo_fundiario.sigef(uf)devolve as mesmas parcelas em outra ordem (públicas, depois privadas) e com a coluna novanatureza; osource_detailspassa a ser por arquivo (§29).antt_pedagio.fluxo_pedagiosai comsentidoem maiúsculas (CRESCENTE,DECRESCENTE): o filtro e ogroupbypelo texto publicado mudam, e o volume não (§24).anp_diesel.vendas_dieselsai comprodutoDIESEL S10(eraDIESEL S-10) eregiaopelo nome canônico (Centro-Oeste, eraREGIÃO CENTRO-OESTE): o filtro pelo texto antigo volta vazio (§97).agrobr conab levantamentoslista todos os levantamentos, e não só os 10 primeiros (§92).- A classe de licença muda: IMEA e Notícias Agrícolas passam a
zona_cinza, Comtrade (livrena 1.1.0) arestritoe Acervo Fundiário alivre; com CEPEA e Notícias Agrícolas juntos,nc. Na 1.1.0, a classe só saía emdatasets.info(nome)["license"];MetaInfo.licenseedatasets.info()["licenses"]são novos na 2.0. Revise filtros por licença (§11).
Passa a levantar erro
- Status HTTP de erro sai como
SourceUnavailableError, e não comohttpx.HTTPStatusError: troque oexcept(§75). - Argumento desconhecido ou com nome errado, que a 1.1.0 descartava em silêncio, levanta erro antes da rede:
TypeErrornas 77 funções que perderam o**kwargs, eTypeErrorouInvalidParameterErrornas 33 que o mantêm: corrija o nome (§78). - Parâmetro impossível (UF inexistente, período invertido) levanta
InvalidParameterErrorantes da rede, onde a 1.1.0 devolvia vazio ou erro de fonte; na 2.0, a regra vale em todas as fontes (§66, §90). as_polars=Truesem o Polars levantaImportError, e não devolve mais pandas: instaleagrobr[polars](§8). O extra passa a exigirpolars>=0.20.3: com um Polars mais antigo fixado, a instalação acusa conflito (§19).- Os nomes antigos de parâmetro (
data_inicial,start,commodity,cultura,estado,cod_municipio,max_featurese outros) levantamTypeError(InvalidParameterErroremzarc.zoneamento,mapbiomas.coberturaemapbiomas.transicao): troque pelo nome novo (§85). as_polars,return_metae as opções depois deles passam a ser só por nome; no IBGE, também os filtros secundários (§88).- Falha de layout em todas as fontes de um dataset levanta
ParseError, e não maisSourceUnavailableError(§90). - Na CLI,
--output,--jsonesnapshot usesaem com código 2: use--formato(§92). precos_dieselcom período que começa depois de hoje levantaInvalidParameterErrorantes da rede, onde a 1.1.0 devolvia vazio na UF e no Brasil (§97).embrapa_solos.mapa_solos(ordem=...)casa a classe inteira: um trecho do nome ("latos") levantaInvalidParameterErrorcom a lista das classes (§97).AGROBR_HTTP_RATE_LIMIT_<FONTE>e orate_limit_*por argumento recusam negativo,infenancomValidationError(§91).cadastro_rural,desmatamento,exportacao,importacao,uso_do_soloezoneamento_agricoladentro dedatasets.deterministic(...)levantamInvalidParameterErrorantes da rede, onde a 1.1.0 devolvia o dado corrente: tire essas chamadas do bloco (§71).normalize.municipio_para_ibge(nome)semuflevantaInvalidParameterErrorquando o nome é de mais de um município (521 municípios dividem 240 nomes), onde a 1.1.0 devolvia calado o código do primeiro da lista: passeuf(§90).abiove.exportacao(ano, produto="total")levantaInvalidParameterError, onde a 1.1.0 devolvia vazio: para o total dos produtos, useagregacao="mensal"(§39).
Deixa de levantar erro
datasets.estimativa_safrasem observações em todas as fontes devolve o vazio do contrato comUserWarning, e não maisSourceUnavailableError: confiradf.empty(estimativa_safra).cftc.cotsem relatório no recorte devolve vazio tipado, e não maisSourceUnavailableError; as contagens saem emInt64(§99).
API removida
- Saem
agrobr.configure(), os módulosquality,sla,export,pluginsevalidators.semantice oload_baseline_fingerprint, e ocache.get_policypassa a valer só para o CEPEA: remova os usos (§9, §10, §50, §83). Ouf=deanda.entregase dedatasets.fertilizantetambém sai: era parâmetro explícito na 1.1.0, e passá-lo levantaTypeError, porque os PDFs só trazem o total nacional (§50). - Os subpacotes
agrobr.conab.custo_producaoeagrobr.conab.serie_historicasaem: importe as funções deagrobr.conab(§93). b3.oi_historicopassa a se chamarb3.posicoes_abertas_historico, também emsync.b3; no dataset, a mesma consulta édatasets.futuros_agricolas(tipo="oi_historico"), nova na 2.0 (§98).- O parâmetro
_moedadecepea.indicadorsai: passá-lo levantaTypeError(§6).
Para ficar na série 1.x enquanto migra: pip install "agrobr<2".
BCB PTAX: moedas, boletins e contratos explícitos¶
bcb.ptax acrescenta moeda="USD", boletim="fechamento" e top=1000. O padrão continua fechamento do dólar; use boletim="todos" para abertura, intermediários e fechamento, ou selecione abertura/intermediario. A nova bcb.ptax_moedas() expõe o catálogo OData atual em três colunas (moeda, nome, tipo_moeda), com contrato 1.0. A aquisição passa a depender desse catálogo para validar a moeda, com recursos e falhas explícitos; ele não é uma tabela histórica de vigência.
Cotações passam ao contrato 2.0, parser 2, mantendo como prefixo cotacao_compra, cotacao_venda, data_hora, data e acrescentando moeda, paridade_compra, paridade_venda, tipo_boletim. Medidas usam float64 finito anulável; data_hora e data usam datetime64[ns], sem fuso, inclusive vazios. data deixa de ser coluna de objetos Python date; use .dt.date na aplicação se precisar dessa representação. Atualize schemas e chaves: a identidade é moeda, horário completo e tipo publicado dentro da rota. Não descarte frações de segundo.
As rotas por dia/período podem chamar o mesmo fechamento de Fechamento PTAX e Fechamento. O seletor reconhece ambos; a saída preserva a diferença para não inventar texto publicado. Em todos, tipo novo, vazio ou null permanece com diagnóstico; seletores específicos geram erro quando não conseguem classificar a linha. Considere a variação de rótulo ao juntar resultados de rotas distintas. Não some os boletins nem use a última linha como média diária.
Datas passam a validação estrita. Data única junto de intervalo gera erro; apenas início completa fim com a data de hoje no calendário de Brasília, apenas fim completa início com fim−30 dias. Os filtros parciais antes ignorados agora são respeitados. Moeda aceita três letras ASCII e normaliza apenas caixa; símbolos ausentes no catálogo atual geram erro antes do GET de cotações. Vazio, erro HTTP e envelope sem value são situações distintas.
top controla páginas, sem cortar a saída. A coleta valida todas as páginas antes de filtrar boletins. Preserve metadados: cobertura das cotações e do catálogo é separada, e sem total independente fica unknown mesmo após página vazia. Hash/tamanho superiores representam manifesto de recursos. A cotação histórica usa a unidade monetária corrente daquela data; não rotule toda a série como BRL nem atribua UTC ao relógio publicado.
Use BCB_PTAX_V2 e BCB_PTAX_MOEDAS_V1, de agrobr.contracts.bcb_ptax, ou os registros bcb_ptax/bcb_ptax_moedas. Não existia contrato de cotações V1 registrado. Veja API e contratos.
BCB Focus: anual/mensal, identidade e contrato 2.0¶
bcb.focus acrescenta o argumento nomeado periodicidade="anual"|"mensal"; o padrão continua anual, com indicador "PIB Agropecuária". A saída mantém as dez colunas anteriores e acrescenta periodicidade e indicador_detalhe. Atualize seleções de colunas e chaves de armazenamento: o detalhe anual antes descartado distingue Exportações, Importações e Saldo, por exemplo. A chave completa inclui periodicidade, indicador, detalhe, data da pesquisa, referência e base de cálculo. Não some bases ou detalhes diferentes.
Schema/contrato passam a 2.0, parser a 2; o novo contrato registrado é bcb_focus, constante BCB_FOCUS_V2. Datas civis usam datetime64[ns], estatísticas float64 e contagem/base Int64, inclusive no vazio. Use .isna() para ausências; detalhe vazio publicado continua distinto de nulo. data_referencia mantém texto YYYY ou MM/YYYY: projeções futuras são legítimas e não representam observações realizadas.
Indicadores exigem o nome exato, sem aliases ou ajuste de caixa. Quantidades booleanas/fracionárias, datas inválidas, JSON malformado, campos ausentes e duplicatas agora geram erro explícito. Estatísticas finitas inconsistentes permanecem com aviso. A ordem ganha desempates por referência textual, base e detalhe anual; resultados limitados na mesma data podem mudar em relação à ordem anterior.
top é tamanho de página; max_registros corta somente após validar a página inteira. Páginas curtas já não encerram a coleta automaticamente: o client avança pela quantidade recebida até vazio, limite ou contagem reconciliada. Preserve source_details.coverage: término da aquisição não comprova o total da fonte. O hash/tamanho superiores identificam manifesto, com hashes individuais dos corpos. Veja API e contrato.
BCB SGS: histórico por blocos e contrato 3.0¶
bcb.sgs mantém os 17 aliases e as quatro colunas, mas passa ao schema 3.0 e parser 2; o período passa a
inicio/fim (§85). Séries que publicam dataFim (ex.: TR) ganham a coluna opcional data_fim depois das quatro; a 1.1 descartava esse campo. Datas civis usam sempre datetime64[ns], inclusive no pandas 3, que antes podia inferir us. Valores usam float64, códigos Int64 e nomes desconhecidos são nulos. Use .isna() para ausências. O novo contrato registrado é bcb_sgs, constante BCB_SGS_V3; o BCB_SGS_V2 conserva o schema 2.1, e não existia contrato SGS V1 registrado.
Intervalos longos são divididos por anos civis, unidos e ordenados antes de aplicar ultimos. Sem datas, a janela padrão usa uma única data de referência, a de hoje no calendário de Brasília; apenas início preenche o fim, mas apenas fim conserva o início omitido. Sem inicio, fim nem ultimos, o bcb.sgs lê só os últimos 10 anos, contados a partir de hoje no calendário de Brasília; na 1.1.0, a mesma chamada trazia a série inteira nas séries que não são diárias (o pib_agropecuaria vinha desde 1995); nas diárias, como dolar_ptax_venda, a fonte recusava a consulta sem data inicial (HTTP 406). Para o recorte antigo, passe inicio com a primeira data da série. Para mais de 20 observações na série 1, informe as duas datas com ultimos, pois a rota nativa de últimos valores recusa 21.
Parâmetros booleanos usados como código/quantidade, strings numéricas como código, datas malformadas e intervalos invertidos agora falham antes da rede. Dados inválidos deixam de virar nulos silenciosamente. Duplicatas no mesmo corpo e valores conflitantes entre blocos geram erro. Referências mensais/trimestrais anteriores ao dia inicial continuam presentes, com aviso e origem; não as trate automaticamente como observações diárias.
O envelope oficial de ausência de valores, com HTTP 404 ou 200, passa a vazio tipado com aviso, sem comprovar a existência do código. Falhas de blocos não retornam parcial. Preserve os metadados: cobertura distingue aquisição dos blocos de completude da série, que permanece desconhecida; o hash/tamanho superiores identificam um manifesto, com hashes próprios dos corpos. Veja a API SGS e o contrato.
Comtrade: World, cobertura e contratos 2.0¶
comtrade.comercio passa ao contrato 2.1 (comercio_bilateral), trade_mirror ao 2.0 e datasets.comercio_internacional ao 3.0. partner=None, world, mundo e "0" agora enviam o agregado World explicitamente. Para conservar a antiga consulta que omitia o parâmetro e retornava todos os parceiros publicados, use partner="all" ou "todos". Não some o agregado com seus componentes. No datasets.comercio_internacional, os filtros e as colunas saem em português: parceiro=None envia o World (§85, §87).
O bilateral mantém 22 colunas e acrescenta classificacao e classificacao_original; o dataset também preserva as 24 em vazio. No contrato 2.1, as 3 marcas de estimativa da ONU entram como flags anuláveis (27 colunas): veja a seção 58. Sua chave usa periodo, reporter_code, partner_code, hs_code, fluxo_code, classificacao. O espelho passa de 18 a 24 colunas, com revisão/flag de cada perna e dois códigos numéricos. ISO descritivo pode ser nulo. Inteiros usam Int64, medidas float64 e flags boolean anulável. Use .isna() para ausências.
HS aceita 2/4/6 dígitos ASCII, incluindo listas textuais; códigos ímpares e parâmetros desconhecidos agora falham. Períodos mensais distinguem YYYYMM de YYYY, que expande o ano inteiro. Falhas de bloco e respostas incompatíveis deixam de ser ignoradas. Espelho não aceita fluxo, World ou países iguais e rejeita revisões HS incompatíveis na mesma célula.
O client compara contagem independente à união de partições. O padrão require_complete=False (exigir_completo no dataset) devolve parcial com aviso; use True quando a aplicação exigir cobertura comprovada. Preserve source_details para conhecer limites e tentativas. O hash superior identifica um manifesto de recursos, com tamanho próprio; cada corpo tem seu hash. Snapshot apenas preenche o ano omitido.
Use COMERCIO_BILATERAL_V2 e TRADE_MIRROR_V2 de agrobr.contracts.comtrade, ou o registry. As constantes V1 permanecem históricas. A licença interna é restrito, com aviso na primeira chamada e as dispensas expressas da política da ONU; veja Licenças. Veja API, metadados e limites.
Lista Suja: CSV, contexto de publicação e contrato 2.0¶
lista_suja.empregadores() passa a usar CSV sem dependência opcional e a conferir o TXT anunciado para obter a edição. formato="pdf" conserva acesso ao PDF com agrobr[pdf]; formatos explícitos são exclusivos. O modo auto pode usar PDF após indisponibilidade elegível do CSV, com a causa nos metadados. Corpo inválido ou descoberta incompatível geram erro.
O contrato 2.0 preserva as oito colunas anteriores e acrescenta id_registro, data_decisao, data_atualizacao e data_inclusao_texto. Anos e contagens passam a Int64, inclusive nulos/vazios; ausências textuais passam de strings vazias para nulos. Use .isna() para ausências. Datas civis têm dtype datetime64[ns]. Uma inclusão com intervalo e nova data mantém data_inclusao=NaT e conserva todo o campo em data_inclusao_texto; não extraia uma data sem uma regra explícita da aplicação.
Informe id_registro como texto exato. A chave é local à exportação; preserve também MetaInfo.raw_content_hash, pois documentos podem aparecer em várias linhas e datas de atualização podem ter revisões. Atualização periódica e atualização do cadastro são distintas em source_details.publication. TXT divergente gera erro; TXT ausente ou indisponível deixa a data nula com diagnóstico. Não há seleção de edições históricas nessa API.
Use get_contract("lista_suja_empregadores") ou LISTA_SUJA_EMPREGADORES_V2, de agrobr.contracts.lista_suja. Filtros inválidos e argumentos desconhecidos agora geram InvalidParameterError antes da rede. Veja colunas, proveniência e limites.
defensivos: situação, composição e cache por coleta¶
As APIs formulados, autorizacoes e tecnicos preservam suas colunas anteriores e passam ao schema 1.1. Formulados e autorizações acrescentam situacao textual; formulados e técnicos acrescentam composicao_texto, com a célula original. autorizacoes também acrescenta modalidade_de_emprego, e tecnicos, nome_cientifico, as duas vazias nos CSVs atuais, que não publicam esses campos. Nos técnicos, o parser também corrige ingredientes e grupos com parênteses internos ou vários componentes. A nova composicao(tipo="formulados"|"tecnicos") usa contrato 1.0, com uma linha por posição de componente, incluindo ingredientes repetidos. Concentração e unidade ficam nessa tabela; valores ambíguos permanecem nulos com diagnóstico.
Informe nr_registro como texto exato, preservando zeros e acentos, como "00301" ou "14017/Pré-Mistura". Filtros vazios, numéricos ou booleanos e argumentos desconhecidos agora geram InvalidParameterError antes da rede. situacao="TRUE" compara o texto publicado sem inferir vigência; técnicos não aceitam esse filtro.
O cache passa a ZIPs versionados por família, incluindo composição, tipos e proveniência. Arquivos antigos ficam preservados, mas a primeira chamada com o parser novo precisa coletar novamente. use_cache=False ignora leitura e gravação. Em cache, MetaInfo.fetched_at, fetch_timestamp e o hash identificam a coleta original; timestamp é a hora da consulta atual. Os CSVs correntes não reconstituem um cadastro histórico por data. Veja API e contratos.
cadastro_rural: filtros SICAR e contexto temporal¶
O dataset agora encaminha atualizado_apos ao SICAR e aceita as_polars, os 2 só por nome, como o return_meta. municipio aceita o nome inteiro ou o código IBGE (§86) e segue na 2ª posição: os 7 primeiros posicionais (uf a criado_apos) continuam válidos. Fonte tabular e dataset passam ao contrato 2.1, com as mesmas onze colunas mais a opcional cod_municipio e chave [cod_imovel], mas datas datetime64[ns, UTC], inclusive nulos e vazios. No dataset cadastro_rural, filtros desconhecidos passam a gerar erro antes da rede.
from agrobr import datasets
df, meta = await datasets.cadastro_rural(
"DF", municipio=5300108,
atualizado_apos="2026-09-01", return_meta=True,
)
criado_apos inclui o limite (>=); atualizado_apos usa limite estrito (>). O filtro de atualização é rejeitado nas doze UFs sem esse campo no WFS. Nas demais camadas, a projeção agora solicita a data de atualização que a implementação anterior omitia.
A coleta tabular usa GeoJSON com atributos, sem geometria e sem dependência de GeoPandas. A migração evita o horário sem fuso do CSV, que não coincide com o instante usado pelo CQL. atualizado_apos aceita Z/offset e normaliza para UTC; entradas sem fuso são interpretadas como UTC. Um timestamp retornado pode ser reutilizado com .isoformat(). O filtro aceita precisão de milissegundos: zeros adicionais são normalizados (.212000 vira .212), enquanto valores submilissegundo são rejeitados sem arredondamento. Não use tz_localize("UTC") em dados CSV antigos sem conhecer seu fuso; recupere os instantes no novo transporte quando necessário.
Use get_contract("cadastro_rural") ou SICAR_IMOVEIS_V2, de agrobr.contracts.sicar. SICAR_IMOVEIS_V1, de agrobr.contracts.datasets, permanece como contrato histórico, não como alias para UTC.
Remova cadastro_rural de blocos datasets.deterministic(...): o dataset passa a rejeitar esse contexto com InvalidParameterError, inclusive com filtros explícitos. Antes, a data de snapshot virava filtro de criação posterior, selecionando outro conjunto de registros. Uma consulta incremental ao cadastro corrente não recupera o estado do cadastro em uma data passada. Veja filtros e limites.
clima: histórico público e contrato mensal 3.1¶
datasets.clima passa a consultar a API observacional INMET, os ZIPs públicos e, no modo UF, o NASA POWER, nessa ordem. Use fonte="inmet_historico" para escolher os arquivos, fonte="inmet" para a API com token ou fonte="nasa_power" para o ponto representativo da UF. Uma fonte explícita não aciona outra rota. O ZIP cobre 2000 em diante; anos anteriores não o incluem no fallback.
df, meta = await datasets.clima(
estacao="A001", inicio="2000-12-30", fim="2001-01-02",
fonte="inmet_historico", return_meta=True,
)
mensal = await datasets.clima("GO", 2001, fonte="inmet_historico")
O contrato mensal 3.1 mantém a chave [mes, uf] e as fórmulas de agregação. As três temperaturas passam a aceitar nulos, assim como a precipitação: períodos sem medições não recebem zero. Há quatro colunas opcionais novas de localização e base, lat, lon, agregacao_espacial e base_tempo; as de cobertura (estacoes_chuva, estacoes_chuva_parciais, dias, data_inicio e data_fim) estão na seção 17. Coordenadas NASA são preservadas; no agregado INMET, ficam nulas. As bases diárias são UTC no INMET e LST no NASA; um ponto solicitado à NASA não equivale à média das estações estaduais.
O modo estação valida clima_estacao 1.0 para diário e o novo clima_estacao_horaria 1.0, com chave [data, hora_utc, estacao], para horário. agregacao="mensal" em estação passa a gerar erro; antes podia devolver horas sem agregá-las. Combinações de UF/ano com estação, datas ignoradas no modo UF e argumentos desconhecidos também falham antes da rede. as_polars=True converte após validar o contrato.
O contrato atual está em agrobr.contracts.clima.CLIMA_V3; agrobr.contracts.datasets.CLIMA_V2 permanece histórico. fonte continua identificando a instituição (inmet ou nasa_power), enquanto meta.selected_source diferencia o acesso inmet_historico. meta.source_details preserva recursos, hashes, membros, metadados por edição e cobertura por variável. O catálogo atual de estações operantes da API difere das estações presentes nos arquivos; use a rota explícita para controlar essa seleção.
Em datasets.deterministic(...), clima usa o ano do contexto somente quando ano não é informado. O contexto não corta observações na data indicada, não força execução offline nem congela a revisão dos arquivos. Isso é declarado nos metadados; preserve os dados e os hashes para reproduzir a edição consultada. Veja o contrato e os limites de cobertura.
ANA: proveniência de consultas com várias páginas¶
return_meta=True agora preenche raw_content_hash e raw_content_size também quando a ANA retorna mais de uma página. Nesse caso, o hash identifica a serialização UTF-8 de {"query": ..., "resources": ...}, com chaves ordenadas, ensure_ascii=False e separadores (',', ':'). raw_content_size mede essa serialização. O tamanho total dos corpos originais está em source_details["resource_bytes"].
source_details publica hash_kind="resource_manifest_sha256", manifest_encoding="canonical_json_utf8", manifest_fields=["query", "resources"], query e resources. A consulta lógica contém fonte, recurso, where, bbox, max_registros e formato; resources preserva a ordem da aquisição e contém pagina (a partir de 1), sha256 e bytes.
Uma única página conserva o hash e o tamanho do corpo; zero páginas conserva hash nulo e tamanho zero. Esta mudança de proveniência não altera dados, colunas, geometrias, CRS, requisições nem o source_url; os tipos e o parâmetro max_registros (antes max_features) mudam pelas regras das seções 85 e 89. O manifesto de hashes do MetaInfo não armazena corpos; use a coleta bruta para preservá-los em disco.
Imports de constantes de contrato¶
Atualize os imports diretos que mudaram de nome no 2.0:
Os imports nomeados históricos continuam disponíveis com DeprecationWarning. Eles conservam o schema da versão indicada e ficam fora de __all__ e do registro ativo. Os contratos atuais possuem suas próprias colunas; alterar um contrato histórico não modifica o atual. Os três aliases descritos abaixo seguem a mesma política de aviso e exportação, mas continuam apontando ao contrato atual, como já faziam.
Módulo em agrobr.contracts |
Nome anterior | Nome atual |
|---|---|---|
datasets → clima |
CLIMA_V1 / CLIMA_V2 |
CLIMA_V3 |
ibge |
IBGE_PAM_V1 |
IBGE_PAM_V2 |
datasets → antt_pedagio |
ANTT_PEDAGIO_FLUXO_V1 / ANTT_PEDAGIO_FLUXO_V2 |
ANTT_PEDAGIO_FLUXO_V3 |
conab → conab_custos |
CONAB_CUSTO_PRODUCAO_V1 / CONAB_CUSTO_PRODUCAO_V2 |
CONAB_CUSTOS_V3 |
datasets |
CREDITO_RURAL_V1_1 |
CREDITO_RURAL_V2 |
datasets |
EXPORTACAO_V1 |
EXPORTACAO_V1_1 |
datasets |
IMPORTACAO_V1 |
IMPORTACAO_V1_2 |
datasets |
MAPBIOMAS_COBERTURA_V1 |
MAPBIOMAS_COBERTURA_V2 |
datasets |
MAPBIOMAS_TRANSICAO_V1 |
MAPBIOMAS_TRANSICAO_V2 |
datasets |
PRECO_ATACADO_V1 |
PRECO_ATACADO_V2 |
datasets |
MAPA_PSR_APOLICES_V1 |
MAPA_PSR_APOLICES_V2 |
datasets → desmatamento |
DESMATAMENTO_PRODES_V1 / DESMATAMENTO_DETER_V1 |
DESMATAMENTO_PRODES_V2 / DESMATAMENTO_DETER_V2 |
datasets → anp_diesel |
ANP_DIESEL_PRECOS_V1 |
ANP_DIESEL_PRECOS_V2 |
datasets |
FERTILIZANTE_V1 |
FERTILIZANTE_V2 |
datasets → zarc |
ZONEAMENTO_AGRICOLA_V1 |
ZONEAMENTO_AGRICOLA_V2 |
datasets → sicar |
SICAR_IMOVEIS_V1 |
SICAR_IMOVEIS_V2 |
datasets → comtrade |
COMERCIO_BILATERAL_V1 / TRADE_MIRROR_V1 |
COMERCIO_BILATERAL_V2 / TRADE_MIRROR_V2 |
ibge |
IBGE_CENSO_AGRO_MUNICIPAL_V1 |
IBGE_CENSO_AGRO_MUNICIPAL_V2 |
preco_atacado passa a 2.0 e mapa_psr_apolices a 2.1: no atacado, categoria sai nula para produto fora da
tabela do agrobr; nas apólices, seguradora entra na chave. Quem valida a categoria trata o nulo, e quem junta
apólices pela chave antiga inclui a seguradora. PRECO_ATACADO_V1 e MAPA_PSR_APOLICES_V1 devolvem os
contratos 1.0 da 1.1.0, com DeprecationWarning; não descrevem a saída atual.
Os nomes canônicos IBGE_LSPA_V2, IBGE_CENSO_AGRO_LEGADO_V2 e
CONAB_SAFRA_V2 também identificam os contratos atuais (ibge.lspa 2.0, ibge.censo_agro_legado 2.1, conab.safras 2.0). Seus três nomes antigos
terminados em _V1 permanecem aliases para compatibilidade de import e
apontam ao mesmo contrato atual; não disponibilizam o schema antigo. Para
consultas por dataset, prefira get_contract(nome) e leia contract.version.
Os contratos que mudam de versão pelas regras de nome e de tipo da 2.0 (abate_trimestral, antt_pedagio_pracas,
condicao_lavouras, movimentacao_portuaria, oferta_demanda_global, posicionamento_fundos, comercio_internacional
e progresso_safra, em CONAB_PROGRESSO_V2 de agrobr.contracts.datasets, com uf no lugar de estado) ganham constante nova, e a antiga segue importável, sem aviso, com o schema anterior (2 exceções:
POSICIONAMENTO_FUNDOS_V1 passou à 1.1, com as colunas opcionais swap_spread e other_spread, e
COMERCIO_BILATERAL_V1, a antiga de comercio_internacional, é histórica e emite DeprecationWarning): veja a
seção 89. O bcb_sgs não tinha contrato na 1.1.0: use BCB_SGS_V3, de agrobr.contracts.bcb_sgs.
Também sobem de versão major anp_diesel_precos (2.0), desmatamento_prodes (2.0), desmatamento_deter (2.1) e
fertilizante (2.0); get_contract(nome) devolve o atual.
estimativa_safra: contrato 3.1 e seleção temporal¶
O contrato do dataset passa a ser ESTIMATIVA_SAFRA_V3_1, em agrobr.contracts.estimativa_safra. A fonte CONAB continua usando CONAB_SAFRA_V2; seu alias não passa a representar o dataset novo. Para obter o contrato certo, use get_contract("estimativa_safra"), versão "3.1".
As dez colunas anteriores continuam presentes, com duas adições nullable, ano_lspa e mes_lspa, e duas de unidade, unidade_producao (mil_ton) e unidade_area (mil_ha), iguais nas 2 fontes. A chave passa de [safra, produto, uf, levantamento] para [fonte, safra, produto, uf, levantamento, ano_lspa, mes_lspa]. Atualize chaves de banco, deduplicação e verificações de schema: a mudança de identidade exige uma versão major. Linhas LSPA antigas não contêm informação suficiente para reconstruir o mês somente pela safra; recupere a referência pela proveniência arquivada ou faça nova consulta explícita.
Os 3 argumentos posicionais produto, safra, uf são preservados; return_meta passa a só por nome (§88), como os novos fonte, levantamento, mes e as_polars. Use levantamento para CONAB e mes para LSPA; combinações incompatíveis falham antes da rede, e referências explícitas indisponíveis não são substituídas por outra fonte ou período.
from agrobr import datasets
conab_mt = await datasets.estimativa_safra(
"soja", safra="2024/25", uf="MT", levantamento=1
)
lspa_mt = await datasets.estimativa_safra(
"soja", safra="2024/25", uf="MT", mes="01"
)
A segunda chamada consulta janeiro do ano civil 2025. O levantamento 1 CONAB é outra referência; não representa janeiro LSPA. Informe a mesma UF ao comparar fontes, pois uf=None retorna UFs na CONAB e Brasil no LSPA. Consulte o contrato completo.
Recorte sem observações. Quando todas as fontes consultadas respondem sem dados para o recorte (por exemplo, a safra que a aba da CONAB ainda não publica, ou a safra seguinte à mais recente dos levantamentos da CONAB, com o LSPA ainda sem o ano), o dataset devolve o vazio do contrato, com UserWarning e o aviso em meta.validation_warnings, e não mais SourceUnavailableError. Quem usava a exceção para detectar "sem dado" passa a conferir df.empty. Com uma fonte vazia e a outra fora do ar, segue SourceUnavailableError; com a outra falhando por layout, ParseError.
1. ANDA aceita somente o produto total¶
Antes, um produto específico era aceito, embora o PDF da ANDA trouxesse apenas o total de fertilizantes:
Agora, use o único valor representado pela fonte:
O que fazer: remova filtros de produto específico nas consultas ANDA e não interprete o total publicado como volume de uma categoria de fertilizante.
2. Toda coluna estável precisa estar presente¶
Na série 1.x, um adaptador podia omitir uma coluna stable que aceitasse
nulos:
df = pd.DataFrame(
{
"data": pd.to_datetime(["2026-09-04"]),
"produto": ["soja"],
"valor": [135.0],
"unidade": ["BRL/sc60kg"],
"fonte": ["cepea"],
}
)
contracts.get_contract("preco_diario").validate(df)
No 2.0, a coluna deve existir; nullable permite valor nulo, não ausência da
coluna:
O que fazer: ao produzir DataFrames para validação, crie todas as colunas
stable; preencha com pd.NA somente aquelas cujo contrato marca como
nullable.
3. conab.safras passa ao contrato 2.0¶
Código 1.x podia presumir que levantamento e data de publicação sempre existiam:
No contrato 2.0, os dois campos são nulos nas linhas da série histórica (§27); no dataset estimativa_safra
(contrato 3.1), também nas linhas do fallback IBGE LSPA:
levantamentos = df["levantamento"].astype("Int64")
datas = pd.to_datetime(df["data_publicacao"], errors="coerce")
sem_levantamento = df[df["levantamento"].isna()]
O que fazer: trate os dois campos como opcionais e use dtypes pandas que aceitem nulos.
area_colhida sai nula pela CONAB: o boletim publica uma área só, que a 1.x
copiava para as 2 colunas. Use area_plantada. data_publicacao passa a ser a
data do boletim; na 1.x, era o dia da consulta.
4. bcb.credito_rural passa ao contrato 2.0¶
Na 1.1.0, a chamada padrão (agregacao="municipio") não agregava: devolvia os registros do SICOR,
um por mês, UF, programa, subprograma, fonte de recursos, tipo de seguro, atividade e modalidade, com 21 colunas no
custeio (20 no investimento e na comercialização, que não têm área). A coluna volume do contrato 1.x nunca saiu:
No 2.0, "municipio" levanta InvalidParameterError, e a agregação padrão é por UF; a opção por programa agrupa
também pelo programa:
por_uf = await bcb.credito_rural("soja", agregacao="uf")
por_programa = await bcb.credito_rural("soja", agregacao="programa")
colunas = [
"programa",
"cd_programa",
"qtd_contratos",
"valor",
"area_financiada",
"fonte",
]
resultado = por_programa[colunas]
As agregações uf e programa têm 11 colunas. Das 21 da chamada padrão da 1.1.0, 12 não saem nelas: regiao,
mes_emissao, ano_emissao, cd_sub_programa, cd_fonte_recurso, fonte_recurso, cd_tipo_seguro, tipo_seguro,
cd_modalidade, modalidade, cd_atividade e atividade. Código da 1.1.0 que agrupa por mês, fonte de recursos,
modalidade ou atividade cai em KeyError nelas. O recorte da 1.1.0 é o agregacao="registro":
registros = await bcb.credito_rural("soja", safra="2024/25", agregacao="registro")
por_mes_e_fonte = registros.groupby(["mes_emissao", "fonte_recurso"])["valor"].sum()
O registro devolve as 21 colunas da 1.1.0, mais agregacao e fonte, no contrato
bcb.credito_rural_registro 1.0, também no dataset credito_rural.
Diferenças em relação à 1.1.0:
- a safra sai
"2024/25"(seção 76); - os nomes de programa e tipo de seguro vêm das tabelas oficiais do BCB (seção 30), e os de fonte de recursos,
modalidade e atividade, da descrição oficial inteira. A 1.1.0 tinha dicionários digitados: a fonte
0403, de 39 dos 277 registros do custeio da soja de MT em 2024/25, saíaDesconhecido (0403); - código de fonte de recursos, modalidade ou atividade fora da tabela deixa o nome nulo, em vez de
Desconhecido (…); area_financiadasai em todas as finalidades, nula no investimento e na comercialização;- sem fallback BigQuery: com o OData fora, levanta
SourceUnavailableError. O fallback só vale paraagregacao="uf"semprogramanemtipo_seguro, porque a tabela da Base dos Dados não traz programa nem seguro.
O que fazer: substitua agregacao="municipio" por "registro" (o mesmo recorte, registro a registro) ou por "uf"
ou "programa" (agregado), remova o uso de volume e adapte a seleção às novas colunas. Para dados municipais via
BigQuery, use a integração opcional agrobr[bigquery] fora desse contrato.
5. DERAL preserva a safra no produto¶
Na série 1.x, primeira e segunda safras podiam ser fundidas:
Agora, os rótulos identificados pela fonte ficam separados:
milho = df[df["produto"].isin(["milho", "milho_1", "milho_2"])]
feijao = df[df["produto"].isin(["feijao", "feijao_1", "feijao_2"])]
O que fazer: inclua os sufixos _1 e _2 em filtros, agrupamentos e chaves;
o nome sem sufixo continua possível quando a planilha não identifica a safra.
6. CEPEA rejeita parâmetros inválidos¶
Antes, produto ou praça desconhecidos e alguns intervalos inválidos podiam resultar em DataFrame vazio:
Agora, indicador(), ultimo() e pracas() levantam
InvalidParameterError:
from agrobr import InvalidParameterError
try:
df = await cepea.indicador("soja", inicio="2026-01-01")
except InvalidParameterError as exc:
print(f"Parâmetro inválido: {exc}")
O que fazer: valide ou normalize entradas do usuário e trate
InvalidParameterError separadamente de ausência de dados e falhas da fonte.
Sai o _moeda. O parâmetro reservado _moeda de indicador() não convertia nada e sai. Passá-lo, por nome ou como 5º argumento posicional, levanta TypeError: remova o argumento. As unidades publicadas seguem na coluna unidade.
7. Erros de parâmetros interrompem a cascata dos datasets¶
Na série 1.x, aplicações podiam tratar uma entrada inválida como falha de fonte:
No 2.0, uma entrada inválida não tenta fallbacks:
from agrobr import InvalidParameterError, SourceUnavailableError
try:
df = await datasets.preco_diario("soja")
except InvalidParameterError:
corrigir_entrada()
except SourceUnavailableError:
tentar_mais_tarde()
O que fazer: capture InvalidParameterError antes dos erros de disponibilidade
e solicite a correção do parâmetro em vez de repetir a consulta.
8. as_polars=True exige Polars¶
Antes, pedir Polars sem a dependência instalada podia devolver pandas:
Agora, instale o extra antes de solicitar esse formato:
df = await cepea.indicador("soja", as_polars=True)
# df é polars.DataFrame; sem o extra, a chamada levanta ImportError
O que fazer: instale agrobr[polars] ou mantenha as_polars=False e trabalhe
com pandas. O extra exige polars>=0.20.3.
9. Módulos experimentais foram removidos¶
Imports diretos encontrados por exploração do pacote deixam de existir:
from agrobr.export import export_csv
from agrobr.quality import quick_check
from agrobr.validators import validate_safra
Use APIs públicas mantidas ou recursos nativos do DataFrame:
from agrobr import contracts
contracts.get_contract("estimativa_safra").validate(df)
df.to_csv("safra.csv", index=False, encoding="utf-8")
O que fazer: remova usos de quality, sla, export, plugins,
validators.semantic e validators.validate_safra. Não há substituto direto
para o sistema de plugins ou para a validação semântica experimental; implemente
regras específicas na aplicação quando necessário.
10. agrobr.configure() foi removida¶
A chamada deprecada nunca alterou o comportamento real de fetch, cache ou fallback:
No 2.0, remova a chamada. Para o modo determinístico suportado, use o contexto do dataset:
from agrobr import datasets
async with datasets.deterministic("2026-09-04"):
df = await datasets.preco_diario("soja")
O que fazer: use as variáveis de ambiente AGROBR_* documentadas para cada
configuração efetiva. O modo determinístico atualmente cobre apenas
preco_diario; consulte o guia de snapshots.
11. Novos avisos de licença e fallback¶
Antes, uma consulta podia trocar de fonte sem um sinal dedicado ao chamador:
Agora, é possível tornar qualquer fallback explícito na política da aplicação:
import warnings
from agrobr import datasets
from agrobr.exceptions import SourceFallbackWarning
warnings.filterwarnings("error", category=SourceFallbackWarning)
df = await datasets.preco_diario("soja")
A primeira chamada ao CEPEA também emite um aviso sobre a licença CC BY-NC 4.0. O que fazer: mantenha o aviso visível, revise as licenças das fontes e escolha conscientemente se um fallback deve ser aceito, registrado ou convertido em erro.
Classificações de licença na 2.0¶
Quem filtra por licença (na 1.1.0, só datasets.info(nome)["license"]; na 2.0, também MetaInfo.license e datasets.info(nome)["licenses"], novos) deve atualizar sua política para estas mudanças:
| Fonte ou conjunto de fontes | Antes | Agora |
|---|---|---|
| IMEA — séries públicas | restrito |
zona_cinza |
| Notícias Agrícolas — publicador | restrito |
zona_cinza |
| UN Comtrade | livre |
restrito |
| Acervo Fundiário/INCRA | nc |
livre |
CEPEA e Notícias Agrícolas em data_sources |
— (datasets.info("preco_diario") já dava nc) |
nc |
B3 permanece zona_cinza. Arquivos não públicos do IMEA continuam sujeitos à autorização escrita prevista nos termos. Dados de origem CEPEA conservam CC BY-NC 4.0, inclusive no fallback; quando as duas fontes aparecem nos metadados, prevalece nc. Comtrade conserva as dispensas de redistribuição previstas em sua política. O Acervo deixa de emitir o aviso de vedação comercial.
As novas classes também aparecem em datasets.info()["licenses"] e na descrição das fontes; datasets.info("comercio_internacional")["license"] e source_details["license"]["classification"] das novas consultas Comtrade passam a restrito. Arquivos de metadados já salvos não são regravados. MetaInfo.from_dict() recalcula license pela tabela instalada, mas conserva as classificações antigas dentro de source_details. Ao ler arquivos antigos, confira sua proveniência e a tabela atual de licenças antes de aplicar um filtro.
livre admite uso comercial no escopo descrito, mas pode exigir atribuição, preservação de avisos, indicação de alterações e condições ND/SA. zona_cinza não concede permissão nem estabelece proibição geral. A reclassificação não muda o fluxo de aquisição nem os valores retornados.
O MapBiomas Alerta mantém livre, mas seus dados, inclusive os obtidos pela API, estão sob CC BY-SA 3.0 BR: preserve atribuição, link da licença, indicação de alterações e as condições SA para adaptações. Imagens e laudos de terceiros exigem termos próprios. Um filtro baseado só em license == "livre" não verifica essas obrigações; consulte o escopo do MapBiomas Alerta.
12. Custos preservam a aba publicada¶
Remova tecnologia= de conab.custo_producao, conab.custo_producao_total e datasets.custo_producao. O contrato ativo é 3.0, com 25 colunas. Use agrobr.contracts.conab_custos.CONAB_CUSTOS_V3 ou get_contract("custo_producao"). Selecione planilha e aba sem ambiguidade; contexto, rótulos literais e números físicos de linha são preservados.
conab.custo_producao(produto, uf=...) e custo_producao_total sem planilha e aba levantam InvalidParameterError quando o catálogo do produto tem mais de um contexto possível, como na soja de MT (a 1.1.0 escolhia sozinha). Liste as planilhas com conab.catalogo_custos(produto) e as abas com conab.catalogo_custos(produto, planilha=...), e passe as duas; só planilha= não basta.
Não há chave primária artificial. Preserve ocorrências repetidas, distinção de subtotal/total, tokens de safra anuláveis e referências de preços separadas. Receitas negativas são válidas; quantidades e preços unitários ausentes não são derivados de outros custos. Veja o contrato completo.
13. Produtos SICOR e vazio válido¶
Substitua cafe_arabica e cafe_conilon por cafe no crédito rural. O SICOR não distingue essas modalidades. Milho e trigo agora usam correspondência exata, excluindo silagem e sarraceno dos agregados; totais antigos podem mudar.
Filtros válidos sem registros retornam DataFrame vazio com colunas e tipos do contrato. Na finalidade investimento, o produto é um item de investimento, não necessariamente a cultura financiada. Não trate ausência de registros como crédito igual a zero sem avaliar a cobertura da fonte.
14. Tipos e proveniência¶
Contratos rejeitam inteiros fracionários, texto com valores não textuais e booleanos numéricos/textuais. Use tipos anuláveis (Int64, Float64, boolean) para preservar ausências. required_columns inclui todas as colunas estáveis, mesmo anuláveis, e MetaInfo.schema_version corresponde à versão do contrato do dataset.
Instale agrobr[polars] para conversão: o extra inclui pyarrow. Erros de conversão não são mais apresentados como ausência de Polars quando a dependência que falta é outra.
MetaInfo: timestamps UTC com fuso¶
Os quatro campos temporais de MetaInfo (fetched_at, timestamp, cache_expires_at e fetch_timestamp) passam a usar sempre UTC com fuso, inclusive em atribuições posteriores. Valores naive de entrada são interpretados como UTC; valores aware com outro offset são convertidos preservando o instante. Por exemplo, 2024-06-15T23:30:00-03:00 torna-se 2024-06-16T02:30:00+00:00. Campos opcionais mantêm None.
from_dict() continua aceitando strings ISO antigas sem fuso. No construtor e em atribuições, forneça objetos datetime; string crua gera AttributeError, sem conversão implícita. to_dict() passa a incluir +00:00 em todos os timestamps preenchidos; atualize comparações de strings e schemas de consumidores. Compare ou subtraia esses campos com datetime.now(UTC), importando UTC de datetime; utcnow() continua retornando datetime naive e não serve para essa comparação direta. Datas civis publicadas nas colunas dos datasets mantêm seus contratos próprios.
MetaInfo: duas convenções de identidade da fonte¶
selected_source e attempted_sources podem identificar o adaptador do dataset ou a rota informada pela fonte. comercio_internacional, desmatamento, empregadores_lista_suja, unidades_conservacao, unidades_conservacao_federais, uso_do_solo, cultivares_registradas e cultivares_protegidas preservam a proveniência interna quando informada, inclusive com uma única tentativa. Os demais datasets usam o nome do adaptador (DatasetSource.name): numa consulta simples de cadastro_rural, os campos são "sicar" e ["sicar"], embora a API da fonte identifique sicar_wfs.
Na regra da base, mais de uma tentativa interna ou selected_source="cache" faz o dataset incorporar a proveniência da fonte. As tentativas combinam adaptadores anteriores e rotas internas em ordem, sem duplicatas; a seleção usa a rota informada ou o adaptador se ela estiver ausente. from_cache continua indicando reutilização da aquisição e é propagado separadamente: seu valor True, sozinho, não muda os nomes publicados. Essas convenções permanecem distintas na 2.0; confira os identificadores do dataset consumido ao persistir ou comparar proveniência.
15. CEPEA e limites históricos¶
Revise séries anteriores de soja Paraná, frango resfriado, etanol anidro e açúcar refinado: a seleção antiga podia usar outra tabela. O refinado usa sua página própria e unidade BRL/kg. As laranjas são publicadas na página de citros e permanecem disponíveis.
Suíno preserva a coluna Estado como praça; as linhas legadas afetadas ficam em quarentena, fora das consultas normais e sem perder os originais. Para leite, data é o primeiro dia do mês de referência, praca é a UF ou BRASIL e a unidade é BRL/L; a tabela spot não entra. O histórico CEPEA acumula no cache: solicitar um ano não obriga a fonte a publicar um ano de dados.
16. Snapshots e parâmetros de período¶
Snapshots exigem pyarrow ou fastparquet e aceitam somente CEPEA, CONAB e IBGE. Zero arquivos remove o diretório criado e levanta SnapshotError, exportada em agrobr; a CLI sai com código 1. Snapshots parciais registram erros por fonte no manifesto. load_from_snapshot() recusa pyarrow anterior ao 14.0.1 (CVE-2023-47248) com ImportError, antes de ler o Parquet; atualize com pip install "pyarrow>=14.0.1".
PPM rejeita anos futuros; PRODES exige ano inteiro dentro do intervalo da camada. Abate, leite trimestral e PIB aceitam formatos como 2025-T4, normalizados para 202504. ZARC aceita aliases e nomes da tábua, mas a disponibilidade depende da safra. Arquivos anuais legados de queimadas são suportados; o fallback pode baixar centenas de MB. HTTP 400/404 na solicitação do token indica arquivo não publicado e retorna vazio após validação da data. No download, HTTP 404 retorna vazio, mas HTTP 400 levanta SourceUnavailableError. As operações token/download são serializadas no processo; o histórico consulta os dias sequencialmente.
17. Unidades históricas, cache e medições ausentes¶
ibge.pam e o contrato producao_anual 2.2 mantêm os números publicados e acrescentam unidade_producao, unidade_rendimento, unidade_valor_producao e condicao_produto. Agrupe ou converta explicitamente antes de comparar períodos. Laranja muda de mil frutos para toneladas em 2001; café muda de em coco para beneficiado em 2002; moedas anteriores a 1994 não são reais.
Muda calado. ibge.pam passa a devolver as localidades em que o IBGE publica produção zero, com área, produção e rendimento 0.0 (soja 2023: 27 UFs, e não 25; 142 municípios de MT, e não 128), e as colunas saem na ordem do contrato (ano, localidade, localidade_cod…). Para a contagem e a média da 1.1.0, filtre producao > 0, e leia as colunas pelo nome.
O contrato mensal clima 3.1 preserva precipitação e temperaturas ausentes. Na 1.1.0, a chuva da UF no INMET era a soma das estações; agora é a média dos totais das estações com chuva válida em todos os dias do mês. A estação com o mês incompleto fica fora e é contada em estacoes_chuva_parciais (estacoes_chuva conta as que entraram); sem nenhuma completa, como no mês corrente, precip_acum_mm sai nulo, com UserWarning e a mesma mensagem em MetaInfo.validation_warnings. Em MT, fevereiro de 2026, 12 das 34 estações com chuva tinham só 6 a 25 dos 28 dias: com elas na média, o mensal seria 254,1 mm; só com as 22 completas, é 305,7 mm. Somatórios parciais não são extrapolados: dias, data_inicio e data_fim dão a cobertura diária de cada mês, no INMET e no mensal do NASA POWER (schema 1.2). O modo diário por estação permanece no contrato clima_estacao 1.0; o horário usa clima_estacao_horaria 1.0.
As migrações do cache preservam automaticamente os registros afetados em indicadores_quarentena, no mesmo DuckDB, antes de retirá-los da área ativa. Isso inclui suíno e praças ausentes das migrações 5/6, as séries CEPEA da 7 e o refinado legado do Notícias Agrícolas com unidade incorreta, tratado na 8. A preservação não depende de backup manual. Consulte o procedimento de auditoria e recuperação abaixo.
datasets.preco_diario levanta SourceUnavailableError se fonte e cache falham; resultados legitimamente vazios por filtro continuam válidos. O aviso de fallback também cobre a troca interna CEPEA → Notícias Agrícolas e não é absorvido quando convertido em erro. Publicação CONAB ausente fica nula, não recebe a data da consulta. Navegadores são encerrados ao sair do contexto da página; chamadas sync repetidas não reutilizam recursos de um loop fechado.
18. Preservação automática do cache existente¶
O agrobr 2.0 exige DuckDB 1.5.2 ou mais recente. As versões 1.5.0 e 1.5.1 foram
excluídas por falhas de alteração de tabelas indexadas, inclusive em bancos legados.
A migração 2 adiciona somente colunas faltantes: hit_count e stale já existentes
não recebem ALTER, preservando seus valores em bancos parcialmente migrados.
A primeira abertura do cache atualiza o schema para a versão 11, mesmo quando a
consulta pede um produto não afetado. Toda a sequência pendente é uma única
transação: copiar para quarentena, conferir o conteúdo, retirar ou corrigir a área ativa e
registrar as versões. Acréscimos de coluna (migrações 2, 10 e 11) são idempotentes e
correm antes dessa transação, pois o DuckDB não altera uma tabela já modificada na
mesma transação. Falhas de escrita, permissão ou registro da versão levantam
CacheMigrationError (exportada por agrobr) e revertem a atualização; não são
tratadas como um cache vazio. Corrija a causa antes de tentar novamente.
A tabela indicadores_quarentena fica no mesmo arquivo agrobr.duckdb configurado
por AGROBR_CACHE_DIR (padrão: ~/.agrobr/cache). Ela conserva todos os
campos e tipos originais, inclusive ID, praça, valor decimal, unidade, fonte,
metodologia, coleta e versão do parser. Acrescenta quarantine_migration,
quarantined_at e quarantine_reason. Consultas normais e offline leem somente
indicadores; a quarentena não é um fallback e não tem expiração automática.
As regras são conservadoras quando o legado não permite distinguir observações corretas de incorretas:
- Migração 5: registros com praça nula, de qualquer fonte.
- Migração 6: suíno CEPEA anterior ao parser 2 ou Notícias Agrícolas anterior ao 3.
- Migração 7: parser CEPEA anterior ao 2 para
soja_parana,frango_resfriado,etanol_anidro,acucar_refinado,leite,laranja_industriaelaranja_in_natura. - Migração 8: refinado CEPEA ou Notícias Agrícolas rotulado
BRL/sc50kg, em vez deBRL/kg, independentemente da versão do parser. O legado NA já usava a versão 2; o número sozinho não permite reconhecer a unidade correta. - Migração 9: leite do Notícias Agrícolas sai da área ativa, pois seu parser
gravou a data de fechamento, enquanto CEPEA usa o mês de referência. Trigo
CEPEA anterior ao parser 2 rotulado
BRL/sc60kgpassa aBRL/ton; algodão desse mesmo legado rotuladoBRL/@passa acBRL/lb. Os números publicados permanecem iguais; a migração corrige apenas esses rótulos comprovadamente incorretos, conservando também as linhas originais em quarentena. - Migração 10: acrescenta
valor_usdepeso_medio_kgaindicadorese, quando já existe, aindicadores_quarentena; nada é posto em quarentena, e registros anteriores ficam nulos nessas colunas até nova coleta. - Migração 11: acrescenta
anomaliesàs mesmas tabelas e grava a marca de média semanal no cache. Os registros anteriores recebem["media_semanal"]no etanol hidratado e anidro do Notícias Agrícolas, que só publica médias semanais, e lista vazia nos demais; nada é posto em quarentena.
Só são executadas as migrações ainda pendentes. Novas observações dos parsers corrigidos usam CEPEA 2 e Notícias Agrícolas 3. A correção de rótulos da migração 9 não converte valores entre unidades. Os demais registros em quarentena podem exigir conferência com a fonte antes de qualquer recuperação.
Reserve espaço adicional para a cópia das linhas afetadas, índices, transação e WAL; o tamanho necessário depende do banco e não há um multiplicador fixo garantido. A quarentena preserva o histórico da migração, mas não protege contra perda ou corrupção física do arquivo: mantenha também seus backups externos.
Auditar e recuperar em uma cópia¶
Feche normalmente todas as conexões e processos que usam o banco antes de copiá-lo, para concluir o checkpoint. Não copie apenas o arquivo principal de um banco ainda em uso ou com transação pendente. Use caminhos explícitos; o exemplo pressupõe que o arquivo de origem fechado esteja no diretório atual.
import shutil
from pathlib import Path
import duckdb
origem = Path("agrobr.duckdb")
copia = Path("agrobr-auditoria.duckdb")
if copia.exists():
raise FileExistsError(copia)
shutil.copy2(origem, copia)
with duckdb.connect(str(copia), read_only=True) as conn:
resumo = conn.execute("""
SELECT quarantine_migration, produto, fonte, unidade, COUNT(*) AS registros
FROM indicadores_quarentena
GROUP BY ALL ORDER BY ALL
""").fetchall()
print(resumo)
Para reconstruir a área ativa somente nessa cópia de auditoria, os originais podem ser reinseridos sem alterar tipos, chaves, sequência de IDs ou versão do schema. Execute apenas após avaliar os registros; a operação não corrige seus valores ou rótulos e não deve ser aplicada ao cache de produção:
with duckdb.connect(str(copia)) as conn:
conn.execute("BEGIN TRANSACTION")
try:
conn.execute("""
INSERT INTO indicadores BY NAME
SELECT * EXCLUDE (quarantine_migration, quarantined_at, quarantine_reason)
FROM indicadores_quarentena
""")
conn.execute("COMMIT")
except duckdb.Error:
conn.execute("ROLLBACK")
raise
Se já houver observações com as mesmas chaves, a inserção falha sem sobrescrevê-las. Nesse caso, consulte os originais diretamente na quarentena e decida quais IDs reconstruir na cópia. A quarentena permanece disponível após a reinserção.
Instalações que já executaram versões antigas das migrações 5/6/7 podem ter registros ausentes. A migração 8 preserva o que ainda existe, mas não recria o que já foi excluído. Reinstalar uma versão anterior da biblioteca não restaura dados. Sem backup anterior, a quantidade perdida pode permanecer desconhecida; a janela recente do CEPEA não garante recuperação integral.
Cache e política de fallback¶
Em cepea.indicador(..., return_meta=True) e datasets.preco_diario,
selected_source="cache" identifica a leitura local. data_sources lista as
fontes efetivas das linhas retornadas, também identificadas na coluna fonte.
Uma consulta quente ou offline tem attempted_sources=["cache"] e não representa
uma nova tentativa de fallback.
Quando a coleta falha e o cache a substitui, attempted_sources preserva as
tentativas e termina em "cache". O dataset emite SourceFallbackWarning,
inclusive nesse caminho interno, e respeita sua conversão em erro. A API direta
CEPEA emite StaleDataWarning para esse uso de cache após falha. Esses avisos não
são uma política de autorização por provedor: para rejeitar dados anteriormente
obtidos pelo Notícias Agrícolas, verifique data_sources ou a coluna fonte,
mesmo offline.
Banco ilegível: na 1.1.0, com o agrobr.duckdb danificado (queda de energia, disco cheio ou antivírus no meio
da gravação), o cepea.indicador seguia sem cache a cada chamada, sem UserWarning (só um logger.warning), até
alguém apagar o arquivo. Na 2.0,
o banco que o DuckDB acusa como ilegível (leitura incompleta, checksum ou arquivo inválido) vai para
agrobr.duckdb.corrompido-<AAAAMMDDHHMM>, com o WAL, o agrobr avisa uma vez com os 2 caminhos (UserWarning), e a
consulta seguinte cria um banco novo. A quarentena das migrações vai junto com o arquivo movido. Arquivo em uso
por outro processo e disco cheio não movem nada. Veja o que o agrobr grava no disco.
19. Dependências, falhas e saídas estruturadas¶
Os mínimos de segurança também passam a HTTPX 0.28.1, httpcore 1.0.9, lxml 6.1.0, requests 2.33.0, soupsieve 2.9.0 (piso explícito novo) e GeoPandas 1.1.4 no extra geo, e o certifi 2026.7.22 (autoridades certificadoras do TLS) entra como dependência direta do core. Veja a justificativa na política de dependências.
Atualize as dependências com o pacote: pandas mínimo 2.2.2, Typer 0.26.0, pdfplumber 0.11.10 no extra PDF, pyogrio 0.8.0 no extra geo e polars 0.20.3 no extra polars (o as_polars=True dos datasets usa o tipo String, que o Polars só tem a partir dele). Esses limites excluem combinações que falhavam no import, na CLI ou na extração numérica de PDFs. O transporte SIDRA passa a HTTP assíncrono direto; sidrapy não é mais uma dependência.
Consultas NASA divididas em blocos falham integralmente se um bloco não puder ser obtido. Erros de agregação são rejeitados antes da rede. Início depois de hoje (calendário de Brasília) em clima_ponto e ano posterior ao corrente em clima_uf também levantam InvalidParameterError antes da rede; na 1.1.0, a resposta sem nenhum dia virava ParseError. Não interprete ausência de medições como cobertura completa.
Na CLI, JSON/CSV ocupa somente stdout; progresso e erros usam stderr. Resultados vazios produzem [] ou o cabeçalho CSV. snapshot list --formato json vazio produz []. doctor expõe erros de cache, respeita as configurações de health e retorna código 1 para erros locais ou indisponibilidade de qualquer fonte consultada. Isso diagnostica a saúde da coleta e não significa, por si só, instalação defeituosa. Avisos como credencial ausente não são confundidos com queda da fonte.
Retornos vazios usam o contrato da modalidade solicitada, inclusive PRODES/DETER, futuros, seguro rural e MapBiomas estadual. Contratos numéricos rejeitam booleanos, complexos e infinitos; datas numéricas não são interpretadas silenciosamente como timestamps de 1970.
Snapshots novos são publicados após a conclusão do manifesto e verificados por SHA-256 na leitura. Cancelar a criação libera o nome para uma nova tentativa. Snapshots antigos permanecem legíveis; veja as limitações de integridade e interrupção abrupta.
20. LSPA preserva mês, variável e unidade¶
O contrato lspa passa a 2.0. Use a chave [ano, mes, produto, localidade, variavel]; mes sempre existe e consultas anuais preservam os meses publicados. variavel_cod identifica a variável SIDRA e unidade informa a medida de cada linha. Não trate o rótulo do mês como produto ou variável. O dataset estimativa_safra continua selecionando o mês mais recente e consolidando as sub-safras nas suas próprias unidades.
21. Censo legado usa a geografia e os cabeçalhos oficiais¶
O contrato censo_agropecuario_legado passa a 2.1. nivel="uf" retorna totais estaduais; sem uf, consulta os 27 diretórios. Para categorias nacionais de atividade, use nivel="brasil" sem filtro estadual. Nos municípios, inclua uf na chave para distinguir homônimos; códigos históricos ausentes permanecem nulos.
Atualize filtros de categoria e variavel conforme o contrato: eles refletem os rótulos reais, incluindo a hierarquia dos cabeçalhos. Leia unidade por linha; contagens, áreas, produção e valores monetários são medidas distintas, com a escala da célula oficial aplicada e precisão decimal preservada.
Na 1.1.0, censo_agro_legado("maquinas", uf="PA") devolvia calada a Tabela 6 (pessoal ocupado) como tratores: o Para/Tab_7Mn.zip do IBGE é cópia do Tab_6Mn.zip, e o pessoal ocupado de Baixo Amazonas (124.592 pessoas) saía como total_tratores. Descarte séries de máquinas do Pará gravadas com a 1.x. Na 2.0, uf="PA" levanta SourceUnavailableError, e a consulta sem uf devolve as outras 26 UFs, com o aviso no MetaInfo e um UserWarning: a tabela municipal de maquinaria do Pará não está no FTP.
22. Café, cana e catálogo CONAB¶
Remova cana_industria das consultas de série histórica: na 1.x, as tabelas industriais passavam pelo parser agrícola, que não as interpretava, e na 2.0 serie_historica("cana_industria") levanta InvalidParameterError. Açúcar, etanol de cana e de milho e ATR por safra e UF saem de conab.cana_industria() e de datasets.producao_acucar_etanol(), com colunas próprias (contrato); etanol_total_mil_l inclui o etanol de milho.
Para café, o contrato serie_historica_safra 1.1 acrescenta as colunas opcionais area_em_producao_mil_ha e area_formacao_mil_ha. A área plantada total é a soma quando ambas existem; produtividade continua referente à área em produção. Produção e produtividade passam corretamente de mil sacas de 60 kg e sacas/ha para mil toneladas e kg/ha. Revise séries de café persistidas com o parser anterior. Em todos os produtos da série histórica, e não só no café, o zero publicado na planilha passa a sair 0.0: antes virava nulo, e a UF sem produção naquela safra não tinha linha (amendoim 2ª safra, BA 2011/12: produção nula na 1.1.0, 0.0 na 2.0). Séries persistidas com o parser anterior têm menos linhas e nulos onde a fonte publica zero. A safra zerada em todas as UFs (não levantada) continua fora.
No café (cafe, cafe_arabica, cafe_conilon), ES, RJ e SP saíam com regiao="NORTE", porque a sub-região mineira "Norte, Jequitinhonha e Mucuri" era lida como macrorregião. Agora saem SUDESTE, e a região só muda com o rótulo exato da macrorregião. Refaça agregações por região feitas com séries de café persistidas na 1.x.
Em cana, a aba Área da planilha agrícola é a área colhida (título oficial "Série Histórica de Área Colhida"). Ela passa para a coluna opcional nova area_colhida_mil_ha do contrato 1.1, e area_plantada_mil_ha fica nula nesse produto. Na 1.x, esse valor saía como área plantada: troque a coluna onde lia area_plantada_mil_ha da cana. Para a área total, use cana_area_total.
Muda calado: algodao na série histórica. Na 1.1.0, conab.serie_historica("algodao") devolvia a produção e a produtividade do caroço de algodão (a semente), porque a última aba de cada métrica na planilha da CONAB sobrescrevia as anteriores. Na 2.0, algodao é o algodão em caroço (pluma mais semente), e a semente passa a algodao_caroco, com algodao_pluma para a pluma (#112); a área é a mesma nos três. Na mesma planilha (setembro de 2026), BA 2023/24, algodao dá 1.686,4 mil t e 4.874 kg/ha na 2.0, contra 978,1 mil t e 2.826,9 kg/ha na 1.1.0 (cerca de 1,7×). Para manter a série da 1.x, troque algodao por algodao_caroco; não junte séries de algodao gravadas com a 1.x a consultas da 2.0.
23. Preços e valores de produção respeitam a unidade da linha¶
Em preco_diario, valor está em unidade: algodão em cBRL/lb exige divisão por 100 para exibição em BRL/lb. Na PEVS, o valor de produção usa moeda, enquanto quantidade produzida usa a unidade física do produto. Preserve as unidades históricas informadas pelo SIDRA ao combinar períodos.
24. ANTT preserva cobrança e frequência¶
O contrato ativo antt_pedagio_fluxo é 3.0, com 13 colunas. Use ANTT_PEDAGIO_FLUXO_V3, de agrobr.contracts.antt_pedagio, ou get_contract("antt_pedagio_fluxo"). A chave é data, concessionaria, praca, sentido, tipo_veiculo, categoria_eixo, tipo_cobranca, frequencia. Mantenha cobranças manuais e automáticas separadas.
Somente contagens textuais explícitas alimentam n_eixos; números isolados e categorias tarifárias ficam nulos. Rótulos e espaços da categoria são preservados. Faixas comerciais explícitas podem qualificar no filtro de pesados sem receber contagem exata inventada.
Escolha frequencia="mensal" ou "diaria"; nenhuma substitui a outra silenciosamente. O recorte de datas ainda valida o CSV anual inteiro baixado. Tetos de CSV/spool/transferência: 512 MiB / 1 GiB / 3 GiB. O limite padrão do parser é de 500 mil linhas selecionadas; exceder orçamento gera erro.
O contrato do cadastro de praças passa a 2.0 (ANTT_PEDAGIO_PRACAS_V2), com km_m, ano_do_pnv_snv e data_da_inativacao tipados (§89); o período do fluxo é inicio/fim. Metadados do tráfego preservam todos os recursos, hashes, frequência, estatísticas de EOF e cobertura. raw_content_size é o tamanho do manifesto, o mesmo objeto do raw_content_hash, que identifica a consulta e a aquisição; os bytes de catálogos e CSVs recebidos em todas as tentativas vão em source_details["received_bytes"] (§57). Veja a referência da API.
Com uf/rodovia, praça sem vínculo único no cadastro sai do resultado com aviso (antes a consulta inteira falhava). CSV sem cabeçalho passa a ParseError. As funções legadas parser.parse_trafego, parse_trafego_v1, parse_trafego_v2, join_fluxo_pracas, heavy_vehicle_mask, client.download_csv e as constantes CATEGORIA_MAP, EIXOS_TIPO_MAP, COLUNAS_FLUXO, COLUNAS_V2 e ANO_INICIO_V2 foram removidas: use fluxo_pedagio() ou, para um arquivo local, parser.parse_trafego_file().
Texto do fluxo e coluna municipal. sentido sai em maiúsculas: Crescente e CRESCENTE viram CRESCENTE (idem DECRESCENTE), e os rótulos de fluxo_pedagio saem sem os espaços externos que a ANTT publica. Quem filtrava ou agrupava pelo texto publicado troca o valor; o volume não muda (no CSV mensal oficial de 2023, o total, o volume por sentido e o enriquecido conferem). Concessionária e praça do cadastro também saem sem espaço externo, e o vínculo com UF, rodovia e município se mantém. Em pracas_pedagio, a coluna municipal continua nesta versão, como cópia de municipio, mas emite FutureWarning e aviso no MetaInfo e sai na próxima versão major: use municipio.
25. INCRA: WFS 2.0, 22 colunas e o marcador de data vazia¶
incra.quilombolas() e incra.quilombolas_geo() passam a ler a camada em WFS 2.0.0/JSON e devolvem 22 colunas (contrato incra_quilombolas 2.0): as 10 anteriores, na mesma ordem, seguidas de feature_id, regional, processo, data_publicacao_2, responsavel, esfera, data_cadastro, codigo_sipra, descricao, data_decreto, tipo_levantamento e escala. Selecione colunas pelo nome.
data_publicacao,data_titulo,data_publicacao_2edata_decretosaem emdatetime64[ns], edata_cadastroemdatetime64[ns, UTC]. O marcador0001-01-01da fonte ("sem data") viraNaTsem aviso; outra data fora de 1900–2099 (erro de digitação da fonte), inclusive emdata_cadastro, viraNaT, comUserWarninge aviso emmeta.validation_warnings.incra.vinculos_quilombolassegue a mesma regra nas colunasperimetro_*.codigoefamiliassãoInt64;area_haéfloat64em hectares publicados; os demais textos usam o dtype padrão do pandas (§89).bboxusa EPSG:4326, equilombolas_geo()devolve as coordenadas nesse CRS sem reparo topológico (omake_validda 1.x saiu).- O Acervo Fundiário segue a mesma regra:
sigef_geo,snci_geoeassentamentos_geodeixam de reparar o polígono commake_valide o entregam como o INCRA publica, possivelmente inválido, com aviso e contagem noMetaInfo. Antes de área, interseção ou junção espacial, usegdf["geometry"] = gdf.geometry.make_valid(). - Parâmetros inválidos levantam
InvalidParameterErrorantes da rede; o corte pormax_registrosemiteUserWarning.
Novas funções: incra.andamento_quilombola() (quadro "Andamento dos processos", PDF) e incra.vinculos_quilombolas() (relação por NUP), ambas com agrobr[pdf]. Veja a página da fonte.
26. PPM: galinhas no lugar de galinhas_poedeiras¶
A categoria 32793 da tabela 3939 é "Galináceos - galinhas" e, pelas notas técnicas da PPM, inclui poedeiras e matrizeiras. Use ibge.ppm("galinhas") ou datasets.pecuaria_municipal("galinhas"). galinhas_poedeiras continua aceito como alias, com FutureWarning, e os números não mudam; a coluna especie passa a sair "galinhas" nos dois casos. Filtros por especie == "galinhas_poedeiras" precisam trocar para "galinhas".
27. CONAB: safra passada vem da revisão mais recente¶
conab.safras(produto, safra=X) sem levantamento passa a ler X da publicação mais recente que a traz. Para a safra anterior à corrente, é o último levantamento da safra seguinte, que a CONAB revisa (gergelim MT 2024/25: 401,2 mil ha no 12º levantamento de 2024/25, 695 no 12º de 2025/26). Antes vinha o último levantamento da própria safra. Duas ou mais safras atrás da edição mais recente, a revisão só existe na série histórica, e o número passa a vir dela (soja 2022/23: 159.154,3 mil t, contra 154.609,5 no 12º levantamento de 2023/24); nessas linhas, levantamento e data_publicacao ficam nulos. Safra anterior ao início da série do produto (soja: 1976/77) sai vazia, como em conab.serie_historica; antes, levantava SourceUnavailableError. datasets.estimativa_safra, datasets.producao_anual (rota CONAB) e conab.brasil_total(safra=X) seguem a mesma regra. Em safra antiga, o brasil_total lê cerca de 35 séries, uma por linha de produto, e recalcula os subtotais e o BRASIL. conab.balanco(safra=X) também passa a ler a publicação mais recente cuja aba Suprimento traz X (trigo 2024/25: 7.873,4 mil t em set/2026, contra 7.536,1 em set/2025); antes vinha a edição da própria safra. conab.balanco() sem produto passa a incluir a soja, que vem da aba própria "Suprimento - Soja" e antes ficava de fora. Para o número original, passe levantamento, que agora também existe em balanco e brasil_total: o agrobr avisa quando há publicação mais recente. Nesses casos, levantamento e data_publicacao são os da publicação usada, e MetaInfo.source_details["publicacao"] diz qual foi.
No fallback CONAB de datasets.producao_anual, a chamada sem ano passa a entregar o ano civil anterior (safra já colhida), e não mais a estimativa da safra em curso rotulada com o ano seguinte.
28. ComexStat: aliases pelo produto inteiro e códigos de cada período¶
Os aliases de comexstat.exportacao/importacao (e os produtos de datasets.exportacao/importacao) passam a somar todos os códigos NCM do produto, com os códigos vigentes em cada ano. Antes, vários apontavam para um único código, alguns já extintos, e voltavam vazios ou parciais sem aviso. A tabela completa (entra / não entra) está na API ComexStat.
| Alias | Antes | Agora |
|---|---|---|
soja, soja_grao |
12019000 (vazio até 2011) |
12019000 + 12010090 |
soja_semeadura |
12011000 (vazio até 2011) |
12011000 + 12010010 |
farelo_soja |
23040010 |
2304 (inclui 23040090, 78 % das exportações de 2025) |
milho |
10059010 |
1005 |
arroz |
10063021 |
1006 |
trigo |
10019900 (vazio até 2011) |
1001 |
algodao |
520100 |
5201 + 5203 |
cafe |
09011110 |
09011 + 09012 |
cafe_arabica, cafe_conilon |
09011110, 09011190 |
removidos: InvalidParameterError (a NCM não separa espécie) |
acucar |
17011400 (vazio até 2011) |
1701 |
etanol |
22071000 (exportação vazia ou residual desde 2012) |
2207 |
carne_bovina |
02023000 |
0201 + 0202 |
carne_frango |
02071400 (desde 2024, só o resíduo do código antigo) |
02071 |
carne_suina |
02032900 |
0203 |
ureia |
31021010 |
310210 |
kcl |
31042090 |
310420 |
dap |
31053000 (vazio até 2018) |
310530 |
npk |
3105 (incluía MAP e DAP) |
31052000 |
ssp, tsp |
vazio antes de 2017 | InvalidParameterError antes de 2017 |
defensivos, agrotoxicos |
3808 |
3808 sem os 27 códigos de uso exclusivamente domissanitário |
Para reproduzir um recorte antigo, passe o código ou prefixo NCM em produto (ex.: comexstat.exportacao("10059010") para o milho em grão, "3105" para a posição inteira dos adubos compostos). Os datasets consolidam os códigos de cada produto e não devolvem mais a coluna ncm. Em MetaInfo.source_details["query"], ncm_prefixo (texto) virou ncm_prefixos (lista), mais ncm_excluidos.
29. Acervo Fundiário: SIGEF público e privado, SNCI por UF¶
acervo_fundiario.sigef e snci (e as variantes _geo) deixam de recusar UFs por uma lista fixa: UF sem arquivo no servidor levanta SourceUnavailableError (HTTP 404). As constantes acervo_fundiario.models.SIGEF_UFS_DISPONIVEIS e SNCI_UFS_DISPONIVEIS foram removidas. O SNCI sai por UF, e a lista muda com o tempo: em 01/10/2026, AC, DF e RR estavam sem arquivo (o de RR existia em 22/09/2026). Com bbox, sigef e snci (tabela) filtram pela geometria em qualquer versão do pyogrio e do GDAL: na 1.1.0, com o pyogrio anterior ao 0.10 (GDAL 3.8), voltavam vazios, sem aviso.
O SIGEF deixa de ler o Sigef Brasil_{UF}.zip e lê os 2 arquivos em que o INCRA o publica, Sigef Público_{UF}.zip e Sigef Privado_{UF}.zip, que particionam a UF. O que muda para quem chama sigef(uf) como na 1.1.0:
- as mesmas parcelas saem com a coluna nova
natureza("publico"ou"privado"), primeiro as públicas e depois as privadas, cada parte na ordem do arquivo: quem dependia da ordem do arquivo único precisa ordenar (porcodigo_parcela, por exemplo); natureza="publico"ou"privado"baixa só aquele arquivo;MetaInfo.source_urlé a URL codificada do 1º arquivo lido (Sigef%20P%C3%BAblico_GO.zip);source_detailspassa asource_details["arquivos"]["publico"|"privado"](comurl,etag,last_modified,sha256…);attempted_sourceslista os arquivos lidos;schema_versioné1.1;- o cache passa a
acervo_fundiario/sigef_publico/esigef_privado/; a pastaacervo_fundiario/sigef/da 1.1.0 não é mais lida e pode ser apagada.
30. Crédito rural (SICOR): programa e tipo de seguro pela tabela oficial do BCB¶
bcb.credito_rural e o dataset credito_rural publicam o nome do programa e filtram por programa=/tipo_seguro=
com os nomes das tabelas de domínio do BCB (Programa.csv e TipoGarantiaEmpreendimento.csv): programa = trecho da
descrição oficial antes do primeiro " - "; tipo de seguro = descrição oficial. O filtro não diferencia maiúsculas, então
programa="Pronaf" e programa="Pronamp" continuam valendo. Mudam os valores publicados e o que cada filtro seleciona:
| Código | Antes | Agora |
|---|---|---|
programa 0001 |
Pronaf | PRONAF |
programa 0050 |
Pronamp | PRONAMP |
programa 0070 |
Funcafe | FUNCAFÉ (PROGRAMA DE DEFESA DA ECONOMIA CAFEEIRA) |
programa 0100 |
Moderfrota | PRLC-BA (PROG RECUP LAVOURA CACAUEIRA BAIANA) ENCERRADO — Moderfrota é 0154 |
programa 0110 |
Inovagro | PRODECER III — Inovagro é 0162 |
programa 0152 |
RenovAgro | PROIRRIGA — RenovAgro é 0222 |
programa 0156 |
Moderagro/Moderfrota | ABC + Programa para a Adaptação à Mudança do Clima e Baixa Emissão de Carbono |
programa 0200 |
Proirriga | PROCERA |
programa 0999 |
Sem programa específico | FINANCIAMENTO SEM VÍNCULO A PROGRAMA ESPECÍFICO |
programa 0153, 0162, 0222 e demais oficiais |
Desconhecido (código) | nome da tabela oficial (MODERAGRO, INOVAGRO, RenovAgro…) |
tipo de seguro 1 |
Proagro | Proagro tradicional |
tipo de seguro 2 |
Sem seguro | Proagro mais |
tipo de seguro 3 |
Seguro privado | Outro seguro |
tipo de seguro 9 |
Não se aplica | Sem adesão a seguro |
tipo de seguro 0 |
Desconhecido (0) | Não se aplica |
Os códigos 0002, 0102, 0104, 0106, 0108, 0112, 0114 e 0150 não existem na tabela oficial e saíram do
dicionário. Quem filtrava tipo_seguro="Sem seguro" recebia contratos com Proagro Mais: use "Sem adesão a seguro".
A tabela completa está em fontes/BCB.
31. SGS: ipa_agricola no lugar de ipa_agropecuario¶
A série 7460 do SGS é o IPA-DI por origem de produtos agrícolas (sem os pecuários), conforme o nome oficial.
O alias passa a ser ipa_agricola; ipa_agropecuario continua aceito, emite FutureWarning e devolve
nome_serie="ipa_agricola". Quem filtra nome_serie == "ipa_agropecuario" depois de consultar deve trocar
para "ipa_agricola". O código numérico 7460 não muda.
32. Embrapa Solos: 85 colunas e medidas laboratoriais como texto¶
embrapa_solos.perfis() passa a ler o WFS 2.0 em JSON e devolve 85 colunas (contrato embrapa_solos_perfis 3.0): as 19 da 1.x, na mesma ordem, seguidas dos demais atributos publicados, uf_original e feature_id. Cada linha é um horizonte ou camada (34.464 na camada); codigo_pon identifica o ponto de amostragem. mapa_solos() ganha ordem3, subordem3, gdegrupo3 e feature_id (19 colunas).
- As 9 medidas laboratoriais (
areia_total,silte,argila,ph_h2o,carbono_organico,ctc,saturacao_bases,aluminio,fosforo) deixam de serfloat: são o texto publicado, inclusiveNULL. A 1.x convertia comerrors="coerce"e transformava em nulo, sem aviso, os<1,<0.5,0,19e as marcas defosforo. Converta na aplicação, por exemplopd.to_numeric(df["argila"].replace("NULL", pd.NA)); emfosforo, trate antes os censurados e a vírgula. anosai emInt64edata_coletemdatetime64[ns];NULLvira ausente nessas 2 colunas, e ano ou data fora do formato, ou data impossível (2024-02-30), levantaParseError. Pela regra de datas,data_coletde formato válido com ano fora de 1900–2099 viraNaT, comUserWarninge aviso emmeta.validation_warnings(em 07/10/2026, 73 dos 34.464 registros da camada, como0982-11-01e1892-07-14).max_registros(padrão 50.000; 5.000 perfis e 3.000 polígonos nas funções_geo) limita o prefixo lido em ordem defid.ufeordemfiltram localmente esse prefixo, e o corte que deixa a seleção parcial emiteUserWarning;max_registros=Nonevarre a camada inteira.tamanho_paginadefine o tamanho da página.- Custo: cada página espera 2 s (o ritmo da fonte no agrobr), e
ufeordemnão reduzem as páginas, porque filtram depois da leitura.perfis()lê em páginas de 250 (a camada inteira são ~138 páginas, mais de 4 min), eperfis_geo()em páginas de 100 até 5.000 linhas (50 páginas, mais de 1,5 min). Exemplos: 310 s emperfis(uf="GO")e 113 s emperfis_geo(uf="DF"). Subatamanho_pagina(até 1.000; 100 nas_geo) ou reduzamax_registros. bboxe as funções_geousam EPSG:4326. Veja a página da fonte.
33. Crédito rural (SICOR): produto e finalidade como pedidos, safra validada¶
bcb.credito_rural e o dataset credito_rural publicam em produto a chave pedida, sem acento e em minúsculas, como
producao_anual e estimativa_safra; o filtro continua com a grafia oficial do SICOR. finalidade sai em minúsculas
também pelo fallback BigQuery, que publicava CUSTEIO. Quem filtrava pela grafia antiga deve trocar:
| Pedido | Antes | Agora |
|---|---|---|
algodao ou algodão |
algodão | algodao |
cafe ou café |
café | cafe |
cana |
cana-de-açucar | cana |
feijao ou feijão |
feijão | feijao |
mandioca |
mandioca (aipim, macaxeira) | mandioca |
item de investimento, ex.: CANA-DE-AÇUCAR |
cana-de-açucar | cana-de-acucar |
Soja, milho, arroz, trigo e sorgo não mudam. A safra aceita só AAAA, AAAA/AA e AAAA/AAAA com anos consecutivos;
"2023/25", "2024/2023", "23/24" e texto livre levantam InvalidParameterError antes da rede (antes eram lidos em
silêncio como outra safra, voltavam vazios ou estouravam ValueError no cliente).
34. FUNAI: 19 colunas e data de atualização com o dia primeiro¶
funai.terras_indigenas() passa a ler o WFS 2.0 em JSON e devolve 19 colunas (contrato funai.terras_indigenas 2.0): as 9 da 1.x, na mesma ordem, seguidas de feature_id, gid, reestudo_ti, cr, faixa_fronteira, undadm_codigo, undadm_nome, undadm_sigla, dominio_uniao e epsg.
data_atualizacaosegue emdatetime64[ns], agora lida com o dia primeiro, como a FUNAI publica (dd/mm/aaaa), e nula em parte das TIs. A 1.x convertia compd.to_datetime(errors="coerce")semdayfirste trocava dia e mês quando o dia era até 12. Data ilegível viraNaT, com aviso emmeta.validation_warnings.ufé o texto publicado: TIs em mais de um estado vêm como "AM, RR", e o filtroufcasa qualquer uma delas.max_registros(padrão 10.000; 1.000 nas_geo) etamanho_paginasão parâmetros novos.ufefasefiltram localmente o prefixo lido, e o corte que deixa a seleção parcial emiteUserWarning. Saída geo ebboxem EPSG:4326. Veja a página da fonte.- Custo: cada página espera 2 s (o ritmo da fonte no agrobr), e
ufefasenão reduzem as páginas.terras_indigenas()lê em páginas de 250, eterras_indigenas_geo()em páginas de 10 TIs, até 1.000 (até 100 páginas). Exemplo: 141 s emterras_indigenas_geo(uf="AC"). Subatamanho_pagina(até 1.000; 100 nas_geo).
35. ZARC: nove culturas das safras 2017/2018 a 2023/2024¶
As tábuas anuais de 2017/2018 a 2023/2024 publicam nove rótulos que o catálogo não reconhecia: zarc.zoneamento e o
dataset zoneamento_agricola recusavam o filtro cultura= antes da rede e, sem filtro, publicavam um nome improvisado.
Agora zarc.culturas() tem 107 culturas e o filtro aceita o rótulo oficial ou a chave:
| Rótulo oficial | Antes (sem filtro) | Agora |
|---|---|---|
| Milho | milho | milho |
| Arroz Irrigado | arroz_irrigado | arroz_irrigado |
| Feijão 1ª Safra | feijao_1a_safra | feijao_1 |
| Trigo Irrigado | trigo_irrigado | trigo_irrigado |
| Mamona Semi-árido Sequeiro | mamona_semi-arido_sequeiro | mamona_semiarido_sequeiro |
| Cevada Grãos Irrigada | cevada_graos_irrigada | cevada_graos_irrigada |
| Cevada Grãos Sequeiro | cevada_graos_sequeiro | cevada_graos_sequeiro |
| Aveia Sequeiro | aveia_sequeiro | aveia_sequeiro |
| Aveia Irrigada | aveia_irrigada | aveia_irrigada |
Quem filtrava feijao_1a_safra ou mamona_semi-arido_sequeiro depois de consultar deve trocar pelas chaves novas.
Cultura do catálogo ausente na safra pedida continua levantando InvalidParameterError, agora com as safras em que
aparece (ex.: milho de 2017/2018 a 2023/2024; milho_1 de 2024/2025 a 2026/2027). Nos 11 rótulos de cultura que o ZARC
renomeou na safra 2024/2025, o erro também aponta a chave equivalente da tábua consultada; a tabela de pares e a chave
de junção entre safras (cultura_codigo e manejo) estão na página da fonte. Na 2.0, o filtro se
chama produto (§85); a coluna de saída segue cultura.
36. IBAMA: arquivo vigente, edição no MetaInfo e bbox da _geo pelo polígono¶
ibama.embargos() e ibama.embargos_geo() passam a ler o CSV vigente do conjunto "Fiscalização - termo de embargo"
(atualização diária). A 1.x lia um ZIP que a fonte deixou de atualizar em 03/05/2026; quem guardou resultados da 1.x
tem a foto dessa data (em 23/09/2026 faltavam 2.454 termos, 525 desembargos e 237 cancelamentos).
- O download passa de ~47 MB (ZIP) a ~208 MB (CSV sem compressão; a fonte não publica ZIP).
meta.source_details["ultima_atualizacao_relatorio"]traz a edição lida (horário de Brasília).embargos_geo(bbox=...)filtra pela interseção do polígono com a caixa; antes filtrava pelo ponto de referência do termo e devolvia polígonos fora da caixa.embargos(bbox=...)continua pelo ponto, e o ponto com latitude e longitude zeradas (não informado na fonte) fica fora do filtro; na 1.1.0, a caixa que contém (0, 0) devolvia esses termos. Veja a página da fonte.
37. Censo Agropecuário: linha Total publicada¶
ibge.censo_agro() e datasets.censo_agropecuario passam a publicar a linha categoria = "Total" quando a fonte
a publica. A 1.x descartava essa linha em todos os temas. Número de estabelecimentos não soma entre categorias, então o
total oficial não se recompunha: irrigação, Brasília 2017, 2.726 estabelecimentos no Total e 3.224 somando os métodos.
- Para somar categorias, filtre
categoria != "Total"; para o total oficial, use a linhaTotal. - Contrato
censo_agropecuario1.2 e parser 3 do censo SIDRA atual. Veja o contrato.
38. B3: mês do contrato nas opções e filtro vencimento¶
b3.posicoes_abertas_historico(..., vencimento="V26") passa a trazer o futuro e as opções do mês do contrato, e o datasets.futuros_agricolas(..., tipo="oi_historico", vencimento=...), novo na 2.0,
segue a mesma regra. A 1.x comparava o código bruto e devolvia só o futuro: quem soma
posicoes_abertas por vencimento passa a somar também as opções.
- Para manter o comportamento da 1.x, passe
tipo="futuro"emb3.posicoes_abertas_historico; no dataset, filtre a colunatipodo resultado (df[df["tipo"] == "futuro"]). O código publicado de uma opção (MYOA, ex.:VVJK) casa só aquela série. vencimento_mesevencimento_anodas opções deixam de ser nulos. São o mês e o ano do contrato, não os da expiração, que pode cair no mês anterior: opções de café arábica e conillon e de soja cross e FOB (ex.:ICFH27C035000expira em 12/02/2027). Contratob3.posicoes_abertas1.1, com os dois campos não nulos.- Ticker ou
XprtnCdfora do padrão levantaParseError(na 1.x o valor ficava nulo). Filtrovencimentoem outro formato levantaInvalidParameterErrorantes da rede. Veja a página da fonte.
39. ABIOVE: edição mais recente e edicao¶
abiove.exportacao(ano, mes=...) e o fallback ABIOVE de datasets.exportacao passam a ler a edição mais recente da
planilha que publica ano. Na 1.x, ano e mes escolhiam o arquivo (exp_{ano}{mes}.xlsx, ou a última edição do
próprio ano): o número de um ano passado ficava preso à edição de dezembro, sem as revisões da ABIOVE (em setembro/2026,
19 das 96 células de 2025; farelo, dez/2025: 2.020.365,023 t em exp_202512.xlsx e 1.990.304,323 t na edição corrente), e um mês sem
edição própria (ex.: ano=2026, mes=1) levantava SourceUnavailableError.
messó filtra o mês dos dados. Fora de 1-12 levantaInvalidParameterErrorantes da rede; mês ainda não publicado devolve DataFrame vazio.- Para o número original, passe
edicao="AAAA-MM"(ex.:edicao="2025-12"); valem as edições deanoe deano + 1. MetaInfo.source_details["edicao"]traz o arquivo e o mês da edição lida, eraw_content_hash, o SHA-256 da planilha. Veja a API.datasets.exportacaonão aceitames. Na 1.1.0, o argumento chegava ao fallback ABIOVE; na 2.0, levantaTypeError(seção 78). Para um mês, useabiove.exportacao(ano, mes=...)ou filtre a colunamesdo resultado.abiove.exportacao(ano, produto="total")levantaInvalidParameterError: para o total dos produtos, useagregacao="mensal"(com ou semproduto="total"). Na soma mensal comproduto="grao"(ou outro), a colunaprodutotraz o produto filtrado; na 1.1.0, trazia"total".- A leitura da planilha também mudou, e
exportacao(2024)passa de 72 para 48 linhas. Na 1.1.0,volume_tonvinha em mil toneladas, como a planilha publica, ereceita_usd_milvinha do preço médio (US$/t), e não do valor FOB; os dois eram do ano anterior aano, e o volume do óleo vinha de outra tabela. Na 2.0,volume_toné o peso em toneladas ereceita_usd_milo valor FOB em US$ mil, doanopedido. Farelo, jan/2024: 1.398,86 e 535,0 na 1.1.0 (peso e preço de jan/2023); 1.841.694,766 t e US$ 932.466,466 mil na 2.0. - Saem as linhas
totale um segundomilhode cada mês: vinham das tabelas de participação do complexo soja nas exportações do Brasil, só em US$. Ficamgrao,farelo,oleoemilho; para o total, useagregacao="mensal". Não junte séries da ABIOVE gravadas com a 1.1.0 a consultas da 2.0.
40. Comtrade: aliases com o mesmo significado da ComexStat¶
Os aliases de comtrade.comercio, comtrade.trade_mirror e datasets.comercio_internacional passam a somar só os códigos
HS do produto, com o mesmo significado da ComexStat (seção 28). A tabela completa (entra / não entra) está na
API Comtrade.
| Alias | Antes | Agora |
|---|---|---|
suco_laranja |
2009 (sucos de todas as frutas: +US$ 357 mi, +11,4 %, em 2025) |
200911, 200912, 200919 |
carne_frango |
0207 (aves em geral: +US$ 212 mi, +2,5 %, em 2025) |
020711 a 020714; antes de 1996, InvalidParameterError, e em 1996 no Brasil, que reportou na HS 1992 (H0) |
cafe |
0901 (com cascas e sucedâneos) |
090111, 090112, 090121, 090122 |
algodao |
5201 |
5201 + 5203 |
soja |
1201 (com a semente) |
120190 (desde 2012) + 120100 (até 2011) |
complexo_soja |
1201 + 1507 + 2304 |
soja + 1507 + 2304 |
Para reproduzir um recorte antigo, passe o código HS em produto (ex.: comtrade.comercio("2009")). comtrade.produtos()
devolve o mapa novo. celulose (4703) e tabaco (2401) não mudam; a doc passa a dizer o que fica de fora.
41. PSR: seguradora na chave das apólices e registro publicado em dobro¶
mapa_psr.apolices e datasets.seguro_rural(tipo="apolices") passam a usar o contrato mapa_psr_apolices 2.1, com
seguradora na chave primária (não nula). Na 1.1.0, o dataset levantava ContractViolationError em 2007, 2008, 2009, 2011 e
2012, porque o MAPA publica o mesmo número de apólice em duas seguradoras; agora esses anos saem inteiros. Quem junta apólices
pela chave antiga precisa incluir a seguradora.
O registro publicado duas vezes e igual em todas as colunas (1 caso, em 2009) sai uma vez só, com aviso e a contagem em
source_details["duplicatas_colapsadas"]. A fonte passa a levantar ContractViolationError, como o dataset, se a chave repetir
com valores diferentes.
Colunas novas no fim, nas apólices e nos sinistros: cod_municipio (Int64) e inicio_vigencia, fim_vigencia e data_apolice (datetime64[ns]). A vigência de 2006 a 2015 sai nula, com aviso: nesses anos o MAPA publica início igual ao fim, ou seja, não publica a vigência. Quem seleciona colunas por posição ou compara o conjunto de colunas inteiro precisa contar com as quatro.
42. PSR: geocódigo publicado como "-" sai nulo¶
Em mapa_psr.apolices, mapa_psr.sinistros e datasets.seguro_rural, cd_ibge sai nulo quando o MAPA publica "-" no
lugar do geocódigo (1.516 apólices entre 2006 e 2025) ou deixa a célula vazia. Na 1.1.0, esses casos saíam como os textos "-"
e "". Filtros e junções por cd_ibge precisam tratar o nulo.
Para o município inteiro, passe o código ou o nome em municipio: o filtro compara o código, e entram as apólices rotuladas
com o nome do distrito (§86). Em mapa_psr.apolices e
mapa_psr.sinistros, as_polars e return_meta são só por nome (§88).
43. CONAB: cereais de inverno nas edições de out/2019 a jan/2022¶
Nessas edições, as abas de trigo, aveia, canola, centeio, cevada e triticale levam o ano no nome ("Trigo 2021"). Na 1.1.0, conab.safras (e datasets.estimativa_safra com fonte="conab") procurava a aba sem o ano e levantava erro para os seis cereais. Agora a aba é escolhida pelo cabeçalho: vale a mais recente que publica a safra pedida. Quando a edição ainda não publica o inverno da própria safra (levantamentos 1 a 4 de 2019/20, 3 e 4 de 2020/21 e 2 a 4 de 2021/22), a consulta sai vazia, como nos levantamentos de outros anos que não publicam o ano, e não mais com erro.
Muda calado: a safra dos cereais de inverno e do café. Trigo, aveia, canola, centeio, cevada e triticale saem nos levantamentos com o ano civil da colheita ("Safra 2025"). Na 1.1.0, conab.safras e datasets.estimativa_safra (fonte CONAB) rotulavam esse ano como a safra que começa nele (2025/26); na 2.0, como a safra que termina nele (2024/25). A mesma safra traz outra colheita: na planilha do 12º levantamento de 2024/25, o trigo do RS rotulado 2024/25 é 3.913,9 mil t (colheita 2024) na 1.1.0 e 3.665,6 mil t (colheita 2025) na 2.0. Na série histórica (conab.serie_historica e datasets.serie_historica_safra), esses 6 cereais e o café (cafe, cafe_arabica, cafe_conilon) saem com o ano publicado: safra é "2025", e não mais "2025/26". Para converter o que foi gravado com a 1.x: no levantamento, recue um ano (2025/26 → 2024/25); na série histórica, fique com o primeiro ano (2025/26 → 2025).
44. Progresso CONAB: a linha "N estados" deixa de sair como BR¶
Em conab.progresso_safra e datasets.progresso_safra (contrato 2.0), a última linha de cada bloco da planilha, "7 estados",
"12 estados" etc., sai com uf = "MEDIA_ESTADOS" (a coluna estado passa a uf; §87). Na 1.1.0 ela saía como BR, mas é a média da própria CONAB dos
estados monitorados (de 88% a 99,9% da área, conforme a cultura), não o Brasil, e não se reproduz com as áreas do
levantamento. As colunas novas n_estados e cobertura_area_pct trazem o número de estados e a cobertura lidos da nota
"(Esses N estados correspondem a X% da área cultivada)", sem recálculo (0,98 = 98%), e são nulas nas linhas de UF.
O filtro uf="BR" levanta InvalidParameterError com a cobertura publicada quando a planilha não traz a linha "Brasil"
(nenhum boletim conferido traz). Troque por uf="MEDIA_ESTADOS" e leve em conta a cobertura. O parser_version do
progresso passa de 1 para 3.
Na 1.1.0, o bloco do trigo, cujo cabeçalho traz o ano civil ("Trigo - Safra 2026"), não era reconhecido, e as linhas dele
herdavam a cultura e a safra do bloco anterior. No boletim de 28/09 a 04/10/2026, a colheita do trigo em 8 estados saía como
cultura = "Soja", safra = "2026/27", operacao = "Colheita", e o próprio cabeçalho virava uma linha de soja com
estado = "Trigo - Safra 2026" e percentuais nulos. A 2.0 lê o cabeçalho: essas linhas saem como cultura = "Trigo",
safra = "2026", e a linha do cabeçalho some. Um filtro de colheita de soja antes de a soja ser colhida passa a voltar
vazio; para o trigo, use produto="Trigo".
45. CEPEA: trigo nas duas praças e variação do dia no meta¶
cepea.indicador("trigo") sem praca traz o Paraná e o Rio Grande do Sul. Na 1.1.0, a coleta no CEPEA trazia só o Paraná
(o fallback do Notícias Agrícolas já trazia as duas). cepea.ultimo("trigo") sem praca devolve a data mais recente entre as
duas praças e, no empate, o Paraná, porque a ordem é pela praça. Para a série da 1.1.0, passe praca="parana". O
datasets.preco_diario("trigo") segue no Paraná e, numa data sem o Paraná, usa o Rio Grande do Sul, rotulado na coluna
praca, pelo desempate dos produtos regionais.
No Indicador do CEPEA, meta["variacao"] passa a ser a variação do dia ("Var./Dia"). Na 1.1.0, o parser guardava ali a
última coluna de variação da tabela, que nas páginas diárias é a do mês. A do mês vai em meta["variacao_mes"] e a da semana
em meta["variacao_semana"]. No etanol, cujas páginas são semanais, a variação da semana deixa variacao e sai só em
variacao_semana. Como na 1.1.0, as variações vêm só no Indicador recém-coletado da fonte: a leitura do cache, morna ou
offline, não as traz.
46. Custos CONAB: itens pelo subtotal publicado e categoria pela seção¶
Na 1.1.0, o custo_producao somava ao custeio o grupo valorado junto dos subitens, lia como item o cabeçalho de seção com
zeros e o bloco "Gestão da propriedade familiar" depois do H, e classificava a categoria pelo rótulo exato, que muda com o
ano. Na 2.0.0 (parser 5, contrato 3.0 mantido):
- os itens de cada seção fecham com o subtotal publicado sempre que a planilha fecha. Vale a leitura que fecha (grupo,
subitens ou os dois; agregado de gestão ou os componentes dele), e a linha que sai fica em
meta.source_details["parser"]["notes"]com o valor publicado; - o cabeçalho romano com zeros abre a seção, e a linha depois do subtotal ou do total da seção vira a nota
memo_after_total; - subtotal ou total de fórmula que não fecha na própria planilha gera aviso (
UserWarningemeta.validation_warnings) com os números publicados; nenhuma linha é recalculada; categoriasai da seção publicada (IV e V:custos_fixos; II, III e VI:outros) e, no custeio, do rótulo normalizado. Mão de obra, agrotóxicos, mudas e máquinas próprias deixam de cair emoutrosconforme a grafia do ano.
Quem somava valor_ha dos itens de uma seção passa a obter o subtotal publicado. Quem filtrava categoria == "outros"
para achar mão de obra ou agrotóxicos passa a usar mao_de_obra e insumos. Detalhes e as 116 abas recusadas no
contrato.
47. IMEA: registro publicado em duplicata sai uma vez só¶
imea.cotacoes passa a colapsar o registro que o IMEA publica mais de uma vez, igual em todas as colunas: ele sai uma vez só,
com aviso e a contagem em source_details["duplicatas_colapsadas"] (linhas e indicadores). Na 1.1.0, as cópias saíam
todas: em 25/09/2026, 69 linhas a mais na soja (R$/sc). A chave (indicador, localidade, data, safra e unidade) repetida com
valores diferentes segue saindo inteira, agora com aviso e a contagem em source_details["chaves_repetidas"]. As duas chaves
entram no source_details de toda consulta. imea.cotacoes ganha as colunas indicador_id e indicador e muda a ordem
(cadeia primeiro, data_publicacao no fim): leia as colunas pelo nome.
48. MetaInfo: hash, tamanho e localizador do corpo que deu o dado¶
O MetaInfo das fontes passa a identificar o corpo adquirido, pela regra dos
contratos:
raw_content_hasheraw_content_sizedeixam de sair nulo e zero quando a resposta vem de um corpo só: ABIOVE, ANDA, INMET, Acervo Fundiário, ANA, ANTT (praças), B3, CFTC, CONAB, DERAL, IBAMA, IBGE, ICMBio (ucs_geo), IMEA, PSR, Queimadas, SICAR, UNICA e Rio Verde.- No CEPEA,
raw_content_hashdeixa o formatosha256:seguido de 16 dígitos hexadecimais, um prefixo de 64 bits, e passa ao SHA-256 completo, com 64 dígitos e sem prefixo. Quem comparava com o formato antigo precisa mudar. Ofetch_timestamppassa a vir preenchido na coleta. - Na ANEC,
raw_content_hashdeixa de ser o fingerprint da estrutura do PDF (MD5 com 16 dígitos hexadecimais) e passa ao SHA-256 completo do PDF, com o tamanho emraw_content_size. O fingerprint vai parasource_details["layout_fingerprint"]. Quem comparava com o formato antigo precisa mudar. source_urlpassa a ser o recurso que deu o dado:- no CFTC, a consulta com os filtros; antes, o endpoint sem filtros;
- na B3, o download do CSV com o token como
[REDACTED]. Antes, era o gerador de ticket, que agora fica emsource_details["ticket_url"]; - no IBGE, a consulta à SIDRA quando há uma só. Antes, era a página da SIDRA, que agora fica em
source_details["pagina"]. Ofetch_timestampdo IBGE passa a vir preenchido.
49. USDA PSD: gateway novo e rótulos pelos catálogos oficiais¶
Na 1.1.0, usda.psd e o oferta_demanda_global consultavam a OpenData antiga da FAS, que responde 500, e rotulavam
errado 6 dos 9 atributos, o farelo de soja e a UE. Na 2.0.0 (parser 2; contrato oferta_demanda_global 2.0, seção 87):
- o host é o gateway
https://api.fas.usda.gov/api/psd, com a chave no cabeçalhoX-Api-Key(a mesmaAGROBR_USDA_API_KEYdo api.data.gov); attribute,unit,countrye o nome da commodity fora do cadastro vêm dos catálogos oficiais guardados no pacote, eattribute_brusa os IDs certos:
| Rótulo | ID na 1.1.0 | ID na 2.0.0 |
|---|---|---|
producao |
125 (Domestic Consumption) | 28 (Production) |
estoque_inicial |
28 (Production) | 20 (Beginning Stocks) |
consumo_domestico |
57 (Imports) | 125; 126 no açúcar; 142 no algodão |
importacao |
130 (Feed Dom. Consumption) | 57 (Imports) |
estoque_final |
84 (TY Imp. from U.S.) | 176 (Ending Stocks) |
oferta_total |
176 (Ending Stocks) | 86 (Total Supply) |
Entram também distribuicao_total (178) e, no algodão, perdas (150);
- farelo_soja passa de 4233000 (Oil, Cottonseed) a 0813100 (Meal, Soybean), e ue/eu de E2 (EU-15) a E4
(European Union);
- colunas novas: attribute_id, unit_id, last_update_year e last_update_month. As duas últimas são a última
atualização da série, não a edição consultada, e last_update_month sai nulo quando o PSD publica 00;
- commodity, país ou atributo fora dos catálogos levanta InvalidParameterError antes da rede. Antes, código de 7
dígitos ou país de até 3 letras ia direto ao servidor, que responde [] sem erro;
- pivot=True nomeia cada coluna pelo attribute_br ou, sem ele, pelo nome oficial. Rótulo repetido na mesma série
levanta ParseError, e falha no pivot deixa de devolver o formato longo em silêncio;
- em consulta por código direto fora do cadastro, commodity passa do próprio código ao nome oficial do catálogo (ex.:
0430000 → Barley); código fora do catálogo continua voltando igual em models.commodity_name;
- nomes públicos de agrobr.usda: models.PSD_COLUMNS_MAP sai, porque mapeava o PascalCase da OpenData antiga, que o
gateway não usa; client.fetch_psd_country, fetch_psd_world e fetch_psd_all_countries passam a devolver
RespostaPSD(url, corpo, dados, status) em vez da lista de registros, que agora está em .dados.
Quem filtrava por attribute_br recebe agora o atributo certo. Quem usava os IDs do PSD_ATTRIBUTES ou o código
4233000 como farelo precisa trocar pelos da tabela. Detalhes na fonte e no
contrato. No datasets.oferta_demanda_global (contrato 2.0), os filtros e as
colunas saem em português; a fonte usda.psd mantém os nomes em inglês
(§85, §87).
50. Limpeza de código morto¶
A limpeza tira código sem efeito e não muda dado. Mudam erros de entrada inválida, e saem nomes públicos sem uso na produção:
utils.validate_bbox, usado por SFB, Acervo Fundiário, ANA, IBAMA, ICMBio e MapBiomas Alerta, levantaInvalidParameterErrorem vez deValueError. Como é subclasse deValueError, quem capturaValueErrorcontinua pegando, e quem capturaAgrobrErrorpassa a pegar. No IBAMA, área publicada com ponto levantaParseError, em vez de "12.5" virar 125.- Saem nomes públicos sem uso na produção:
utils.concat_csv_pages(sem substituto);alt.sicar.parser.parse_imoveis_csv(usealt.sicar.imoveis);anec.models.normalize_produto(useresolve_produto, que recusa produto desconhecido); obcb.parser.parse_credito_ruraldeixa de resolverfonte_recurso,modalidadeeatividade, que a chamada padrão da 1.1.0 publicava e as agregaçõesufeprogramada 2.0 não publicam (os códigoscd_*seguem). Os 3 nomes voltam noagregacao="registro"(seção 4), eresolve_fonte_recurso,resolve_modalidade,resolve_atividade,SICOR_FONTES_RECURSO,SICOR_MODALIDADESeSICOR_ATIVIDADESficam embcb.models, com os nomes das tabelas oficiais eNonepara código fora da tabela (a 1.1.0 devolviaDesconhecido (<código>));defensivos.parser.parse_formulados_csveparse_tecnicos_csv(useparse_*_bundle, que devolve as tabelas e os detalhes) edefensivos.models.FORMULADOS_COLS_DROP/TECNICOS_COLS_DROP;lista_suja.models.DOWNLOAD_URL(useconstants.URLS[Fonte.LISTA_SUJA]["download"]),RENAME_MAPePDF_HEADER_ROW_MARKER;rnc.client.fetch_registradas/fetch_protegidas(usefetch_*_bundle, com.contente.resource.url) ernc.parser.parse_registradas_csv/parse_protegidas_csv(useparse_*_bundle(...).frame);alt.mapa_psr.client.download_csvefetch_periodo(useopen_periodo). Na chamada direta abcb.bigquery_client.fetch_credito_rural_bigquery, safra inválida levantaValueErrorem vez de sumir do filtro. - Também saem nomes públicos sem uso na produção:
ibge.ftp_client.extract_xls_from_zip(sem substituto); emdesmatamento.parser, o parser v1 CSV/GeoJSON (parse_prodes_csv,parse_deter_csv,parse_deter_geojsoneparse_prodes_geojson; usedesmatamento.prodes,deter,prodes_geoedeter_geo), e as 12 constantes de colunas do v1 emdesmatamento.models(PRODES_COLUNAS_WFS*,DETER_COLUNAS_WFS*,COLUNAS_SAIDA_PRODES*,COLUNAS_SAIDA_DETER*,PRODES_GEOM_COLUMNeMAX_FEATURES_GEO);b3.models.parse_numero_br(usenormalize.numeric.safe_float);anda.models.ANDA_UFS(sem substituto);deral.models.DERAL_PRODUTOSenormalize_condicao(as culturas publicadas ficam emDERAL_PRODUTOS_PUBLICADOS).normalize.encoding.ENCODING_CHAINperdeutf-16eascii, que nunca rodavam depois doiso-8859-1.anda.entregasedatasets.fertilizanteperdem o parâmetrouf: os PDFs publicados só trazem o total nacional (uf="BR"), e passaruflevantaTypeError. Na ABIOVE,produtofora da lista levantaInvalidParameterError(subclasse deValueError) antes da rede, eagregacaofora de"detalhado"e"mensal"levantaInvalidParameterErrorem vez de virar"detalhado". Layouts sem publicação deixam de ser lidos: tabela por UF na ANDA, aba por cultura no DERAL e, na ABIOVE, produtos em colunas, tabela com cabeçalho nomeado e produto pelo nome da aba (a planilha levantaParseError).
51. ANEC: boletins com 4 produtos e coluna sem nome¶
As edições até a W2/2026 publicam 4 produtos por período (soja, farelo, milho e trigo); DDGS e sorgo entram na W3/2026.
Na 1.1.0, a W1 e a W2/2026 saíam erradas: soja, farelo e milho das duas semanas vinham como last_week, o quadro mensal
era lido por posição (em janeiro de 2025, trigo com 6 t e sorgo com o total, 6.614.352 t) e, na W1, o trigo da semana
corrente (144.290 t) e o farelo de São Francisco do Sul (65.000 t) sumiam. Na 2.0, as duas edições saem lidas pelo nome e
fecham com a linha TOTAL do boletim.
Coluna sem nome de produto passa a ParseError. Na W14/2026, a primeira coluna da semana corrente tem dados e nenhum
rótulo: a 1.1.0 descartava esses valores, e a 2.0 recusa a edição, porque o agrobr não adivinha o produto.
A soma dos portos de cada coluna semanal é conferida com a linha TOTAL publicada. Divergência acima do arredondamento sai
em UserWarning e em meta.validation_warnings, sem mudar os valores. Veja a fonte.
52. Datas das fontes: a mesma regra no pandas 2 e no 3¶
Na 1.1.0, IBAMA, Acervo Fundiário, CFTC, INMET, MapBiomas Alerta e Queimadas convertiam datas com
pd.to_datetime(errors="coerce"), e o resultado dependia da versão do pandas: a data fora do intervalo do datetime64[ns]
(antes de 1677 ou depois de 2262) virava NaT no pandas 2 e saía como publicada no pandas 3. No CSV vigente do IBAMA, os
embargos datados de 1667 e 2925 mudam de valor com o ambiente.
Na 2.0, as 6 fontes seguem uma regra só, nas 2 versões:
- valor ilegível ou com ano fora de 1900–2099 vira
NaT, inclusive as datas de 1677 a 1899 e de 2100 a 2262, que a 1.1.0 publicava nas 2 versões; - no IBAMA, também vira
NaTa data de embargo ou de desembargo de dia posterior à edição do próprio arquivo (ULTIMA_ATUALIZACAO_RELATORIO): na edição de 23/09/2026, os termos datados de 2063, 2080 e 2090. A edição é a maior data válida da coluna; sem nenhuma, a consulta avisa e não aplica esta regra; - a consulta que descarta valores emite
UserWarninge põe a mesma mensagem emmeta.validation_warnings, com a fonte, a coluna e a quantidade.
Toda coluna de data das saídas públicas, de fontes e datasets, sai em datetime64[ns] (Datetime("ns") no polars). Com
o pandas 3, a 1.1.0 devolvia s, ms, us ou ns conforme a fonte e a entrada, e juntar 2 datasets pela data no polars
falhava por unidade.
O INMET descarta a observação sem data e o CFTC recusa a resposta com ParseError, como já faziam com data ilegível. O
texto publicado de uma data descartada continua no corpo bruto da fonte. Veja Normalização.
53. MetaInfo: fetch_timestamp é a hora da aquisição, também no dataset¶
Na 1.1.0, o fetch_timestamp de todo dataset era a hora em que ele montava o MetaInfo, e não a da aquisição do dado. No
acerto de cache, o dataset declarava uma aquisição que não houve: o datasets.preco_diario lido do DuckDB do CEPEA e o
datasets.clima pelo ZIP do INMET saíam com a hora da chamada.
Na 2.0, o fetch_timestamp é o horário UTC da aquisição do corpo que o topo do MetaInfo descreve, e o dataset repassa o
da fonte (regra nos contratos):
- corpo recebido agora: a hora dessa aquisição;
- corpo lido do cache (INMET, Acervo Fundiário, ANEC, ZARC e Agrofit): a hora da aquisição original, igual ao
fetched_at; antes, essas fontes publicavam a hora da chamada; - vários corpos (BCB Focus, PTAX e SGS, Comtrade, PRODES/DETER, Embrapa Solos, FUNAI e INCRA): a aquisição mais recente,
igual ao
fetched_at; antes, a hora da montagem; - registros do cache DuckDB do CEPEA: a coleta original (o
parsed_atmais recente das linhas devolvidas), igual aofetched_at, na fonte e nodatasets.preco_diario.
Quem media o frescor pelo fetch_timestamp do dataset passa a ler a aquisição. A hora da montagem continua em timestamp.
O datasets.preco_diario não tem mais a fonte cache (datasets.info("preco_diario")["sources"] passa de ["cepea", "cache"] a ["cepea"]): quando a coleta falha, o cepea.indicador lê o cache
DuckDB e devolve fetched_at e fetch_timestamp com a coleta original dos registros; antes, a fonte cache do dataset
publicava a hora da chamada.
54. B3: proveniência de ajustes, historico e posicoes_abertas_historico¶
Na 1.1.0, b3.ajustes saía com raw_content_hash nulo e raw_content_size zero, e b3.historico, sem os corpos de cada
dia. Na 2.0:
b3.ajustesedatasets.futuros_agricolas(tipo="ajustes"): SHA-256, tamanho e hora da aquisição doPRyymmdd.ziprecebido, no topo. A B3 remonta o ZIP externo a cada pedido, então o hash do topo muda entre 2 downloads do mesmo pregão. A identidade estável fica emsource_details["zip_interno"]esource_details["xml"](nome, SHA-256 e bytes);b3.historico:source_details["corpos"]traz cada dia recebido. Com um dia só, o topo é o desse corpo; com vários, o topo fica nulo e zero, efetched_at/fetch_timestampsão a aquisição mais recente, pela regra da seção 53.b3.posicoes_abertas_historico:source_details["corpos"]traz cada dia com arquivo, com a URL do download (token como[REDACTED]) e oticket_url, pela mesma regra dohistorico. Dia sem arquivo não entra.- Dia sem pregão (feriado, fim de semana ou pregão ainda não publicado):
b3.ajustesdevolve o vazio do contrato, sem aviso, com o SHA-256 e o tamanho do ZIP vazio que a B3 responde; nohistorico, o dia entra emcoverage["empty_dates"]e não no aviso de histórico incompleto. Na 1.1.0, levantavaSourceUnavailableError. b3.ajustes(data=...)devolve só as linhas do pregão pedido, eb3.historico, uma linha por pregão e vencimento. Na 1.1.0, vinham também linhas datadas do pregão seguinte (13/02/2025, boi: 15 → 11 linhas).
Quem comparava o hash de 2 downloads do mesmo pregão deve comparar o do XML.
55. as_polars: o tipo de cada coluna vem do contrato¶
Na 1.1.0, os datasets não declaravam as_polars: o argumento caía no **kwargs e era descartado, e nenhum dataset
devolvia polars. Na 2.0, as_polars=True devolve um DataFrame do polars. Quem passava o argumento a um dataset e usava
o resultado como pandas precisa tirar o argumento ou converter com df.to_pandas().
Na 2.0, todos os datasets tipam pelo contrato: int → Int64, float → Float64,
str → String e bool → Boolean, mesmo com a coluna toda nula; a coluna de data toda nula sai Datetime("ns"). A coluna
fora do contrato segue o tipo do dado. Por isso o extra exige polars>=0.20.3, a primeira versão com o tipo String.
56. Embrapa Solos: texto com dupla codificação reparado¶
Na 1.1.0, os perfis saíam com o texto como a Embrapa publica, parte dele com dupla codificação (UTF-8 lido como Latin-1): "BrasÃlia", "São Carlos", "Aptidão". Filtro e junção por nome de município saíam vazios.
Na 2.0, o texto que volta inteiro por Latin-1 → UTF-8 e tem a assinatura ("Ã" ou "Â" seguido de um caractere entre U+0080 e
U+00BF) sai reparado ("Brasília", "São Carlos"), com a contagem por coluna em MetaInfo.validation_warnings. Texto legítimo
com "Ã" fica como está. Quem já tratava a dupla codificação por conta própria deve tirar esse passo, para não aplicá-lo 2
vezes. O texto com a assinatura que a fonte publica sem volta (cortado no meio de uma sequência UTF-8, com "�" ou "€") fica como publicado e ganha contagem própria no mesmo aviso. O parser_version da Embrapa passa a 3.
57. MetaInfo: source_url, manifestos e cache¶
bcb.focus: osource_urldeixa de ser a última página da consulta (vazia, com$skip) e passa a ser a consulta, sem$tope$skip. As páginas seguem emsource_details["resources"].antt_pedagio.fluxo_pedagio:raw_content_sizedeixa de somar todos os bytes recebidos e passa ao tamanho do manifesto, o mesmo objeto doraw_content_hash. O total recebido, com tentativas e falhas, vai emsource_details["received_bytes"], e o dos CSVs que entraram no dado, emsource_details["data_file_bytes"].bcb.sgsebcb.ptax/bcb.ptax_moedas: osource_urlpassa a ser a consulta, e não o último recurso. No SGS, o intervalo inteiro pedido (antes, o último bloco de datas); na PTAX, a consulta sem$tope$skip.conab.custo_producaoecusto_producao_total:raw_content_sizepassa ao tamanho do manifesto, como na ANTT. O total recebido vai emsource_details["received_bytes"], e o da planilha, emsource_details["data_file_bytes"].bcb.credito_rural,bcb.credito_rural_totaledatasets.credito_rural: osource_urldeixa de ser a entidade OData e passa a ser a consulta, com$filtere$selecte sem$top; oraw_content_hashe oraw_content_sizepassam a ser os do manifesto{query, resources}, com cada página emsource_details["resources"].ibge.*(PAM, LSPA, PPM, abate, censos, PEVS, leite e PIB agro): ocache_expires_atpassa a nulo. Na 1.1.0, todas essas, menos os censos legado e de 1985, carimbavam um vencimento sem cache nenhum; cada chamada consulta o IBGE.conab.safras: ocache_expires_atpassa a nulo. Na 1.1.0, carimbava 24 h sem cache nenhum; cada chamada baixa a publicação da CONAB.
58. Comtrade: marcas de estimativa da ONU¶
comtrade.comercio (contrato comercio_bilateral 2.1) e datasets.comercio_internacional (contrato 3.0) ganham peso_liquido_estimado, peso_bruto_estimado
e quantidade_estimada, flags anuláveis da ONU. True diz que a medida publicada é estimada pela ONU, e não declarada pelo
país. Com peso líquido estimado no resultado, meta.validation_warnings traz o HS e o período, e peso_liquido_kg,
volume_ton e o ratio_peso do trade_mirror usam o valor estimado. O trade_mirror lista essas células por perna em
source_details["peso_estimado"]. Quem compara com a ComexStat pode filtrar ou marcar essas linhas.
59. CONAB: safras e balanco recusam produto desconhecido antes da rede¶
conab.safras com um produto fora de CONAB_PRODUTOS levantava ParseError ("Produto não suportado") depois de 4
requisições. Na 2.0, levanta InvalidParameterError antes da rede, com a lista dos válidos. Quem capturava ParseError para
esse caso passa a capturar InvalidParameterError.
conab.balanco com um produto fora dos 6 da aba Suprimento (soja, milho, arroz, feijao, trigo e algodao, com ou
sem acento) baixava a planilha e devolvia um quadro vazio. Na 2.0, também levanta InvalidParameterError antes da rede.
60. exportacao e importacao: as colunas do contrato, pelas 2 fontes¶
Na 1.1.0, a exportacao saía com colunas diferentes conforme a fonte: pela ComexStat, com o volume_ton, fora do contrato;
pelo fallback ABIOVE, também com o receita_usd_mil e em outra ordem. No pandas o concat passava; no polars, só com
how="diagonal".
Na 2.0, a exportacao (contrato 1.1) e a importacao (1.2) saem com as colunas do contrato, na ordem dele. O volume_ton
(t = kg_liquido / 1000) passa a ser coluna opcional do contrato, e o receita_usd_mil sai do dataset (é o valor_fob_usd em
mil e segue em agrobr.abiove).
61. ANDA: agregacao desconhecida recusada antes da rede¶
anda.entregas com agregacao fora de "detalhado" e "mensal" (por exemplo, "semanal") baixava o PDF e devolvia o
detalhado em silêncio. Na 2.0, levanta InvalidParameterError (subclasse de ValueError) antes da rede, como a ABIOVE
(seção 50). O dataset fertilizante não tem o parâmetro e não muda.
62. Queimadas: FRP negativo e foco repetido não derrubam mais o mês¶
datasets.queimadas recusava o mês inteiro com ContractViolationError quando o INPE publicava um foco com FRP negativo ou o
mesmo foco 2 vezes (7 dos 20 meses lidos de 2023 a 2026, entre eles ago/2024, o exemplo da doc). Na 2.0, queimadas.focos e o
dataset entregam o mês: a cópia igual sai uma vez; a chave repetida que difere só no FRP sai em 1 linha, com o frp nulo; a que
difere em outra coluna sai do resultado; e o FRP negativo sai nulo. Cada caso vem com aviso e a contagem em
meta.validation_warnings e source_details. Quem lia pela fonte o FRP negativo ou as 2 linhas do foco repetido passa a
recebê-los assim. Veja o contrato.
63. MapBiomas: classe fora da legenda sai nula, com aviso¶
Na 1.1.0, mapbiomas.cobertura, mapbiomas.transicao e o uso_do_solo estadual devolviam Classe {id} quando a
planilha trazia um código fora da legenda conhecida. Na 2.0, o rótulo (classe, classe_de ou classe_para) sai nulo,
o classe_id publicado fica, e a consulta emite UserWarning e põe a mesma mensagem em meta.validation_warnings,
com os códigos. O recorte municipal segue a mesma regra. Por isso os contratos mapbiomas_cobertura e
mapbiomas_transicao passam a 2.0 (MAPBIOMAS_COBERTURA_V2 e MAPBIOMAS_TRANSICAO_V2): coluna obrigatória que vira
anulável é mudança major. Quem filtrava classe.str.startswith("Classe ") passa a filtrar classe.isna(). O código 0 entra na legenda: sai
"Não observado", e não mais "Classe 0", e o filtro isna() não o pega.
Coleção 11 por padrão. Sem colecao, mapbiomas.cobertura, mapbiomas.transicao e datasets.uso_do_solo leem a
coleção 11 (1985–2025), e não mais a 10: a mesma chamada devolve outros números, e entram classes novas, como
"Savana Alagada (beta)". Para o recorte da 1.1.0, passe colecao=10.
64. CEPEA: sem rede e sem cache, erro em vez de tabela vazia¶
Na 1.1.0, cepea.indicador sem rede e sem nada no cache para o período devolvia a tabela vazia, sem erro nem aviso, e
o MetaInfo dizia from_cache=True; cepea.ultimo levantava ParseError (erro de layout). Na 2.0, os 2 levantam
SourceUnavailableError, com attempted_sources (as fontes tentadas e o cache). Erro de layout da página continua
ParseError. Com cache, a resposta sai dele com StaleDataWarning, como antes. Com offline=True e o cache vazio,
indicador segue devolvendo a tabela vazia, agora com from_cache=False e cache_expires_at nulo. Quem tratava a
tabela vazia como falta de rede passa a capturar SourceUnavailableError. cepea.ultimo(produto, offline=True) sem dado no cache levanta o mesmo SourceUnavailableError, com o motivo "offline sem dado no cache" (antes, ParseError).
65. IBGE: uf com nível sem filtro é recusada¶
Na 1.1.0, ibge.pam, ibge.ppm, ibge.censo_agro, ibge.censo_agro_historico, ibge.silvicultura,
ibge.extracao_vegetal e o datasets.producao_anual com uf e nivel="brasil" (ou "regiao" no histórico)
devolviam o agregado do país ou da região, sem o filtro e sem aviso. Na 2.0, levantam InvalidParameterError antes da
rede. Com uf, use nivel="uf" ou "municipio"; para o agregado, tire a uf.
66. Parâmetro impossível recusado antes da rede¶
Na 1.1.0, estas consultas devolviam um quadro vazio (ou o dado sem o filtro) sem erro, ou levantavam erro de
indisponibilidade depois da rede. Na 2.0, levantam InvalidParameterError:
- conab.serie_historica com ano_inicio > ano_fim ou UF inexistente, antes da rede;
- desmatamento.prodes (e o dataset) com ano posterior ao corrente, antes da rede; com um ano válido sem feição, o
resultado segue vazio, agora com aviso;
- conab.ceasa_precos e o preco_atacado com produto ou CEASA fora do que a CONAB/PROHORT publica, com os válidos
(depois da rede, contra a resposta: produto publicado fora dos 48 de ceasa_produtos() filtra);
- ibge.abate e ibge.leite_trimestral com UF desconhecida (antes, SourceUnavailableError), antes da rede;
- cftc.cot com inicio > fim, conab.custo_sociobiodiversidade com ano posterior ao corrente e antaq.movimentacao
com UF inexistente, antes da rede ou da descarga;
- datasets.futuros_agricolas com data e tipo="historico", ou com inicio, fim ou vencimento e tipo="ajustes"/"posicoes";
- b3.historico e futuros_agricolas(tipo="historico") com o código de uma opção no vencimento (ex.: VVJK): os ajustes só trazem futuros, e a 1.1.0 devolvia vazio. Use o código do mês do contrato (ex.: V26);
- UF inexistente (ex.: uf="XX"), antes da rede:
- bcb.credito_rural e datasets.credito_rural: a 1.1.0 filtrava a UF depois da consulta e devolvia vazio;
- conab.safras e os datasets estimativa_safra e producao_anual: vazio pelo filtro local da CONAB (no
producao_anual, a 1.1.0 passava o código inexistente ao IBGE antes);
- queimadas.focos e comexstat.exportacao/importacao: vazio pelo filtro local, depois da descarga;
- datasets.clima: na 1.1.0, o INMET e a NASA POWER recusavam a UF, e o dataset levantava SourceUnavailableError.
Já eram erro na 1.1.0, com ValueError, a UF inexistente na ANTT (pedágio), na ANP (diesel), no Desmatamento, na Embrapa
Solos, na FUNAI, no INCRA, na NASA POWER e no inmet.clima_uf (este, depois de baixar o catálogo de estações). Na 2.0,
levantam InvalidParameterError, que é subclasse de ValueError, antes da rede: quem capturava ValueError continua
pegando.
Quem tratava o vazio (ou o SourceUnavailableError do abate e do leite) como "sem dado" passa a capturar
InvalidParameterError.
67. USDA: sem market_year, o ano anterior até o WASDE de maio¶
Na 1.1.0, usda.psd sem market_year e datasets.oferta_demanda_global sem o ano (ano_comercial na 2.0) pediam o ano-calendário corrente, que o PSD
só publica a partir do WASDE de maio: de janeiro a abril, o resultado vinha vazio, sem aviso. Na 2.0, se o ano corrente
vem vazio, a consulta pede o anterior, e source_details["market_year"] diz qual foi usado (market_year_tentados
traz os pedidos). Quem precisa de um ano fixo passa o ano (market_year na fonte, ano_comercial no dataset); com ele, não há recuo.
68. CLI: datas do JSON em ISO 8601¶
Na 1.1.0, --formato json saía com as datas em milissegundos desde 1970 (1790035200000), o padrão do
DataFrame.to_json. Na 2.0, em todos os comandos, as datas saem em ISO 8601 ("2026-09-22T00:00:00.000"). Quem lia o
número passa a ler o texto: pd.to_datetime(...), datetime.fromisoformat(...) ou, no jq, .data[:10].
69. MapBiomas Alerta: max_registros no lugar de limit, ordem por código e tipo_data¶
Na 1.1.0, alertas(limit=...) e alertas_geo(limit=...) definiam o tamanho da página, e a consulta parava calada em 50
páginas (5.000 alertas no padrão). A ordem padrão da API repetia e perdia alertas entre as páginas, e o bbox ia na ordem
errada e voltava vazio. Na 2.0:
- limit sai. max_registros (padrão 5000) é o teto de linhas, com aviso quando corta, e max_registros=None traz a
coleção inteira. limit= levanta TypeError;
- a paginação vai em ordem de código e é conferida contra o totalCount: código repetido ou coleção incompleta levantam
ParseError;
- o bbox passa a filtrar (antes, toda consulta com caixa voltava vazia);
- tipo_data="publicacao" filtra pela data de publicação. O padrão segue a detecção, com aviso quando o período termina a
menos de 293 dias de hoje;
- data invertida ou fora de AAAA-MM-DD/DD/MM/AAAA levanta InvalidParameterError antes da rede.
Quem passava limit=100 para ter 100 alertas por página tira o argumento (ou usa max_registros=None para a coleção inteira).
70. CEPEA: o período antigo vem da série histórica¶
Na 1.1.0, cepea.indicador e datasets.preco_diario só tinham a janela recente da página (cerca de 15 pregões) e o que o
cache tinha acumulado: um período anterior vinha vazio ou incompleto, sem aviso. Na 2.0, esse período vem da série
histórica do CEPEA. A primeira consulta que precisa dela baixa a série inteira do produto (uma planilha de até ~0,6 MB por
indicador) e grava no cache; o padrão sem inicio (365 dias) também passa por ela. Série indisponível avisa em
validation_warnings, e período que fica sem dado levanta SourceUnavailableError. Para usar só o cache, passe
offline=True. A laranja não tem série. cepea.indicador e datasets.preco_diario saem com 2 colunas novas, valor_usd e
peso_medio_kg (as mesmas que a migração 10 acrescenta ao cache). cepea.pracas("soja") devolve só paranagua; Paraná está
em soja_parana, e praca="parana" em soja levanta InvalidParameterError.
71. Modo determinístico: aviso onde o modo não se aplica¶
Na 1.1.0, todo dataset aceitava datasets.deterministic(...), mas só o preco_diario o honrava (cache local, sem rede,
corte na data). Os que vão à rede consultavam a fonte corrente calados, com meta.snapshot preenchido, como se o dado
fosse o da data. Na 2.0, esses datasets avisam em validation_warnings e com UserWarning que o dado é o corrente. Seis
deles passam a recusar o contexto com InvalidParameterError, antes da rede, porque a fonte não tem como devolver o dado
como estava na data: cadastro_rural, desmatamento, exportacao, importacao, uso_do_solo e zoneamento_agricola.
Na 1.1.0, eles devolviam o dado corrente: tire essas chamadas do bloco deterministic(...). O preco_diario determinístico sem o produto no cache local
levanta SourceUnavailableError, em vez de devolver vazio: popule o cache (ou copie ~/.agrobr/cache/) antes de
reproduzir noutra máquina. Um período sem dado, com o produto no cache, segue vazio.
72. Censo de 1995: informantes nas lavouras¶
Em ibge.censo_agro e datasets.censo_agropecuario, a variável 151 das lavouras temporárias e permanentes de 1995
(tabelas 492 e 504 da SIDRA) sai como informantes, e não mais como estabelecimentos: a SIDRA a chama de "Número de
informantes". Em 2017, estabelecimentos segue vindo do número de estabelecimentos agropecuários (variáveis 10084 e
9504). Quem filtrava variavel == "estabelecimentos" nas lavouras de 1995 passa a filtrar "informantes".
73. Logs fora da saída padrão¶
Na 1.1.0, usado como biblioteca, o agrobr imprimia os logs do structlog (debug e info) na saída padrão, e o
logging.basicConfig não os controlava: python exporta.py > dados.csv saía com log no topo do CSV. Na 2.0, os logs do agrobr
passam pelo logging da biblioteca padrão, em JSON, no logger do módulo que os emite (agrobr.cepea.parsers.v1, por exemplo).
Sem configuração, só avisos e erros saem, na saída de erro; logging.basicConfig(level=logging.DEBUG) liga todos, e
logging.getLogger("agrobr") controla só o agrobr. O import agrobr não configura o structlog nem o logging.
Aplicação que usa o structlog. A configuração do structlog da aplicação, feita antes ou depois do import, vale só para os
logs dela; os do agrobr seguem no logging, em JSON. Na 1.1.0, ela valia também para os do agrobr: para vê-los, configure o
logging (logging.basicConfig ou um handler no logger "agrobr").
CLI. --verbose mostra os logs INFO na saída de erro; sem ele, só avisos e erros. Os logs da CLI saem legíveis, no
formato de console do structlog, sem cor e um por linha, como na 1.1.0; o JSON vale para o uso como biblioteca.
74. Datasets: colunas na ordem do contrato e data em datetime64¶
Na 1.1.0, 7 datasets (balanco, censo_agropecuario_legado, pib_agro, producao_anual,
queimadas, serie_historica_safra e clima) devolviam as colunas na ordem da fonte quando havia dado, e na ordem do
contrato quando vinham vazios. Na 2.0, todo dataset devolve as colunas do contrato na ordem dele, com as colunas extras
ao fim, na ordem da fonte, e o MetaInfo.columns acompanha. Quem lia por posição (df.iloc[:, 3], df.columns[0]) passa
a ler pelo nome. A coluna data do queimadas (e das fontes queimadas.focos e focos_geo) sai em datetime64[ns]
(Datetime("ns") no polars), e não mais como datetime.date numa coluna object: df["data"].dt.date devolve a data
de antes. Em nasa_power.clima_uf e clima_ponto(agregacao="mensal"), as temperaturas passam a vir antes de
precip_acum_mm, e dias, data_inicio e data_fim depois de lat/lon: leia também essas colunas pelo nome.
75. Status HTTP de erro: SourceUnavailableError, não httpx.HTTPStatusError¶
Na 1.1.0, um 403 ou um 404 da fonte saía em várias fontes como httpx.HTTPStatusError, cru, e em outras como
SourceUnavailableError. Na 2.0, todo status HTTP de erro sai como SourceUnavailableError, com a fonte e o status
na mensagem: "HTTP 403" ou "HTTP 404", na maioria das fontes seguido do motivo
("HTTP 403: a fonte recusou o pedido (bloqueio de WAF ou permissão)", "HTTP 404: o recurso não existe na URL").
Quem capturava httpx.HTTPStatusError destas fontes passa a capturar SourceUnavailableError e a ler o status na
mensagem ("HTTP 404" in str(erro)): ABIOVE, ANDA, ANEC, ANP (diesel), ANTT (pedágio), B3, BCB (SGS, PTAX e Focus), CFTC, ComexStat, Defensivos, DERAL, Desmatamento, Embrapa Solos, FUNAI, IBAMA, IBGE (Censo legado, pelo FTP), ICMBio, IMEA, INCRA, INMET (arquivo histórico e API), Lista Suja, MapBiomas, MAPA PSR, NASA POWER, Queimadas, RNC, SFB, SICAR, UNICA, USDA e ZARC. Na 1.1.0,
elas levantavam httpx.HTTPStatusError no 403, no 404 ou nos dois. As consultas da SIDRA (IBGE) levantavam ValueError
com o corpo da página de erro, e agora levantam o mesmo SourceUnavailableError.
- USDA, 404 do PSD: o gateway responde 404 para um ano sem dado (soja do Brasil em 1950, por exemplo). A tabela vazia
segue, mas agora com aviso em
validation_warningseUserWarning, porque o mesmo 404 sai se a URL da API mudar. - Datasets: o
SourceUnavailableErrorfinal trazattempted_sourcescom as fontes tentadas, na ordem, e__cause__com o erro da última. Emerrors, uma fonte que falhou por status HTTP passa a ter o tipo"unavailable"(na 1.1.0,"network"). NetworkErrorsegue exportado, mas nada o levanta na 2.0.
76. Crédito rural: a safra sai "AAAA/AA"¶
Na 1.1.0, o bcb.credito_rural e o datasets.credito_rural publicavam a safra como "2023/2024"; o novo
bcb.credito_rural_total nasceu no mesmo formato. Na 2.0, os 3 publicam "2023/24", o formato dos outros datasets
(estimativa_safra, balanco, progresso_safra, serie_historica_safra; nesta, os cereais de inverno e o café saem com o ano
publicado, §43), e o merge pela safra volta a casar. A entrada
continua aceitando "2023/24", "2023/2024" e "2024". Para converter o que foi gravado com a 1.1.0:
df["safra"] = df["safra"].map(agrobr.normalize.dates.normalizar_safra).
77. Entrada hostil: teto de expansão, semana_url e nome de snapshot¶
- Teto de expansão: ZIP e XLSX que expandem além do teto da fonte levantam
ResourceLimitErrorantes de descomprimir. Os tetos ficam acima do maior arquivo que cada fonte publica (a tabela está em Resiliência); o dado legítimo não muda. semana_url:conab.progresso_safraedatasets.progresso_safrasó aceitam páginas emhttps://www.gov.br/conab/. Outra URL (inclusivehttp://ou outra porta) levantaInvalidParameterError, antes do pedido.- Nome de snapshot: os nomes reservados do Windows (
CON,PRN,AUX,NUL,COM1–COM9eLPT1–LPT9, com ou sem extensão, em qualquer caixa) e os terminados em ponto levantamValueErrorem todo sistema, para o snapshot abrir no Windows.
78. Argumento fora da assinatura levanta TypeError¶
Na 1.1.0, as 110 funções públicas abaixo aceitavam **kwargs: argumento desconhecido ou com nome errado era descartado em silêncio,
ou repassado ao fetcher, que lia só as chaves que conhecia. O recorte saía mais largo que o pedido, sem erro:
ibama.embargos(municipio="X") devolvia o Brasil inteiro, e datasets.progresso_safra("soja", uf="MT") também. Na 2.0, 77
delas passam à assinatura explícita, e o argumento fora dela levanta TypeError antes da rede; as outras 33 mantêm o
**kwargs e recusam o nome desconhecido.
- Datasets (32):
abate_trimestral,balanco,cadastro_rural,censo_agropecuario,censo_agropecuario_historico,censo_agropecuario_legado,censo_agropecuario_municipal_1985,clima,comercio_internacional,condicao_lavouras,credito_rural,embarques_anec,estimativa_safra,exportacao,extrativismo_vegetal,fertilizante,futuros_agricolas,importacao,leite_industrial,movimentacao_portuaria,oferta_demanda_global,pecuaria_municipal,pib_agro,posicionamento_fundos,preco_atacado,producao_anual,progresso_safra,queimadas,seguro_rural,serie_historica_safra,silvicultura,uso_do_solo. - Funções de fonte (45):
abiove.exportacao,acervo_fundiario.assentamentos,acervo_fundiario.assentamentos_geo,acervo_fundiario.sigef,acervo_fundiario.sigef_geo,acervo_fundiario.snci,acervo_fundiario.snci_geo,alt.sicar.imoveis,alt.sicar.imoveis_geo,alt.sicar.resumo,ana.demanda_irrigacao,ana.demanda_irrigacao_geo,ana.disponibilidade_hidrica,ana.disponibilidade_hidrica_geo,ana.hidrografia,ana.hidrografia_geo,ana.pivos_irrigacao,ana.pivos_irrigacao_geo,anda.entregas,b3.ajustes,b3.historico,b3.posicoes_abertas,b3.posicoes_abertas_historico,conab.ceasa_precos,conab.progresso_safra,deral.condicao_lavouras,ibama.embargos,ibama.embargos_geo,icmbio.ucs_geo,imea.cotacoes,inmet.clima_uf,inmet.estacao,inmet.historico,mapbiomas_alerta.alertas,mapbiomas_alerta.alertas_geo,queimadas.focos,queimadas.focos_geo,rio_verde.ensaio_soja,sfb.cnfp,sfb.cnfp_geo,sfb.concessoes,sfb.concessoes_geo,sfb.ifn_conglomerados,sfb.ifn_conglomerados_geo,usda.psd. - Funções que mantêm
**kwargs(33): na 1.1.0, também descartavam o nome desconhecido; na 2.0, recusam antes da rede. LevantamTypeError:anec.comparacao_anual,anec.destinos,anec.embarques,anec.embarques_mensais,desmatamento.prodes,prodes_geo,deter,deter_geo,embrapa_solos.perfis,perfis_geo,mapa_solos,mapa_solos_geo,funai.terras_indigenas,terras_indigenas_geo,icmbio.ucs,incra.quilombolas,quilombolas_geoe os datasetscusto_producao,desmatamentoezoneamento_agricola. LevantamInvalidParameterError:comtrade.comercio,comtrade.trade_mirror,defensivos.formulados,autorizacoes,tecnicos,lista_suja.empregadores,mapbiomas.cobertura,mapbiomas.transicao,nasa_power.clima_ponto,clima_uf,rnc.registradas,protegidasezarc.zoneamento. - Argumentos que só chegavam ao fallback:
datasets.exportacao(mes=...)ia à ABIOVE (seção 39), edatasets.producao_anual(safra=...), à CONAB. Na 2.0, os 2 levantamTypeError. Useabiove.exportacao(ano, mes=...)ou filtre omesdo resultado, econab.safras(produto, safra=...)ou oanodoproducao_anual.
O que fazer: tire o argumento ou use o nome da assinatura (help(função) mostra os aceitos). O CHANGELOG lista as mudanças
por fonte.
79. ZARC: contrato 2.1, sem chave primária¶
O contrato zarc.zoneamento, do dataset zoneamento_agricola, passa de 1.0 a 2.1. O 1.0 declarava a chave
[cultura, safra, geocodigo, solo_codigo, ciclo_codigo]; o 2.1 não declara chave: a fonte publica mais de uma linha para a
mesma combinação (duplicatas literais e riscos distintos), e o agrobr preserva cada ocorrência publicada. O 2.1 acrescenta
13 colunas no fim das 46 da 1.1.0 (cultura_original, safra_inicio, safra_fim, cultura_codigo, clima_codigo,
manejo_codigo, produtividade_texto, nm_codigo, municipio_sicor_codigo, mesorregiao_codigo, microrregiao_codigo,
registro_origem e cod_municipio), e solo_codigo, ciclo_codigo e dec1–dec36 passam a Int64.
O que fazer: quem deduplicava pelas 5 colunas descarta linhas que a fonte publica. Para identificar a linha, use
registro_origem (a posição no CSV) junto com meta.raw_content_hash (o SHA-256 do corpo): a posição só vale dentro do
mesmo corpo e não identifica a observação entre revisões. Veja o contrato.
80. Corpo fora do formato: ParseError, não SourceUnavailableError¶
Com uma resposta HTTP 200 em outro formato (por exemplo, um JSON {"value": []} onde a fonte publica outra estrutura),
o SGS, a ComexStat, o ZARC e o Desmatamento levantavam SourceUnavailableError na 1.1.0. Na 2.0, levantam ParseError. No
Desmatamento, o corpo vazio também passa a ParseError.
O que fazer: nada, para quem captura AgrobrError, a base das 2. Quem capturava só SourceUnavailableError para tratar
esse caso passa a capturar também ParseError.
81. Censo municipal 1985: casa a casa, com o status de cada uma (contrato 2.0)¶
Na 1.1.0, o ibge.censo_agro_municipal_1985 lia 53 CSVs extraídos por OCR de 22 UFs. Esses CSVs tinham temas
trocados, moeda errada, colunas perdidas e níveis confundidos, e a 2.0.0 refez a extração inteira a partir dos 28 PDFs
do IBGE.
A API tem a mesma assinatura (tema, e uf, nivel, as_polars e return_meta só por nome), mas o que volta muda:
- O nível estadual passa de
totalauf, no argumento e na colunanivel.nivel="total"devolvia as linhas da UF e agora levantaInvalidParameterError;nivel="uf"levantavaValueErrore agora devolve essas linhas. Troque"total"por"uf"no argumento e nos filtros da colunanivel. - 1 linha por casa do PDF, com a chave
(volume, tabela, pagina_pdf, linha, coluna). Não há mais 1 linha por localidade e variável. Pivote pelacoluna(ou pelocoluna_nome) se precisar do formato largo. valorsó vem na casa confirmada pelas somas impressas.valor_lidotraz a leitura sempre, e ostatusdiz o nível de confiança. Quem usava todos os valores da 1.1.0 escolhe ostatusaceito:df[df["valor"].notna()](só as confirmadas) oudf[df["status"].isin([...])].- O tema segue o título impresso, igual em todos os volumes. 19 nomes mudaram, porque o mapa antigo estava deslocado (por
exemplo, a 91 é
depositos_producao, e nãomeios_transporte). Consultetemas_censo_agro_municipal_1985(). - 27 UFs (eram 22): entram MA, PI, CE, RN e TO.
- Recusas: tema, UF ou nível inválidos levantam
InvalidParameterError, e a UF cujo volume não traz a tabela também, com as UFs que a têm. A tabela que está no volume, mas de que a extração não leu nenhuma casa (AM 80, AP 80, RR 80 e RR 119), levantaParseError. Na 1.1.0, tema, UF e nível inválidos e a UF sem a tabela levantavamValueError. Das 4 tabelas que hoje levantamParseError, AM 80, AP 80 e RR 80 davamValueError, e a RR 119 devolvia 36 linhas.
O contrato vai de 1.0 a 2.0:
| 1.1.0 (contrato 1.0) | 2.0 (contrato 2.0) |
|---|---|
ano, uf, nivel, tema, localidade |
iguais; localidade é o nome como lido, com o ruído da leitura |
uf_cod, localidade_cod |
saem: os municípios de 1985 não correspondem 1:1 aos códigos atuais |
categoria, variavel |
coluna_nome (só confirmado), coluna_nome_lido, coluna_nome_status e variavel |
valor |
valor (só confirmado) e valor_lido |
unidade |
unidade (só com a folha confirmada) e unidade_lida |
confianca |
status da casa, com a precisão medida no contrato |
fonte |
sai; a proveniência está no MetaInfo (o PDF do IBGE e o SHA-256 dele) |
| — | entram volume, tabela, pagina_pdf, pagina_impressa, linha, coluna, marcador e reparado |
O contrato 1.0 segue em agrobr.contracts.ibge.IBGE_CENSO_AGRO_MUNICIPAL_V1, o mesmo import da 1.1.0, agora com
DeprecationWarning.
Quem lia os CSVs do pacote direto (agrobr/data/censo_1985/tab_067.csv a tab_119.csv e o _index.csv): eles saem. O
pacote passa a ser um Parquet com 1 linha por casa, a cobertura.parquet e o manifesto.json, que são internos: leia pela API
ou pelo dataset censo_agropecuario_municipal_1985.
Veja o contrato 2.0.
82. CLI: --formato inválido sai com erro, e o CSV do Windows sai em UTF-8¶
Na 1.1.0, -o/--formato com um valor fora da lista (-o xml) saía com código 0 e a tabela, e health --output fazia o
mesmo com o texto. Na 2.0, os 8 comandos de dados (os 7 da 1.1.0 e conab levantamentos, que ganha --formato) aceitam só table, csv e json em --formato, e health, doctor e snapshot list, só
text e json (§92): outro valor sai com código 2, a mensagem na saída de erro e a saída padrão vazia. Quem testava o código de
saída de um script passa a ver o erro.
No Windows, o CSV da 1.1.0 saía com \r\r\n em cada linha e, redirecionado para arquivo ou pipe, em cp1252: o
pandas.read_csv padrão falhava em "Paranaguá", e o csv.reader via linhas vazias intercaladas. Na 2.0, a saída padrão da
CLI sai em UTF-8, e o CSV com uma quebra por linha (\r\n no Windows, \n no Linux e no macOS). No Linux e no macOS, os
bytes do CSV não mudam.
83. Cache: a política só do CEPEA, e sai o load_baseline_fingerprint¶
Na 1.1.0, o agrobr.cache.get_policy tinha 21 políticas (CEPEA, IBGE, CONAB, BCB, ComexStat, INMET, ANDA, NASA POWER e
Notícias Agrícolas) e devolvia a do CEPEA, calada, para fonte fora da tabela ou texto qualquer. Só o cache de indicadores
do CEPEA vence por ela; as outras fontes não têm esse cache (ver a seção 57). Na 2.0, o POLICIES e o SOURCE_POLICY_MAP
ficam só com o CEPEA (cepea_diario), e o get_policy, o calculate_expiry e o get_next_update_info de outra fonte
levantam InvalidParameterError ("não tem cache no agrobr"), com as fontes que têm. O endpoint="semanal" do CEPEA passa
à política diária, a que o cache usa para todos os produtos. O agrobr doctor mostra a expiração só do CEPEA, no texto e
no cache_expiry do --formato json; antes, 1 linha por fonte, com TTL de fonte sem cache.
O load_baseline_fingerprint e o save_baseline_fingerprint saem do agrobr.cepea.parsers, sem uso no agrobr. Para
gravar e ler o Fingerprint em JSON: fingerprint.model_dump(mode="json") e Fingerprint.model_validate(dados)
(agrobr.models).
84. Desmatamento: paginação, corte e custo da chamada padrão¶
Na 1.1.0, desmatamento.prodes, deter, prodes_geo e deter_geo faziam 1 requisição WFS com até 50.000 feições
(10.000 nas _geo). Na 2.0, o agrobr pagina:
tamanho_pagina: 500 feições por página (100 emprodes_geoedeter_geo), até 2.000 (500 nas_geo);max_registros: 50.000 (10.000 nas_geo);max_registros=Nonelê a seleção inteira;- cada requisição espera 2 s (o ritmo do TerraBrasilis no agrobr). Sem filtro, a chamada padrão faz até 100 páginas, mais de
3 min só de espera. Exemplos: 497 s em
prodes(bioma="Amazônia"), 187 s emprodes_geodo Cerrado, MT, 2023, e mais de 600 s emdeter_geoda Amazônia, no PA. Comtamanho_pagina=2000, o PRODES da Amazônia caiu para 142 s.
O corte. Quando a seleção passa de max_registros, o agrobr lê o prefixo em ordem crescente de fid (PRODES) ou de
gid (DETER), e não por data, e emite UserWarning ("retornadas N de M ocorrências por limite local"). Os 50.000 da chamada
padrão são uma parte da camada: em 27/09/2026, eram 802.281 feições no PRODES da Amazônia e 460.092 no DETER.
A saída. prodes e deter devolvem as colunas da 1.1.0, na mesma ordem, seguidas dos atributos publicados pelo WFS
(13 colunas a mais no PRODES e 10 no DETER: 20 e 19 no total), com as linhas em ordem de fid/gid; area_km2 sai com a precisão publicada (não mais 4
casas). No DETER, data passa a datetime64[ns], e municipio_id passa de Int64 a texto, como o declaram o contrato da fonte
(desmatamento_deter_feicoes) e o do dataset (desmatamento_deter, que o põe na chave); para juntar pelo município, use o cod_municipio (Int64) do
datasets.desmatamento.
A receita. ano (PRODES), uf, inicio, fim e classe (DETER) vão no filtro CQL do servidor e reduzem as
páginas: filtre antes de subir o limite. Suba tamanho_pagina até o máximo e use max_registros=None só com filtro. Veja a
página da fonte.
85. Nomes de parâmetro: o mesmo vocabulário em toda a API¶
Na 2.0, o mesmo conceito tem o mesmo nome em todas as funções: inicio/fim para período por data, ano_inicio/ano_fim
para período por ano, uf para a unidade da federação, produto para o produto e municipio para o município (seção 86).
Os nomes antigos levantam TypeError, com o nome recusado também em desmatamento.*, datasets.desmatamento e
datasets.zoneamento_agricola, que aceitam **kwargs. Em zarc.zoneamento, mapbiomas.cobertura e
mapbiomas.transicao, levantam InvalidParameterError com o nome recusado. Por posição, nada muda, salvo onde a seção 88 diz.
| Função | 1.1.0 | 2.0 |
|---|---|---|
bcb.sgs, bcb.ptax |
data_inicial, data_final |
inicio, fim |
bcb.focus |
data_inicial |
inicio |
cftc.cot |
commodity, start, end |
produto, inicio, fim |
datasets.posicionamento_fundos |
start, end, combined |
inicio, fim, combinado |
desmatamento.deter, deter_geo, datasets.desmatamento |
data_inicio, data_fim |
inicio, fim |
mapbiomas_alerta.alertas, alertas_geo |
start_date, end_date |
inicio, fim |
alt.antt_pedagio.fluxo_pedagio |
data_inicio, data_fim (versões de desenvolvimento) |
inicio, fim |
conab.serie_historica, datasets.serie_historica_safra |
inicio, fim (anos) |
ano_inicio, ano_fim |
normalize.lista_safras |
inicio, fim (safras) |
safra_inicio, safra_fim |
conab.progresso_safra |
cultura, estado |
produto, uf |
datasets.progresso_safra |
estado |
uf |
mapbiomas.cobertura, mapbiomas.transicao, datasets.uso_do_solo |
estado |
uf |
conab.custo_producao, custo_producao_total |
cultura |
produto |
usda.psd |
commodity |
produto |
alt.mapa_psr.apolices, sinistros |
cultura |
produto |
zarc.zoneamento, datasets.zoneamento_agricola |
cultura |
produto |
alt.sicar.imoveis, imoveis_geo, imoveis_geo_stream, resumo |
cod_municipio |
municipio |
alt.sicar.imoveis_geo |
max_features |
max_registros |
ana.hidrografia, pivos_irrigacao, demanda_irrigacao, disponibilidade_hidrica e os 4 _geo |
max_features |
max_registros |
datasets.oferta_demanda_global |
country, market_year, attributes, pivot |
pais, ano_comercial, atributos, pivotar |
datasets.comercio_internacional |
reporter, partner, freq |
declarante, parceiro, frequencia |
No BCB, na B3, no CEPEA (cepea.indicador, datasets.preco_diario e a CLI), no CFTC, no Desmatamento, no MapBiomas
Alerta, no fluxo da ANTT e nos datasets deles, inicio e fim aceitam date, datetime (a hora é descartada) e texto
AAAA-MM-DD ou DD/MM/AAAA ("01/02/2024" é 1º de fevereiro). alt.anp_diesel.* e datasets.precos_diesel aceitam
date e datetime, mas, para texto, exigem AAAA-MM-DD. inmet.estacao, inmet.historico_periodo, datasets.clima
no modo estação e nasa_power.clima_ponto aceitam date ou texto AAAA-MM-DD e recusam datetime. Nessas fontes ANP,
INMET e NASA POWER, texto DD/MM/AAAA levanta InvalidParameterError. No CEPEA, o mês e o dia do texto têm dois dígitos:
"2024-1-5", que a 1.1.0 aceitava, passa a levantar InvalidParameterError; use "2024-01-05" ou "05/01/2024".
Antes, cada fonte aceitava um formato. O filtro ano_inicio/ano_fim da série histórica recusa tipo inválido e intervalo
invertido antes da rede.
Ficam os nomes que são termo técnico da fonte ou que não têm par na 2.0: na fonte Comtrade, reporter, partner, freq e
require_complete; na fonte USDA, country, market_year, attributes e pivot, e as colunas em inglês; parameters
na NASA POWER; year na ANEC; lat/lon; sources no MapBiomas Alerta; especie em ibge.ppm e ibge.abate; setor
em ibge.pib_agro; data (um dia) no bcb.ptax; nivel="estado" no MapBiomas; combined no cftc.cot, termo do relatório COT Disaggregated Combined (no dataset, posicionamento_fundos(..., combinado=True)); e cultura nos defensivos (AGROFIT),
em que o produto é o defensivo e a cultura é o alvo. A coluna de saída cultura do ZARC, do PSR e dos custos também fica.
Proveniência. No SGS e na PTAX, source_details["query"]["defaulted_fields"] traz inicio/fim no lugar de
data_inicial/data_final. No SICAR, a chave source_details["sicar"]["max_features"] passa a max_registros. Quem lê essas
chaves troca o nome.
86. Município: nome inteiro ou código IBGE¶
municipio aceita o código IBGE de 7 dígitos (int ou texto) ou o nome inteiro do município, sem diferenciar caixa,
acento e espaços repetidos; nomes anteriores conhecidos ("Açu") levam ao atual. Pedaço de nome, nome de mais de um município
sem uf, nome de outra UF e código fora do cadastro levantam InvalidParameterError com os candidatos, antes da rede.
A resolução é a de normalize.resolver_municipio(valor, uf=None), nova na 2.0, que devolve codigo_ibge, nome e uf.
Vale em alt.sicar (as 4 funções) e datasets.cadastro_rural, mapbiomas.cobertura e datasets.uso_do_solo municipal,
alt.mapa_psr.apolices, sinistros e datasets.seguro_rural, zarc.zoneamento e datasets.zoneamento_agricola, e
alt.anp_diesel.precos_diesel e datasets.precos_diesel. O filtro cod_municipio do SICAR, que já existia na 1.1.0, sai, e
também os que só as versões de desenvolvimento da 2.0 tinham (cod_municipio no cadastro_rural, geocodigo no MapBiomas
e cd_ibge no PSR): o código vai em municipio.
Muda calado. Na 1.1.0, o nome casava por pedaço. Agora casa por inteiro, e a mesma chamada pode trazer outro recorte sem erro:
| Fonte | 1.1.0 | 2.0 |
|---|---|---|
| SICAR | pedaço do nome, com o acento exato (ILIKE '%nome%') |
o município de nome exato; onde a UF tem o nome exato e outros que o contêm, só o exato |
| MapBiomas | municipio="Pinheiro" trazia os 7 municípios com "pinheiro" no nome |
só Pinheiro (MA) |
PSR e seguro_rural |
pedaço do rótulo publicado, em qualquer UF | o código do município: entram as apólices rotuladas com o nome do distrito (Caxias do Sul, 2024: 274 → 693 apólices) e saem os homônimos de outras UFs |
| ZARC | pedaço do nome | o nome inteiro: municipio="herval" trazia Santa Maria do Herval e agora traz Herval (RS, 4307104) |
| ANP | o nome da planilha, em qualquer UF | o código ou o nome do IBGE, com a UF do município no filtro: "Santana do Livramento" passa a "Sant'Ana do Livramento" ou 4317103 |
O que fazer: use o código IBGE ou o nome completo, com uf quando o nome se repete. Para achar o nome a partir de um pedaço,
normalize.buscar_municipios("sorr", uf="MT"). Para o comportamento antigo do PSR (rótulo publicado), filtre a coluna
municipio do resultado.
87. Colunas renomeadas na saída¶
Muda calado para quem exporta. Quem lê a coluna pelo nome antigo recebe KeyError; quem só grava o frame (to_csv,
Parquet, banco) ou itera as colunas recebe outro schema, sem erro.
estado → uf. Em conab.progresso_safra e datasets.progresso_safra (contrato progresso_safra 2.0), e em
mapbiomas.cobertura, mapbiomas.transicao e datasets.uso_do_solo, estadual e municipal (contratos mapbiomas_cobertura
2.0, mapbiomas_transicao 2.0 e mapbiomas_cobertura_municipal 1.1), inclusive na chave primária. No progresso,
MEDIA_ESTADOS e BR seguem como valores. O queimadas.focos mantém a coluna estado, com o nome do estado publicado pelo
INPE, ao lado de uf, com a sigla.
datasets.posicionamento_fundos, contrato 2.0. A fonte cftc.cot mantém os nomes do relatório do CFTC; o dataset sai em
português. O mapa está em agrobr.contracts.datasets.POSICIONAMENTO_FUNDOS_COLUNAS_V2 (nome antigo → novo).
| 1.1.0 | 2.0 |
|---|---|
commodity |
produto |
open_interest |
posicoes_abertas |
managed_money_long / _short / _spread / _net |
fundos_compra / fundos_venda / fundos_spread / fundos_saldo |
producer_long / _short |
produtores_compra / produtores_venda |
swap_long / _short |
swap_compra / swap_venda |
other_long / _short |
outros_compra / outros_venda |
nonreportable_long / _short |
nao_reportaveis_compra / nao_reportaveis_venda |
change_managed_money_long / _short |
variacao_fundos_compra / variacao_fundos_venda |
change_open_interest |
variacao_posicoes |
swap_spread e outros_spread são colunas novas na 2.0 (nas versões de desenvolvimento, swap_spread e other_spread).
datasets.oferta_demanda_global, contrato 2.0. A fonte usda.psd mantém as colunas em inglês.
| 1.1.0 | 2.0 |
|---|---|
commodity_code |
codigo_produto |
commodity |
produto |
country_code |
codigo_pais |
country |
pais |
market_year |
ano_comercial |
attribute |
atributo |
attribute_br |
atributo_br |
value |
valor |
unit |
unidade |
codigo_atributo, codigo_unidade, ano_atualizacao e mes_atualizacao são colunas novas na 2.0 (nas versões de
desenvolvimento, attribute_id, unit_id, last_update_year e last_update_month; seção 49).
No modo pivotado, os identificadores fixos usam os nomes novos, e as colunas dos atributos seguem com o rótulo de cada um.
datasets.comercio_internacional, contrato 3.0. A fonte comtrade.comercio mantém os nomes técnicos.
| 1.1.0 | 2.0 |
|---|---|
reporter_code |
codigo_declarante |
reporter_iso |
iso_declarante |
reporter |
declarante |
partner_code |
codigo_parceiro |
partner_iso |
iso_parceiro |
partner |
parceiro |
fluxo_code |
codigo_fluxo |
hs_code |
codigo_hs |
produto_desc |
descricao_produto |
conab.brasil_total. produto passa a ser o identificador normalizado, sem as notas de rodapé, e a coluna nova rotulo
traz o texto publicado: o filtro produto == "SOJA" volta vazio, e o certo é produto == "soja". feijao_cores_1, _2 e
_3 distinguem as 3 safras.
comexstat.exportacao/importacao com agregacao="detalhado". A coluna cod_porto passa a cod_urf (é o código da
URF publicado em CO_URF), e cod_unidade, cod_pais, cod_via e cod_urf saem como texto, com os zeros à esquerda.
Troque df["cod_porto"] por df["cod_urf"] e compare os códigos como texto. Na importacao, valor_frete_usd e
valor_seguro_usd entram também na agregação mensal, a padrão (a 1.1.0 somava só peso e FOB), e, no detalhado, ficam no
lugar dos VL_FRETE e VL_SEGURO que a 1.1.0 deixava com o nome do arquivo.
Coluna nova cod_municipio. Os datasets municipais, inclusive o desmatamento no DETER, e as fontes que dividem o
contrato com eles (SICAR, queimadas, PSR, MapBiomas municipal e ZARC) ganham a coluna cod_municipio (Int64, o código IBGE de 7 dígitos); o censo_agropecuario_municipal_1985 fica fora: os
municípios de 1985 não correspondem 1:1 aos códigos atuais. Quem exporta o
frame ou compara o conjunto de colunas recebe uma coluna a mais; o parâmetro cod_municipio do SICAR é outra coisa e sai
(§86).
O que fazer: troque os nomes no consumidor. Para ler arquivos gravados antes, renomeie do nome antigo para o novo
(df.rename(columns={antigo: novo ...}); no posicionamento_fundos, df.rename(columns=POSICIONAMENTO_FUNDOS_COLUNAS_V2)).
88. Flags e filtros secundários só por nome¶
as_polars, return_meta e as opções que vêm depois deles passam a ser só por nome em todas as fontes e datasets: por posição,
TypeError, antes de qualquer download. Exemplos: bcb.credito_rural, cepea.indicador (também validate_sanity,
force_refresh e offline), comexstat.exportacao/importacao, conab.safras (o levantamento segue na 4ª posição),
balanco e brasil_total (também levantamento), conab.custo_producao, inmet.*, nasa_power.* (também parameters), alt.anp_diesel.*,
alt.antt_pedagio.*, alt.mapa_psr.* e os datasets correspondentes. Em datasets.cadastro_rural, os 7 primeiros
argumentos (uf a criado_apos) seguem posicionais.
No IBGE, só os filtros principais seguem posicionais, iguais na fonte e no dataset:
| 1.1.0 | 2.0 |
|---|---|
ibge.pam("soja", 2023, "MT") |
ibge.pam("soja", 2023, uf="MT") |
datasets.producao_anual("soja", 2023, "municipio", "MT") |
datasets.producao_anual("soja", 2023, uf="MT", nivel="municipio") |
ibge.censo_agro("efetivo_rebanho", 2017) |
ibge.censo_agro("efetivo_rebanho", ano=2017) |
ibge.pib_agro("2024T1") |
ibge.pib_agro(trimestre="2024T1") |
datasets.leite_industrial("leite", "2024T1") |
datasets.leite_industrial("2024T1", produto="leite") |
Pesquisas anuais mantêm produto (ou espécie) e ano por posição; o abate, espécie e trimestre; os censos, só o tema; o leite,
só o trimestre; o PIB, só o setor (na fonte) ou o produto (no dataset). Um trimestre na posição do setor
(ibge.pib_agro("2024T1")) levanta InvalidParameterError com os setores válidos.
89. Tipos da saída¶
A 2.0 fixa uma regra para todas as fontes: data em datetime64[ns] (instante com fuso em datetime64[ns, UTC]), inteiro por
natureza (ano, código, contagem) em Int64, medida em float64, texto no dtype padrão do pandas instalado (object no pandas
2, str no 3), e o resultado vazio com os mesmos tipos do cheio. Column.validate e validate_dataset exigem datetime64
nas colunas de data: texto conversível e objeto date passam a ser erro de contrato. Rótulo de período (safra, AAAA-MM,
trimestre) segue em texto.
Muda calado: colunas de data que eram texto.
| Função | Coluna | 1.1.0 | 2.0 |
|---|---|---|---|
deral.condicao_lavouras, datasets.condicao_lavouras |
data |
texto com o nome da aba: dd-mm-aaaa, dd-mm-aa, "Atual" e "Anterior" |
datetime64[ns] com a data da célula (contrato 2.0) |
imea.cotacoes |
data_publicacao |
texto AAAA-MM-DD HH:MM:SS |
datetime64[ns] |
inmet.estacoes |
inicio_operacao, DT_FIM_OPERACAO |
texto ISO com fuso | datetime64[ns, UTC], o mesmo instante |
antaq.movimentacao, datasets.movimentacao_portuaria |
data_atracacao |
texto | datetime64[ns], com a hora (contrato 2.0) |
alt.antt_pedagio.pracas_pedagio |
data_da_inativacao |
texto, "" quando vazia |
datetime64[ns], NaT quando vazia (contrato 2.0) |
Data inexistente na fonte (como 31/02/2024) vira NaT, com aviso em meta.validation_warnings; texto que não é data levanta
ParseError. Na FUNAI e no INCRA, as datas já saíam em datetime64 na 1.1.0 e seguem assim: a data_atualizacao da FUNAI,
que a 1.1.0 lia com o mês primeiro, sai com o dia primeiro (seção 34), e o marcador 0001-01-01 do INCRA vira NaT
(seção 25). No INMET, o mesmo instante em UTC pode cair no dia seguinte: para a data local publicada, use
.dt.tz_convert("America/Sao_Paulo").dt.date.
A armadilha do filtro por texto. Comparar uma coluna datetime64 com texto dd/mm/aaaa não dá erro: o pandas lê o texto
com o mês primeiro quando o dia vai até 12. df[df.data == "01/02/2026"] traz 2 de janeiro, sem aviso. Compare com
pd.Timestamp("2026-02-01") ou date(2026, 2, 1). Para o texto antigo, df["data"].dt.strftime("%d/%m/%Y"). Exportado,
o texto também muda: to_csv e astype(str) dão 2026-09-14, e não 14/09/2026.
No DERAL, o filtro pela semana corrente (data == "Atual") volta vazio, e o filtro pelo nome da aba ("02-10-23") pode
voltar vazio ou casar outra data, sem aviso: use
df[df.data == df.data.max()] ou pd.Timestamp. O - publicado em pct, plantio_pct e colheita_pct passa a 0 (na
1.1.0, nulo), e a aba cujo nome difere da data da célula segue a célula, com aviso.
Muda calado: inteiros e medidas.
| Função | Coluna | 1.1.0 | 2.0 |
|---|---|---|---|
ibge.abate, datasets.abate_trimestral |
animais_abatidos |
float64 |
Int64 (contrato 2.1) |
ibge.ppm, datasets.pecuaria_municipal |
valor |
int64 (float64 se a resposta trazia -, ... ou X) |
float64: é medida, e não contagem, porque a coluna mistura cabeças, mil litros, mil dúzias e kg, conforme a espécie |
bcb.sgs, datasets.series_economicas |
codigo |
int64 |
Int64 (contrato bcb_sgs 3.0) |
alt.antt_pedagio.pracas_pedagio |
km_m, ano_do_pnv_snv |
texto | float64, Int64 |
mapbiomas_alerta.alertas, alertas_geo |
alert_code |
int64 |
Int64 |
b3.ajustes, b3.historico |
vencimento_mes, vencimento_ano |
int64 |
Int64 |
alt.mapa_psr.*, datasets.seguro_rural |
ano_apolice |
int64 |
Int64 |
rio_verde.ensaio_soja |
ciclo_dias |
float64 |
Int64 |
conab.brasil_total |
métricas | Decimal/object |
float64 |
Códigos e anos do IBGE, da ANA, do SFB e da Embrapa Solos também saem em Int64, no cheio e no vazio. Não há truncamento:
a fração numa contagem levanta ParseError. O ibge.abate e o datasets.abate_trimestral também ganham a coluna
categoria, depois de especie.
Zero do SIDRA. O - que o SIDRA publica para zero absoluto passa a sair 0, e não nulo, em ibge.pam, ibge.ppm,
ibge.silvicultura, ibge.extracao_vegetal, ibge.leite_trimestral e ibge.pib_agro e nos datasets que os usam. Na PPM,
município com rebanho zero sai 0.0, e média e contagem mudam sem aviso. Para a conta da 1.1.0, filtre a medida > 0
(na PAM, producao > 0; seção 17).
Muda calado: texto. O texto sai no dtype padrão do pandas instalado, e não em string[python]; nos nulos, NaN no pandas
3 e None no 2, em vez de pd.NA. Ficam em string[python], de propósito, a fonte e os dicionários da ComexStat e o
antt_pedagio.fluxo (contrato 3.0), porque o teto de memória dessas consultas conta cada texto guardado. A coluna
anomalies do CEPEA sai em object, com o JSON ou None (no Polars, String ou null). ibge.pib_agro sai com
precos na forma canônica ("corrente", e não " CORRENTE ").
Muda calado: o vazio. Consulta sem linhas devolve as colunas e os tipos do contrato, e não mais tudo object: B3,
MapBiomas Alerta (com o CRS EPSG:4326 no _geo), ibama.embargos_geo, icmbio.ucs_geo, IBGE, CONAB e as demais. A
ibge.pam devolve sempre as 14 colunas declaradas, com as medidas não pedidas nulas.
O que fazer: teste a família do dtype com pd.api.types (is_integer_dtype, is_string_dtype,
is_datetime64_any_dtype), o nulo com isna(), e não com is pd.NA ou == "NULL"; compare datas com Timestamp ou
date; para ter int64, astype("int64") quando não houver nulo.
Contratos que mudam de versão por essas regras:
| Contrato | 1.1.0 | 2.0 |
|---|---|---|
abate_trimestral |
1.0 | 2.1 |
antt_pedagio_pracas |
1.0 | 2.0 |
condicao_lavouras |
1.0 | 2.0 |
movimentacao_portuaria |
1.0 | 2.0 |
oferta_demanda_global |
1.0 | 2.0 |
posicionamento_fundos |
1.0 | 2.0 |
comercio_internacional |
1.0 | 3.0 |
bcb_sgs |
— | 3.0 |
embrapa_solos_perfis |
— | 3.0 |
Nos contratos que já existiam na 1.1.0, a constante antiga segue com o schema anterior (menos POSICIONAMENTO_FUNDOS_V1,
que passa a 1.1, com swap_spread e other_spread), e a nova tem outro nome:
IBGE_ABATE_V2 (agrobr.contracts.ibge), ANTT_PEDAGIO_PRACAS_V2, CONDICAO_LAVOURAS_V2, MOVIMENTACAO_PORTUARIA_V2,
OFERTA_DEMANDA_GLOBAL_V2 e POSICIONAMENTO_FUNDOS_V2 (agrobr.contracts.datasets), COMERCIO_INTERNACIONAL_V3
(agrobr.contracts.comtrade). O bcb_sgs, sem contrato na 1.1.0, está em BCB_SGS_V3 (agrobr.contracts.bcb_sgs). O registro
(get_contract(nome)) devolve sempre o atual.
90. Erros: a classe diz a causa¶
Falha de layout em todas as fontes de um dataset levanta ParseError, com errors, attempted_sources e a causa
original em __cause__, e não mais SourceUnavailableError. Falha mista (rede numa fonte, layout noutra) segue como
SourceUnavailableError. Erro de programação (um TypeError interno, por exemplo) propaga como está, sem acionar o fallback.
Quem fazia except SourceUnavailableError para "a fonte falhou" passa a tratar ParseError à parte, ou AgrobrError na
borda da aplicação.
Nome desconhecido num catálogo levanta UnknownNameError, subclasse de InvalidParameterError e de KeyError, com os
nomes válidos: datasets.get_dataset, contracts.get_contract, normalize.uf_para_nome, uf_para_regiao e
uf_para_ibge. except KeyError e except ValueError seguem pegando. A exceção é exportada em agrobr.
Entrada inválida levanta InvalidParameterError antes da rede, com os valores válidos na mensagem, onde a 1.1.0 devolvia
vazio, o dado sem filtro ou um erro cru (ValueError, TypeError, AttributeError). A regra da seção 66 vale agora em
todas as fontes. Exemplos: contrato fora de b3.contratos(), produto sem contrato no CFTC, cadeia desconhecida no IMEA,
uf ou tipo fora do catálogo no inmet.estacoes, produto fora da planilha no DERAL, safra malformada na UNICA, ano em
texto na ABIOVE, produto desconhecido no Notícias Agrícolas, ano fora do intervalo no USDA, no Comtrade e na ANDA, filtros da
ANTAQ, tipo_veiculo da ANTT, evento com tipo="apolices" no seguro_rural, uf que não é texto, bbox fora do
intervalo, safra inválida no normalize e max_pages ≤ 0 nas semanas do progresso. O satélite das queimadas e a classe do
MapBiomas são conferidos depois do download, contra o que o arquivo publica. InvalidParameterError é subclasse de
ValueError: quem tratava df.empty depois de uma entrada do usuário passa a capturar a exceção. No normalize.municipio_para_ibge, nome de mais de um município sem uf levanta o mesmo erro do resolver_municipio, com os candidatos; a 1.1.0 devolvia o código do primeiro da lista.
Resposta fora do formato levanta ParseError, e não mais um vazio que parece "sem dado": contagem do ArcGIS sem count
(ANA e SFB), envelope do SICOR sem value, preços da CEASA sem resultset, página da ANEC sem a lista de artigos, lista vazia
do IMEA, catálogo do INMET que não é lista, alerta_info do MapBiomas Alerta sem o período, aba dos totais da CONAB sem
cabeçalho, baseline estrutural corrompido e consenso do CEPEA sem registros. Os vazios legítimos (count zero, value=[],
dia sem preço) seguem vazios. Campo pedido ausente numa camada ArcGIS (ANA e SFB) também levanta ParseError, com o nome do campo; antes, a coluna saía do resultado sem erro.
INMET sem observação. inmet.estacao e inmet.clima_uf sem nenhuma observação no período levantam
SourceUnavailableError, e não mais ParseError. Quem capturava ParseError para "sem dado" troca a classe.
Mensagens. "UF invalida" passa a "UF inválida: 'XX'. Valores válidos: AC, AL, …", e "after N retries" passa a "after N attempts". Quem casava o texto troca o termo.
Avisos novos, no UserWarning e em meta.validation_warnings: consulta SIDRA vazia (a cada chamada), ano de criação
ambíguo no CNFP do SFB, filtro de praça da ANTT sem resultado, linhas repetidas idênticas na ANP (removidas), ordem da
Embrapa sem correspondência numa leitura completa e data digitada errado na fonte (vira NaT). Quem trata aviso como erro
precisa acomodá-los.
91. Variáveis de ambiente¶
Muda calado. A página das variáveis de ambiente lista todas, com o padrão e os valores aceitos.
- Pasta do cache. Na 1.1.0, só
AGROBR_CACHE_CACHE_DIRvalia;AGROBR_CACHE_DIRera ignorada, e a variável vazia apontava a pasta corrente. Na 2.0,AGROBR_CACHE_DIRé o nome principal, e o antigo segue como alias; com as duas definidas e diferentes, vale a nova, comUserWarning; vazia, vale o padrão~/.agrobr/cache. Quem já tinhaAGROBR_CACHE_DIRdefinida com outra pasta passa a gravar o cache nela. Defina só uma; prefiraAGROBR_CACHE_DIR. - Cache desligado.
AGROBR_ANEC_CACHE_DISABLEDeAGROBR_ACERVO_FUNDIARIO_CACHE_DISABLEDaceitam1,true,yeseon(desligam) e0,false,no,offe vazio (mantêm), sem caixa. Na 1.1.0, só1desligava, etrueera ignorado. Outro valor (sim) levantaInvalidParameterError. AGROBR_HTTP_MAX_RETRIESconta o total de tentativas por pedido, como sempre contou: o padrão 3 faz até 3 pedidos.0passa a fazer 1 pedido, sem repetição (na 1.1.0, quebrava toda requisição), e negativo é recusado comValidationErrorao carregar as configurações.AGROBR_HTTP_MAX_CONCURRENT_<FONTE>menor que 1 é recusado comValidationError(na 1.1.0,0travava a chamada).AGROBR_HTTP_RATE_LIMIT_<FONTE>e orate_limit_*passado aoHTTPSettingsrecusam negativo,infenancomValidationError(na 1.1.0, eram aceitos);0segue permitido.
No código, o mesmo vale para retry_async e with_retry: max_attempts=0 faz 1 tentativa, e espera 0 é espera zero
(antes, os dois viravam os padrões); para o padrão, passe None ou omita. run_all_checks com concurrency menor que 1,
generate_report com formato fora de json, html e md, send_alert com level inválido, benchmark_* com
iterations menor que 1 e cache.get_policy com endpoint desconhecido levantam InvalidParameterError.
92. CLI: --formato em todos os comandos e snapshot use retirado¶
A referência da CLI traz todos os comandos e opções.
health,doctoresnapshot listusam--formato text|json(-o), como os comandos de dados usam--formato table|csv|json.health --output json,doctor --jsonesnapshot list --jsonsaem com código 2: troque por--formato json.snapshot usesai: o comando não ativava nada. O modo determinístico se configura no código, por processo (async with datasets.deterministic("AAAA-MM-DD")), e o snapshot se lê comsnapshots.load_from_snapshot(..., snapshot_name=...).- Muda calado:
ibge produtos --pesquisa PAMconsultava o LSPA (a caixa alta caía no padrão). Na 2.0,pamelspavalem sem diferenciar caixa, e outro nome sai com código 2. Quem usavaPAMpara obter o LSPA passa a--pesquisa lspa. - Ano inválido, pesquisa e fonte desconhecidas saem com código 2 antes da consulta; falha de coleta segue com código 1. Os
logs saem legíveis na saída de erro (
WARNING;INFOcom--verbose), e o JSON e o CSV ficam sozinhos na saída padrão. - Opções novas:
cepea indicador --praca,conab safras --levantamentoeconab balanco --safra/--levantamento. - Muda calado:
agrobr conab levantamentoslista todos os levantamentos, e não só os 10 primeiros, e o avisoListando levantamentos...sai na saída de erro. Para ler a lista num script, use--formato csvou--formato json.
93. CONAB: um caminho por função¶
Os subpacotes agrobr.conab.custo_producao e agrobr.conab.serie_historica saem; os nomes de mesmo nome em agrobr.conab
são as funções. import agrobr.conab.custo_producao e from agrobr.conab.serie_historica import produtos_disponiveis
levantam ModuleNotFoundError: use from agrobr.conab import custo_producao, serie_historica e
conab.produtos_serie_historica(), que lista os produtos, as categorias e as URLs da série sem requisição. O
agrobr.conab.ceasa fica com o __all__ vazio (from agrobr.conab.ceasa import * não exporta nada): use
conab.ceasa_precos, ceasa_produtos, ceasa_categorias e lista_ceasas.
94. Downloads pesados e cache¶
- Muda calado:
ibama.embargoseembargos_geoguardam o CSV (~208 MB) na pasta de cache por 1 hora. Dentro da hora, a mesma chamada devolve a coleta anterior, commeta.from_cache=Trueemeta.fetched_atna hora da coleta; chamadas simultâneas baixam uma vez só.use_cache=False, argumento novo, baixa de novo sem ler nem gravar o cache. acervo_fundiariocomuse_cache=FalseouAGROBR_ACERVO_FUNDIARIO_CACHE_DISABLEDnão grava mais nada no cache: o ZIP (até 766 MB por UF) vai para uma pasta temporária, apagada no fim da consulta. Na 1.1.0, a opção só pulava a leitura.b3.historicobaixa no máximoAGROBR_HTTP_MAX_CONCURRENT_B3dias ao mesmo tempo (padrão 3), em vez de um download por dia útil de uma vez. Período longo fica mais lento no pico; suba a variável para mais paralelismo.validators.save_baseline,load_baselineevalidate_against_baselinegravam e leem emstructuresdentro da pasta do cache, e não mais em.structuresno diretório corrente. Para o caminho antigo, passebaselines_dir=".structures".
95. Retornos como cópia¶
Muda calado. datasets.get_dataset, contracts.get_contract, datasets.list_products e datasets.info,
normalize.ibge_para_municipio, buscar_municipios, coordenada_para_municipio e listar_ufs,
health.get_affected_datasets e os artigos da ANEC devolvem cópias. Alterar o objeto devolvido deixa de mudar o catálogo
ou a chamada seguinte. Quem usava a mutação como configuração global passa a usar a instância devolvida: por exemplo,
get_dataset(nome) e o fetch dela.
No utils.parse_links_from_html com base_url, um href relativo sem barra ("arquivo.pdf") passa a sair como URL absoluta;
antes, saía como estava.
96. O que é API pública¶
A 2.0 declara o que segue o versionamento semântico: as funções das fontes, datasets, contracts, as exceções, o MetaInfo,
o normalize, o agrobr.sync e os comandos da CLI. A lista nominal está na página da API pública. O resto
(cache, http, utils, health, alerts, benchmark, validators, constants e os subpacotes internos de cada fonte)
é interno, salvo os poucos nomes que a doc ensina e a página lista, e pode mudar numa versão menor. Declarar a API pública não move nenhum import; as remoções e renomeações da 2.0 estão nas seções 9, 50, 93 e 98 e na tabela de constantes. Quem usa um nome interno deve fixar a versão do agrobr.
97. Outras mudanças por fonte¶
datasets.clima:agregacaopassa aNone. No modo UF,Nonee"mensal"devolvem meses, e"diario"levantaInvalidParameterError(na 1.1.0, era o padrão, aceito e ignorado: a saída já era mensal); para dados diários, use o modo estação. No modo UF semfonte, ano anterior a 2000 vai direto à NASA POWER, efonte="inmet"com esse ano levantaInvalidParameterError.zarc.zoneamento(cultura=...)levantaInvalidParameterError: Argumentos desconhecidos: ['cultura']: useproduto=.imea.cotacoesaceita a safra como"2024/25"e"2024/2025", além de"24/25";unica.producao_historica, como"2018/19"e"18/19", além de"2018/2019".deral.condicao_lavourasaceita os sinônimos de produto do agrobr, edatasets.condicao_lavourasaceita"milho"e"feijao"(as duas safras) e declaraas_polars.unica.safra_resumo(periodo=...)confere o período contra a edição lida. Quando a edição publica sóacumuladoemensal,periodo="quinzena"levantaInvalidParameterErrorcom os períodos da edição; a 1.1.0 devolvia o quadro rotuladoquinzena. O resultado ganha as colunasdata_inicioedata_fim, entreperiodoevalor: leia as colunas pelo nome.conab.ceasa_categorias()ganhaOVOS(os ovos, antes emHORTALICAS), eCOCO VERDEpassa deHORTALICASaFRUTAS.datasets.preco_diariodeclaraas_polars.- ANP: linhas semanais idênticas são removidas, com aviso e a quantidade em
meta.validation_warnings; valores conflitantes seguem levantandoParseError. - ANP,
vendas_diesel: muda calado.produtousa o rótulo deprecos_diesel(DIESEL S-10saiDIESEL S10), e o join por produto entre vendas e preços casa; os outros combustíveis (DIESEL S-500,DIESEL S-1800,DIESEL MARÍTIMO,DIESEL (OUTROS )) seguem como publicados.regiaosai com o nome canônico:REGIÃO CENTRO-OESTEviraCentro-Oeste(idemNorte,Nordeste,SudesteeSul). Quem filtrava pelo texto publicado troca o valor; os volumes não mudam.vendas_diesel(uf=...)passa a filtrar a UF; na 1.1.0, devolvia o Brasil inteiro, e a colunaufvinha vazia em todas as linhas. - ANP,
precos_diesel: período que começa depois de hoje levantaInvalidParameterErrorantes da rede, em todos os níveis (na 1.1.0, vazio sem aviso na UF e no Brasil); no município, limite fora de 2022 até o ano corrente também. Ano dentro do intervalo cujo arquivo a ANP ainda não publicou segueSourceUnavailableError. A saída ganhaperiodo_inicio,periodo_fim,nivel,unidade,agregacao,n_semanasen_postos_mediae muda a ordem das colunas. No mensal,n_postossai nulo, e a média de postos das semanas do mês, que a 1.1.0 punha emn_postos, vai paran_postos_media. - ANP,
precos_diesel: muda calado com pandas 3. Na 1.1.0 com pandas 3,datatrocava dia e mês quando o dia era até 12: a semana de 01/09/2024 saía como 09/01/2024, e a de 07/01/2024 como 01/07/2024. Por isso,inicioefimperdiam semanas do período e traziam semanas de outros meses (MT, S10, 1º semestre de 2024: 154 linhas em vez de 171), e a média mensal herdava o erro, inclusive com meses que ainda não chegaram. Com pandas 2, a 1.1.0 já saía certa. Na 2.0, adatasemanal é a data inicial publicada pela ANP, em todos os níveis, eperiodo_inicioeperiodo_fimdão o primeiro e o último dia da semana. - Embrapa Solos:
mapa_solosemapa_solos_geocasamordemcom a classe inteira deordem1(uma das 15 publicadas), aceitando caixa, acento e singular ("latossolo"). Um trecho do nome ("latos") deixa de casar e levantaInvalidParameterErrorcom a lista das classes: troque pelo nome da classe ("latossolos"). - ANTT:
rodoviacompara sem caixa, espaço, hífen e zero à esquerda ("BR 40","br-040");tipo_veiculoetipo_cobranca, sem caixa e acento. - RNC e cultivares: os filtros de texto ignoram caixa e acento (
especie="feijao"acha"Feijão").rnc.protegidasacrescentatermino_protecao_texto; nas 2 funções,nome_cientificoenome_comumsaem com os espaços repetidos colapsados, e a junção pelo texto antigo pode não casar. - Queimadas:
satelitesem diferenciar caixa, ebiomasem diferenciar caixa e acento. Na 1.1.0,bioma="Amazonia"não filtrava e devolvia todos os biomas da UF (MT, mar/2025: 2.047 focos, contra 1.185 na 2.0). Pedaço do nome (bioma="amaz"), que a 1.1.0 aceitava, levantaInvalidParameterError. O-999publicado emrisco_fogo,numero_dias_sem_chuvaeprecipitacaosai nulo. - Rio Verde: muda calado.
ensaio_sojalê as colunas na posição publicada; na 1.1.0,empresasaía com a sigla colada ("Brasmax BRMX"),cultivarsem o prefixo egrupo_maturacaocom a tecnologia ("IPRO"); na 2.0,"Brasmax","BRMX Guepardo IPRO"e"6.7", eciclo_diassai emInt64. A safra 2025/2026 traz 107 linhas (eram 105), esafras_disponiveis()lista também 2023/2024. - Anos padrão e limites de ano seguem o calendário de Brasília, e não o relógio da máquina, no SGS, na PTAX, nas queimadas, no PRODES, no USDA, no Comtrade, na ComexStat, na ANEC, na ANTT e na ANP. Num servidor em UTC, das 21h às 24h de 31/12, o ano seguinte deixa de ser aceito.
defensivos: o formato do cache sobe para 2; a primeira consulta baixa de novo.- SICAR,
resumo(uf)sem município: a contagem é de feições publicadas, e versões do mesmocod_imovelcontam separado; oMetaInfotrazsource_details["sicar"]["unidade"] = "feicoes_publicadas"e um aviso emvalidation_warnings. Para contar imóveis, use o resumo por município. - SFB, IFN:
sfb.ifn_conglomeradose o_geoleem as camadas ativas do IFN (o serviçoConglomeradosaiu do ar e as duas funções falhavam);lotevem pela junção com o cadastro de lotes emco_lote(código órfão ou duplicado levantaParseError), e entra a colunaciclo(texto anulável, schema IFN 1.1): ajuste seleção por posição. O filtro debiomadeixa de voltar vazio por diferença de caixa. A proveniência por página está na página da fonte.
98. B3: oi_historico passa a se chamar posicoes_abertas_historico¶
b3.oi_historico, da 1.1.0, passa a se chamar b3.posicoes_abertas_historico, também em sync.b3. As opções não mudam;
só sai o **kwargs (seção 78), e o nome antigo deixa de existir (AttributeError):
O dataset ganha a mesma consulta em datasets.futuros_agricolas(..., tipo="oi_historico"), valor de tipo novo na 2.0
(a 1.1.0 aceitava só ajustes, historico e posicoes). Colunas, unidades e a política para dia sem arquivo são as da fonte.
99. CFTC: recorte sem relatório devolve vazio tipado¶
cftc.cot com um recorte sem relatório devolve o DataFrame vazio, com as colunas e os tipos do preenchido, e não mais
SourceUnavailableError. Quem usava a exceção para detectar "sem observação" passa a conferir df.empty (is_empty() no
Polars); falha de transporte segue SourceUnavailableError, e resposta fora do formato, ParseError. As 18 contagens e
variações saem em Int64, no vazio e no cheio (na 1.1.0, as 13 contagens saíam em int64 e as 3 variações já em Int64; swap_spread e other_spread são novas). Acima de 50.000 registros, a consulta avisa que a completude
não foi comprovada (UserWarning e meta.validation_warnings): reduza o período.