Skip to main content

SDK oficial Python para integração com a API Brasil NFe - Emissão de NF-e, NFC-e, NFS-e, CT-e, MDF-e, DC-e e mais

Project description

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, 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)

Autenticação

O SDK usa dois tokens enviados nos headers HTTP:

  • Tokenobrigató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
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).


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, 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}")

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, 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)

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,
        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")
)

Consultas

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")

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.1.0
Package-Type python
User-Agent brasilnfe-python-sdk/...

Suporte

SDKs em outras linguagens:


Licença

MIT © Brasil NFe LTDA

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

brasilnfe-1.1.0.tar.gz (47.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

brasilnfe-1.1.0-py3-none-any.whl (56.4 kB view details)

Uploaded Python 3

File details

Details for the file brasilnfe-1.1.0.tar.gz.

File metadata

  • Download URL: brasilnfe-1.1.0.tar.gz
  • Upload date:
  • Size: 47.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for brasilnfe-1.1.0.tar.gz
Algorithm Hash digest
SHA256 f33a7e41eb8565a94464e860fdb986295a02bfebb6cc4d256e91c503e38199c4
MD5 85e8328b13847d336163c894bb6f1224
BLAKE2b-256 ccc4c47fdb069eaa261ca6aaf5018f0c1d975d52c058cb7f2d993170c366b493

See more details on using hashes here.

File details

Details for the file brasilnfe-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: brasilnfe-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 56.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for brasilnfe-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 319c48e80a2fdb9eb8aaf7448a4d94c6755eb250b05a6aa98952109d2fbf2e77
MD5 0e440b832a596a308cc2d293c65a69ac
BLAKE2b-256 40dcf40028fb233f3898112c6dd7b6503b94c11a6f194151f7e3fa89fd79aa9f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page