Pular para o conteúdo principal

Configuração

O cliente é configurado só no construtor. Não existe configuração global: cada NfeClient (ou AsyncNfeClient) guarda a sua, imutável, e é seguro compartilhar uma instância entre threads.

As duas chaves​

ParâmetroVariável de ambienteFamília de APIHost
api_keyNFE_API_KEYNFS-ehttps://api.nfe.io
api_keyNFE_API_KEYempresas, certificados, webhookshttps://api.nfse.io
data_api_keyNFE_DATA_API_KEYconsulta de CNPJhttps://legalentity.api.nfe.io
data_api_keyNFE_DATA_API_KEYconsulta de CPFhttps://naturalperson.api.nfe.io
data_api_keyNFE_DATA_API_KEYconsulta de CEPhttps://address.api.nfe.io
import os

from nfeio import NfeClient

# Explícito: o argumento vence a variável de ambiente.
client = NfeClient(
api_key=os.environ["NFE_API_KEY"],
data_api_key=os.environ["NFE_DATA_API_KEY"],
)

# Ou lendo NFE_API_KEY e NFE_DATA_API_KEY do ambiente:
client = NfeClient()
  • Não há fallback entre as chaves. Os hosts de consulta recusam a chave principal com 403, e o SDK nunca tenta uma no lugar da outra. Se você tem uma chave só, passe o mesmo valor nos dois parâmetros.
  • Chave ausente não impede criar o cliente. O erro aparece na primeira chamada que precisa dela: ConfigurationError dizendo qual parâmetro ou variável configurar. Assim um cliente que só emite NFS-e não precisa de data_api_key.
  • Uma chave explícita vazia (api_key="") é recusada na hora, com ConfigurationError.
  • A chave vai no cabeçalho Authorization e nunca aparece em repr, logs ou exceções: o repr do cliente mostra só os 4 últimos caracteres (NfeClient(api_key=SecretStr('****abcd'), ...)).
Produção e teste

Não existe host nem chave de homologação. O ambiente (produção ou teste) é uma configuração da empresa na NFE.io, e a nota volta com o campo environment preenchido.

Todas as opções​

OpçãoPadrãoO que faz
api_keyNFE_API_KEYChave de NFS-e, empresas, certificados e webhooks.
data_api_keyNFE_DATA_API_KEYChave das consultas de CNPJ, CPF e CEP.
timeoutTimeout(connect=10, read=60, total=120)Prazos por tentativa, em segundos. Precisam ser finitos.
max_retries3Novas tentativas de requisições seguras (0 a 10).
retry_base_delay / retry_max_delay1.0 / 30.0Backoff exponencial (dobra a cada tentativa, com variação de ±30%).
max_retry_after60.0Maior Retry-After respeitado. Acima disso, o erro sobe sem espera.
max_response_bytes10 MiBRespostas maiores são recusadas com ResponseTooLargeError.
app_infoNone(nome, versão) acrescentado ao User-Agent.
ssl_contextNonessl.SSLContext próprio, que precisa verificar certificado e hostname.
ca_bundleNoneCaminho de um PEM com CAs extras (proxy corporativo, por exemplo).
base_urlshosts oficiaisTroca o host de uma família de API (só https).
transportHttpClientTransportTransporte HTTP próprio (veja abaixo).
from nfeio import NfeClient, Timeout

client = NfeClient(
timeout=Timeout(connect=10, read=60, total=120), # os padrões
max_retries=3,
app_info=("meu-erp", "2.4.0"), # vai no User-Agent
)

Timeouts​

Timeout(connect, read, total) vale para cada tentativa:

  • connect: DNS, TCP e handshake TLS;
  • read: cada leitura do socket (cabeçalhos e cada bloco do corpo);
  • total: a tentativa inteira, da conexão ao último byte.

Um número também é aceito: timeout=90 significa "esta tentativa pode levar até 90 s" (read = total = 90, connect = min(10, 90)). None, zero, negativo e infinito são recusados com ConfigurationError: não existe requisição sem prazo.

Limite da biblioteca padrão

A resolução de DNS não respeita o timeout de conexão.

Retry​

O retry depende do método e de quando a falha aconteceu:

Método429408, 500, 502, 503, 504Falha antes de conectarFalha depois de enviar
GET, PUT, DELETErepeterepeterepeterepete
POST (emissão, upload, criação)nãonãorepetenão

Um POST nunca é repetido depois que pode ter chegado à API, porque a API pode criar a nota e mesmo assim responder 500 ou 504. Esses erros chegam com outcome_unknown=True, e a decisão de tentar de novo é sua, depois de reconciliar. A receita está em Tratamento de erros.

Retry-After é respeitado até max_retry_after segundos. Sem ele, a espera é exponencial: 1 s, 2 s, 4 s… até 30 s, com variação aleatória de ±30%.

Opções por chamada​

Todo método aceita options=RequestOptions(...). Os campos são opcionais, e None mantém o valor do cliente.

