SDK oficial em Python para a API Brasil NFe. Emissão, cancelamento, consulta e gestão de documentos fiscais eletrônicos brasileiros (NF-e, NFC-e, NFS-e, CT-e, MDF-e, DC-e, NF3-e), geração de SPED / SINTEGRA / FCI, e gestão de empresas e certificados digitais — em uma única biblioteca idiomática, tipada e testada.
Paridade 100% com os SDKs oficiais em C#, PHP e Node.
- Instalação
- Quickstart
- Autenticação
- Arquitetura
- Recursos
- Exemplos por recurso
- Tratamento de erros
- Utilitários
- Configuração avançada
- Desenvolvimento
- Tabelas de referência
- Suporte
pip install brasilnfeRequisitos:
- Python 3.8+
requests(instalado automaticamente)
from brasilnfe import BrasilNFe, StatusSefazEnvio
client = BrasilNFe(token="SEU_TOKEN_AQUI")
resp = client.consultas.status_sefaz(
StatusSefazEnvio(modelo_documento=55, tipo_ambiente=2)
)
print(resp.status_sefaz.ds_status_resposta_sefaz) # "Serviço em operação"Parâmetros do cliente:
| Parâmetro | Tipo | Obrigatório | Default |
|---|---|---|---|
token |
str |
sim | — |
user_token |
str |
não | "" (necessário para o recurso empresa) |
url |
str |
não | "https://api.brasilnfe.com.br/services/" |
timeout |
int (segundos) |
não | 300 |
session |
requests.Session |
não | sessão padrão (permita configurar retries/proxy) |
O SDK usa dois tokens enviados nos headers HTTP:
Token— obrigatório, identifica a empresa.UserToken— opcional, identifica o usuário (necessário só para o recursoempresa).
# Só emissão/consulta:
client = BrasilNFe(token="TOKEN_EMPRESA")
# Com gestão de empresas:
client = BrasilNFe(token="TOKEN_EMPRESA", user_token="TOKEN_USUARIO")Os tokens são obtidos no portal https://www.brasilnfe.com.br.
O SDK segue a mesma estrutura dos SDKs C# (principal), PHP e Node:
BrasilNFe ← fachada principal
├── .nota_fiscal (NotaFiscal) ← emitir NF-e, NFC-e, NFS-e, CT-e, MDF-e, DC-e, NF3-e
├── .eventos (Eventos) ← cancelar, CC-e, inutilizar, manifestar, encerrar MDF-e
├── .consultas (Consultas) ← status SEFAZ, busca, cadastro, cálculo de impostos
├── .arquivos (Arquivos) ← SPED, SINTEGRA, FCI, XML, DANFE
└── .empresa (Empresa) ← cadastro de empresas e certificados A1
Todos os modelos são @dataclass tipados com snake_case (PEP 8). O
serializer interno converte automaticamente para o formato da API
(PascalCase/camelCase) e vice-versa, sem nenhuma configuração adicional.
| Categoria | Método | Recurso |
|---|---|---|
| Emissão | enviar_nota_fiscal |
nota_fiscal |
enviar_nota_fiscal_lote |
nota_fiscal |
|
enviar_nota_fiscal_servico (NFS-e) |
nota_fiscal |
|
enviar_nota_fiscal_complementar |
nota_fiscal |
|
enviar_manifesto_transporte (MDF-e) |
nota_fiscal |
|
enviar_conhecimento_transporte (CT-e) |
nota_fiscal |
|
enviar_declaracao_conteudo (DC-e) |
nota_fiscal |
|
enviar_nf_enercom (NF3-e/NFCom) |
nota_fiscal |
|
| Eventos | cancelar_nota_fiscal |
eventos |
enviar_carta_correcao |
eventos |
|
inutilizar_numeracao |
eventos |
|
manifestar_nota_fiscal |
eventos |
|
encerrar_manifesto_transporte |
eventos |
|
| Consultas | status_sefaz |
consultas |
calcular_impostos |
consultas |
|
pre_visualizar_nota_fiscal |
consultas |
|
buscar_nota_fiscal |
consultas |
|
buscar_nota_fiscal_servico |
consultas |
|
consultar_cadastro_sefaz |
consultas |
|
buscar_arquivo_sped |
consultas |
|
| Arquivos | obter_arquivo_sintegra |
arquivos |
obter_arquivo_fci |
arquivos |
|
obter_arq_enercom |
arquivos |
|
obter_arquivo_sped |
arquivos |
|
obter_arquivo_sped_unificado |
arquivos |
|
recriar_arquivo_sped |
arquivos |
|
pegar_arquivo (XML/DANFE → bytes) |
arquivos |
|
pegar_arquivo_evento (→ bytes) |
arquivos |
|
obter_arquivos_por_range |
arquivos |
|
| Empresa | alterar_certificado |
empresa |
verificar_certificado |
empresa |
|
adicionar_empresa |
empresa |
|
editar_empresa |
empresa |
|
buscar_empresa |
empresa |
|
buscar_todas_empresas |
empresa |
Total: 36 métodos públicos (paridade com C#/PHP/Node).
from datetime import datetime
from brasilnfe import (
BrasilNFe, Cliente, Contato, Endereco, Imposto, Icms, Pis, Cofins,
NotaFiscalEnvio, Pagamento, Produto,
)
client = BrasilNFe(token="SEU_TOKEN")
nf = NotaFiscalEnvio(
modelo_documento=55,
tipo_ambiente=2, # 2 = Homologação
finalidade=1, # 1 = Normal
natureza_operacao="VENDA DE MERCADORIA",
data_emissao=datetime.now(),
indicador_presenca=1,
consumidor_final=True,
cliente=Cliente(
cpf_cnpj="11144477735",
nm_cliente="Cliente Teste",
indicador_ie=9, # 9 = Não contribuinte
endereco=Endereco(
cep="01310100",
logradouro="Avenida Paulista",
numero="1000",
bairro="Bela Vista",
cod_municipio="3550308",
municipio="São Paulo",
uf="SP",
cod_pais=1058,
pais="Brasil",
),
contato=Contato(email="cliente@example.com"),
),
produtos=[
Produto(
nm_produto="Notebook XPS 13",
cod_produto_servico="NB-001",
ean="SEM GTIN",
ncm="84713012",
cfop=5102,
unidade_comercial="UN",
quantidade=1,
valor_unitario=5500.00,
valor_total=5500.00,
origem_produto=0,
imposto=Imposto(
icms=Icms(cod_situacao_tributaria="102"),
pis=Pis(cod_situacao_tributaria="49"),
cofins=Cofins(cod_situacao_tributaria="49"),
),
),
],
pagamentos=[
Pagamento(indicador_pagamento=0, forma_pagamento="01", vl_pago=5500.00),
],
)
resp = client.nota_fiscal.enviar_nota_fiscal(nf, crt=1) # 1 = Simples Nacional
if resp.ok and resp.return_nf.ok:
print(f"Chave: {resp.return_nf.chave_nf}")
print(f"Status: {resp.return_nf.ds_status_resposta_sefaz}")
# XML e DANFE em base64: resp.base64_xml, resp.base64_file
else:
print(f"Rejeitada: {resp.error or resp.return_nf.ds_status_resposta_sefaz}")Mesmo NotaFiscalEnvio, trocando modelo_documento=65 e acrescentando
indicador_presenca=1 (presencial) + um Pagamento válido.
from brasilnfe import (
BrasilNFe, NotaFiscalServicoEnvio, NFSInfo, Tomador, Servico, Valores,
)
client = BrasilNFe(token="SEU_TOKEN")
nfse = NotaFiscalServicoEnvio(
tipo_ambiente=2,
nfs_info=[
NFSInfo(
tomador=Tomador(nome="Contratante LTDA", cpf_cnpj="12345678000199"),
servico=Servico(
descricao="Consultoria em TI",
item_lista_servico="01.01",
valores=Valores(valor_servico=1500.00, aliquota=5.0),
),
)
],
)
resp = client.nota_fiscal.enviar_nota_fiscal_servico(nfse)from brasilnfe import CTeEnvio, DCeEnvio, ManifestoTransporteEnvio
client.nota_fiscal.enviar_conhecimento_transporte(CTeEnvio(...))
client.nota_fiscal.enviar_manifesto_transporte(ManifestoTransporteEnvio(...))
client.nota_fiscal.enviar_declaracao_conteudo(DCeEnvio(...))from brasilnfe import BrasilNFe, CancelarNotaFiscalEnvio
client = BrasilNFe(token="SEU_TOKEN")
resp = client.eventos.cancelar_nota_fiscal(
CancelarNotaFiscalEnvio(
chave_nf="35250312345678901234567890123456789012345678",
justificativa="Erro de digitação na quantidade.",
tipo_documento=0, # 0 = NF/NFC/CT/MDF/DC, 1 = NFS-e
tipo_ambiente=2,
)
)
# resp.status: 1=Processado, 2=Aguardando, 3=Errofrom brasilnfe import CartaCorrecaoEnvio
client.eventos.enviar_carta_correcao(
CartaCorrecaoEnvio(
chave_nf="3525...",
correcao="Correção do endereço do destinatário.",
numero_sequencial=1,
tipo_ambiente=2,
)
)from brasilnfe import (
InutilizarNumeracaoEnvio, ManifestarNotaFiscalEnvio,
EncerrarManifestoTransporteEnvio,
)
client.eventos.inutilizar_numeracao(
InutilizarNumeracaoEnvio(
modelo_documento=55, serie=1,
numero_inicial=100, numero_final=105,
justificativa="Salto de numeração no sistema interno.",
tipo_ambiente=2, ano=2025,
)
)
client.eventos.manifestar_nota_fiscal(
ManifestarNotaFiscalEnvio(
chave="3525...",
tipo_manifestacao=1, # 1=Confirmação, 2=Ciência, 3=Desconhece, 4=Não realizada
)
)
client.eventos.encerrar_manifesto_transporte(
EncerrarManifestoTransporteEnvio(chave_mdfe="5825...", uf_encerramento="SP")
)from brasilnfe import (
StatusSefazEnvio, BuscarNotaFiscalEnvio, ConsultarCadastroEnvio,
PreVisualizarNotaFiscalEnvio, Produto,
)
from datetime import datetime
# Status SEFAZ
client.consultas.status_sefaz(StatusSefazEnvio(modelo_documento=55, tipo_ambiente=1))
# Buscar NF-e/NFC-e/CT-e emitidas no período (0=entrada, 1=saída)
client.consultas.buscar_nota_fiscal(BuscarNotaFiscalEnvio(
tipo_documento_fiscal=1,
dt_inicio=datetime(2025, 3, 1),
dt_fim=datetime(2025, 3, 31),
))
# Consultar cadastro
client.consultas.consultar_cadastro_sefaz(
ConsultarCadastroEnvio(cpf_cnpj_ie="12345678000199", uf="SP")
)
# Calcular impostos (sem emitir)
client.consultas.calcular_impostos(produtos=[Produto(...)])
# Pré-visualizar DANFE
client.consultas.pre_visualizar_nota_fiscal(PreVisualizarNotaFiscalEnvio(...))
# Buscar SPED já gerado
client.consultas.buscar_arquivo_sped(codigo="ABC123")from pathlib import Path
from brasilnfe import PegarArquivoEnvio, SpedEnvio, SintegraEnvio
# Baixar DANFE em PDF
pdf = client.arquivos.pegar_arquivo(
PegarArquivoEnvio(chaves=["3525..."], file_type=2, tipo_documento_fiscal=1)
)
Path("danfe.pdf").write_bytes(pdf)
# Baixar XML
xml = client.arquivos.pegar_arquivo(
PegarArquivoEnvio(chaves=["3525..."], file_type=1, tipo_documento_fiscal=1)
)
# Gerar SPED Fiscal
from datetime import datetime
client.arquivos.obter_arquivo_sped(SpedEnvio(
crt=3, dt_inicio=datetime(2025,3,1), dt_fim=datetime(2025,3,31),
))
# SPED unificado, SINTEGRA, FCI, recriar SPED, range por período
# — mesmos padrões (ver exemplos na pasta examples/).Requer
user_tokenna inicialização.
from brasilnfe import BrasilNFe, CertificadoEnvio, EmpresaEnvio, Endereco
import base64
client = BrasilNFe(token="TOKEN_EMPRESA", user_token="TOKEN_USUARIO")
# Cadastrar empresa
client.empresa.adicionar_empresa(EmpresaEnvio(
cnpj="12345678000199",
rz_social="ACME LTDA",
nm_fantasia="ACME",
ie="1234567890",
crt=3,
endereco=Endereco(cep="01310100", uf="SP", municipio="São Paulo"),
))
# Listar empresas
empresas = client.empresa.buscar_todas_empresas()
# Alterar certificado A1 (.pfx em base64)
pfx = base64.b64encode(open("cert.pfx", "rb").read()).decode()
client.empresa.alterar_certificado(
CertificadoEnvio(base64_certificate_file=pfx, senha="senha-do-pfx")
)
# Verificar certificado
info = client.empresa.verificar_certificado(
CertificadoEnvio(base64_certificate_file=pfx, senha="senha-do-pfx")
)
print(info.cn, info.validade)O SDK diferencia três camadas de erro:
from brasilnfe import (
BrasilNFeError, BrasilNFeRequestError, BrasilNFeResponseError,
BrasilNFeSerializationError, BrasilNFeAuthenticationError,
)
try:
resp = client.nota_fiscal.enviar_nota_fiscal(nf)
except BrasilNFeRequestError as e:
# Falha de rede / timeout / erro HTTP de transporte
print("erro de rede:", e, "original:", e.original)
except BrasilNFeResponseError as e:
# Resposta HTTP fora da faixa 2xx
print("status:", e.status_code, "body:", e.body)
except BrasilNFeSerializationError as e:
# JSON inválido, base64 inválido, etc
print("serialização:", e)
else:
# Rejeições da SEFAZ não lançam exceção — verificar resp.error/resp.return_nf
if not resp.ok:
print("rejeitada:", resp.error, resp.avisos)Hierarquia:
BrasilNFeError
├── BrasilNFeRequestError (rede / timeout)
├── BrasilNFeResponseError (HTTP ≠ 2xx)
├── BrasilNFeSerializationError (JSON / base64)
├── BrasilNFeAuthenticationError (tokens ausentes)
└── BrasilNFeValidationError (validação pré-envio)
Todos os modelos expõem .to_dict() / .from_dict(data):
from brasilnfe import NotaFiscalEnvio
nf = NotaFiscalEnvio(modelo_documento=55, tipo_ambiente=2)
payload = nf.to_dict() # dict pronto para JSON
nf2 = NotaFiscalEnvio.from_dict(payload)from dataclasses import dataclass
from brasilnfe import BrasilNFeHelper, TipoRateio
@dataclass
class Item:
valor_total: float
valor_frete: float = 0.0
itens = [Item(300.0), Item(200.0), Item(500.0)]
BrasilNFeHelper.ratear(
itens,
valor_total=50.0,
seletor=lambda i: i.valor_frete,
seletor_proporcao=lambda i: i.valor_total,
tipo_rateio=TipoRateio.SUBSTITUIR,
atualizar_item=lambda i, v: setattr(i, "valor_frete", v),
)
# Arredondamento correto: soma bate exatamente em 50.00client = BrasilNFe(token="...", timeout=600) # 10 minutosimport requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
session.mount("https://", HTTPAdapter(
max_retries=Retry(total=3, backoff_factor=1, status_forcelist=[502, 503, 504])
))
client = BrasilNFe(token="...", session=session)client = BrasilNFe(token="...", url="https://sandbox.brasilnfe.com.br/services/")git clone https://github.com/BrasilNFe/brasilnfe-python-sdk.git
cd brasilnfe-python-sdk
pip install -e ".[dev]"
pytest -vLint / type check:
ruff check brasilnfe tests
mypy brasilnfe| Modelo | Documento |
|---|---|
| 55 | NF-e (Nota Fiscal Eletrônica) |
| 57 | CT-e (Conhecimento de Transporte Eletrônico) |
| 58 | MDF-e (Manifesto de Documentos Fiscais) |
| 65 | NFC-e (Nota Fiscal de Consumidor) |
| 66 | NF3-e / NFCom |
| Código | Ambiente |
|---|---|
| 1 | Produção (efeito fiscal real) |
| 2 | Homologação (testes na SEFAZ) |
| Código | Regime |
|---|---|
| 1 | Simples Nacional |
| 2 | Simples Nacional c/ Sublimite |
| 3 | Regime Normal |
| 4 | MEI |
| Código | Finalidade |
|---|---|
| 1 | Normal |
| 2 | Complementar |
| 3 | Ajuste |
| 4 | Devolução |
| Código | Significado |
|---|---|
| 1 | Evento processado |
| 2 | Aguardando processamento |
| 3 | Ocorreu um erro |
| Header | Valor |
|---|---|
Token |
token da empresa |
UserToken |
token do usuário |
Package-Version |
1.1.0 |
Package-Type |
python |
User-Agent |
brasilnfe-python-sdk/... |
- Portal: https://www.brasilnfe.com.br
- Documentação da API: https://www.brasilnfe.com.br/docs
- Issues: https://github.com/BrasilNFe/brasilnfe-python-sdk/issues
- E-mail: contato@brasilnfe.com.br
SDKs em outras linguagens:
- C# (principal): https://github.com/BrasilNFe/brasil-nfe
- PHP: https://github.com/BrasilNFe/brasilnfe-php-sdk
- Node/TypeScript: https://github.com/BrasilNFe/brasilnfe-node-sdk
MIT © Brasil NFe LTDA