A Guard from a Pydantic model
Everything validated so far was one string. A support desk that files tickets needs an object with fields, and Guardrails' second job is producing one.
from pydantic import BaseModel
from guardrails import GuardTwo imports: the Pydantic base class, and Guard.
class Ticket(BaseModel):
order_id: str
issue: str
priority: int
tickets = Guard.for_pydantic(Ticket)
outcome = tickets.parse('{"order_id": "8821", "issue": "late", "priority": 2}', num_reasks=0)
print(outcome.validated_output)
print(type(outcome.validated_output))A dictionary, not a Ticket. The Pydantic class describes the shape Guardrails should expect and produces the JSON schema it sends to a model, but what you get back is plain data. Build the model yourself with Ticket(**outcome.validated_output) if you want an instance.
This is parse() from lesson 14 doing more work than it did there. On a string Guard it only validates. On a structured Guard it has to turn text into data first, and that happens in three steps worth knowing about.
What parse does before it validates
texts = [
'```json\n{"order_id": "8821", "issue": "late", "priority": 2}\n```',
'{"order_id": "8821", "issue": "late", "priority": 2, "agent": "ravi"}',
'{"order_id": "8821", "issue": "late", "priority": "2"}',
]
for text in texts:
print(tickets.parse(text, num_reasks=0).validated_output)Three different inputs, one identical result. The Concurrency page names the steps: extraction pulls the JSON out of whatever the model wrapped it in, pruning drops properties the schema did not ask for, and type coercion turns the string "2" into the integer 2.
That third step is worth remembering when a validator of yours never seems to fire. By the time it runs, the value may not be the type the model produced.
When the shape is wrong
outcome = tickets.parse('{"order_id": "8821", "issue": "late"}', num_reasks=0)
print(outcome.validation_passed)
print(outcome.validated_output)
print(outcome.reask.fail_results[0].error_message)A missing field is not a validator failure. It is a structural failure, recorded on outcome.reask rather than in the summaries, and lesson 20 is what happens when you let Guardrails do something about it.
- Add a field with a default value to
Ticketand leave it out of the JSON. - Give
prioritythe typestrand pass the integer2. Coercion runs both ways. - Pass a JSON list where the schema expects an object and read what comes back.
You understood something today that you didn't yesterday.