Jev Python SDK Tutorial: From Install to Production
Install typesafe-sdk, call sync and async clients, read typed answers, and handle production failures.
On this page
Requirements and installComplete synchronous support exampleFirst Noul, Choice, and ScoreRun and read the answersAsync clientExceptions, retries, and production handlingRequirements and install
Use Python 3.10+ and a TypeSafe API key. Create an isolated environment so your application has a reproducible dependency set.
python -m venv .venv
source .venv/bin/activate
python -m pip install typesafe-sdk
Set TYPESAFE_API_KEY in your local environment or runtime secret store. On a local shell you can read it without echoing it:
read -s TYPESAFE_API_KEY
export TYPESAFE_API_KEY
Complete synchronous support example
Save as support.py, or download the complete file. This makes a live request when run and therefore requires your key.
from typesafe_sdk import TypeSafeClient, Choice, Score, Noul
state = {'ticket': {'subject': 'Duplicate subscription charge', 'message': 'I was charged twice this month. Please refund the duplicate before Friday.'}, 'customer_plan': 'pro'}
with TypeSafeClient() as client:
response = client.system_one(
model="jev-1.13.0",
state=state,
questions={
"department": Choice(
instructions="Which team should handle this ticket?",
criteria={"billing": "Payments and refunds", "technical": "Bugs and outages",
"sales": "New purchases", "other": "None of these"}),
"urgency": Score(
instructions="How urgent is the request?",
criteria=["No deadline", "This week", "Within a day", "Immediate harm"]),
"refund_requested": Noul(
instructions="Does the customer explicitly request a refund?")
}
)
answer = response.choices["department"]
# Educational threshold, not a production recommendation.
queue = answer.choice if answer.confidence >= 0.85 else "manual_review"
print({"queue": queue, "confidence": answer.confidence,
"urgency": response.scores["urgency"].score,
"refund_requested": response.nouls["refund_requested"].noul,
"model": response.model, "usage": response.usage})
First Noul, Choice, and Score
Noul(instructions=...) asks one yes/no question. Choice(instructions=..., criteria={...}) uses a category map. Score(instructions=..., criteria=[...]) uses an ordered rubric. You can begin with just one entry, then add the other independent questions without duplicating state.
Run and read the answers
python support.py
Read response.nouls[name].noul, response.choices[name].choice, and response.scores[name].score. Choice and Score expose confidence and probabilities. Inspect response.usage and log response.model; the selected route and the actual model are both relevant to later evaluation.
Async client
For async applications, use AsyncTypeSafeClient and await system_one(). Reuse a client in its managed lifecycle and limit concurrent requests instead of opening unlimited calls.
import asyncio
from typesafe_sdk import AsyncTypeSafeClient, Noul
async def main():
async with AsyncTypeSafeClient() as client:
response = await client.system_one(
model="jev-1.13.0",
state="Please refund the duplicate charge.",
questions={"refund": Noul(instructions="Is a refund requested?")})
print(response.nouls["refund"].noul)
asyncio.run(main())
Exceptions, retries, and production handling
The official SDK retries transient failures by default and honors retry headers when available. Consult the retry reference for RetryPolicy options in your installed release. Do not wrap a default retry loop in another unlimited retry loop.
Authentication and validation failures require a configuration fix, not repeated calls. On exhausted transient retries, send the task to review or a safe fallback. Treat missing required outputs as failures. Never execute a refund merely because a refund request was detected.
Pin your package versions with your project’s lockfile and pin the model when thresholds matter. Re-run a labeled evaluation after changing instructions, criteria, or dependency versions.