Brasil NFe — SDK Python
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.
Sumário
- 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
Instalação
pip install brasilnfe
Requisitos:
- Python 3.8+
requests(instalado automaticamente)
Quickstart
from brasilnfe import BrasilNFe, StatusSefazEnvio
client = BrasilNFe(token="SEU_TOKEN_AQUI")
resp = client.consultas.status_sefaz(
StatusSefazEnvio(modelo_documento=55)
)
print(resp.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) |
Autenticação
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.
Arquitetura
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.
Recursos
Tabela de features
| 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 |
|
enviar_econf (Conciliação Financeira) |
eventos |
|
enviar_evento (Reforma Tributária) |
eventos |
|
| Consultas | status_sefaz |
consultas |
calcular_impostos |
consultas |
|
pre_visualizar_nota_fiscal |
consultas |
|
buscar_nota_fiscal_servico |
consultas |
|
buscar_nota_fiscal |
consultas |
|
consultar_cadastro_sefaz |
consultas |
|
buscar_arquivo_sped |
consultas |
|
consultar_lote_nfe |
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 |
|
deletar_empresa |
empresa |
|
buscar_empresa |
empresa |
|
buscar_todas_empresas |
empresa |
|
gerar_link_ativacao (→ URL string) |
empresa |
|
consultar_numeracao |
empresa |
|
atualizar_numeracao |
empresa |
|
ativar_assinatura |
empresa |
|
cancelar_assinatura |
empresa |
|
consultar_servicos |
empresa |
|
consultar_faturas |
empresa |
Total: 46 métodos públicos (paridade com C#/PHP/Node).
Exemplos por recurso
Nota Fiscal (emissão)
NF-e (modelo 55)
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)
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}")
NFC-e (modelo 65)
Mesmo NotaFiscalEnvio, trocando modelo_documento=65 e acrescentando
indicador_presenca=1 (presencial) + um Pagamento válido.
NFS-e (serviço)
from brasilnfe import (
BrasilNFe, NotaFiscalServicoEnvio, NFSInfo, Tomador, Contato, Servico, Valores,
)
client = BrasilNFe(token="SEU_TOKEN")
nfse = NotaFiscalServicoEnvio(
tipo_ambiente=2,
nfs_info=[
NFSInfo(
tomador=Tomador(
nm_tomador="Contratante LTDA",
cpf_cnpj="12345678000199",
contato=Contato(email="financeiro@contratante.com.br"),
),
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)
CT-e / MDF-e / DC-e
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(...))
Eventos
Cancelar NF-e / NFC-e / CT-e
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=Erro
Carta de Correção (CC-e)
from 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,
)
)
Inutilização, Manifestação, Encerramento MDF-e
from brasilnfe import (
InutilizarNumeracaoEnvio, ManifestarNotaFiscalEnvio,
EncerrarManifestoTransporteEnvio,
)
client.eventos.inutilizar_numeracao(
InutilizarNumeracaoEnvio(
modelo_documento=55, serie=1,
numeracao_inicial=100, numeracao_final=105,
justificativa="Salto de numeração no sistema interno.",
tipo_ambiente=2,
)
)
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="5825...", tipo_ambiente=2)
)
Consultas
from brasilnfe import (
StatusSefazEnvio, BuscarNotaFiscalEnvio, ConsultarCadastroEnvio,
PreVisualizarNotaFiscalEnvio, Produto,
)
from datetime import datetime
# Status SEFAZ
client.consultas.status_sefaz(StatusSefazEnvio(modelo_documento=55))
# 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")
Arquivos
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/).
Empresa
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)
Tratamento de erros
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)
Utilitários
Serialização direta
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)
Rateio de valores (frete / desconto / seguro)
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.00
Configuração avançada
Timeout customizado
client = BrasilNFe(token="...", timeout=600) # 10 minutos
requests.Session com retry
import 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)
Apontar para sandbox / URL alternativa
client = BrasilNFe(token="...", url="https://sandbox.brasilnfe.com.br/services/")
Desenvolvimento
git clone https://github.com/BrasilNFe/brasilnfe-python-sdk.git
cd brasilnfe-python-sdk
pip install -e ".[dev]"
pytest -v
Lint / type check:
ruff check brasilnfe tests
mypy brasilnfe
Tabelas de referência
Modelos de documento
| 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 |
Ambientes
| Código | Ambiente |
|---|---|
| 1 | Produção (efeito fiscal real) |
| 2 | Homologação (testes na SEFAZ) |
CRT (Regime Tributário)
| Código | Regime |
|---|---|
| 1 | Simples Nacional |
| 2 | Simples Nacional c/ Sublimite |
| 3 | Regime Normal |
| 4 | MEI |
Finalidade da NF-e
| Código | Finalidade |
|---|---|
| 1 | Normal |
| 2 | Complementar |
| 3 | Ajuste |
| 4 | Devolução |
Status de evento SEFAZ
| Código | Significado |
|---|---|
| 1 | Evento processado |
| 2 | Aguardando processamento |
| 3 | Ocorreu um erro |
Headers enviados pelo SDK
| Header | Valor |
|---|---|
Token |
token da empresa |
UserToken |
token do usuário |
Package-Version |
1.2.0 |
Package-Type |
python |
User-Agent |
brasilnfe-python-sdk/... |
Suporte
- 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
Licença
MIT © Brasil NFe LTDA
Metadata
Release files for brasilnfe 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| brasilnfe-1.2.0.tar.gz | 76.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| brasilnfe-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 163.4 kB
Release files / brasilnfe-1.2.0.tar.gz
| Download URL | brasilnfe-1.2.0.tar.gz |
|---|---|
| Size | 76.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
39be31b8cb209694e131376353bbbb23dd65c96b86b2f3257f0210cc7e59afec
|
|
BLAKE2b-256 checksum How to use checksums |
d4c003b792b08e8be5dad3533396287771ec4ce26e1242324537dfb3bdc35851
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.0
|
Release files / brasilnfe-1.2.0-py3-none-any.whl
| Download URL | brasilnfe-1.2.0-py3-none-any.whl |
|---|---|
| Size | 87.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b1877a43432b9cba50e30556f2de47f0eb3e572917ea044baf57bc2f63c538f3
|
|
BLAKE2b-256 checksum How to use checksums |
43aef4ee716e1d41dbaf31fe1b8134232ed4bd7f851cd487e2f1e5a339caca6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.0
|
Security for brasilnfe 1.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.