Configuração e certificado A1
Use Configuracao para fixar a identidade da aplicação, a UF, o modelo e o ambiente. Os exemplos desta documentação usam apenas identificadores zerados e HOMOLOGAÇÃO. Identificadores sintéticos não passam por validação fiscal e não devem ser enviados a um serviço remoto.
from acbr import Configuracao
config = Configuracao(
cnpj="00000000000000", # Placeholder sintético; nunca transmitir.
uf="CE",
modelo=55,
ambiente=2, # HOMOLOGAÇÃO.
)Campos e validação
| Campo | Tipo / padrão | Verificação Python |
|---|---|---|
cnpj | str, obrigatório | Exatamente 14 dígitos; não verifica dígitos verificadores, cadastro ou autorização |
uf | str, obrigatório | Sigla maiúscula de uma UF brasileira |
modelo | int, padrão 55 | 55 (NF-e) ou 65 (NFC-e); booleano é rejeitado |
ambiente | int, padrão 2 | 1 ou 2; mantenha 2 nos testes |
certificado | CertificadoA1 | None | Exigido por assinar e por todas as operações de rede |
csc | Csc | None | Objeto opcional para configurações NFC-e |
A configuração é uma dataclass imutável. Ela não corrige o documento de entrada: mantenha Ide.modelo, Ide.tpAmb, emitente e demais campos coerentes com a configuração. Para HOMOLOGAÇÃO, o enum do documento é "taHomologacao", enquanto Configuracao.ambiente recebe o inteiro 2.
A1 sem segredo no código
Geração local e ajuda não exigem A1. Para uma integração que realmente precise dele, mantenha o arquivo em armazenamento protegido e entregue a senha por seu mecanismo de segredos. O exemplo completo a1_config.py lê ACBR_PFX_PATH e ACBR_PFX_PASSWORD em tempo de execução, sem imprimir conteúdo ou realizar operação fiscal.
import os
from pathlib import Path
from acbr import CertificadoA1, Configuracao
certificado = CertificadoA1(
pfx=Path(os.environ["ACBR_PFX_PATH"]).read_bytes(),
senha=os.environ["ACBR_PFX_PASSWORD"],
)
config = Configuracao(
cnpj="00000000000000", uf="CE", modelo=55, ambiente=2,
certificado=certificado,
)Não coloque PFX, senha, CSC, XML ou arquivos .env com valores em Git. Restrinja o acesso ao arquivo e ao processo que o lê. Variáveis de ambiente não são um cofre: prefira injeção controlada no processo e evite exportações globais em hosts compartilhados. Não copie um segredo para um comando de shell, URL ou argumento de programa.
CertificadoA1 aceita bytes não vazios até 2 MiB e senha do tipo str. A construção não abre o PKCS#12, não verifica validade, cadeia, titularidade ou correspondência com o CNPJ. Uma senha vazia é estruturalmente aceita; use a política adequada ao seu certificado e armazenamento. Materiais sintéticos de teste não são certificados funcionais.
O certificado é serializado em base64 no stdin do worker; não é passado pela linha de comando. Base64 não é criptografia. O processo precisa acessar os bytes em memória, e o Python não oferece garantia de apagar todas as cópias de um segredo da memória.
CSC e NFC-e
from acbr import Csc
csc = Csc(id="1", valor="CSC-SINTETICO-SEM-VALOR")id aceita de 1 a 6 dígitos em texto; valor aceita texto não vazio de até 256 caracteres. O limite Python conta caracteres; o worker aplica limite em bytes UTF-8. Prefira valor ASCII e respeite o teto efetivo de 256 bytes do worker. A estrutura não comprova que o CSC está ativo. O modelo 65 é aceito pela configuração, mas isso não significa que emissão NFC-e tenha sido homologada neste cliente.
Logs seguros
repr de configuração, A1 e CSC oculta os campos marcados como sensíveis. Entretanto, config.to_wire() contém CNPJ, PFX base64, senha e CSC: ele é destinado ao protocolo e não deve ser registrado. Use resultado.to_dict() ou erro.diagnostico.to_dict() como base para logs resumidos. Reavalie dados adicionais antes de incluí-los em observabilidade.
Continue em API pública e recuperação experimental.