Skip to main content

cyberian-client

Python client for the Cyberian Systems verified-inference API.

Each call returns embeddings + a cryptographic receipt attesting that the inference was executed and a sample of it independently re-executed and verified. The receipt is tamper-evident — its receipt_hash commits to every field, so any edit is detectable offline — and client.verify_receipt(receipt_id) asks the platform to re-derive its Merkle roots from the commitments it recorded.

Install

pip install cyberian-client

Requires Python 3.9+. Pulls in httpx and numpy.

Get an API key

https://cyberiansystems.ai/signup — 14-day free trial, no card required. The plaintext key is shown once at signup; save it. We store only its SHA-256.

Quickstart — one shot

from cyberian import Cyberian

client = Cyberian(api_key="cyb_trial_…")  # or set CYBERIAN_API_KEY in env

result = client.submit_and_wait(
    model="bge-large-v1.5",
    inputs=[
        "The property title search revealed no encumbrances.",
        "Quarterly compliance attestation per SOX 404.",
    ],
)

print("receipt_hash:", result.receipt["receipt_hash"])
print("verified:    ", result.verification["valid"])  # True
print("shape:       ", result.embeddings.shape)        # (2, 1024) for BGE-large
print("first vec:   ", result.embeddings[0, :8])

Step-by-step — when you need finer control

job = client.submit_job(model="bge-large-v1.5", inputs=["a", "b", "c"])

# Poll yourself, or use wait_for_completion:
final = client.wait_for_completion(job["id"], timeout_sec=600)

receipt      = client.get_receipt(final["receipt_id"])
verification = client.verify_receipt(final["receipt_id"])
embeddings   = client.get_job_output(final["id"])  # numpy ndarray, float32

Models

Every job names a model (model="..."). The models enabled for your account are listed on your account dashboard, or programmatically:

for m in client.list_models():
    print(m["id"], "—", m["name"])

list_models() returns a list of descriptors; the exact fields are stable across releases but may grow over time, so dereference by name rather than position.

Need a model that isn't enabled for you? Email support@cyberiansystems.ai with the model reference (e.g. a Hugging Face URL). Onboarding a new model is a configuration step on our side — no code change on yours.

Bring your own model (BYOM — enterprise tier)

Upload your own ONNX model and reference it in /jobs and /verify exactly like a catalog model. The platform hashes the file (with every external-data file it references), stores it content-addressed, returns that hash, and pins it into the spec_hash of every job that names the model — so a receipt commits to the exact model bytes the upload returned the hash of.

m = client.upload_model(
    file="/path/to/our-fine-tuned-bge.onnx",   # path or raw bytes
    name="acme-bge-v3",                         # lowercase-kebab handle
    output_dimensions=768,
    tokenizer="BAAI/bge-small-en-v1.5",
    description="ACME risk-classification fine-tune",
)
print(m["model_id"])   # 'byom-<acct>-acme-bge-v3'

# Use it like any model:
result = client.submit_and_wait(model=m["model_id"], inputs=["risk text…"])

client.list_uploaded_models()      # your uploaded models
client.delete_model(m["model_id"]) # soft-delete (refused while a job uses it)

Uploads are idempotent (re-uploading the same bytes+name returns the same model). BYOM is enterprise-tier — other tiers get a QuotaError (402); email upgrade@cyberiansystems.ai to enable it. Uploads are limited to 100 MB.

A model whose weights live in external-data files uploads as one uncompressed ustar tar of model.onnx (at the root) plus exactly the files it references. Python's tarfile writes PAX headers by default, which the platform rejects — use the USTAR format:

import tarfile
with tarfile.open("bundle.tar", "w", format=tarfile.USTAR_FORMAT) as tar:
    tar.add("model.onnx", arcname="model.onnx")
    tar.add("model.onnx_data", arcname="model.onnx_data")
client.upload_model(file="bundle.tar", name="acme-bge-v4", output_dimensions=768,
                    tokenizer="BAAI/bge-small-en-v1.5")

Verification as a Service (VaaS)

You ran inference on your own infrastructure. Cyberian independently verifies the output you computed and issues a receipt certifying it. Useful for compliance — you keep the inference, we provide independent auditable attestation.

import hashlib

# Your in-house inference output:
my_embeddings_bytes = my_pipeline.run(["text"]).astype("float32").tobytes()
my_commitment = hashlib.sha256(my_embeddings_bytes).hexdigest()

receipt = client.verify_outputs(
    model="bge-large-v1.5",
    inputs=["text"],
    claimed_output_commitment=my_commitment,
)
# Raises VerificationFailedError if our independent verification disagrees with
# the commitment you claimed.

