---
title: "sdk/python"
description: "SDK de servidor Python assíncrono para verificação JWT sem rede,autenticação de requisições e validação de assinatura de webhook."
locale: "pt-BR"
---

> Documentation Index
> Fetch the relevant documentation index at: https://vonvon.id/pt-br/sdks/llms.txt
> Use this file to discover all available pages before exploring further.

# sdk/python

## Estado

Implementado e verificado localmente. A verificação de ida e voltacom um IdP real (busca de JWKS, assinatura/verificação de tokencontra uma instância Vonvon ativa) ainda não foi realizada e deve serconcluída antes do uso em produção.

Status do registry: UNPUBLISHED. Instale este SDK somente a partir do checkout do código-fonte do repositório; não use um registry de pacotes externo.

A autenticação de requisições aceita somente Bearer por padrão. Um cookie JWT pertencente ao aplicativo só é lido quando seu nome exato é configurado. O cookie opaco do Core \_\_Host-vonvon.rt.\* nunca é pesquisado nem verificado localmente; troque-o encaminhando o header Cookie completo para o POST /v1/sessions/token da mesma origem exata, com redirects desativados, e aceite somente uma resposta que contenha apenas o campo token.

## Instalar

```shell
pip install "vonvon @ git+https://github.com/StringKe/vonvon#subdirectory=sdk/python"
```

## Início rápido

Construa um `VonvonClient` na inicialização e reutilize-o. Ocliente faz cache do JWKS internamente.

```python
from vonvon import VonvonClient

client = VonvonClient(
issuer="https://vonvon.id",
audience="https://api.yourapp.com",  # optional
)

# Verify a token
claims = await client.verify_token("eyJ...")
print(claims.sub, claims.email, claims.scope)

# Authenticate a request (Bearer-only by default)
status = await client.authenticate_request(headers=dict(request.headers))
if not status.authenticated:
raise Unauthorized()
user_id = status.claims.sub

# Explicit same-origin Core session -> JWT exchange
token = await client.exchange_session_token(
incoming_request_url="https://app.example.com/account",
cookie_header=request.headers["cookie"],
)
```

## Verifica webhook

```python
from vonvon import WebhookVerificationError

try:
webhook = client.verify_webhook(
    payload=request.body,
    headers=dict(request.headers),
    secret="whsec_xxx",
)
import json
event = json.loads(webhook.body)
except WebhookVerificationError as exc:
raise BadRequest(str(exc))
```

## Integração com FastAPI

```python
from fastapi import FastAPI, Depends, HTTPException, Request
from vonvon import VonvonClient, TokenClaims

app = FastAPI()
vonvon = VonvonClient(issuer="https://vonvon.id")

@app.on_event("shutdown")
async def shutdown():
await vonvon.aclose()

async def require_auth(request: Request) -> TokenClaims:
status = await vonvon.authenticate_request(dict(request.headers))
if not status.authenticated:
    raise HTTPException(status_code=401)
return status.claims

@app.get("/me")
async def me(claims: TokenClaims = Depends(require_auth)):
return {"sub": claims.sub, "email": claims.email}
```

## Opções do VonvonClient

| Parâmetro | Padrão | Descrição |
| --- | --- | --- |
| `issuer` | obrigatório | URL do emissor Vonvon |
| `audience` | `None` | Claim aud esperado; None ignora a validação |
| `jwks_ttl` | `3600` | TTL do cache em memória do JWKS em segundos |
| `http_timeout` | `10.0` | Timeout de busca do JWKS em segundos |
| `cookie_name` | `disabled` | Nome do cookie JWT pertencente ao aplicativo; desativado salvo configuração explícita |
| `leeway` | `0` | Tolerância de desvio de relógio em segundos |

## API principal

| Método | Descrição |
| --- | --- |
| `await client.verify_token(token)` | Verifica string JWT; lança `TokenVerificationError` em caso defalha. |
| `await client.authenticate_request(headers, cookies)` | Extrai e verifica o token de headers/cookies. Retorna`AuthStatus`; não lança exceções. |
| `client.verify_webhook(payload, headers, secret)` | Síncrono. Valida HMAC-SHA256 svix + janela de replay de 5 minutos.Lança `WebhookVerificationError` em caso de falha. |
| `await client.aclose()` | Libera os recursos do cliente HTTP subjacente. |

## Notas da plataforma

- Prioridade assíncrona. Chamadores síncronos (Django/Flask) podemenvolver com `asyncio.run()`.
- Depende de `pyjwt[crypto] >=2.8` e `httpx >=0.27`. Python3.10+ obrigatório.
- Implantações com múltiplos workers não compartilham cache JWKS entreprocessos. Um cache compartilhado (Redis) é uma melhoria planejada.

Source: https://vonvon.id/pt-br/sdks/python/index.mdx
