---
title: "sdk/python"
description: "네트워크 호출 없는 JWT 검증, 요청 인증, webhook 서명 검증을 지원하는 비동기 Python 서버 SDK."
locale: "ko"
---

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

# sdk/python

## 상태

로컬에서 구현 및 검증되었습니다. 실제 IdP 왕복 검증(JWKS 가져오기, 실제 Vonvon 인스턴스에 대한 토큰 서명/검증)은 아직 수행되지 않았으며 프로덕션 사용 전에 완료되어야 합니다.

Registry 상태: UNPUBLISHED. 이 SDK는 저장소 소스 checkout에서만 설치하고 외부 package registry를 사용하지 마세요.

요청 인증은 기본적으로 Bearer만 허용합니다. 애플리케이션 소유 JWT cookie는 정확한 이름을 설정한 경우에만 읽습니다. 불투명한 \_\_Host-vonvon.rt.\* Core cookie는 스캔하거나 로컬에서 검증하지 않습니다. 전체 Cookie header를 redirect가 비활성화된 exact same-origin POST /v1/sessions/token으로 전달해 교환하고 token 필드만 포함한 응답만 허용하세요.

## 설치

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

## 빠른 시작

시작 시 `VonvonClient`를 하나 생성하여 재사용하세요. 클라이언트는 JWKS를 내부적으로 캐시합니다.

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

## 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))
```

## 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}
```

## VonvonClient 옵션

| 파라미터 | 기본값 | 설명 |
| --- | --- | --- |
| `issuer` | 필수 | Vonvon 발급자 URL |
| `audience` | `None` | 예상 aud 클레임; None이면 검증을 건너뜁니다 |
| `jwks_ttl` | `3600` | 초 단위 JWKS 인메모리 캐시 TTL |
| `http_timeout` | `10.0` | 초 단위 JWKS 가져오기 타임아웃 |
| `cookie_name` | `disabled` | 애플리케이션 소유 JWT cookie 이름이며 명시적으로 설정한 경우에만 활성화됩니다 |
| `leeway` | `0` | 초 단위 클럭 편차 허용 범위 |

## 핵심 API

| 방법 | 설명 |
| --- | --- |
| `await client.verify_token(token)` | JWT 문자열을 검증합니다. 실패 시 `TokenVerificationError`를 발생시킵니다. |
| `await client.authenticate_request(headers, cookies)` | 헤더/cookie에서 토큰을 추출하고 검증합니다. `AuthStatus`를 반환하며 예외를 발생시키지 않습니다. |
| `client.verify_webhook(payload, headers, secret)` | 동기식. svix HMAC-SHA256 + 5분 재사용 방지 윈도우를 검증합니다. 실패 시 `WebhookVerificationError`를 발생시킵니다. |
| `await client.aclose()` | 기반 HTTP 클라이언트 리소스를 해제합니다. |

## 플랫폼 참고 사항

- 비동기 우선 방식입니다. 동기 호출자(Django/Flask)는 `asyncio.run()`으로 감쌀 수 있습니다.
- `pyjwt[crypto] >=2.8`과 `httpx >=0.27`에 의존합니다. Python 3.10 이상이 필요합니다.
- 다중 worker 배포에서는 프로세스 간 JWKS 캐시를 공유하지 않습니다. 공유 캐시(Redis)는 향후 개선 계획에 있습니다.

Source: https://vonvon.id/ko/sdks/python/index.mdx
