import json
import os
from jsonschema import validate
from perceptron import Client, image
client = Client(api_key=os.environ["PERCEPTRON_API_KEY"])
image_url = (
"https://raw.githubusercontent.com/perceptron-ai-inc/perceptron/"
"main/cookbook/_shared/assets/capabilities/ocr/grocery_labels.webp"
)
schema = {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"product": {"type": ["string", "null"]},
"price": {"type": ["string", "null"]},
},
"required": ["product", "price"],
"additionalProperties": False,
},
},
},
"required": ["items"],
"additionalProperties": False,
}
response = client.chat.completions.create(
model="perceptron-mk1.5",
messages=[{
"role": "user",
"content": [
image(image_url),
{"type": "text", "text": (
"Extract the visible product names and their associated listed prices "
"in reading order. Preserve spelling, currency symbols, and decimal "
"separators exactly as printed. Use null for a field you cannot read; "
"do not guess or pair a product with an unrelated price. Return an "
"empty items array if there are no relevant labels."
)},
],
}],
reasoning_effort="high",
max_completion_tokens=2048,
response_format={
"type": "json_schema",
"json_schema": {"name": "product_prices", "strict": True, "schema": schema},
},
)
choice = response.choices[0]
if choice.finish_reason != "stop" or choice.message.tool_calls:
raise RuntimeError(f"Incomplete OCR response: {choice.finish_reason}")
result = json.loads(choice.message.content or "")
validate(instance=result, schema=schema)
print(json.dumps(result, indent=2))