Files
wehub-resource-sync 97e91a83f3
Ruff / Ruff (push) Has been cancelled
Test / Core Tests (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.10) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.11) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.12) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.13) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.9) (push) Has been cancelled
Test / Full Coverage (Python 3.11) (push) Has been cancelled
Test / Core Provider Tests (OpenAI) (push) Has been cancelled
Test / Core Provider Tests (Anthropic) (push) Has been cancelled
Test / Core Provider Tests (Google) (push) Has been cancelled
Test / Core Provider Tests (Other) (push) Has been cancelled
Test / Anthropic Tests (push) Has been cancelled
Test / Gemini Tests (push) Has been cancelled
Test / Google GenAI Tests (push) Has been cancelled
Test / Vertex AI Tests (push) Has been cancelled
Test / OpenAI Tests (push) Has been cancelled
Test / Writer Tests (push) Has been cancelled
Test / Auto Client Tests (push) Has been cancelled
ty / type-check (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:36:38 +08:00

179 lines
5.5 KiB
Markdown

---
title: Receipt Data Extraction with GPT-4 Vision - Expense Tracking
description: Extract and validate receipt data from images using GPT-4 Vision and Instructor. Automate expense tracking with structured receipt parsing.
---
# Extracting Receipt Data using GPT-4 and Python
This post demonstrates how to use Python's Pydantic library and OpenAI's GPT-4 model to extract receipt data from images and validate the total amount. This method is particularly useful for automating expense tracking and financial analysis tasks.
## Defining the Item and Receipt Classes
First, we define two Pydantic models, `Item` and `Receipt`, to structure the extracted data. The `Item` class represents individual items on the receipt, with fields for name, price, and quantity. The `Receipt` class contains a list of `Item` objects and the total amount.
```python
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
quantity: int
class Receipt(BaseModel):
items: list[Item]
total: float
```
## Validating the Total Amount
To ensure the accuracy of the extracted data, we use Pydantic's `model_validator` decorator to define a custom validation function, `check_total`. This function calculates the sum of item prices and compares it to the extracted total amount. If there's a discrepancy, it raises a `ValueError`.
```python
from pydantic import model_validator
@model_validator(mode="after")
def check_total(self):
items = self.items
total = self.total
calculated_total = sum(item.price * item.quantity for item in items)
if calculated_total != total:
raise ValueError(
f"Total {total} does not match the sum of item prices {calculated_total}"
)
return self
```
## Extracting Receipt Data from Images
The `extract_receipt` function uses OpenAI's GPT-4 model to process an image URL and extract receipt data. We utilize the `instructor` library to configure the OpenAI client for this purpose.
```python
import instructor
# <%hide%>
from pydantic import BaseModel, model_validator
class Item(BaseModel):
name: str
price: float
quantity: int
class Receipt(BaseModel):
items: list[Item]
total: float
@model_validator(mode="after")
def check_total(cls, values: "Receipt"):
items = values.items
total = values.total
calculated_total = sum(item.price * item.quantity for item in items)
if calculated_total != total:
raise ValueError(
f"Total {total} does not match the sum of item prices {calculated_total}"
)
return values
# <%hide%>
client = instructor.from_provider("openai/gpt-5-nano")
def extract(url: str) -> Receipt:
return client.create(
model="gpt-5.4-mini",
max_tokens=4000,
response_model=Receipt,
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {"url": url},
},
{
"type": "text",
"text": "Analyze the image and return the items in the receipt and the total amount.",
},
],
}
],
)
```
## Practical Examples
In these examples, we apply the method to extract receipt data from two different images. The custom validation function ensures that the extracted total amount matches the sum of item prices.
```python
# <%hide%>
from pydantic import BaseModel, model_validator
import instructor
class Item(BaseModel):
name: str
price: float
quantity: int
class Receipt(BaseModel):
items: list[Item]
total: float
@model_validator(mode="after")
def check_total(cls, values: "Receipt"):
items = values.items
total = values.total
calculated_total = round(sum(item.price * item.quantity for item in items), 2)
if calculated_total != total:
raise ValueError(
f"Total {total} does not match the sum of item prices {calculated_total}"
)
return values
client = instructor.from_provider("openai/gpt-5-nano")
def extract(url: str) -> Receipt:
return client.create(
model="gpt-4o",
max_tokens=4000,
response_model=Receipt,
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {"url": url},
},
{
"type": "text",
"text": "Analyze the image and return the items in the receipt and the total amount.",
},
],
}
],
)
# <%hide%>
url = "https://templates.mediamodifier.com/645124ff36ed2f5227cbf871/supermarket-receipt-template.jpg"
receipt = extract(url)
print(receipt)
"""
items=[Item(name='Lorem ipsum', price=9.2, quantity=1), Item(name='Lorem ipsum dolor sit', price=19.2, quantity=1), Item(name='Lorem ipsum dolor sit amet', price=15.0, quantity=1), Item(name='Lorem ipsum', price=15.0, quantity=1), Item(name='Lorem ipsum', price=15.0, quantity=1), Item(name='Lorem ipsum dolor sit', price=15.0, quantity=1), Item(name='Lorem ipsum', price=19.2, quantity=1)] total=107.6
"""
```
By combining the power of GPT-4 and Python's Pydantic library, we can accurately extract and validate receipt data from images, streamlining expense tracking and financial analysis tasks.