Guardrails AIguardrails-ai 0.11.0 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
27 small wins to finish your pathNext lesson

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.

python
from pydantic import BaseModel
from guardrails import Guard

Two imports: the Pydantic base class, and Guard.

Example
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

Example
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

Example
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.

Try it yourself
  • Add a field with a default value to Ticket and leave it out of the JSON.
  • Give priority the type str and pass the integer 2. 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.