Verifying more than one batch in a single call

For larger workloads, split your outputs into batches of up to 1000 inputs and pass one commitment per batch (in input order) via claimed_output_commitments. You get a single receipt covering every batch:

batches = [inputs[i:i + 1000] for i in range(0, len(inputs), 1000)]
commitments = [
    hashlib.sha256(
        my_pipeline.run(batch).astype("float32").tobytes()
    ).hexdigest()
    for batch in batches
]

receipt = client.verify_outputs(
    model="bge-large-v1.5",
    inputs=inputs,
    claimed_output_commitments=commitments,
)

Pass exactly one of claimed_output_commitment (single batch) or claimed_output_commitments (multi-batch). If the number of commitments doesn't match the batch count, the platform returns a commitment_count_mismatch error telling you how many it expected. Per-request limits depend on your account.

Receipt fields

The receipt your jobs / VaaS calls return is a hash-chained object (receipt_hash covers every other field):

Field Meaning
receipt_id UUID of this receipt.
job_id UUID of the underlying job.
spec_hash SHA-256 commitment to the execution spec used.
inputs_root Merkle root over the inputs you submitted.
outputs_root Merkle root over the outputs that were produced.
verification_attestation Merkle root committing to the independent verification work.
executor_attestation_ids Anonymized identifiers of the providers that executed the batch.
issued_at UTC ISO-8601 timestamp.
receipt_hash SHA-256 of the entire receipt body — self-referential check.

Account management

info = client.get_account()
print(info["tier"], info["effective_tier"], info["subscription_status"])
print(info["chunks_consumed_period"], "/", info["limits"]["chunks_per_period"])

# Mint an additional key (old one stays valid until you revoke it)
new_key = client.rotate_key()

# Revoke a specific key by its 12-char key_id (the prefix shown in /account)
client.revoke_key(key_id="a1b2c3d4e5f6")

Error handling

Typed exceptions; catch the most specific one you care about.

from cyberian import (
    Cyberian,
    AuthError,                # 401, 403
    TrialExpiredError,        # 402 — email upgrade@cyberiansystems.ai
    QuotaError,               # 402 / 413
    RateLimitError,           # 429 — has .retry_after_sec
    ServiceBusyError,         # 503 — has .retry_after_sec
    JobFailedError,           # job ended in FAILED state during wait_for_completion
    VerificationFailedError,  # /verify returned valid=False
    NetworkError,             # transport-level (no HTTP response); wait_for_completion retries automatically
    ApiError,                 # any other 4xx/5xx
    CyberianError,            # base of everything above
)

try:
    result = client.submit_and_wait(model="bge-large-v1.5", inputs=[…])
except RateLimitError as exc:
    time.sleep(exc.retry_after_sec)
    result = client.submit_and_wait(model="bge-large-v1.5", inputs=[…])
except TrialExpiredError:
    print("Email upgrade@cyberiansystems.ai for an extension or enterprise tier.")
    raise

Trial limits

trial (default) free (post-trial)
Period 14 days 30 days
Chunks per period 400 100
Chunks per day 100 25
Requests per minute 60 10
Max chunks per request 100 50
Max inputs per request 1000 500

A "chunk" is the platform's internal billing unit (one batched inference). The platform chooses how to group your inputs into chunks. Counting chunks (not raw requests) means the quota tracks actual compute consumption.

Documentation

Metadata

Release files for cyberian-client 0.4.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cyberian-client 0.4.4
File Size Uploaded Provenance
cyberian_client-0.4.4.tar.gz 23.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for cyberian-client 0.4.4
File Interpreter ABI Platform
cyberian_client-0.4.4-py3-none-any.whl Python 3 none any Details

Total release size: 39.4 kB

Release files / cyberian_client-0.4.4.tar.gz

Download URL cyberian_client-0.4.4.tar.gz
Size 23.0 kB
Tags Source
SHA-256 checksum
How to use checksums
f576a9c1cd030cd383a7d4794e21214575bb2e4e8c74b92736636f921f9f7507
BLAKE2b-256 checksum
How to use checksums
1c1fa4b6c2dbdba27e28681b35e1fb58c0f59ecb88ef36eefbd15503733e2fc1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Release files / cyberian_client-0.4.4-py3-none-any.whl

Download URL cyberian_client-0.4.4-py3-none-any.whl
Size 16.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3de4cb956fdb2a44be3d98d1f5873093f8b6617349cd0e8a0fe319144c720591
BLAKE2b-256 checksum
How to use checksums
d2ac4be484f6a6f517d70421e06c3208f772936e8d6ddd4560fc23bd117aea93
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Security for cyberian-client 0.4.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page