Skip to main content

cerno — Python client

Three kinds of question about a piece of text, answered by a locally hosted model:

  • noul — how likely is the answer yes
  • choice — which one of up to 20 options
  • score — where on a rubric of 2–10 levels

Each question is one forward pass, so answers come back in tens of milliseconds.

uv add cerno-sdk
from cerno import Client

client = Client("http://localhost:3000")

answers = (
    client.systemone("Ticket: server room at 31C, rising, servers throttling.")
    .noul("urgent", "Is this urgent?")
    .choice("team", "Which team?", ["IT", "Facility", "HR"])
    .score("sev", "How severe?", ["harmless", "minor", "moderate", "high", "critical"])
    .send()
)

answers.noul("urgent")        # 0.991
answers.choice("team")        # "Facility"
answers.score("sev")          # 5
answers.legend("sev")         # "critical"
answers.confidence("team")    # 0.939

Questions in one call share their state, so the text is sent and prefilled once.

Async

Same surface, await on send():

from cerno import AsyncClient

async with AsyncClient("http://localhost:3000") as client:
    answers = await client.systemone(text).noul("spam", "Is this spam?").send()

Reading the answer honestly

Every answer carries the evidence it came from:

answers.label_mass("team")         # 0.999 — share of the model's probability on the letters
answers.truncated("team")          # some label fell outside the host's reporting window
answers.truncated_labels("team")   # ("C",) — which ones; their raw_logprobs entry is a bound
answers["team"].raw_logprobs       # {"A": -4.54, "B": -0.02, ...}
answers["team"].probabilities      # per option, in request order

truncated is worth checking when you act on a probability rather than on the winner: it means at least one option ranked below everything the host reported, so its probability is an upper bound, not an observation.

label_mass is worth checking before trusting any answer at all: it is how much of the model's own probability fell on the offered letters. The probabilities are normalised over the letters alone, so they look just as decisive when the model was about to write something else and the letters were far down its ranking. Well below 1, the answer was read off tokens the model was not going to write.

To flatten an overconfident model, scale the logits before they are normalised:

client.systemone(text).calibration(2.5).noul("urgent", "Is this urgent?").send()

Above 1 flattens, below 1 sharpens, and raw_logprobs is unaffected either way.

Errors

from cerno import ApiError

try:
    answers = client.systemone(text).choice("team", "Which?", options).send()
except ApiError as err:
    err.code         # "too_many_options" — branch on this, never on the message
    err.question_id  # "team"

UnexpectedResponse is raised instead when a body is not something cerno sends — a non-2xx that is not a cerno error, or a 2xx that is not an answer — which usually means a proxy between you and the service. TransportError means the service could not be reached or timed out; the httpx exception is its __cause__. All three derive from CernoError.

The builder refuses two easy mistakes with a TypeError before anything is sent: a string where the options belong (.choice("team", "Which team?") would otherwise ask about eleven single letters), and a string or bool as a score rubric.

Metadata

Release files for cerno-sdk 0.1.3

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

Source distribution (sdist)

Source distribution for cerno-sdk 0.1.3
File Size Uploaded
cerno_sdk-0.1.3.tar.gz 19.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cerno-sdk 0.1.3
File Interpreter ABI Platform
cerno_sdk-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 27.9 kB

Release files / cerno_sdk-0.1.3.tar.gz

Download URL cerno_sdk-0.1.3.tar.gz
Size 19.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0748750ddc6d0e2925f977f67ccd6b95b09b9f5b0414a11497e841c744f057fb
BLAKE2b-256 checksum
How to use checksums
ab889d7a64affa53bcf484a1fe7285aa2f7f40c69106b4497135db5a53c2b18f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / cerno_sdk-0.1.3-py3-none-any.whl

Download URL cerno_sdk-0.1.3-py3-none-any.whl
Size 8.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
18cfe3994605c7650873cf5519558e8c809fc67e5b9a4cd28372150c0a5fe0d9
BLAKE2b-256 checksum
How to use checksums
228ebf1290946c1a397f9460a235e635a11478e371875bff98a85d94f8ad4182
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.1.4

2 release files

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

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