OpenAI & Azure OpenAI
OpenAI's and Azure OpenAI's Structured Outputs feature accepts a JSON Schema in strict
mode, but it requires a constrained subset: every object must set
additionalProperties: false, every property must be required, and several keywords are
disallowed. weirding's to_json_schema(..., strict=True) emits exactly the
OpenAI ∩ Databricks intersection, so the schema it returns is accepted unmodified by both
providers.
You author the schema once in XML, compile it, export the strict variant, and pass it as
response_format. Claude is one peer among providers here — the XML-authored schema is the
single source of truth and the strict export is the OpenAI/Azure-facing artifact.
End-to-end
import json
import weirding
from openai import OpenAI
SCHEMA_XML = """
<Invoice description="Structured fields extracted from an invoice">
<vendor type="string" required="true"/>
<total type="number" required="true"/>
<currency type="string" required="true" enum="USD|EUR|GBP"/>
</Invoice>
"""
# XML schema -> IR -> strict provider schema
ir = weirding.compile(SCHEMA_XML)
schema = weirding.to_json_schema(ir, strict=True)
client = OpenAI()
resp = client.chat.completions.create(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "Extract the invoice fields."},
{"role": "user", "content": "Invoice from Acme Corp, total 1240.50 EUR."},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "Invoice",
"schema": schema,
"strict": True,
},
},
)
payload = resp.choices[0].message.content # JSON string
# Validate the result back with the same weirding model
Invoice = weirding.from_schema(ir, name="Invoice")
invoice = Invoice.model_validate(json.loads(payload))
from_schema(ir, ...) reuses the IR you already compiled, so the validating model and the
provider schema come from one definition. If you prefer, validate with plain Pydantic by
constructing the model the same way.
Azure OpenAI
Azure OpenAI exposes the identical Structured Outputs subset, so the same strict schema works without changes — only the client construction differs:
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint="https://<resource>.openai.azure.com",
api_version="2024-08-01-preview",
api_key="...",
)
# response_format payload is identical to the OpenAI example above
Which model deployments and API versions support Structured Outputs is a caller concern
— it is gated by your Azure deployment and the api_version you pin, not by weirding. Check
the Azure docs for the deployment/version matrix.
Gotchas
- Strict mode is lossy by design.
to_json_schema(strict=True)drops validation keywords the providers do not accept in strict mode (minimum,maximum,pattern,format, length/item bounds,default, and more), promotes every field torequired, and collapses nullable fields to{"type": [T, "null"]}. Re-validate with the weirding model (or any full-strength JSON Schema validator) after parsing if you need those constraints enforced. - Unrepresentable constructs raise. A nullable root, an
anyOf/oneOf/allOfthat is not a simple nullable, an unresolvable$ref, or a schema exceeding the 64-key cap raisesweirding.SchemaErrorrather than emitting a schema the provider would reject. Fix the XML schema rather than working around the error.