Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bios_sdk-0.1.1.tar.gz (36.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bios_sdk-0.1.1-py3-none-any.whl (35.2 kB view details)

Uploaded Python 3

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

Hashes for bios_sdk-0.1.1.tar.gz
Algorithm Hash digest
SHA256 0ba78d8467af4ad0261e67dfd9b29084442d9509b4d31d9674a603bed883254d
MD5 b985659e977cfd154a2dff457988f69f
BLAKE2b-256 2c1c1a1e10636be63aa382dcf76862b0a256cdb26d5043257c4b5f1ff017985c

See more details on using hashes here.

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

Hashes for bios_sdk-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 17bc41d31eab4459ed67e790658c7f6d2dcfca75f518b33a5fe5c69cfe5bf5e7
MD5 e6450824660b630c095a8dfb3ba6f6eb
BLAKE2b-256 ec881a97e15d6bab163303df88b8c430c989f1b648a8d79702be6f60ced4b971

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page