flare-sdk
Cliente leve para enviar logs e requests ao Flare, o sistema de observabilidade da lunacheckout.
Uma app instrumentada manda telemetria para POST /ingest com o token da sua
source; o Flare recebe, resolve token → source e grava. Este pacote é o lado
cliente desse contrato — a parte que envia.
[sua API] ──flare-sdk──> POST /ingest (Bearer token) ──> [Flare] ──> dashboard
Princípios
- Nunca derruba a sua app. Toda falha de envio (Flare fora do ar, rede caída, token errado) é engolida. Telemetria quebrada não pode virar um 500 na sua API.
- Nunca bloqueia a request. Os eventos entram numa fila e uma thread de background os entrega em lote. Se a fila enche, o evento é descartado — nunca se segura o request esperando o Flare.
- Zero dependências no core. O transporte usa a stdlib (
urllib).pip install flare-sdknão puxa mais nada. O middleware de FastAPI é um extra opcional que nem sequer importa framework novo (fala ASGI direto). - Sobrevive ao fork. uvicorn/gunicorn forkam workers; o SDK recria a thread de entrega por processo, sem você pensar nisso.
Instalação
pip install flare-sdk
# com o middleware de FastAPI (opcional; não puxa dependência nova):
pip install "flare-sdk[fastapi]"
Começo rápido
O jeito mais comum: pluge no logging que você já usa. Uma linha, e tudo que a
app já loga passa a chegar ao Flare.
import logging
from flare_sdk import FlareHandler
logging.getLogger().addHandler(
FlareHandler(
token="seu-source-token",
endpoint="https://flare.lunacheckout.com/ingest",
)
)
logging.getLogger("checkout").info(
"pagamento aprovado", extra={"order_id": 42, "gateway": "pagarme"}
)
order_id e gateway viram atributos pesquisáveis no Flare — não texto
espremido na mensagem.
Configuração por ambiente
token e endpoint caem para as variáveis FLARE_TOKEN e FLARE_INGEST_URL
quando omitidos. Assim você liga o SDK sem tocar no código:
export FLARE_TOKEN="seu-source-token"
export FLARE_INGEST_URL="https://flare.lunacheckout.com/ingest"
from flare_sdk import FlareHandler
logging.getLogger().addHandler(FlareHandler()) # lê do ambiente
Instrumentando requests (FastAPI / Starlette)
Uma linha registra method, path, status_code e duration_ms de cada request.
As rotas são agrupadas pelo template (/orders/{id}), não pelo id concreto —
senão a tela de métricas explodiria em cardinalidade.
from fastapi import FastAPI
from flare_sdk import Flare
from flare_sdk.fastapi import FlareMiddleware
app = FastAPI()
flare = Flare() # token/endpoint do ambiente
app.add_middleware(FlareMiddleware, client=flare)
Se a rota levantar, a request é registrada como 500 e a exceção é re-levantada
— o middleware observa, não sequestra o seu erro.
Em Lambda / Cloud Run: flush_after_request=True
Em serverless a thread de entrega congela junto com o container ao fim da invocação, então o lote precisa sair antes disso:
app.add_middleware(FlareMiddleware, client=flare, flush_after_request=True)
⚠️ Não resolva isso com um middleware próprio:
@app.middleware("http") # não faz o que parece
async def flush(request, call_next):
response = await call_next(request)
flare.flush(timeout=3) # roda cedo demais
return response
@app.middleware("http") é um BaseHTTPMiddleware, e o call_next dele retorna
no http.response.start — antes de o corpo ser transmitido e, portanto, antes
de o FlareMiddleware gravar a request. O flush acha a fila sem o evento atual;
ele fica para trás e só sai numa invocação seguinte, se houver. O sintoma é
traiçoeiro: a request mais recente nunca aparece no dashboard.
Com a opção, o flush roda dentro do próprio middleware, logo depois do registro —
não há como inverter a ordem. É bloqueante de propósito (segura a resposta alguns
ms para o lote sair), por isso é opt-in: num servidor de longa duração deixe False
e use o envio em background.
Enviando eventos à mão
Além do handler, você pode mandar logs, requests ou qualquer evento direto:
from flare_sdk import Flare
flare = Flare(token="...", endpoint="https://flare.lunacheckout.com/ingest")
flare.log("job iniciado", severity="INFO", job="reconciliação")
flare.request("POST", "/charge", 201, duration_ms=87.4, gateway="pagarme")
flare.capture({"message": "evento cru", "severity": "DEBUG", "qualquer": "coisa"})
Um mesmo cliente serve o handler e as chamadas manuais — passe-o ao handler para compartilhar uma fila só:
handler = FlareHandler(client=flare)
Severidade
Use os nomes de sempre do logging (o Flare os entende todos): DEBUG, INFO,
WARNING, ERROR, CRITICAL. No modelo OTel do Flare, erro é tudo com número
>= 17 (ERROR e CRITICAL/FATAL).
Referência de configuração
| Parâmetro | Default | O que faz |
|---|---|---|
token |
$FLARE_TOKEN |
Token da source (Bearer). Obrigatório. |
endpoint |
$FLARE_INGEST_URL |
URL completa do /ingest. Obrigatório. |
batch_size |
100 |
Máximo de eventos por POST. |
flush_interval |
2.0 |
Segundos até mandar um lote parcial. |
max_queue |
10000 |
Teto da fila; além disso, descarta (ver dropped). |
timeout |
5.0 |
Timeout de cada POST, em segundos. |
max_retries |
3 |
Retries de erro transiente (5xx/rede), com backoff. |
default_attributes |
{} |
Atributos anexados a todo evento (ex.: service). |
on_error |
None |
Callback (exc) -> None para observar falhas de envio. |
Erros permanentes (4xx: token inválido, lote malformado, corpo grande demais) são descartados sem retry — repetir mandaria o mesmo 4xx.
Encerramento limpo
O cliente registra um atexit que drena a fila no fim do processo. Em jobs curtos,
force o envio com flush() ou use o context manager:
with Flare() as flare:
flare.log("job de 1 tiro")
# sai daqui com a fila drenada
flare.flush(timeout=5) # ou explicitamente
Observando a saúde do próprio SDK
flare = Flare(..., on_error=lambda exc: logging.getLogger("flare").warning("envio falhou: %s", exc))
...
flare.dropped # quantos eventos foram descartados por fila cheia (sinal de saturação)
Desenvolvimento
pip install -e ".[dev]"
pytest
Nenhum teste toca a rede — o transporte é substituído por um dublê. Cobertura mínima 85%.
Licença
MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flare_sdk-0.5.0.tar.gz.
File metadata
- Download URL: flare_sdk-0.5.0.tar.gz
- Upload date:
- Size: 31.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f62e08c06cede9b967f1bd688a4a47ba2e62de79255d40c3ac646a4eb33d77b
|
|
| MD5 |
00c8d6e14d30ea8b85234e041aac3b61
|
|
| BLAKE2b-256 |
27669d02ffcdf06b89d15d96c0619e45e55d13d393c21105d6e59148ca46db2b
|
Provenance
The following attestation bundles were made for flare_sdk-0.5.0.tar.gz:
Publisher:
publish.yml on flyrecheckout/flare-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flare_sdk-0.5.0.tar.gz -
Subject digest:
4f62e08c06cede9b967f1bd688a4a47ba2e62de79255d40c3ac646a4eb33d77b - Sigstore transparency entry: 2218459479
- Sigstore integration time:
-
Permalink:
flyrecheckout/flare-sdk@01f2b1aeace811ce33be2e5f172ec2c5de7aa5d1 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/flyrecheckout
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@01f2b1aeace811ce33be2e5f172ec2c5de7aa5d1 -
Trigger Event:
release
-
Statement type:
File details
Details for the file flare_sdk-0.5.0-py3-none-any.whl.
File metadata
- Download URL: flare_sdk-0.5.0-py3-none-any.whl
- Upload date:
- Size: 22.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
893677fac8b4e7b817a2c8ab73d1ca775de22a1dc619e85803f88db6d07b9447
|
|
| MD5 |
ed8d73277039ef8b70a0f57f320711da
|
|
| BLAKE2b-256 |
391360663544b1636b11c41d30a4071e71685f1825bcd2221d8a3fa40ec0a7b5
|
Provenance
The following attestation bundles were made for flare_sdk-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on flyrecheckout/flare-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flare_sdk-0.5.0-py3-none-any.whl -
Subject digest:
893677fac8b4e7b817a2c8ab73d1ca775de22a1dc619e85803f88db6d07b9447 - Sigstore transparency entry: 2218459528
- Sigstore integration time:
-
Permalink:
flyrecheckout/flare-sdk@01f2b1aeace811ce33be2e5f172ec2c5de7aa5d1 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/flyrecheckout
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@01f2b1aeace811ce33be2e5f172ec2c5de7aa5d1 -
Trigger Event:
release
-
Statement type: