structout-llm
Guaranteed structured output from any LLM — with automatic retries and Pydantic validation.
pip install structout-llm
The Problem
LLMs don't always return valid JSON. They add markdown fences, extra text, wrong types, missing fields. Your code breaks. You add manual parsing. It breaks again.
structout-llm fixes this — automatically.
Quick Start
from pydantic import BaseModel
from structout import extract
class Person(BaseModel):
name: str
age: int
city: str
result = extract(
instruction="Extract person details",
schema=Person,
provider="openai",
model="gpt-4o",
api_key="sk-...",
text="John Doe is 28 years old and lives in Mumbai."
)
print(result.data.name) # "John Doe"
print(result.data.age) # 28
print(result.attempts) # 1
print(result.latency_ms) # 1243.5
Supported Providers
| Provider | Install | Models |
|---|---|---|
| OpenAI | pip install openai |
gpt-4o, gpt-4o-mini, ... |
| Anthropic | pip install anthropic |
claude-sonnet-4, claude-haiku-4 |
| Gemini | pip install google-genai |
gemini-2.5-flash, gemini-1.5-pro |
Features
- ✅ Auto retry — retries with error context when validation fails
- ✅ Pydantic validation — full type safety and field validation
- ✅ JSON extraction — handles markdown fences, extra text, trailing commas
- ✅ Safe mode —
extract_safe()never raises, returns error in result - ✅ Metrics — tokens, latency, attempts tracked per call
- ✅ Provider agnostic — same API for OpenAI, Anthropic, Gemini
extract() vs extract_safe()
# extract() raises ExtractionError if all retries fail
try:
result = extract(instruction, schema, provider, model, api_key)
except ExtractionError as e:
print(f"Failed after {e.attempts} attempts: {e.message}")
# extract_safe() never raises — check result.success instead
result = extract_safe(instruction, schema, provider, model, api_key)
if not result.success:
print(f"Failed: {result.error}")
ExtractionResult
result.data # Validated Pydantic model instance
result.success # True if extraction succeeded
result.attempts # How many retries were needed
result.tokens_in # Input tokens used
result.tokens_out # Output tokens used
result.latency_ms # Total time in milliseconds
result.raw_output # Raw LLM response string
result.error # Error message if failed, else None
License
MIT
Release files for structout-llm 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| structout_llm-0.1.0.tar.gz | 9.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| structout_llm-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.4 kB
Release files / structout_llm-0.1.0.tar.gz
| Download URL | structout_llm-0.1.0.tar.gz |
|---|---|
| Size | 9.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f66df8e51937b4251cb2ca3b2d79b24f057cac4b042fff0ed86517d65b6cf43d
|
|
BLAKE2b-256 checksum How to use checksums |
df9cbdddbb5c2c30baf69090af595b899cc44291cf41736c1ea731d5342e3077
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / structout_llm-0.1.0-py3-none-any.whl
| Download URL | structout_llm-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5658067c15edb167479769735ce741a373f59bc0a2d4398cca301e3c012c03a2
|
|
BLAKE2b-256 checksum How to use checksums |
04957f35776582f4c244fd13a278580287459297e5b96bf61b5a73b57d32e4fb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|