Jev Python SDK tutorial
Install the TypeSafe Python SDK, send a typed Jev request, and safely consume Choice, Score, Noul, and confidence results.
1. Install and authenticate
Keep the API key on the server. The SDK reads TYPESAFE_API_KEY from the environment, so it does not need to appear in application code.
python -m pip install "typesafe-sdk==0.7.2" "truststore>=0.10.5"
export TYPESAFE_API_KEY="your-api-key" 2. Make a typed decision
State carries the facts to inspect. Questions define the closed decisions you want back. This example routes a support message and separately checks urgency.
from typesafe_sdk import Choice, Noul, TypeSafeClient
with TypeSafeClient() as client:
response = client.system_one(
state={"message": "Stripe has failed for 3 days."},
questions={
"department": Choice(
instructions="Which team should handle this?",
criteria={
"billing": "Payments or subscriptions",
"technical": "Bugs or integrations",
"sales": "Pricing or account questions",
},
),
"is_urgent": Noul(
instructions="Does the message convey urgency?"
),
},
) 3. Read the answer safely
Choice answers expose a winning label, a probability distribution, and confidence. Noul returns the estimated probability that its statement is true. Treat the result as decision data, not generated prose.
department = response.answers["department"]
print(department.choice)
print(department.probabilities)
print(department.confidence)
urgent = response.answers["is_urgent"]
print(urgent.noul) # P(true) 4. Production checklist
Pin and log the model version, keep question identifiers stable, validate every answer before applying side effects, and send low-confidence or high-risk cases to a person.
Work through a complete example and its failure paths
Concurrent TLS note: older truststore releases can crash with a shared SSLContext. These commands require truststore>=0.10.5 while retaining the tested SDK 0.7.2. This transitive dependency constraint is not a claim that this site reproduced the crash or tested live TLS on every platform.truststore 0.10.5 ↗
The complete file below has no placeholder functions. It prints a suggestion or review state; it does not update tickets, spend money, or publish content.
Verification: pinned-package type/syntax checks and mock transports, not live API performance or accuracy tests. Real SDK runs require your own server-side key and may incur charges. Calibration and input examples run offline.
Choosing sync or async
The synchronous call above suits scripts. The async version below requires Python 3.11+. Inside an existing event loop, await suggest_team(client) rather than nesting asyncio.run. Context managers release connections.
timeout=2 limits each request and max_retries=1 permits two attempts. asyncio.timeout(8) bounds the whole operation. A transport failure triggers review, not a negative urgency judgment.
The deliverable is suggest_team(client), an async integration function with a review fallback. The type lesson separately teaches answer interpretation; the reliability lesson adds durable storage and duplicate delivery. A single SDK call is not a complete workflow.
python_async.py
import asyncio
from math import isfinite
from typesafe_sdk import AsyncTypeSafeClient, Choice, Noul, Score, RetryPolicy
async def suggest_team(client):
# Overall deadline bounds requests, retries and backoff together.
async with asyncio.timeout(8):
response = await client.system_one(
model="jev-1.13.0",
state={"message": "Checkout fails for every customer.", "scope": "all customers"},
questions={
"route": Choice(instructions="Which team owns this incident?", criteria={
"technical": "Bugs or integrations", "billing": "Invoices", "human": "Unclear ownership"}),
"severity": Score(instructions="How blocked are customers?", criteria=[
"Unaffected", "Workaround available", "Core workflow blocked"]),
"urgent": Noul(instructions="Does the message describe an ongoing service disruption?"),
},
)
route = response.choices["route"]
# The SDK validates the response shape. This branch is application policy.
valid = route.choice in {"technical", "billing", "human"} and isfinite(route.confidence) and 0 <= route.confidence <= 1
# Teaching threshold only; calibrate on independently labeled outcomes.
return {"action": "review" if not valid or route.choice == "human" or route.confidence < 0.75 else "suggest",
"team": route.choice, "severity": response.scores["severity"].score,
"urgent_probability": response.nouls["urgent"].noul}
async def main():
try:
async with AsyncTypeSafeClient(timeout=2, retry=RetryPolicy(max_retries=1)) as client:
print(await suggest_team(client))
except Exception:
print({"action": "review", "reason": "provider_or_configuration_failure"})
if __name__ == "__main__":
asyncio.run(main())
Download this fileRun
python -m pip install "typesafe-sdk==0.7.2" "truststore>=0.10.5"
export TYPESAFE_API_KEY="your-server-side-key"
python python_async.pyHow to verify the run
API examples print structured fields such as action and team. Labels and scores may differ from mocks. Removing the key should produce review without exposing raw error text. The calibration script prints development and held-out metrics, not model-quality evidence.