Official Python SDK for the BIOS training and deployment platform API
Project description
bios
Official Python SDK for the BIOS fine-tuning platform API.
Installation
pip install bios
Quick Start
from bios import BiOS
client = BiOS(api_key="bios-...")
# Search for models
result = client.models.search(query="llama", type="llm", limit=5)
for model in result["models"]:
print(f"{model['id']} -- {model['totalParams']}B params")
# Create a training job
job = client.training.create(
idempotency_key="training-create-20260711-0001",
model="meta-llama/Llama-3.1-8B-Instruct",
dataset_ids=["ds_abc123", "ds_def456"],
method="sft",
adapter="lora",
epochs=3,
learning_rate=2e-4,
lora_rank=16,
)
print(f"Job {job['id']} created -- status: {job['status']}")
Authentication
The SDK supports two authentication methods:
API Key (recommended). Keys start with bios- (legacy usf- keys stay
valid):
client = BiOS(api_key="bios-...")
Environment variables. When api_key or base_url is omitted, the SDK
reads BIOS_API_KEY and BIOS_BASE_URL from the environment:
export BIOS_API_KEY=bios-...
export BIOS_BASE_URL=https://api.usbios.ai # optional; this is the default
client = BiOS() # uses BIOS_API_KEY / BIOS_BASE_URL
JWT Access Token:
client = BiOS(
access_token="eyJhbG...",
org_id="org_abc123",
)
Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
str |
BIOS_API_KEY env var |
API key for authentication (prefix: bios-; legacy usf- keys stay valid) |
access_token |
str |
None |
JWT access token (alternative to API key) |
org_id |
str |
None |
Organization ID (required for JWT auth) |
workspace_id |
str |
None |
Workspace ID (optional, overrides key default) |
base_url |
str |
BIOS_BASE_URL env var, then https://api.usbios.ai |
Canonical production hostname (release-gated; this documentation does not assert current availability). During prelaunch/dev, pass https://api-dev.usbios.ai explicitly. |
timeout |
float |
30.0 |
Request timeout in seconds |
inference_key |
str |
None |
Optional per-deployment key used only by client.inference |
inference_base_url |
str |
base_url |
Explicit dev or production inference hostname |
inference_timeout |
float |
900.0 |
End-to-end inference/stream timeout in seconds |
Resources
Inference
Inference keys are separate from control-plane API keys. Streaming yields each
OpenAI SSE chunk as a dictionary and closes the upstream response when the
iterator is closed. Calls are never retried automatically; if your application
chooses to retry, reuse the same idempotency_key. The header is propagated,
but the SDK does not claim server-side replay/deduplication unless the endpoint
returns an explicit replay acknowledgement.
client = BiOS(
api_key="bios-control-plane-key",
inference_key="sk-bios-deployment-key",
# Use https://api-dev.usbios.ai explicitly during dev.
)
tools = [{
"type": "function",
"function": {
"name": "lookup",
"parameters": {"type": "object", "properties": {"id": {"type": "integer"}}},
},
}]
stream = client.inference.stream_chat_completions(
messages=[{"role": "user", "content": "Look up record 42"}],
tools=tools,
idempotency_key="chat-42-attempt-1",
)
try:
for chunk in stream:
print(chunk)
finally:
stream.close() # cancels/disconnects an unfinished generation
Models
Search the HuggingFace model catalog, fetch training configs, and check adapter compatibility.
# Search models
result = client.models.search(query="llama", type="llm", limit=10)
# Get model config
config = client.models.get_config("meta-llama/Llama-3.1-8B")
print(f"{config['totalParams']}B params, MoE: {config['isMoE']}")
# 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")
Datasets
Upload, import, preview, and manage training datasets.
# List datasets
datasets = client.datasets.list()
# Upload a dataset
uploaded = client.datasets.upload(
file_path="./training_data.jsonl",
name="My SFT Dataset",
)
print(f"Uploaded: {uploaded['id']}")
# Import from HuggingFace
imported = client.datasets.import_from_huggingface(
repo_id="databricks/dolly-15k",
integration_id="int_abc123",
name="Dolly 15k",
)
# Preview dataset rows
preview = client.datasets.preview("ds_abc123", page=1, page_size=5)
print(preview["columns"])
# Validate before uploading
result = client.datasets.validate("./data.jsonl")
if result["format_valid"]:
print(f"Valid {result['detected_format']} with {result['num_samples']} rows")
else:
print("Errors:", result["validation_errors"])
# Search HuggingFace Hub
hub_results = client.datasets.search_hub(query="code instruct")
# Preview a Hub dataset
hub_preview = client.datasets.preview_hub(
dataset_id="databricks/dolly-15k",
split="train",
limit=5,
)
# Get format specs
specs = client.datasets.get_format_specs()
# Get storage usage
usage = client.datasets.get_storage_usage()
# Delete a dataset
client.datasets.delete("ds_abc123")
Training
Create, monitor, stop, and resume fine-tuning jobs.
request = {
"idempotency_key": "training-create-20260711-0001",
"model": "meta-llama/Llama-3.1-8B-Instruct",
"dataset_ids": ["ds_abc123", "ds_def456"],
"method": "sft",
"adapter": "lora",
"epochs": 3,
"learning_rate": 2e-4,
"lora_rank": 16,
"lora_alpha": 32,
"gpu_type": "A100_80GB",
"gpu_count": 1,
"gpu_priorities": [
{"gpu_type": "A100_80GB", "gpu_count": 1},
{"gpu_type": "H100_80GB", "gpu_count": 1},
{"gpu_type": "L40S", "gpu_count": 1},
],
"queue_if_unavailable": True,
"queue_deadline": "2026-07-18T00:00:00Z",
"max_price_hour_cents": 500,
}
# Side-effect-free validation, canonical sizing, live stock and alternatives
check = client.training.preflight(request)
print(check["request_hash"], check.get("recommended"), check["queue_eligible"])
# Create the paid job only after reviewing preflight
job = client.training.create(**request)
# List jobs
jobs = client.training.list(status="running")
page = client.training.list_page(limit=50, offset=0)
# Get job details
job = client.training.get("job_abc123")
print(f"Status: {job['status']}, Progress: {job.get('progress', 0)}%")
# Get metrics
metrics = client.training.get_metrics("job_abc123")
for point in metrics["metrics"]:
print(point["step"], point.get("loss"))
# Get checkpoints
checkpoints = client.training.get_checkpoints("job_abc123")
for cp in checkpoints:
print(f"{cp['name']}: {cp['size_bytes']} bytes")
# Get logs
logs = client.training.get_logs("job_abc123")
for entry in logs["logs"]:
print(entry["level"], entry["message"])
# Stop a job
client.training.stop("job_abc123", keep_data=True)
# Resume a stopped job
client.training.resume("job_abc123", idempotency_key="training-resume-20260711-0001")
# Delete a checkpoint
client.training.delete_checkpoint("job_abc123", "cp_xyz789")
Wallet
View wallet balance and transaction history.
# Get balance
balance = client.wallet.get_balance()
print(f"Balance: ${balance['balance_cents'] / 100:.2f}")
print(f"Available: ${balance['available_cents'] / 100:.2f}")
# List transactions
txns = client.wallet.get_transactions(limit=20)
for t in txns:
print(f"{t['type']}: ${t['amount_cents'] / 100:.2f} -- {t.get('description')}")
# Get pricing
pricing = client.wallet.get_pricing()
Inference deployment management
The same client.inference resource that makes OpenAI-compatible chat calls also
manages model-serving deployments (create, monitor, stop, and delete).
request = {
"name": "llama-api",
"source_type": "hf_model",
"hf_model_id": "meta-llama/Llama-3.1-8B-Instruct",
"gpu_type": "H100_80GB",
"gpu_count": 1,
"allow_capacity_queue": True,
"max_price_hour_cents": 500,
}
# No wallet mutation and no GPU allocation.
check = client.inference.preflight(request)
print(check["selected_gpu"], check["alternatives"], check["billing"])
deployment = client.inference.create(request, idempotency_key="deploy-create-20260711-0001")
print(deployment["inference_key"]) # returned once; store securely
status = client.inference.status(deployment["id"])
print(status["status"], status.get("status_reason"), status.get("queue_expires_at"), status.get("wallet_authorization_status"))
# status stays "failed" for existing filters when status_reason is "queue_expired".
notification_history = client.inference.notifications(deployment["id"])
print([(row["event_type"], row["state"], row["attempt_count"]) for row in notification_history])
# Bounded newest-first listing; keep filters unchanged while using next_cursor.
page = client.inference.list_page(limit=100, status="running", search="llama")
if page["has_more"]:
older = client.inference.list_page(
limit=100, status="running", search="llama", cursor=page["next_cursor"]
)
print(older["deployments"])
# Lazy traversal avoids one unbounded response.
for item in client.inference.iter_all(status="running"):
print(item["name"])
client.inference.stop(deployment["id"])
client.inference.delete(deployment["id"])
GPU
View GPU pricing and get hardware recommendations.
# Get all 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")
# Authoritative model-aware choices, live stock, total pricing, and alternatives
options = client.gpu.get_options(
"meta-llama/Llama-3.1-8B-Instruct",
train_type="qlora",
method="sft",
)
# 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']}")
print(f"Total VRAM: {rec['total_vram_gb']}GB")
print(f"Cost: ${rec['estimated_cost_per_hour_cents'] / 100:.2f}/hr")
print(f"Reason: {rec['reason']}")
Introspect
Discover the permissions and scope of your API key.
info = client.introspect()
print(f"Org: {info['org']['name']}")
print(f"Scopes: {', '.join(info['scopes'])}")
print(f"Allowed tools: {len(info['allowed_mcp_tools'])}")
Error Handling
All API errors raise ApiError with status, code, request_id, and message attributes.
from bios import BiOS, ApiError
client = BiOS(api_key="bios-...")
try:
job = client.training.get("bad_id")
except ApiError as e:
if e.status == 404:
print("Job not found")
elif e.status == 401:
print("Invalid API key")
elif e.status == 403:
print("Insufficient permissions")
else:
print(f"API error {e.status}: {e.message}")
if e.request_id:
print(f"Request ID: {e.request_id}")
Python Version Support
- Python 3.10+
License
MIT
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 bios_sdk-0.1.1.tar.gz.
File metadata
- Download URL: bios_sdk-0.1.1.tar.gz
- Upload date:
- Size: 36.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ba78d8467af4ad0261e67dfd9b29084442d9509b4d31d9674a603bed883254d
|
|
| MD5 |
b985659e977cfd154a2dff457988f69f
|
|
| BLAKE2b-256 |
2c1c1a1e10636be63aa382dcf76862b0a256cdb26d5043257c4b5f1ff017985c
|
File details
Details for the file bios_sdk-0.1.1-py3-none-any.whl.
File metadata
- Download URL: bios_sdk-0.1.1-py3-none-any.whl
- Upload date:
- Size: 35.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17bc41d31eab4459ed67e790658c7f6d2dcfca75f518b33a5fe5c69cfe5bf5e7
|
|
| MD5 |
e6450824660b630c095a8dfb3ba6f6eb
|
|
| BLAKE2b-256 |
ec881a97e15d6bab163303df88b8c430c989f1b648a8d79702be6f60ced4b971
|