pydantic-ai-examples 1.12.0__tar.gz → 1.39.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/.gitignore +2 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/PKG-INFO +3 -3
- pydantic_ai_examples-1.39.1/pydantic_ai_examples/bank_support.py +101 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/data_analyst.py +2 -2
- pydantic_ai_examples-1.12.0/pydantic_ai_examples/bank_support.py +0 -95
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/LICENSE +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/README.md +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/__main__.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/__init__.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/__main__.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/api/__init__.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/api/agentic_chat.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/api/agentic_generative_ui.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/api/human_in_the_loop.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/api/predictive_state_updates.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/api/shared_state.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/api/tool_based_generative_ui.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/chat_app.html +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/chat_app.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/chat_app.ts +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/__init__.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/agent.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/custom_evaluators.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/datasets/time_range_v1.yaml +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/datasets/time_range_v1_schema.json +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/datasets/time_range_v2.yaml +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/datasets/time_range_v2_schema.json +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/example_01_generate_dataset.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/example_02_add_custom_evaluators.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/example_03_unit_testing.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/example_04_compare_models.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/models.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/flight_booking.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/py.typed +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/pydantic_model.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/question_graph.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/rag.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/roulette_wheel.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/slack_lead_qualifier/__init__.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/slack_lead_qualifier/agent.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/slack_lead_qualifier/app.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/slack_lead_qualifier/functions.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/slack_lead_qualifier/modal.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/slack_lead_qualifier/models.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/slack_lead_qualifier/slack.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/slack_lead_qualifier/store.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/sql_gen.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/stream_markdown.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/stream_whales.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/weather_agent.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/weather_agent_gradio.py +0 -0
- {pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pydantic-ai-examples
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.39.1
|
|
4
4
|
Summary: Examples of how to use Pydantic AI and what it can do.
|
|
5
5
|
Author-email: Samuel Colvin <samuel@pydantic.dev>, Marcelo Trylesinski <marcelotryle@gmail.com>, David Montague <david@pydantic.dev>, Alex Hall <alex@pydantic.dev>, Douwe Maan <douwe@pydantic.dev>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -34,8 +34,8 @@ Requires-Dist: logfire[asyncpg,fastapi,httpx,sqlite3]>=3.14.1
|
|
|
34
34
|
Requires-Dist: mcp[cli]>=1.4.1
|
|
35
35
|
Requires-Dist: modal>=1.0.4
|
|
36
36
|
Requires-Dist: pandas>=2.2.3
|
|
37
|
-
Requires-Dist: pydantic-ai-slim[ag-ui,anthropic,groq,openai,vertexai]==1.
|
|
38
|
-
Requires-Dist: pydantic-evals==1.
|
|
37
|
+
Requires-Dist: pydantic-ai-slim[ag-ui,anthropic,groq,openai,vertexai]==1.39.1
|
|
38
|
+
Requires-Dist: pydantic-evals==1.39.1
|
|
39
39
|
Requires-Dist: python-multipart>=0.0.17
|
|
40
40
|
Requires-Dist: rich>=13.9.2
|
|
41
41
|
Requires-Dist: uvicorn>=0.32.0
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Small but complete example of using Pydantic AI to build a support agent for a bank.
|
|
2
|
+
|
|
3
|
+
Run with:
|
|
4
|
+
|
|
5
|
+
uv run -m pydantic_ai_examples.bank_support
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import sqlite3
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
from pydantic_ai import Agent, RunContext
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class DatabaseConn:
|
|
18
|
+
"""A wrapper over the SQLite connection."""
|
|
19
|
+
|
|
20
|
+
sqlite_conn: sqlite3.Connection
|
|
21
|
+
|
|
22
|
+
async def customer_name(self, *, id: int) -> str | None:
|
|
23
|
+
res = cur.execute('SELECT name FROM customers WHERE id=?', (id,))
|
|
24
|
+
row = res.fetchone()
|
|
25
|
+
if row:
|
|
26
|
+
return row[0]
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
async def customer_balance(self, *, id: int) -> float:
|
|
30
|
+
res = cur.execute('SELECT balance FROM customers WHERE id=?', (id,))
|
|
31
|
+
row = res.fetchone()
|
|
32
|
+
if row:
|
|
33
|
+
return row[0]
|
|
34
|
+
else:
|
|
35
|
+
raise ValueError('Customer not found')
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class SupportDependencies:
|
|
40
|
+
customer_id: int
|
|
41
|
+
db: DatabaseConn
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class SupportOutput(BaseModel):
|
|
45
|
+
support_advice: str
|
|
46
|
+
"""Advice returned to the customer"""
|
|
47
|
+
block_card: bool
|
|
48
|
+
"""Whether to block their card or not"""
|
|
49
|
+
risk: int
|
|
50
|
+
"""Risk level of query"""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
support_agent = Agent(
|
|
54
|
+
'openai:gpt-5',
|
|
55
|
+
deps_type=SupportDependencies,
|
|
56
|
+
output_type=SupportOutput,
|
|
57
|
+
instructions=(
|
|
58
|
+
'You are a support agent in our bank, give the '
|
|
59
|
+
'customer support and judge the risk level of their query. '
|
|
60
|
+
"Reply using the customer's name."
|
|
61
|
+
),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@support_agent.instructions
|
|
66
|
+
async def add_customer_name(ctx: RunContext[SupportDependencies]) -> str:
|
|
67
|
+
customer_name = await ctx.deps.db.customer_name(id=ctx.deps.customer_id)
|
|
68
|
+
return f"The customer's name is {customer_name!r}"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@support_agent.tool
|
|
72
|
+
async def customer_balance(ctx: RunContext[SupportDependencies]) -> str:
|
|
73
|
+
"""Returns the customer's current account balance."""
|
|
74
|
+
balance = await ctx.deps.db.customer_balance(
|
|
75
|
+
id=ctx.deps.customer_id,
|
|
76
|
+
)
|
|
77
|
+
return f'${balance:.2f}'
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
if __name__ == '__main__':
|
|
81
|
+
with sqlite3.connect(':memory:') as con:
|
|
82
|
+
cur = con.cursor()
|
|
83
|
+
cur.execute('CREATE TABLE customers(id, name, balance)')
|
|
84
|
+
cur.execute("""
|
|
85
|
+
INSERT INTO customers VALUES
|
|
86
|
+
(123, 'John', 123.45)
|
|
87
|
+
""")
|
|
88
|
+
con.commit()
|
|
89
|
+
|
|
90
|
+
deps = SupportDependencies(customer_id=123, db=DatabaseConn(sqlite_conn=con))
|
|
91
|
+
result = support_agent.run_sync('What is my balance?', deps=deps)
|
|
92
|
+
print(result.output)
|
|
93
|
+
"""
|
|
94
|
+
support_advice='Hello John, your current account balance, including pending transactions, is $123.45.' block_card=False risk=1
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
result = support_agent.run_sync('I just lost my card!', deps=deps)
|
|
98
|
+
print(result.output)
|
|
99
|
+
"""
|
|
100
|
+
support_advice="I'm sorry to hear that, John. We are temporarily blocking your card to prevent unauthorized transactions." block_card=True risk=8
|
|
101
|
+
"""
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/data_analyst.py
RENAMED
|
@@ -47,7 +47,7 @@ def load_dataset(
|
|
|
47
47
|
"""
|
|
48
48
|
# begin load data from hf
|
|
49
49
|
builder = datasets.load_dataset_builder(path) # pyright: ignore[reportUnknownMemberType]
|
|
50
|
-
splits: dict[str, datasets.SplitInfo] = builder.info.splits or {}
|
|
50
|
+
splits: dict[str, datasets.SplitInfo] = builder.info.splits or {}
|
|
51
51
|
if split not in splits:
|
|
52
52
|
raise ModelRetry(
|
|
53
53
|
f'{split} is not valid for dataset {path}. Valid splits are {",".join(splits.keys())}'
|
|
@@ -87,7 +87,7 @@ def run_duckdb(ctx: RunContext[AnalystAgentDeps], dataset: str, sql: str) -> str
|
|
|
87
87
|
data = ctx.deps.get(dataset)
|
|
88
88
|
result = duckdb.query_df(df=data, virtual_table_name='dataset', sql_query=sql)
|
|
89
89
|
# pass the result as ref (because DuckDB SQL can select many rows, creating another huge dataframe)
|
|
90
|
-
ref = ctx.deps.store(result.df())
|
|
90
|
+
ref = ctx.deps.store(result.df())
|
|
91
91
|
return f'Executed SQL, result is `{ref}`'
|
|
92
92
|
|
|
93
93
|
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"""Small but complete example of using Pydantic AI to build a support agent for a bank.
|
|
2
|
-
|
|
3
|
-
Run with:
|
|
4
|
-
|
|
5
|
-
uv run -m pydantic_ai_examples.bank_support
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from dataclasses import dataclass
|
|
9
|
-
|
|
10
|
-
from pydantic import BaseModel
|
|
11
|
-
|
|
12
|
-
from pydantic_ai import Agent, RunContext
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class DatabaseConn:
|
|
16
|
-
"""This is a fake database for example purposes.
|
|
17
|
-
|
|
18
|
-
In reality, you'd be connecting to an external database
|
|
19
|
-
(e.g. PostgreSQL) to get information about customers.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
@classmethod
|
|
23
|
-
async def customer_name(cls, *, id: int) -> str | None:
|
|
24
|
-
if id == 123:
|
|
25
|
-
return 'John'
|
|
26
|
-
|
|
27
|
-
@classmethod
|
|
28
|
-
async def customer_balance(cls, *, id: int, include_pending: bool) -> float:
|
|
29
|
-
if id == 123:
|
|
30
|
-
if include_pending:
|
|
31
|
-
return 123.45
|
|
32
|
-
else:
|
|
33
|
-
return 100.00
|
|
34
|
-
else:
|
|
35
|
-
raise ValueError('Customer not found')
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@dataclass
|
|
39
|
-
class SupportDependencies:
|
|
40
|
-
customer_id: int
|
|
41
|
-
db: DatabaseConn
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class SupportOutput(BaseModel):
|
|
45
|
-
support_advice: str
|
|
46
|
-
"""Advice returned to the customer"""
|
|
47
|
-
block_card: bool
|
|
48
|
-
"""Whether to block their card or not"""
|
|
49
|
-
risk: int
|
|
50
|
-
"""Risk level of query"""
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
support_agent = Agent(
|
|
54
|
-
'openai:gpt-5',
|
|
55
|
-
deps_type=SupportDependencies,
|
|
56
|
-
output_type=SupportOutput,
|
|
57
|
-
instructions=(
|
|
58
|
-
'You are a support agent in our bank, give the '
|
|
59
|
-
'customer support and judge the risk level of their query. '
|
|
60
|
-
"Reply using the customer's name."
|
|
61
|
-
),
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@support_agent.instructions
|
|
66
|
-
async def add_customer_name(ctx: RunContext[SupportDependencies]) -> str:
|
|
67
|
-
customer_name = await ctx.deps.db.customer_name(id=ctx.deps.customer_id)
|
|
68
|
-
return f"The customer's name is {customer_name!r}"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
@support_agent.tool
|
|
72
|
-
async def customer_balance(
|
|
73
|
-
ctx: RunContext[SupportDependencies], include_pending: bool
|
|
74
|
-
) -> str:
|
|
75
|
-
"""Returns the customer's current account balance."""
|
|
76
|
-
balance = await ctx.deps.db.customer_balance(
|
|
77
|
-
id=ctx.deps.customer_id,
|
|
78
|
-
include_pending=include_pending,
|
|
79
|
-
)
|
|
80
|
-
return f'${balance:.2f}'
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if __name__ == '__main__':
|
|
84
|
-
deps = SupportDependencies(customer_id=123, db=DatabaseConn())
|
|
85
|
-
result = support_agent.run_sync('What is my balance?', deps=deps)
|
|
86
|
-
print(result.output)
|
|
87
|
-
"""
|
|
88
|
-
support_advice='Hello John, your current account balance, including pending transactions, is $123.45.' block_card=False risk=1
|
|
89
|
-
"""
|
|
90
|
-
|
|
91
|
-
result = support_agent.run_sync('I just lost my card!', deps=deps)
|
|
92
|
-
print(result.output)
|
|
93
|
-
"""
|
|
94
|
-
support_advice="I'm sorry to hear that, John. We are temporarily blocking your card to prevent unauthorized transactions." block_card=True risk=8
|
|
95
|
-
"""
|
|
File without changes
|
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/__main__.py
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/__init__.py
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/ag_ui/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/chat_app.html
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/chat_app.py
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/chat_app.ts
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/__init__.py
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/agent.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/evals/models.py
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/flight_booking.py
RENAMED
|
File without changes
|
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/pydantic_model.py
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/question_graph.py
RENAMED
|
File without changes
|
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/roulette_wheel.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/stream_markdown.py
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/stream_whales.py
RENAMED
|
File without changes
|
{pydantic_ai_examples-1.12.0 → pydantic_ai_examples-1.39.1}/pydantic_ai_examples/weather_agent.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|