LIVE · LANȚ DE AUDIT · UE
SISTEM · 99,99% UPTIME
v 1.0 ↗ FĂCUT ÎN UE

nexbasira (Python)

SDK Python server-side. Aceeași suprafață de resurse ca SDK-ul Node, bazat pe requests pentru reîncercări transparente, cu Session mockabil pentru teste.

Instalare

pip install nexbasira

Necesită Python 3.10+.

Inițializare

from nexbasira import NexBasira

nb = NexBasira(
    api_key=os.environ["NB_PUBLIC_KEY"],
    api_secret=os.environ["NB_SECRET_KEY"],
    # base_url="https://app.nexbasira.com/api/v1/public",  # default
    # timeout=30,                                              # default
)

Resurse

nb.sessions       # create / list / retrieve / end / invite
nb.evidence       # list / retrieve / signed download URL
nb.whiteboards    # list per session
nb.webhooks       # register / rotate_secret / test_fire / construct_event
nb.branding       # read-only
nb.org            # read-only

Tipare comune

Creare + invitație

session = nb.sessions.create(
    notes="Vehicle damage claim CL-2026-0042",
    scheduled_for="2026-05-23T10:00:00Z",
    locale="fr",
)

invite = nb.sessions.invite(
    session.id,
    recipient_email="alex@policyholder.com",
    send_email=True,
)

print(invite.url)  # shown ONCE

Paginare cu iterator

# Auto-pages through all sessions:
for session in nb.sessions.iter(limit=50):
    print(session.id, session.status)

# Or one page at a time if you want pagination control:
page = nb.sessions.list_page(limit=25)
# page.data, page.has_more, page.next_cursor

POST idempotent

import uuid

session = nb.sessions.create(
    notes="...",
    idempotency_key=str(uuid.uuid4()),
)

Verificarea unui webhook (Flask)

from flask import Flask, request, abort
from nexbasira import NexBasira, InvalidSignatureError

app = Flask(__name__)
nb = NexBasira(api_key="...", api_secret="...")

@app.post("/nb-webhook")
def webhook():
    sig = request.headers.get("NB-Signature", "")
    secret = os.environ["NB_WEBHOOK_SECRET"]
    try:
        # IMPORTANT: pass request.data (raw bytes), NOT request.get_json()
        event = nb.webhooks.construct_event(request.data, sig, secret)
    except InvalidSignatureError:
        abort(401, "bad signature")

    if event.type == "session.completed":
        on_completed(event.data)
    elif event.type == "audit.anchored":
        on_anchored(event.data)
    return "", 204

FastAPI / async

SDK-ul este sincron prin design (fără async def pe metodele de resurse). În handler-ele FastAPI, apelați-l dintr-un run_in_threadpool sau folosiți anyio.to_thread.run_sync():

from fastapi import FastAPI, Request, HTTPException
from anyio.to_thread import run_sync
from nexbasira import InvalidSignatureError

app = FastAPI()

@app.post("/nb-webhook")
async def webhook(req: Request):
    body = await req.body()
    sig = req.headers.get("nb-signature", "")
    try:
        event = await run_sync(
            nb.webhooks.construct_event, body, sig, WEBHOOK_SECRET,
        )
    except InvalidSignatureError:
        raise HTTPException(401, "bad signature")
    return {"ok": True}

Erori tipizate

from nexbasira import (
    AuthenticationError,
    PermissionError,
    NotFoundError,
    RateLimitError,
    InvalidSignatureError,
    NexBasiraError,
)

try:
    nb.sessions.create(...)
except RateLimitError as e:
    time.sleep(e.retry_after_seconds)
    # retry
except NexBasiraError as e:
    log.warning("nb error: %s (status=%d)", e.code, e.status)
    raise

Testare — Session mockabil

SDK-ul folosește un requests.Session sub capotă. Transmiteți-l pe al dvs. (sau un mock) prin argumentul http_session pentru a intercepta în teste:

from unittest.mock import MagicMock
from nexbasira import NexBasira

def test_my_handler():
    session = MagicMock()
    session.request.return_value.status_code = 201
    session.request.return_value.json.return_value = {"id": "sess-1", "status": "created", ...}
    nb = NexBasira(api_key="x", api_secret="y", http_session=session)

    s = nb.sessions.create(notes="test")
    assert s.id == "sess-1"
    session.request.assert_called_once()

Modele tipizate

Generate din specificația OpenAPI via datamodel-code-generator; importabile ca dataclass-uri:

from nexbasira import Session, Evidence, WebhookEvent

def on_completed(session: Session) -> None:
    ...

Ce urmează