VlunaAI Python SDK for billing and usage gate APIs
Project description
vlunaai
Official async Python SDK for VlunaAI Billing and Usage Gate APIs.
The SDK bundles:
- A shared async HTTP client (httpx) with retries + idempotency keys
- Authentication helpers (Service Key signing, Bearer token via context)
- Generated Pydantic v2 models
Documentation:
https://docs.vluna.ai/docs/adapters/sdk
Installation
pip install vlunaai
Requires Python >= 3.8.
Package contents
- Async service client for server-to-server (
/mgt/v1) APIs - Async bearer client for end-user (
/api/v1) APIs - Service Key authentication helpers
- Generated Pydantic v2 models and typed request/response surfaces
Quickstart (Service Key, server-to-server)
Configure Service Key auth (S2S):
- If you use Vluna Cloud (hosted), get these values from the dashboard.
- If you self-host, provision them using your Vluna deployment and service-key setup flow.
Set them in the environment where you run your sdk integration:
export VLUNA_REALM_ID='...'
export VLUNA_SERVICE_KEY_ID='pk-...'
export VLUNA_SERVICE_KEY_SECRET='...'
Use ServiceClient for service-to-service calls to the management surface (/mgt/v1).
import asyncio
import os
from vlunaai import (
VlunaAIConfig,
RequestContext,
ServiceClientOptions,
ServiceKeyCredentials,
create_service_client,
)
def env(name: str) -> str:
value = os.environ.get(name)
if not value:
raise RuntimeError(f'Missing environment variable: {name}')
return value
async def main() -> None:
service_base_url = os.environ.get('VLUNA_SERVICE_BASE_URL', 'https://us-central1.api.vluna.ai/mgt/v1')
realm_id = env('VLUNA_REALM_ID')
principal_id = YOUR_PRINCIPAL_ID # your customer's organization/team/workspace id
user_id = YOUR_USER_ID
client = create_service_client(
ServiceClientOptions(
config=VlunaAIConfig(
base_url=service_base_url,
realm_id=realm_id,
),
service_key=ServiceKeyCredentials(
key_id=env('VLUNA_SERVICE_KEY_ID'),
secret=env('VLUNA_SERVICE_KEY_SECRET'), # base64-encoded secret
),
)
)
try:
ctx = RequestContext(principal_id=principal_id, user_id=user_id)
feature_code = 'openai.gpt5.2'
# 1) authorize: ask Vluna for a lease token before performing work
authz = await client.gate_authorize(body={'feature_code': feature_code, 'feature_family_code': 'llm.premium'}, context=ctx)
if not authz.data:
raise RuntimeError('gate_authorize returned no data')
lease_token = authz.data.lease_token
# ...perform the protected work...
# 2) commit: report usage once the work completes
commit = await client.gate_commit(
body={'lease_token': lease_token, 'feature_code': feature_code, 'quantity_minor': '12345'},
context=ctx,
)
print(commit.model_dump())
# 3) billing helpers
balance = await client.get_credit_balance(context=ctx)
print(balance.model_dump())
# 4) token issuance: your backend can return this access_token to your frontend/mobile app for bearer-auth calls.
token_envelope = await client.issue_platform_token(
body={
'principal_id': principal_id,
'user_id': user_id,
'scopes': ['checkout', 'portal'],
'session_ttl_sec': 900,
},
context=ctx,
)
if not token_envelope.data:
raise RuntimeError('issue_platform_token returned no data')
access_token = token_envelope.data.access_token
print(access_token)
finally:
await client.close()
asyncio.run(main())
Quickstart (Bearer token, end-user calls)
Use BearerClient for user/bearer-auth calls to the public surface (/api/v1).
In a typical setup, your frontend/mobile app fetches an platform access token from your backend (issued via the S2S flow above), then uses it as a bearer token for end-user calls.
import asyncio
import os
from vlunaai import (
VlunaAIConfig,
BearerClientOptions,
RequestContext,
create_bearer_client,
)
def env(name: str) -> str:
value = os.environ.get(name)
if not value:
raise RuntimeError(f'Missing environment variable: {name}')
return value
async def main() -> None:
bearer_base_url = os.environ.get('VLUNA_BEARER_BASE_URL', 'https://us-central1.api.vluna.ai/api/v1')
realm_id = env('VLUNA_REALM_ID')
access_token = env('VLUNA_ACCESS_TOKEN') # obtain from your backend (see ServiceClient.issue_platform_token)
client = create_bearer_client(
BearerClientOptions(
config=VlunaAIConfig(
base_url=bearer_base_url,
realm_id=realm_id,
)
)
)
try:
ctx = RequestContext(access_token=access_token)
products = await client.list_catalog_products(context=ctx)
print(products)
finally:
await client.close()
asyncio.run(main())
Key concepts
realm_id
- Required in
VlunaAIConfig. - Identifies the Realm (business project) and is sent as
X-Realm-Idon every request.
billing_account_id
- Payor/account-scoped endpoints may use
billing_account_id(sent asX-Billing-Account-Id) orprincipal_id. - Runtime metering and gate endpoints should not use
billing_account_idas the user subject.
principal_id
- Your business identifier for the payor account (for example
org_id,team_id, orworkspace_id). - For service-key runtime calls, pass it with
user_idviaRequestContext(principal_id=..., user_id=...).
user_id
- Your business identifier for the runtime user inside the billing account.
- Required with
principal_idfor service-key gate, wallet, budget, and event calls.
More details:
https://docs.vluna.ai/docs/adapters/sdk
Project details
Release history Release notifications | RSS feed
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 vlunaai-0.1.4.tar.gz.
File metadata
- Download URL: vlunaai-0.1.4.tar.gz
- Upload date:
- Size: 79.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa0b802f98b3a8f7f33a5943d53b2e22078ed0280e687219254e4ddfb1c6307e
|
|
| MD5 |
36881c349fab8de7867f7fddd8119d64
|
|
| BLAKE2b-256 |
7aa88ccd0774df4af6d08f5dc4c8eb20044d0c1573b750cd6949df0e1be2de5f
|
File details
Details for the file vlunaai-0.1.4-py3-none-any.whl.
File metadata
- Download URL: vlunaai-0.1.4-py3-none-any.whl
- Upload date:
- Size: 36.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
636993871799bdc8fa1f064f600bcb1b2a5624dd5f6d89bb3339821f47cb213a
|
|
| MD5 |
99388550da8288725089b8c3892a44ae
|
|
| BLAKE2b-256 |
2a70220fd9ff763930550430661847b4bc575abfab0a517f182f794be418550e
|