Python SDK
The official Python SDK for the BiOS fine-tuning platform. Build, train, and manage models programmatically with full type hints and both sync and async support.
Installation
pip install usfbiosRequires Python 3.9+. For async support:
pip install usfbios[async]API Key Setup
Before using the SDK, create an API key from the BIOS console:
- Sign in at
https://bios.us.comwith your account (e.g.bios@us.inc). - Navigate to Settings → API Keys in the dashboard sidebar.
- Click Create API Key and enter a name (e.g. “Python Development”).
- Select the permission scopes your application needs (same scopes as TypeScript SDK).
- Click Create and copy the key (starts with
sk_live_). It is shown only once.
export USFBIOS_API_KEY=sk_live_.... The SDK picks it up automatically so you never hardcode secrets.Configuration
Initialize the client with your API key:
from usfbios import USFBios
client = USFBios(api_key="sk_live_...")
# Or let the SDK read from USFBIOS_API_KEY env var:
client = USFBios()All configuration options:
| Option | Type | Default | Description |
|---|---|---|---|
| api_key | str | env USFBIOS_API_KEY | API key (recommended). Starts with sk_live_. |
| access_token | str | None | JWT token (alternative to API key). |
| base_url | str | https://api.usbios.ai | API base URL. |
| org_id | str | None | Organization ID (required with JWT, auto-resolved with API key). |
| workspace_id | str | None | Workspace ID (required with JWT, auto-resolved with API key). |
| timeout | float | 30.0 | Request timeout in seconds. |
| max_retries | int | 3 | Max retries on transient errors (429, 5xx). |
You can also introspect your API key to check permissions:
info = client.introspect()
print(f"Org: {info.org.name}")
print(f"Workspace: {info.workspace.name}")
print(f"Scopes: {', '.join(info.scopes)}")Resources & Methods
The SDK is organized into resource namespaces. Each method returns typed dataclass objects with full IDE autocompletion.
Models
Search the model catalog, fetch training configs, and check adapter compatibility.
# Search for models
results = client.models.search(query="llama", type="llm", limit=10)
for m in results.models:
print(f"{m.id} - {m.total_params}B params")
# Get model config for GPU planning
config = client.models.get_config("meta-llama/Llama-3.1-8B")
print(f"{config.total_params}B params, MoE: {config.is_moe}")
# Check adapter compatibility
compat = client.models.get_adapter_compatibility(
model_type="llama",
training_method="rlhf",
rlhf_algorithm="dpo",
)
usable = [a for a in compat.adapters if a.compatible]
print(f"{len(usable)} compatible adapters")| Method | Scope | Description |
|---|---|---|
| models.search(**params) | models:read | Search 250+ fine-tunable models |
| models.get_config(model_id) | models:read | Get training config (params, architecture, MoE) |
| models.get_adapter_compatibility(**params) | models:read | Check adapter compatibility for architecture |
Datasets
Upload, import, preview, validate, and manage training datasets.
# Upload a local dataset file
ds = client.datasets.upload(
file_path="./training_data.jsonl",
name="Customer Support SFT",
)
print(f"Uploaded: {ds.id}")
# List all datasets
datasets = client.datasets.list()
print(f"{len(datasets)} datasets")
# Preview rows before training
preview = client.datasets.preview("ds_abc123", page=1, page_size=5)
print(preview.columns)
# Validate a file before uploading
result = client.datasets.validate("./data.jsonl")
if result.valid:
print(f"Valid {result.format} - {result.row_count} rows")
else:
print("Errors:", result.errors)
# Import from HuggingFace
imported = client.datasets.import_from_huggingface(
repo_id="databricks/dolly-15k",
integration_id="int_abc123",
name="Dolly 15k",
)
# Search HuggingFace Hub
hub_results = client.datasets.search_hub(query="code instruct")
# Delete a dataset
client.datasets.delete("ds_abc123")| Method | Scope | Description |
|---|---|---|
| datasets.list(**params) | datasets:read | List datasets in workspace |
| datasets.get(id) | datasets:read | Get dataset details |
| datasets.upload(**params) | datasets:write | Upload a local file (JSONL, CSV, Parquet) |
| datasets.preview(id, **params) | datasets:read | Preview rows with pagination |
| datasets.get_status(id) | datasets:read | Get processing status |
| datasets.validate(file_path) | datasets:write | Validate file format before upload |
| datasets.import_from_huggingface(**params) | datasets:write | Import from HuggingFace via integration |
| datasets.register_huggingface(data) | datasets:write | Register a public HF dataset directly |
| datasets.search_hub(**params) | datasets:read | Search public HuggingFace Hub datasets |
| datasets.preview_hub(**params) | datasets:read | Preview rows from a HF Hub dataset |
| datasets.get_format_specs() | datasets:read | Get supported format specifications |
| datasets.get_storage_usage(workspace_id) | datasets:read | Get storage usage summary |
| datasets.delete(id) | datasets:write | Delete a dataset |
Training
Create, monitor, stop, and resume fine-tuning jobs.
# Create a training job
job = client.training.create(
idempotency_key="training-create-20260711-0001",
model="meta-llama/Llama-3.1-8B-Instruct",
dataset_id="ds_abc123",
method="sft",
adapter="lora",
epochs=3,
learning_rate=2e-4,
lora_rank=16,
lora_alpha=32,
gpu_type="A100_80GB",
)
print(f"Job {job.id} created - status: {job.status}")
# Monitor training
metrics = client.training.get_metrics(job.id)
print(f"Loss: {metrics.current_loss}")
# View logs
logs = client.training.get_logs(job.id)
for line in logs.logs:
print(line)
# List checkpoints
checkpoints = client.training.get_checkpoints(job.id)
for cp in checkpoints:
print(f"Step {cp.step}: loss {cp.loss}")
# Stop and resume
client.training.stop(job.id)
client.training.resume(job.id, idempotency_key="training-resume-20260711-0001")| Method | Scope | Description |
|---|---|---|
| training.create(**params) | training:write | Launch a new fine-tuning job |
| training.list(**params) | training:read | List jobs with optional filters |
| training.get(id) | training:read | Get job details |
| training.get_metrics(id) | training:read | Get loss curves, LR, throughput |
| training.get_checkpoints(id) | training:read | List saved checkpoints |
| training.get_logs(id) | training:read | Get training stdout/stderr logs |
| training.stop(id, keep_data=True) | training:write | Stop a running job |
| training.resume(id, idempotency_key=None) | training:write | Resume from last checkpoint |
| training.delete_checkpoint(job_id, cp_id) | training:write | Delete a specific checkpoint |
Billing & GPU
Check wallet balance, view transactions, get GPU pricing, and get hardware recommendations.
# Check wallet balance
balance = client.wallet.get_balance()
print(f"Balance: {balance.balance_cents / 100:.2f{'}'}")
# View transaction history
txns = client.wallet.get_transactions(limit=20)
for t in txns:
print(f"{t.type}: {t.amount_cents / 100:.2f{'}'} - {t.description}")
# Get GPU pricing
pricing = client.gpu.get_pricing()
for gpu in pricing.gpus:
print(f"{gpu.display_name}: {gpu.price_display} - {gpu.vram_gb}GB VRAM")
# Get recommended GPU for a model
rec = client.gpu.get_recommended("meta-llama/Llama-3.1-8B-Instruct")
if rec:
print(f"Recommended: {rec.display_name} x{rec.recommended_count}")| Method | Scope | Description |
|---|---|---|
| wallet.get_balance() | billing:read | Current balance, available credits, pending charges |
| wallet.get_transactions(**params) | billing:read | Transaction history with pagination |
| wallet.get_pricing() | billing:read | Compute and storage pricing |
| gpu.get_pricing() | (public) | All GPU types with per-second pricing and VRAM |
| gpu.get_recommended(model_id) | (public) | Best GPU configuration for a model |
Integrations
The SDK accesses integrations through the datasets resource for HuggingFace import workflows:
# Import from a connected HuggingFace account
imported = client.datasets.import_from_huggingface(
repo_id="your-org/private-dataset",
integration_id="int_abc123",
name="My Private Dataset",
split="train",
max_samples=10000,
)
print(f"Imported: {imported.id} - {imported.row_count} rows")Error Handling
All SDK methods raise ApiError on non-2xx responses with typed error details:
from usfbios import USFBios, ApiError
client = USFBios()
try:
job = client.training.get("job_nonexistent")
except ApiError as e:
print(f"HTTP {e.status}: {e.message}")
print(f"Code: {e.code}") # e.g. "NOT_FOUND"
print(f"Request ID: {e.request_id}") # for support
# Common error status codes:
# 401 - Invalid or expired API key
# 403 - Key missing required scope
# 404 - Resource not found
# 422 - Validation error
# 429 - Rate limit exceeded (auto-retried)Async Support
The Python SDK provides a fully async client for use with asyncio. Every method from the sync client has an identical async counterpart:
import asyncio
from usfbios import AsyncUSFBios
async def main():
client = AsyncUSFBios(api_key="sk_live_...")
# All methods are awaitable, same signatures as sync client
models = await client.models.search(query="llama 8B")
print(f"Found {len(models.models)} models")
ds = await client.datasets.upload(
file_path="./data.jsonl",
name="Async Upload",
)
job = await client.training.create(
model="meta-llama/Llama-3.1-8B-Instruct",
dataset_id=ds.id,
method="sft",
adapter="lora",
)
# Monitor in a loop
while True:
status = await client.training.get(job.id)
if status.status in ("completed", "failed"):
break
metrics = await client.training.get_metrics(job.id)
print(f"Step {metrics.global_step}: loss {metrics.current_loss:.4f}")
await asyncio.sleep(30)
await client.close()
asyncio.run(main())httpx under the hood. Install with pip install usfbios[async] to include the async dependencies. The async client also supports context managers: async with AsyncUSFBios() as client:Type Hints
The SDK ships with full type hints and dataclass response objects. All request parameters and response types are importable:
from usfbios.types import (
ModelSearchParams,
ModelSearchResponse,
ModelConfig,
Dataset,
DatasetUploadParams,
TrainingJob,
TrainingCreateParams,
TrainingMetrics,
TrainingCheckpoint,
WalletBalance,
Transaction,
GPUPricingResponse,
ApiKeyIntrospection,
)
# All responses are typed dataclasses with IDE autocompletion
job: TrainingJob = client.training.get("job_abc123")
print(job.model) # str
print(job.status) # Literal["pending", "running", "completed", "failed"]
print(job.created_at) # datetimeUser-Agent header with every request. Compatible with Python 3.9+, including CPython, PyPy, and Jupyter notebooks.BiOS Documentation. Need help? Email help-bios@us.inc