Skip to main content

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.

Python License: MIT typed


Sumário

  1. Instalação
  2. Quickstart
  3. Autenticação
  4. Arquitetura
  5. Recursos
  6. Exemplos por recurso
  7. Tratamento de erros
  8. Utilitários
  9. Configuração avançada
  10. Desenvolvimento
  11. Tabelas de referência
  12. 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 recurso empresa).
# 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_token na 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

SDKs em outras linguagens:


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)

Source distribution for brasilnfe 1.2.0
File Size Uploaded Provenance
brasilnfe-1.2.0.tar.gz 76.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for brasilnfe 1.2.0
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page