Official Python SDK for the WLT Console API
Project description
WLT Python SDK
Official Python client library for the WLT Console API.
Installation
pip install wlt-platform
To pin a specific version:
pip install wlt-platform==0.1.12
Quick Start
from wlt import WltClient
# Initialize the client with your API Key (obtain from Console > Secret Management)
# Authentication happens EAGERLY at construction time for the sync WltClient:
# 1. WltClient(api_key=...) immediately calls loginByApiKey to exchange the
# api_key for a short-lived Bearer token. An invalid api_key raises
# AuthenticationError right here -- before any business call is made.
# 2. The token is cached on the client and sent as Authorization: Bearer ...
# with every subsequent request.
# 3. If a later response is an auth failure (HTTP 401/403 or business code in
# {2000, 2002, 2007, 3001}), the SDK re-runs loginByApiKey, swaps the
# cached token, and retries the failed request once.
# (AsyncWltClient defers the first loginByApiKey to the first awaited call.)
client = WltClient(api_key="sk-your-api-key")
# Example: list secrets
result = client.secrets.list()
print(result.data)
# Always close the client when done
client.close()
Context Manager
from wlt import WltClient
with WltClient(api_key="sk-your-api-key") as client:
result = client.secrets.list()
print(result.data)
# client is automatically closed
Async Usage
import asyncio
from wlt import AsyncWltClient
async def main():
async with AsyncWltClient(api_key="sk-your-api-key") as client:
result = await client.secrets.list()
print(result.data)
asyncio.run(main())
All synchronous examples below have identical async equivalents -- just use
AsyncWltClientandawaiteach method call.
Configuration
client = WltClient(
api_key="sk-your-api-key", # Required. Auto-exchanged for Bearer token
timeout=30.0, # Request timeout in seconds (default: 30)
max_retries=2, # Max retry attempts (default: 2)
)
Base URL Configuration
The default base URL is https://daily.sssxuntui.com, which targets the public WLT endpoint and requires no configuration. Override it when pointing at a private deployment, a staging environment, or a regional node.
Configuration Methods
- Constructor argument (highest priority)
from wlt import WltClient
client = WltClient(
api_key="sk-your-api-key",
base_url="https://your.host",
)
- Environment variable
export WLT_BASE_URL=https://your.host
- CLI configuration file -- the
base_urlfield in~/.wlt/config.json(CLI users only)
wlt config set base_url https://your.host
Precedence
| Priority | Source |
|---|---|
| 1 (highest) | Constructor argument / CLI --base-url flag |
| 2 | WLT_BASE_URL environment variable |
| 3 | base_url in ~/.wlt/config.json (CLI users only) |
| 4 (lowest) | Default https://daily.sssxuntui.com |
Trailing slashes are stripped automatically; https://host/ and https://host are equivalent.
Typical Use Cases
- Private deployment: target a customer-managed gateway
- Staging tests: switch to a test environment during development
- Regional nodes: select the nearest point of presence
Module Reference
| Module | Accessor | Description |
|---|---|---|
| Secret | client.secrets |
Secret CRUD, usage stats, model/provider queries |
| ApiKey | client.api_keys |
BYOK API key CRUD, status, connectivity test, providers |
| Usage | client.usage |
Serverless list/stats, call history, gateway providers |
| UserInfo | client.user |
Current user info |
| Billing | client.billing |
Monthly billing queries by GPU, AI service, or detail line items |
| Payment | client.payment |
Recharge records, statistics, model usage billing |
| Model Gallery | client.model_gallery |
Model page, providers, prices |
| Model Lab | client.model_lab |
Model list, chat session, stream inference |
Secret
client.secrets.list()
List secrets with pagination and optional filters.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| page_num | int | No | 1 | Page number, starting from 1 |
| page_size | int | No | 10 | Items per page |
| status | int | No | None | Status filter: 1=active, 0=disabled |
| expired_before_utc | datetime | No | None | Expiry time upper bound (UTC), filter secrets expiring before this time |
Response
Returns BaseResponse[SecretPageResultVO].
SecretPageResultVO fields:
| Field | Type | Description |
|---|---|---|
| totalKeys | int | Total number of secrets |
| activeKeys | int | Number of active secrets |
| totalRequest | int | Total request count |
| avgQps | float | Average QPS |
| pageInfo | PageInfo[SecretVO] | Paginated secret data |
PageInfo fields:
| Field | Type | Description |
|---|---|---|
| total | int | Total record count |
| totalPages | int | Total number of pages |
| currentPage | int | Current page number |
| pageSize | int | Items per page |
| list | list[SecretVO] | Data list |
SecretVO fields:
| Field | Type | Description |
|---|---|---|
| id | int | Secret ID |
| name | str | Secret name |
| keyId | str | Key identifier |
| status | str | Status |
| createdAt | datetime | Creation time |
| lastUsed | datetime | Last used time |
| expiredFlag | bool | Whether expired |
| allowedModels | list[str] | Allowed model list |
| allowedProviders | list[str] | Allowed provider list |
| ipWhiteList | list[str] | IP whitelist |
| minuteTokensQuota | int | Per-minute token quota |
| annualTokensQuota | int | Annual token quota |
| description | str | Description |
| expiredAtUtc | datetime | Expiry time (UTC) |
| byokList | list[ApikeyVO] | Associated BYOK key list |
| defaultSecret | int | Whether default secret: 1=yes, 0=no |
| createUser | str | Creator |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
# Basic listing
result = client.secrets.list()
print(f"Total secrets: {result.data.totalKeys}")
for secret in result.data.pageInfo.list:
print(secret.id, secret.name, secret.status)
# With filters
result = client.secrets.list(page_num=1, page_size=5, status=1)
client.secrets.detail()
Get a single secret's details by ID.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | int | Yes | -- | Secret ID |
Response
Returns BaseResponse[SecretVO].
SecretVO fields: see
client.secrets.list()above.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
detail = client.secrets.detail(id=123)
print(detail.data.name)
print(detail.data.allowedModels)
print(detail.data.allowedProviders)
client.secrets.create()
Create a new secret. Returns the generated API key string.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| name | str | No | None | Secret name |
| allowed_models | list[str] | No | None | List of allowed model names |
| allowed_providers | list[str] | No | None | List of allowed provider names |
| ip_white_list | list[str] | No | None | IP whitelist (CIDR notation) |
| minute_tokens_quota | int | No | None | Per-minute token quota |
| annual_tokens_quota | int | No | None | Annual token quota |
| expired_at_utc | datetime | No | None | Expiry time in UTC |
| byok_ids | list[int] | No | None | List of BYOK key IDs to associate |
Response
Returns BaseResponse[str]. The data field contains the generated API key string (the secret key value -- save it now, the backend will not return it again).
How to obtain the DB
idaftercreate()
create()does not return the database row's numericid, which theedit()/action()(enable/disable/delete) /usage_by_model()methods require. To resolve theid, callclient.secrets.list(...)and match byname:created = client.secrets.create(name="my-secret") page = client.secrets.list(page_num=1, page_size=100) row = next(s for s in page.data.list if s.name == "my-secret") secret_id = row.id # use this for edit / action / usage queriesA future major version may change
create()to return the full record; until then, thelist()lookup is the supported pattern.
from wlt import WltClient
from datetime import datetime, timezone, timedelta
client = WltClient(api_key="sk-your-api-key")
# Minimal creation
result = client.secrets.create(name="my-secret")
print(f"New API key: {result.data}")
# Full creation with all options
result = client.secrets.create(
name="production-key",
allowed_models=["qwen-turbo", "qwen-plus"],
allowed_providers=["dashscope"],
ip_white_list=["10.0.0.0/8"],
minute_tokens_quota=100000,
annual_tokens_quota=50000000,
expired_at_utc=datetime(2027, 1, 1, tzinfo=timezone.utc),
byok_ids=[1, 2],
)
print(f"New API key: {result.data}")
# To obtain the new secret's DB id, look it up by name via list():
page = client.secrets.list(page_num=1, page_size=100)
new_id = next(s.id for s in page.data.list if s.name == "production-key")
client.secrets.edit()
Edit an existing secret.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | int | Yes | -- | Secret ID |
| name | str | No | None | Updated name |
| allowed_models | list[str] | No | None | Updated allowed model list |
| allowed_providers | list[str] | No | None | Updated allowed provider list |
| ip_white_list | list[str] | No | None | Updated IP whitelist |
| minute_tokens_quota | int | No | None | Updated per-minute token quota |
| annual_tokens_quota | int | No | None | Updated annual token quota |
| expired_at_utc | datetime | No | None | Updated expiry time (UTC) |
| byok_ids | list[int] | No | None | Updated BYOK key IDs |
Response
Returns BaseResponse[bool]. data=True on success.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
result = client.secrets.edit(
id=123,
name="updated-secret-name",
allowed_models=["qwen-turbo", "qwen-max"],
minute_tokens_quota=200000,
)
print(f"Success: {result.data}") # True
client.secrets.action()
Perform an action on a secret: "ENABLE", "DISABLE", or "DELETE".
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | int | Yes | -- | Secret ID |
| status | str | Yes | -- | Action: "ENABLE", "DISABLE", or "DELETE" |
Response
Returns BaseResponse[bool]. data=True on success.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
# Disable a secret
result = client.secrets.action(id=123, status="DISABLE")
print(f"Success: {result.data}") # True
# Enable a secret
result = client.secrets.action(id=123, status="ENABLE")
# Delete a secret
result = client.secrets.action(id=123, status="DELETE")
client.secrets.usage_by_model()
Query secret usage breakdown by model with pagination.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| secret_id | int | Yes | -- | Secret ID |
| start_time | datetime | No | None | Query start time |
| end_time | datetime | No | None | Query end time |
| page_num | int | No | 1 | Page number |
| page_size | int | No | 10 | Items per page |
Response
Returns BaseResponse[PageInfo[SecretModelUsageVO]].
SecretModelUsageVO fields:
| Field | Type | Description |
|---|---|---|
| model | str | Model name |
| requests | int | Request count |
| totalTokens | int | Total token consumption |
| promptTokens | int | Prompt token count |
| completionTokens | int | Completion token count |
from wlt import WltClient
from datetime import datetime
client = WltClient(api_key="sk-your-api-key")
result = client.secrets.usage_by_model(
secret_id=123,
start_time=datetime(2026, 4, 1),
end_time=datetime(2026, 4, 21),
page_num=1,
page_size=10,
)
for item in result.data.list:
print(item.model, item.promptTokens, item.completionTokens)
client.secrets.model_list()
Query available models for secret binding.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| model_name | str | No | None | Model name (fuzzy search) |
| provider | str | No | None | Provider identifier |
| series_provider | str | No | None | Series provider identifier |
| model_type | str | No | None | Model type |
| view_all_flag | int | No | None | View all flag (1=view all) |
| page_size | int | No | None | Items per page |
| page_num | int | No | None | Page number |
| usage_type | str | No | None | Usage type: "inference" or "train" |
| training_method | str | No | None | Training method: "sft" or "dpo" |
| tags | list[str] | No | None | Tag filter list, e.g. ["New"] |
| capability | str | No | None | Capability filter, e.g. "text_to_text" |
| model_type_list | list[str] | No | None | Model type list (multi-select) |
| origin_providers | list[str] | No | None | Origin provider list (multi-select) |
| inputs | list[str] | No | None | Input type list, e.g. ["text"] |
| outputs | list[str] | No | None | Output type list, e.g. ["image"] |
Response
Returns BaseResponse[list[ModelInfoVO]].
ModelInfoVO fields:
| Field | Type | Description |
|---|---|---|
| modelId | str | Model ID |
| modelName | str | Model name |
| modelImage | str | Model icon URL |
| isNew | int | Whether new model (1=yes) |
| provider | str | Provider identifier |
| providerName | str | Provider display name |
| originProvider | str | Origin provider identifier |
| seriesProvider | str | Series provider identifier |
| modelType | str | Model type |
| tags | list[str] | Tag list |
| modelSize | str | Model size |
| feature | str | Feature description |
| price | Decimal | Price |
| unit | str | Price unit |
| available | bool | Whether available |
| updated | datetime | Update time |
| deployPlatform | str | Deploy platform |
| regionId | str | Region ID |
| deployFrameworks | list[str] | Deploy framework list |
| labels | list[str] | Label list |
| capabilities | list[str] | Capability list (e.g. text_to_text) |
| inputs | list[str] | Input type set |
| outputs | list[str] | Output type set |
| priceExtend | PartnerApiPriceExtend | Extended price info |
| dataSource | str | Data source (model_card or model_router) |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
# List all inference models
models = client.secrets.model_list(usage_type="inference")
for m in models.data:
print(m.modelName, m.provider)
# Filter by provider
models = client.secrets.model_list(
provider="dashscope",
model_name="qwen",
tags=["New"],
)
for m in models.data:
print(m.modelName)
client.secrets.providers()
Get the list of providers available for secrets.
Parameters
None.
Response
Returns BaseResponse[list[ProviderVO]].
ProviderVO fields:
| Field | Type | Description |
|---|---|---|
| id | str | Provider identifier |
| name | str | Provider display name |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
providers = client.secrets.providers()
for p in providers.data:
print(p.id, p.name)
ApiKey (BYOK)
client.api_keys.list()
List API keys with pagination and optional filters.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| page_num | int | No | 1 | Page number, starting from 1 |
| page_size | int | No | 10 | Items per page |
| provider | str | No | None | Filter by provider |
| timezone | str | No | None | Timezone for time field localization, e.g. "Asia/Shanghai" |
Response
Returns BaseResponse[ApiKeyResultVO].
ApiKeyResultVO fields:
| Field | Type | Description |
|---|---|---|
| totalApiCalls | int | Total API call count |
| activeKeys | int | Number of active keys |
| apiKeys | PageInfo[ApikeyVO] | Paginated API key data |
ApikeyVO fields:
| Field | Type | Description |
|---|---|---|
| id | str | ApiKey ID |
| name | str | Key name |
| key | str | Key content (masked) |
| provider | str | Provider name |
| providerId | str | Provider ID |
| account | str | Account info |
| accountId | str | Account ID |
| projectID | str | Project ID |
| created | datetime | Creation time |
| lastUsedAt | datetime | Last used time |
| status | str | Status |
| accessKeyID | str | AccessKey ID (masked) |
| accessKeySecret | str | AccessKey Secret (masked) |
| resaleStatus | str | Resale status |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
result = client.api_keys.list(page_num=1, page_size=10)
for key in result.data.apiKeys.list:
print(key.id, key.name, key.provider, key.status)
# Filter by provider
result = client.api_keys.list(provider="dashscope")
client.api_keys.create()
Create a new BYOK API key.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| provider | str | Yes | -- | Provider id (NOT display name); use the id field returned by api_keys.providers(), e.g. "dashscope", "openrouter". |
| key_name | str | No | None | Key name |
| status | int | No | None | Initial status |
| access_key_id | str | No | None | AccessKey ID |
| access_key_secret | str | No | None | AccessKey Secret |
| tpm_limit | str | No | None | TPM (tokens per minute) limit |
| token_limit | str | No | None | Total token limit |
Tip:
providerMUST be theidfromapi_keys.providers()(e.g.dashscope), NOT the displayname(e.g."Alibaba Cloud Model Studio - BJ"). Passing the display name returnscode=3000 "Invalid provider".
Response
Returns BaseResponse[ApikeyVO]. The data field contains the newly created API key info.
ApikeyVO fields: see
client.api_keys.list()above.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
new_key = client.api_keys.create(
provider="dashscope",
key_name="my-dashscope-key",
access_key_id="LTAI5t...",
access_key_secret="your-access-key-secret",
tpm_limit="100000",
token_limit="5000000",
)
print(f"Created key ID: {new_key.data.id}")
print(f"Key name: {new_key.data.name}")
client.api_keys.update()
Update an existing API key.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| path_id | str | Yes | -- | ApiKey ID (URL path parameter, for routing) |
| id | int | No | None | ApiKey database primary key (used for locating the record) |
| provider | str | No | None | Provider (must be a valid BYOK provider if provided) |
| key_name | str | No | None | Key name |
| aliyun_account_id | str | No | None | Aliyun account ID |
| status | int | No | None | Status |
| access_key_id | str | No | None | AccessKey ID |
| access_key_secret | str | No | None | AccessKey Secret |
| resale_status | str | No | None | Resale status |
| tpm_limit | str | No | None | TPM limit |
| token_limit | str | No | None | Total token limit |
Response
Returns BaseResponse[bool]. data=True on success.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
result = client.api_keys.update(
path_id="456",
id=456,
key_name="renamed-key",
tpm_limit="200000",
)
print(f"Success: {result.data}") # True
client.api_keys.delete()
Delete an API key.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | str | Yes | -- | ApiKey ID |
Response
Returns BaseResponse[bool]. data=True on success.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
result = client.api_keys.delete(id="456")
print(f"Success: {result.data}") # True
client.api_keys.change_status()
Enable or disable an API key.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | str | Yes | -- | ApiKey ID |
| status | int | Yes | -- | Target status: 1=enable, 0=disable |
Response
Returns BaseResponse[bool]. data=True on success.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
# Disable a key (status: 0=disable, 1=enable)
result = client.api_keys.change_status(id="456", status=0)
print(f"Success: {result.data}") # True
# Enable a key
result = client.api_keys.change_status(id="456", status=1)
client.api_keys.test_connect()
Test API key connectivity by relaying the credentials to the upstream provider.
Behaviour on bad creds: the call returns successfully (no exception) but
r.datamay beFalse, or the SDK may surface a typedAPIErrorwrapping the upstream's 401. Both outcomes mean the SDK is working correctly — only network/auth-against-our-backend failures should be treated as SDK bugs.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| aliyun_account_id | str | No | None | Aliyun account ID (for providers that require it) |
| access_key_id | str | No | None | AccessKey ID |
| access_key_secret | str | No | None | AccessKey Secret |
| provider | str | No | None | Provider name |
Response
Returns BaseResponse[bool]. data=True if connection is successful.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
result = client.api_keys.test_connect(
provider="dashscope",
access_key_id="LTAI5t...",
access_key_secret="your-access-key-secret",
)
if result.data:
print("Connection successful!")
else:
print("Connection failed")
client.api_keys.providers()
Get the list of providers available for API keys.
Parameters
None.
Response
Returns BaseResponse[list[ProviderVO]].
ProviderVO fields:
| Field | Type | Description |
|---|---|---|
| id | str | Provider identifier |
| name | str | Provider display name |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
providers = client.api_keys.providers()
for p in providers.data:
print(p.id, p.name)
Usage
client.usage.serverless_list()
Query serverless usage list with filters.
start_time/end_timeare REQUIRED. The backend NPEs when either is missing. The SDK raises a client-sideValueError("start_time and end_time are required")so you get a usable error before the network call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| start_time | datetime | Yes | -- | Query start time |
| end_time | datetime | Yes | -- | Query end time |
| page_num | int | No | 1 | Page number (>= 1) |
| page_size | int | No | 10 | Items per page (>= 1) |
| api_key | str | No | None | Filter by API Key |
| inputs | list[str] | No | None | Input type filter list |
| outputs | list[str] | No | None | Output type filter list |
| model_ids | list[str] | No | None | Model ID filter list |
Response
Returns BaseResponse[PageInfo[ServerlessUsageRecord]].
ServerlessUsageRecord fields:
| Field | Type | Description |
|---|---|---|
| modelName | str | Model name |
| apiKeyName | str | API Key name |
| requests | str | Request count |
| totalTokens | str | Total token consumption |
| avgLatency | str | Average latency |
| successRate | str | Success rate (%) |
| errorCount | str | Error count |
| totalFee | str | Total fee |
| throughput | str | Throughput (QPS) |
| usageStats | str | Usage statistics info |
from wlt import WltClient
from datetime import datetime
client = WltClient(api_key="sk-your-api-key")
result = client.usage.serverless_list(
start_time=datetime(2026, 4, 1),
end_time=datetime(2026, 4, 21),
page_num=1,
page_size=20,
model_ids=["qwen-turbo"],
)
for record in result.data.list:
print(record.modelName, record.totalTokens)
client.usage.serverless_stats()
Get serverless usage aggregated statistics.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| start_time | datetime | Yes | -- | Query start time |
| end_time | datetime | Yes | -- | Query end time |
| page_num | int | No | 1 | Page number |
| page_size | int | No | 10 | Items per page |
| api_key | str | No | None | Filter by API Key |
| inputs | list[str] | No | None | Input type filter list |
| outputs | list[str] | No | None | Output type filter list |
| model_ids | list[str] | No | None | Model ID filter list |
Response
Returns BaseResponse[ServerlessStatsResult].
ServerlessStatsResult fields:
| Field | Type | Description |
|---|---|---|
| totalRequests | int | Total request count |
| requestTrend | str | Request trend |
| totalTokens | int | Total token consumption |
| tokenTrend | str | Token trend |
| totalUseModel | int | Total number of models used |
| totalUseModelTrend | str | Model usage trend |
| avgLatency | str | Average latency |
| avgLatencyTrend | str | Average latency trend |
from wlt import WltClient
from datetime import datetime
client = WltClient(api_key="sk-your-api-key")
stats = client.usage.serverless_stats(
start_time=datetime(2026, 4, 1),
end_time=datetime(2026, 4, 21),
model_ids=["qwen-turbo", "qwen-plus"],
)
print(stats.data)
client.usage.history()
Query API call history with multi-dimension filters.
start_time/end_timeare REQUIRED (backend NPEs if missing; the SDK raisesValueErrorclient-side).
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| provider | str | No | None | Provider filter |
| feature | str | No | None | Feature module filter |
| request_type | str | No | None | Request type filter |
| start_time | datetime | Yes | -- | Query start time (REQUIRED) |
| end_time | datetime | Yes | -- | Query end time (REQUIRED) |
| keyword | str | No | None | Keyword search |
| page_num | int | No | None | Page number |
| page_size | int | No | None | Items per page |
| model_ids | list[str] | No | None | Model ID filter list |
| inputs | list[str] | No | None | Input type filter list |
| outputs | list[str] | No | None | Output type filter list |
Response
Returns BaseResponse[PageInfo[HistoryRecord]].
HistoryRecord fields:
| Field | Type | Description |
|---|---|---|
| requestId | str | Request ID |
| modelNameVersion | str | Model name and version |
| statusCode | int | HTTP status code |
| latency | float | Gateway latency (ms) |
| totalTokens | int | Total token count |
| timestamp | datetime | Request time |
| requestType | str | Request type |
| modelTechnology | str | Model technology |
| promptTokens | int | Input token count |
| completionTokens | int | Output token count |
| providerTtft | float | TTFT (time to first token, ms) |
| providerLatency | float | Provider latency (ms) |
| providerResponseType | str | Response type |
| apiKeyName | str | API Key name |
| gatewayRequestBodySize | int | Request body size (bytes) |
| errorMsg | str | Error message |
from wlt import WltClient
from datetime import datetime
client = WltClient(api_key="sk-your-api-key")
result = client.usage.history(
start_time=datetime(2026, 4, 1),
end_time=datetime(2026, 4, 21),
provider="dashscope",
page_num=1,
page_size=20,
)
for record in result.data.list:
print(record.modelNameVersion, record.requestType, record.timestamp)
# Search by keyword within a time window (start/end remain required)
result = client.usage.history(
keyword="qwen",
start_time=datetime(2026, 4, 1),
end_time=datetime(2026, 4, 21),
page_num=1,
page_size=10,
)
client.usage.gateway_providers()
Get gateway provider list for usage filtering.
Parameters
None.
Response
Returns BaseResponse[list[ProviderVO]].
ProviderVO fields:
| Field | Type | Description |
|---|---|---|
| id | str | Provider identifier |
| name | str | Provider display name |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
providers = client.usage.gateway_providers()
for p in providers.data:
print(p.id, p.name)
User
client.user.info()
Get the current logged-in user's information.
Parameters
None.
Response
Returns BaseResponse[LoginUser].
LoginUser fields:
| Field | Type | Description |
|---|---|---|
| userId | int | User ID |
| aliyunPk | str | Aliyun PK info |
| parentPk | str | Parent account PK info |
| accountStructure | int | Account type: 1=Partner, 2=Customer main account, 3=SubUser, 4=TokenLogin |
| cmUserId | str | CM user ID |
| tenantCode | str | Tenant code |
| userName | str | Username |
| bucId | int | BUC ID |
| bid | str | BID |
| needAuth | bool | Whether SLR authorization is needed |
| parentUserId | int | Parent account database ID |
| securityToken | str | Security token |
| accessKeyId | str | AccessKey ID |
| timezone | str | Timezone info |
| region | str | Region info |
| userPermission | UserPermissionResponse | User permission info |
| userType | str | User type (e.g. PartnerUser / PartnerUserSub) |
| partnerId | int | Tenant ID |
| partnerName | str | Tenant name |
| partnerLogoUrl | str | Tenant logo URL |
| sourceExternalTicket | str | SSO external ticket |
| thirdChannel | str | Third-party channel source |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
user = client.user.info()
print(f"User ID: {user.data.userId}")
print(f"Username: {user.data.userName}")
Billing
client.billing.query_all_amount()
Query total billing amount for a given billing cycle.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| billing_cycle | str | Yes | -- | Billing cycle, format "YYYY-MM" (e.g. "2026-04") |
Response
Returns BaseResponse[UserBillingMonthResponse].
UserBillingMonthResponse fields:
| Field | Type | Description |
|---|---|---|
| afterDiscountAmountSum | Decimal | Amount after discount |
| deductedByCouponsSum | Decimal | Coupon deduction amount |
| pretaxGrossAmountSum | Decimal | Original amount (list price) |
| pretaxAmountSum | Decimal | Payable amount |
| currency | str | Currency code (e.g. "USD") |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
bill = client.billing.query_all_amount(billing_cycle="2026-04")
print(f"Total amount: {bill.data.pretaxAmountSum}")
print(f"Currency: {bill.data.currency}")
client.billing.query_bill_by_gpu()
Query billing details by GPU spec with pagination.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| billing_cycle | str | Yes | -- | Billing cycle, format "YYYY-MM" |
| page_size | int | No | 10 | Items per page |
| page_num | int | No | 1 | Page number, starting from 1 |
Response
Returns BaseResponse[PageInfo[UserBillingGpuServiceResponse]].
UserBillingGpuServiceResponse fields:
| Field | Type | Description |
|---|---|---|
| afterDiscountAmountSum | Decimal | Amount after discount |
| deductedByCouponsSum | Decimal | Coupon deduction amount |
| pretaxGrossAmountSum | Decimal | Original amount |
| pretaxAmountSum | Decimal | Payable amount |
| listPrice | Decimal | List price (unit price) |
| currency | str | Currency code |
| gpuSpec | str | GPU spec (e.g. "A100-80G") |
| servicePeriodUnit | str | Service period unit (e.g. "Hour") |
| servicePeriodSum | str | Total service period |
| modelResource | str | Model resource identifier |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
result = client.billing.query_bill_by_gpu(
billing_cycle="2026-04",
page_size=10,
page_num=1,
)
for item in result.data.list:
print(f"GPU: {item.gpuSpec}, Amount: {item.pretaxAmountSum}")
client.billing.query_bill_by_service()
Query billing details by AI service with pagination.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| billing_cycle | str | Yes | -- | Billing cycle, format "YYYY-MM" |
| page_size | int | No | 10 | Items per page |
| page_num | int | No | 1 | Page number, starting from 1 |
Response
Returns BaseResponse[PageInfo[UserBillingAiServiceResponse]].
UserBillingAiServiceResponse fields:
| Field | Type | Description |
|---|---|---|
| afterDiscountAmountSum | Decimal | Amount after discount |
| deductedByCouponsSum | Decimal | Coupon deduction amount |
| pretaxGrossAmountSum | Decimal | Original amount |
| pretaxAmountSum | Decimal | Payable amount |
| currency | str | Currency code |
| gpuSpec | str | GPU spec |
| modelResource | str | Model resource identifier |
| servicePeriodUnit | str | Service period unit |
| servicePeriodSum | str | Total service period |
| bizType | str | Business type (e.g. "Deploy", "Finetune") |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
result = client.billing.query_bill_by_service(
billing_cycle="2026-04",
page_size=10,
page_num=1,
)
for item in result.data.list:
print(f"Service: {item.bizType}, Amount: {item.pretaxAmountSum}")
client.billing.query_bill_list()
Query billing detail list with pagination.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| billing_cycle | str | Yes | -- | Billing cycle, format "YYYY-MM" |
| page_size | int | No | 10 | Items per page |
| page_num | int | No | 1 | Page number, starting from 1 |
Response
Returns BaseResponse[PageInfo[UserBillingResponse]].
UserBillingResponse fields:
| Field | Type | Description |
|---|---|---|
| afterDiscountAmount | Decimal | Amount after discount |
| deductedByCoupons | Decimal | Coupon deduction amount |
| pretaxGrossAmount | Decimal | Original amount |
| pretaxAmount | Decimal | Payable amount |
| instanceID | str | Instance ID |
| currency | str | Currency code |
| productCode | str | Product code |
| region | str | Region |
| gpuSpec | str | GPU spec |
| modelResource | str | Model resource identifier |
| servicePeriodUnit | str | Service period unit |
| servicePeriod | str | Service period |
| bizType | str | Business type (e.g. "Deploy", "Finetune") |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
result = client.billing.query_bill_list(
billing_cycle="2026-04",
page_size=20,
page_num=1,
)
print(f"Total records: {result.data.total}")
for item in result.data.list:
print(item)
Payment
client.payment.records()
Query recharge records with pagination.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| page_num | int | No | 1 | Page number, starting from 1 |
| page_size | int | No | 10 | Items per page (max 1000) |
| status_list | list[str] | No | None | Status filter: "0"=processing, "1"=success, "2"=failed, "3"=closed |
| start_time | datetime | No | None | Query start time |
| end_time | datetime | No | None | Query end time |
| transaction_type | str | No | None | Transaction type: "Recharge" or "Refund" |
Response
Returns BaseResponse[PageResponse] where the list field contains RechargeTransactionResponse items.
PageResponse fields (Payment-specific pagination):
| Field | Type | Description |
|---|---|---|
| pageNum | int | Current page number |
| pageSize | int | Items per page |
| total | int | Total record count |
| pages | int | Total number of pages |
| hasNext | bool | Whether there is a next page |
| hasPrevious | bool | Whether there is a previous page |
| list | list | Data list |
RechargeTransactionResponse fields:
| Field | Type | Description |
|---|---|---|
| id | int | Record primary key ID |
| createdAtUtc | str | Creation time (UTC) |
| updatedAtUtc | str | Update time (UTC) |
| userId | int | User ID |
| payChannel | str | Payment channel (e.g. "Stripe") |
| payType | str | Payment type (APP / WEB) |
| transactionType | str | Transaction type (Recharge / Refund) |
| status | str | Status: 0=processing, 1=success, 2=failed, 3=closed |
| callbackAtUtc | str | Callback time (UTC) |
| transactionNo | str | Platform transaction number |
| externalNo | str | External transaction number (Stripe ID) |
| amount | str | Transaction amount |
| refundAmount | str | Refunded amount |
| currency | str | Currency (ISO 4217) |
| refundStatus | str | Refund status: 0=none, 1=partial, 2=full |
| originalTransactionNo | str | Original transaction number (for refund records) |
| extend | str | Extension field (JSON) |
from wlt import WltClient
from datetime import datetime
client = WltClient(api_key="sk-your-api-key")
# List successful recharge records
result = client.payment.records(
page_num=1,
page_size=10,
status_list=["1"], # 0=processing, 1=success, 2=failed, 3=closed
)
print(f"Total: {result.data.total}")
for record in result.data.list:
print(record.transactionNo, record.amount, record.status)
# With time range and transaction type
result = client.payment.records(
start_time=datetime(2026, 4, 1),
end_time=datetime(2026, 4, 21),
transaction_type="Recharge",
)
client.payment.statistics()
Query recharge statistics summary.
Parameters
None.
Response
Returns BaseResponse[RechargeStatisticsResponse].
RechargeStatisticsResponse fields:
| Field | Type | Description |
|---|---|---|
| totalRechargedAmount | str | Total recharged amount |
| totalUsedRechargedAmount | str | Total used recharged amount |
| totalBalanceRechargedAmount | str | Unused recharge balance |
| totalRefundAmount | str | Total refund amount |
| totalFreeAmount | str | Free quota amount |
| currency | str | Currency code |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
stats = client.payment.statistics()
print(f"Total recharged: {stats.data.totalRechargedAmount}")
client.payment.get_record()
Get a single recharge record by transaction number.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| transaction_no | str | Yes | -- | Platform transaction number |
Response
Returns BaseResponse[RechargeTransactionResponse].
RechargeTransactionResponse fields: see
client.payment.records()above.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
record = client.payment.get_record(transaction_no="TXN20260421001")
print(f"Amount: {record.data.amount}")
print(f"Status: {record.data.status}")
print(f"Created: {record.data.createdAtUtc}")
client.payment.billing_list()
Query model usage billing list with pagination.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| page_num | int | No | 1 | Page number, starting from 1 |
| page_size | int | No | 10 | Items per page (max 1000) |
| start_time | str | No | None | Start time, format "yyyy-MM-dd HH:mm:ss" |
| end_time | str | No | None | End time, format "yyyy-MM-dd HH:mm:ss" |
| model_id | str | No | None | Model ID for exact filtering |
Response
Returns BaseResponse[PageInfo[LmModelUsageBillingResponse]].
LmModelUsageBillingResponse fields:
| Field | Type | Description |
|---|---|---|
| id | int | Record primary key ID |
| createdAtUtc | str | Record creation time (UTC) |
| userId | int | User ID |
| username | str | Username |
| modelName | str | Model name |
| modelType | str | Model type |
| feeType | str | Fee type (e.g. "input tokens" / "output tokens") |
| unitPrice | str | Unit price (per 1K tokens) |
| currency | str | Currency (ISO 4217) |
| usedAmout | str | Usage amount (token count). Note: field name matches backend spelling |
| amount | str | Billed amount |
| billingTimeStart | str | Billing start time |
| billingTimeEnd | str | Billing end time |
| extend | str | Extension field (JSON) |
| inputs | set[str] | Input type list |
| outputs | set[str] | Output type list |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
result = client.payment.billing_list(
page_num=1,
page_size=10,
start_time="2026-04-01 00:00:00",
end_time="2026-04-21 23:59:59",
)
print(f"Total: {result.data.total}")
for item in result.data.list:
print(item.modelName, item.amount)
# Filter by model
result = client.payment.billing_list(
start_time="2026-04-01 00:00:00",
end_time="2026-04-21 23:59:59",
model_id="qwen-turbo",
)
client.payment.billing_query_all_amount()
Query model usage billing total amount.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| start_time | str | No | None | Start time, format "yyyy-MM-dd HH:mm:ss" |
| end_time | str | No | None | End time, format "yyyy-MM-dd HH:mm:ss" |
| model_id | str | No | None | Model ID for exact filtering |
Response
Returns BaseResponse[ModelUsageBillingAmountResponse].
ModelUsageBillingAmountResponse fields:
| Field | Type | Description |
|---|---|---|
| totalBillingAmount | str | Total billing amount |
| currency | str | Currency code |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
total = client.payment.billing_query_all_amount(
start_time="2026-04-01 00:00:00",
end_time="2026-04-21 23:59:59",
)
print(f"Total billing amount: {total.data.totalBillingAmount}")
# Filter by specific model
total = client.payment.billing_query_all_amount(
start_time="2026-04-01 00:00:00",
end_time="2026-04-21 23:59:59",
model_id="qwen-turbo",
)
Model Gallery
client.model_gallery.page()
Query model list with pagination.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| page_num | int | No | 1 | Page number, starting from 1 |
| page_size | int | No | 10 | Items per page |
| model_name | str | No | None | Model name (fuzzy search) |
| provider | str | No | None | Provider identifier |
| series_provider | str | No | None | Series provider identifier |
| model_type | str | No | None | Model type |
| view_all_flag | int | No | None | View all flag (1=view all) |
| usage_type | str | No | None | Usage type: "inference" or "train" |
| training_method | str | No | None | Training method: "sft" or "dpo" |
| tags | list[str] | No | None | Tag filter list |
| capability | str | No | None | Capability filter, e.g. "text_to_text" |
| model_type_list | list[str] | No | None | Model type list (multi-select) |
| origin_providers | list[str] | No | None | Origin provider list (multi-select) |
| inputs | list[str] | No | None | Input type list, e.g. ["text"] |
| outputs | list[str] | No | None | Output type list, e.g. ["image"] |
Response
Returns BaseResponse[PageInfo[ModelInfoVO]].
ModelInfoVO fields: see
client.secrets.model_list()above.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
# Browse all models
result = client.model_gallery.page(page_num=1, page_size=10)
print(f"Total models: {result.data.total}")
for model in result.data.list:
print(model.modelName, model.provider)
# Filter by criteria
result = client.model_gallery.page(
usage_type="inference",
provider="dashscope",
tags=["New"],
inputs=["text"],
outputs=["text"],
)
client.model_gallery.providers()
Get the list of model providers.
Parameters
None.
Response
Returns BaseResponse[list[ProviderVO]].
ProviderVO fields:
| Field | Type | Description |
|---|---|---|
| id | str | Provider identifier |
| name | str | Provider display name |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
providers = client.model_gallery.providers()
for p in providers.data:
print(p.id, p.name)
client.model_gallery.get_price()
Get model API price for the current tenant.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| model_name | str | Yes | -- | Model name |
Response
Returns BaseResponse[PartnerApiPriceResponse].
PartnerApiPriceResponse fields:
| Field | Type | Description |
|---|---|---|
| id | int | Record ID |
| partnerId | int | Tenant ID |
| modelName | str | Model name |
| modelType | str | Model type |
| type | str | Resale type (model / BYOK) |
| originProvider | str | Origin provider |
| seriesProvider | str | Series provider |
| capabilities | str | Model capabilities |
| inputs | set[str] | Input type set |
| outputs | set[str] | Output type set |
| priceExtend | PartnerApiPriceExtendDetail | Price details |
| gmtCreate | datetime | Creation time |
| gmtModified | datetime | Modification time |
PartnerApiPriceExtendDetail fields:
| Field | Type | Description |
|---|---|---|
| llmInput | str | LLM input price (per 1K tokens) |
| llmOutput | str | LLM output price (per 1K tokens) |
| vlmInput | str | VLM input price (per 1K tokens) |
| vlmOutput | str | VLM output price (per 1K tokens) |
| image | str | Image generation price |
| imageEa | str | Image unit price |
| imageStep | str | Image step price |
| video | str | Video generation price |
| audio | str | Audio price |
| tieredPricing | list[TieredPricing] | Tiered pricing list |
| videoPricing | list[VideoPricing] | Video pricing list |
| imagePricing | list[ImagePricing] | Image pricing list |
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
price = client.model_gallery.get_price(model_name="Qwen2.5-72B-Instruct")
print(f"Input price: {price.data.priceExtend.llmInput}")
print(f"Output price: {price.data.priceExtend.llmOutput}")
Model Lab
client.model_lab.list()
Get model list for the Model Lab.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| model_name | str | No | None | Model name (fuzzy search) |
| provider | str | No | None | Provider identifier |
| series_provider | str | No | None | Series provider identifier |
| model_type | str | No | None | Model type |
| view_all_flag | int | No | None | View all flag (1=view all) |
| page_size | int | No | None | Items per page. Required by backend (code=1000 if missing). Recommended default: 20 |
| page_num | int | No | None | Page number. Required by backend (code=1000 if missing). Recommended default: 1 |
| usage_type | str | No | None | Usage type: "inference" or "train" |
| training_method | str | No | None | Training method: "sft" or "dpo" |
| tags | list[str] | No | None | Tag filter list |
| capability | str | No | None | Capability filter, e.g. "text_to_text" |
| model_type_list | list[str] | No | None | Model type list (multi-select) |
| origin_providers | list[str] | No | None | Origin provider list (multi-select) |
| inputs | list[str] | No | None | Input type list, e.g. ["text"] |
| outputs | list[str] | No | None | Output type list (max 1 item), e.g. ["image"] |
Response
Returns BaseResponse[list[ModelInfoVO]].
ModelInfoVO fields: see
client.secrets.model_list()above.
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
# List inference models
models = client.model_lab.list(usage_type="inference")
for m in models.data:
print(m.modelName, m.provider)
# Filter by provider and capability
models = client.model_lab.list(
provider="dashscope",
capability="text_to_text",
inputs=["text"],
outputs=["text"],
)
client.model_lab.create_session()
Create a new chat session for multi-turn conversations.
Parameters
None.
Response
Returns BaseResponse[str]. The data field contains a UUID string (session ID).
from wlt import WltClient
client = WltClient(api_key="sk-your-api-key")
session = client.model_lab.create_session()
session_id = session.data # UUID string
print(f"Session ID: {session_id}")
client.model_lab.stream()
Call model stream inference (SSE). Yields each SSE data chunk as a raw JSON string.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| provider | str | Yes | -- | Provider identifier |
| model_name | str | Yes | -- | Model name |
| user_prompt | str | Yes (unless retry) | None | User prompt text |
| session_id | str | No | None | Session ID (for multi-turn conversations, use UUID) |
| task_id | str | No | None | Task ID (for retry, references the failed task) |
| task_type | str | No | "TEXT" |
Task type |
| is_retry | bool | No | False | Whether this is a retry request (requires task_id) |
| options | OptionsDTO | No | None | Model parameter configuration (see below) |
OptionsDTO fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| temperature | float | No | None | Temperature, controls output randomness |
| maxToken | int | No | None | Maximum generated token count |
| topP | float | No | None | Top P sampling parameter |
| topK | int | No | None | Top K sampling parameter |
| presencePenalty | float | No | None | Presence penalty |
| frequencyPenalty | float | No | None | Frequency penalty |
| stopSequences | str | No | None | Stop sequences |
| systemPrompt | str | No | None | System prompt |
| enableThinking | bool | No | None | Enable deep thinking |
| enableProgress | bool | No | None | Enable progress push |
| timeoutSeconds | int | No | None | Task timeout (seconds) |
| enableCache | bool | No | None | Enable result caching |
| enableDocumentInlining | bool | No | None | Enable document inlining |
| budgetTokens | int | No | None | Budget token count |
Response
Returns a generator yielding SSE data chunks as raw JSON strings. Each chunk follows the OpenAI-compatible streaming format. The stream ends with a [DONE] sentinel.
import json
from wlt import WltClient
from wlt.models.model_lab import OptionsDTO
client = WltClient(api_key="sk-your-api-key")
# Create a session for multi-turn conversation
session = client.model_lab.create_session()
# Stream inference (use a provider + model that is actually served by the
# gateway -- discover via `client.model_lab.list()` / `client.usage.gateway_providers()`.
# On the daily environment, `openrouter` + `openai/gpt-5.4-nano` is a known-good pair).
for chunk in client.model_lab.stream(
provider="openrouter",
model_name="openai/gpt-5.4-nano",
user_prompt="Explain quantum computing in one paragraph.",
session_id=session.data,
options=OptionsDTO(
temperature=0.7,
maxToken=2048,
topP=0.9,
systemPrompt="You are a helpful assistant.",
),
):
data = json.loads(chunk)
# Each chunk contains delta content, finish_reason, usage, etc.
if "content" in data:
print(data["content"], end="", flush=True)
print() # newline after streaming completes
Error Handling
All API methods can raise typed exceptions. The SDK auto-refreshes the Bearer token whenever the server returns an authentication failure -- HTTP 401 / 403 or a business code in {2000, 2002, 2007, 3001} (see _AUTH_ERROR_CODES in src/wlt/_http.py). AuthenticationError is only raised if the refresh attempt also fails.
All exception classes are re-exported from the package root, so you can
from wlt import WltError (no need to import from wlt._exceptions):
from wlt import (
WltClient,
# Exception classes (also available as `from wlt._exceptions import ...`
# for backwards compatibility, but the top-level import is preferred).
WltError,
APIError,
AuthenticationError,
PermissionError,
NotFoundError,
ValidationError,
RateLimitError,
InternalError,
ConnectionError,
TimeoutError,
)
client = WltClient(api_key="sk-your-api-key")
try:
result = client.secrets.list()
except AuthenticationError as e:
# code 2000/2002: API Key invalid; code 3001: token expired (auto-refresh failed)
print(f"Auth failed (code={e.code}): {e.message}")
except PermissionError as e:
print(f"Permission denied (code={e.code}): {e.message}")
except NotFoundError as e:
print(f"Not found (code={e.code}): {e.message}")
except ValidationError as e:
print(f"Invalid params (code={e.code}): {e.message}")
except RateLimitError as e:
print(f"Rate limited (code={e.code}): {e.message}")
except InternalError as e:
print(f"Server error (code={e.code}): {e.message}")
except APIError as e:
# Catch-all for any other business error code
print(f"API error (code={e.code}): {e.message}")
except ConnectionError as e:
print(f"Network error: {e.message}")
except TimeoutError as e:
print(f"Request timeout: {e.message}")
Error Code Reference
| Code | Exception | Description |
|---|---|---|
| 200 | (success) | OK |
| 1000 | InternalError |
Server internal error |
| 1001 | ValidationError |
Invalid request parameters |
| 1002 | NotFoundError |
Resource not found |
| 2000 | AuthenticationError |
Login failure |
| 2002 | AuthenticationError |
Authentication error |
| 2007 | PermissionError |
Permission denied |
| 3000 | APIError |
Invalid request (observed in production on Model Gallery detail with non-numeric id) |
| 3001 | AuthenticationError |
Token expired / invalid |
| 3002 | RateLimitError |
Rate limit exceeded |
Provider Values
Valid provider values for Secret allowedProviders and ApiKey operations:
dashscopedashscope-intldashscope-usopenrouterzenlayer
Use client.secrets.providers(), client.api_keys.providers(), or
client.model_gallery.providers() to retrieve the latest available providers dynamically.
Available Services Summary (35 Methods)
| Service | Field | Methods |
|---|---|---|
| User | client.user |
info |
| Secrets | client.secrets |
list, detail, create, edit, action, usage_by_model, model_list, providers |
| ApiKeys | client.api_keys |
list, create, update, delete, change_status, test_connect, providers |
| Usage | client.usage |
serverless_list, serverless_stats, history, gateway_providers |
| Billing | client.billing |
query_all_amount, query_bill_by_gpu, query_bill_by_service, query_bill_list |
| Payment | client.payment |
records, statistics, get_record, billing_list, billing_query_all_amount |
| ModelGallery | client.model_gallery |
page, providers, get_price |
| ModelLab | client.model_lab |
list, create_session, stream |
CLI
Installing wlt-platform also installs a wlt command-line tool wrapping the SDK. Verify with wlt --help; you can also invoke it as python -m wlt --help.
Most subcommands accept a
--jsonflag to emit raw JSON output (useful for scripting).
Authentication Sources
The CLI accepts an API Key from three sources (highest to lowest priority):
| Priority | Source | Notes |
|---|---|---|
| 1 | --api-key flag |
Per-invocation override; the global --api-key flag does not persist (use wlt login --api-key to persist). |
| 2 | WLT_API_KEY environment variable |
Convenient for CI / scripts. |
| 3 | ~/.wlt/config.json |
Written by wlt login; file permissions 0600. |
Base URL resolution for the CLI follows the same precedence:
| Priority | Source |
|---|---|
| 1 | --base-url passed to wlt login (persisted) |
| 2 | WLT_BASE_URL environment variable |
| 3 | base_url in ~/.wlt/config.json |
| 4 | Default https://daily.sssxuntui.com |
The config file uses a dual-key convention -- both api_key / apiKey and base_url / baseUrl are persisted, so the Python CLI and Node.js CLI share the same login state on the same machine.
Common Commands
# Login (persists API Key + optional base URL to ~/.wlt/config.json)
wlt login --api-key sk-xxxxxxxxxxxxxxxxxxxx
wlt login --api-key sk-xxxxxxxxxxxxxxxxxxxx --base-url https://your.host
# Logout (removes local credentials)
wlt logout
# Show current user
wlt whoami
# Manage local config (~/.wlt/config.json)
wlt config set base_url https://your.host
wlt config set api_key sk-xxxxxxxxxxxxxxxxxxxx
wlt config get base_url
wlt config list # api_key shown masked
# Resource commands
wlt secret list [--page-num N] [--page-size N]
wlt secret detail <id>
wlt secret create --name <name>
wlt secret edit <id> --name <new-name>
# Note (cross-language divergence): Python CLI uses `--id <id>` while Node CLI
# uses a positional `<id>`. Both target the same backend endpoint.
wlt secret action --id <id> --status ENABLE|DISABLE|DELETE
# Note: Python CLI's `usage-by-model` currently exposes only <id>+pagination
# flags (the SDK method itself accepts start/end time -- Node CLI exposes
# --start/--end; Python CLI alignment is a known follow-up).
wlt secret usage-by-model <id> [--page-num N] [--page-size N]
wlt secret models
wlt secret providers
wlt apikey list [--page-num N] [--page-size N]
wlt apikey create --name <name> --provider <provider> --key <secret> [--key-id <id>]
wlt apikey update <id> --name <new-name>
wlt apikey delete <id>
wlt apikey change-status <id> --status 1|0
wlt apikey test-connect --provider <provider> --key <secret> [--key-id <id>]
wlt apikey providers
wlt usage list --start <date> --end <date> [--page-num N] [--page-size N]
wlt usage stats --start <date> --end <date>
wlt usage history [--page-num N] [--page-size N] [--start <date>] [--end <date>]
wlt usage providers
wlt billing summary --cycle YYYY-MM
wlt billing by-gpu --cycle YYYY-MM [--page-num N] [--page-size N]
wlt billing by-service --cycle YYYY-MM [--page-num N] [--page-size N]
wlt billing list --cycle YYYY-MM [--page-num N] [--page-size N]
wlt payment records [--page-num N] [--page-size N]
wlt payment statistics
wlt payment detail <transaction_no>
# Note: payment billing-list / billing-amount require full datetime
# "YYYY-MM-DD HH:MM:SS" (NOT bare "YYYY-MM-DD" -- backend rejects it).
# usage list / stats / history accept either form.
wlt payment billing-list --start "2026-04-01 00:00:00" --end "2026-04-30 23:59:59" [--page-num N] [--page-size N]
wlt payment billing-amount --start "2026-04-01 00:00:00" --end "2026-04-30 23:59:59"
wlt model list [--page-num N] [--page-size N]
wlt model providers
wlt model price <model-name>
wlt lab list [--page-num N] [--page-size N]
wlt lab session
wlt lab chat --provider <provider> --model <name> --message "<text>" [--session-id <id>]
Streaming Chat — runnable example
wlt lab chat requires a real provider + model combination that is registered in the model registry. To discover what's available:
# 1. Find available gateway providers
wlt usage providers
# 2. List available models with their callable provider
wlt lab list --page-num 1 --page-size 5
# 3. Stream a real chat (daily endpoint via OpenRouter gateway)
wlt lab chat --provider openrouter --model openai/gpt-5.4-nano --message "Say hi in 5 words"
CLI vs SDK surface
The CLI exposes a curated subset of the SDK's surface. Three things to know when comparing CLI flags to SDK method parameters:
- Some flags re-map to differently-named SDK parameters. The CLI uses
the shorter, more user-friendly name; the SDK uses the backend's JSON name.
wlt apikey create --name <n>→ SDKclient.api_keys.create(key_name=n, ...)wlt apikey create --key <s>→ SDKaccess_key_secret=swlt apikey create --key-id <id>→ SDKaccess_key_id=idwlt apikey test-connect --key <s> --key-id <id>→ same mapping as above
- Not every SDK parameter is exposed as a CLI flag. Lower-traffic filters
such as
status/expired_before_utconsecrets.list(),provider/timezoneonapi_keys.list(),tpm_limit/token_limitonapi_keys.create(), andapi_key/inputs/outputsonusage.serverless_list()are SDK-only. Reach for the SDK when you need them. - Cross-language divergences (Python vs Node CLI):
wlt secret action— Python uses--id <id>, Node uses positional<id>wlt secret usage-by-model— Node accepts--start/--end, Python does not currently (follow-up). The SDK method itself accepts both.
Global Options
| Option | Description |
|---|---|
--help |
Show command help. |
--version |
Show CLI version. |
--api-key <key> |
Override API Key for the current invocation (not persisted). |
--base-url <url> |
Override base URL for the current invocation. |
--json |
Emit raw JSON output (default: human-readable). |
Base URL Resolution
The CLI follows the four-level precedence documented in Base URL Configuration. When --base-url is omitted, the CLI falls back to WLT_BASE_URL, then ~/.wlt/config.json base_url, then the default https://daily.sssxuntui.com.
License
Apache-2.0
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 wlt_platform-0.1.12.tar.gz.
File metadata
- Download URL: wlt_platform-0.1.12.tar.gz
- Upload date:
- Size: 54.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb6a9ef715535d771405a2abc9809f4601bf4c4a50ea4b4102bbc5a9d39a494b
|
|
| MD5 |
f336acbc75c403ee0fe40cb6a7b167c0
|
|
| BLAKE2b-256 |
44a87d83935a57b1e063a8d05aca61cbfa17db57f15b0cd3ab5cccf83bb83453
|
File details
Details for the file wlt_platform-0.1.12-py3-none-any.whl.
File metadata
- Download URL: wlt_platform-0.1.12-py3-none-any.whl
- Upload date:
- Size: 55.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77976f76dc7be48fc3e1ae51cf925969284135be67c6723fbbd0676e411d2f48
|
|
| MD5 |
e0c2d80a6aa247a5b259b71d9ecf3160
|
|
| BLAKE2b-256 |
be55ca70a388545c2f38cabde002bacc86c52de388769619f8e42c0b58a6244a
|