from nfeio import NfeClient, RequestOptions

client = NfeClient()
company_id = "ID_DA_EMPRESA"

page = client.service_invoices.list(
company_id,
options=RequestOptions(timeout=90, max_retries=0),
)
CampoO que faz
api_keyUsa outra chave só nesta chamada (por exemplo, a de outra conta).
timeoutTimeout ou segundos, como no cliente.
max_retriesNovas tentativas desta chamada (0 desliga). Nunca torna um POST repetível.
idempotency_keyEnviado como Idempotency-Key. A API ignora esse cabeçalho hoje, então ele não muda a regra de retry.
extra_headersCabeçalhos adicionais. Não podem sobrescrever Authorization, User-Agent nem Content-Type.

TLS​

TLS é sempre verificado, com versão mínima 1.2. Não existe opção para desligar a verificação: um ssl_context com verify_mode diferente de CERT_REQUIRED ou com check_hostname=False é recusado.

Para confiar numa CA extra (um proxy corporativo que inspeciona TLS, por exemplo):

from nfeio import NfeClient

client = NfeClient(ca_bundle="/etc/ssl/certs/ca-proxy.pem")

ca_bundle e ssl_context são excludentes, e nenhum dos dois vale com transport=: nesse caso, configure TLS no próprio transporte.

Hosts por família de API​

base_urls troca o host de uma família, para apontar para um gateway interno, por exemplo. As chaves aceitas são os valores de ApiFamily: "service_invoices", "account" (empresas, certificados e webhooks), "legal_entity", "natural_person" e "address".

from nfeio import ApiFamily, NfeClient

client = NfeClient(base_urls={ApiFamily.SERVICE_INVOICES: "https://nfe-gateway.minhaempresa.com.br"})

Só https, sem usuário e senha na URL, sem query e sem fragmento.

Transporte próprio​

O transporte padrão usa só a biblioteca padrão (http.client). Para usar outra pilha HTTP, ou um proxy, implemente o protocolo nfeio.transport.Transport (ou AsyncTransport no cliente assíncrono) e passe em transport=. O transporte não pode seguir redirecionamentos e precisa levantar APIConnectionError com a FailurePhase certa em falhas de rede, porque é ela que decide se um POST pode ser repetido.

Proxy

As variáveis HTTPS_PROXY e HTTP_PROXY são ignoradas na versão 0.1. Um parâmetro proxy= está previsto para uma próxima versão.

Ciclo de vida​

O cliente mantém um pool de conexões. Feche ao terminar, ou use como gerenciador de contexto:

from nfeio import NfeClient

with NfeClient() as client:
for company in client.companies.list().auto_paging_iter():
print(company.id)

No cliente assíncrono, o equivalente é async with AsyncNfeClient() as client: ou await client.aclose().

Logs​

O logger nfeio registra requisições e novas tentativas em nível DEBUG, com método, host, caminho, status, tentativa e x-request-id. Ele nunca registra cabeçalhos, corpo, query, chaves ou documentos: ids e documentos no caminho aparecem como *.

import logging

logging.basicConfig()
logging.getLogger("nfeio").setLevel(logging.DEBUG)

NFE.io

A NFE.io é uma empresa de tecnologia que fornece soluções para automatizar e simplificar a emissão e gestão de notas fiscais eletrônicas. Com suas ferramentas, as empresas podem economizar tempo e reduzir erros, aumentando a eficiência e precisão do processo de emissão de notas fiscais.

Um dos principais cases de sucesso da NFE.io é a implementação da solução na empresa de transporte Rodonaves. Com a automatização da emissão e gestão de notas fiscais eletrônicas, a Rodonaves conseguiu reduzir em até 80% o tempo gasto nesse processo, o que se traduziu em uma significativa melhoria na eficiência operacional. Além disso, a empresa também conseguiu eliminar erros e atrasos na emissão de notas fiscais, o que melhorou a relação com seus clientes e aumentou a confiança dos órgãos fiscais.

Outro exemplo é a implementação da NFE.io na empresa de comércio eletrônico, a Loja Integrada. Com a automatização da emissão de notas fiscais, a Loja Integrada conseguiu aumentar a velocidade de emissão de notas em até 10 vezes, o que permitiu que a empresa atendesse a uma maior quantidade de clientes e, consequentemente, aumentar as suas vendas.

Além desses exemplos, a NFE.io também tem outros cases de sucesso com empresas de setores como indústria, construção, varejo e serviços, mostrando a versatilidade e eficácia da sua solução.

Em resumo, a NFE.io é uma empresa de tecnologia que oferece soluções para automatizar e simplificar a emissão e gestão de notas fiscais eletrônicas, ajudando as empresas a economizar tempo e reduzir erros, melhorando a eficiência e precisão do processo. Com cases de sucesso em diferentes setores, a NFE.io tem se destacado como uma empresa líder em automação fiscal.