Contrato, campos e tipos
A entrada segue o contrato ACBr TNFe, fixado na revisão 48590. Os nomes preservam maiúsculas e minúsculas; Ide, Emit, Det, Prod e pag não são nomes intercambiáveis. Consulte a ajuda antes de montar um documento.
Ajuda offline
Na a5 publicada, describe mostra texto em português, enquanto describe --json, ajuda e describe_field consultam os mesmos metadados em JSON. describe_type consulta estritamente um nome de tipo. Veja o guia de ajuda de campos e tipos para o exemplo Ide.tpNF / TTipoNFe, valores de enums e compatibilidade com a a3.
python -m acbr ajuda
python -m acbr ajuda Ide.tpNF
python -m acbr ajuda TTipoNFe
python -m acbr ajuda Ide.cUF
python -m acbr ajuda 'Det[].Prod.vProd'
python -m acbr ajuda TProdSem argumento, a ajuda descreve TNFe. Aceita nome exato de tipo (TProd) ou caminho a partir da raiz (Ide.cUF ou TNFe.Ide.cUF). Use [] ou índice para atravessar uma coleção; Det[0].Prod.vProd é normalizado para TNFe.Det[].Prod.vProd.
from acbr import describe_field
campo = describe_field("Det[].Prod.vProd")
assert campo["kind"] == "decimal"
assert campo["inputType"] == "string"
print(campo["path"], campo.get("constraints", {}))A resposta inclui a versão do SDK, origem e hash do contrato, caminho, tipo Pascal e tipo de entrada. Conforme o campo, traz values para enums, members para objetos, itemType para listas, readonly, constraints e declaredDefault. Um default declarado na ajuda não significa que o Python o insira no documento. Ide.tpNF permite tnEntrada e tnSaida, com padrão declarado tnSaida; consultar somente o tipo TTipoNFe não apresenta esse padrão de campo.
Regras estruturais
| Entrada | Forma correta | Cuidados |
|---|---|---|
| Inteiro | 23, 55 | True, 23.0 e "23" não substituem um inteiro |
| Decimal | "10.00" | Use ponto; respeite scale; float, vírgula e notação científica são rejeitados |
| Enum | "taHomologacao" | Use o nome textual exato informado por values |
| Data/hora civil | "2026-10-17T12:00:00" | Sem Z ou offset; também aceita data AAAA-MM-DD e frações até milissegundos |
| Lista | [{"Prod": {...}}] | Use lista real, incluindo em Det e pag |
| Objeto | {"modelo": 55} | Campos desconhecidos e somente leitura são rejeitados |
| Campo ausente | Omita a chave | None não significa ausência; não há defaults fiscais inseridos pelo Python |
Decimais aceitam até 64 caracteres e a escala do campo quando declarada. O validador limita a profundidade a 128 níveis. Campos de texto e a existência de objetos não comprovam conteúdo fiscal válido.
Documento e validate_document
from acbr import Documento, validate_document
dados = {"Ide": {"modelo": 55, "tpAmb": "taHomologacao"}}
snapshot = validate_document(dados) # Cópia JSON compatível validada.
documento = Documento(snapshot) # Snapshot imutável da entrada.
copia = documento.to_wire() # Nova cópia mutável para integração.
copia["Ide"]["modelo"] = 65
assert documento.to_wire()["Ide"]["modelo"] == 55Todos os campos são opcionais na validação estrutural. Por isso Documento({}) é aceito pelo contrato, embora não represente uma nota utilizável. O runtime continua responsável pela geração e pelo schema; regras fiscais, cadastros e autorização não são inferidos por essa validação.
Documento oculta os dados no repr, mas to_wire() devolve o conteúdo. Não o inclua em logs. Um erro informa o código e, quando disponível, o caminho do campo, sem reproduzir o valor recebido.
Tipos para o editor
from acbr.models import TNFe
from acbr import Documento
entrada: TNFe = {"Ide": {"modelo": 55, "tpAmb": "taHomologacao"}}
documento = Documento(entrada)Os TypedDict e aliases em acbr.models são gerados a partir do contrato. Eles ajudam o editor e o verificador estático; Python não aplica anotações automaticamente em tempo de execução. Documento/validate_document realizam a checagem real. Não edite os modelos para incluir um campo desconhecido; uma atualização exige novo contrato e runtime compatível.
No checkout do SDK, python tools/generate_models.py --check detecta divergência na geração. A biblioteca também autentica o arquivo do contrato e seu hash canônico. CONTRATO_INVALIDO exige reinstalar a fonte íntegra, não alterar os hashes.
Veja erros de contrato e exemplos completos.