Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion pydantic_ai/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from importlib.metadata import version

from .agent import Agent
from .shared import AgentError, CallContext, ModelRetry, UnexpectedModelBehaviour, UserError

__all__ = 'Agent', 'AgentError', 'CallContext', 'ModelRetry', 'UnexpectedModelBehaviour', 'UserError'
__all__ = 'Agent', 'AgentError', 'CallContext', 'ModelRetry', 'UnexpectedModelBehaviour', 'UserError', '__version__'
__version__ = version('pydantic_ai')
45 changes: 35 additions & 10 deletions examples/README.md → pydantic_ai_examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,35 @@ Examples of how to use Pydantic AI and what it can do.

## Usage

These examples are distributed with `pydantic-ai` so you can run them either by cloning the [pydantic-ai repo](https://github.com/pydantic/pydantic-ai) or by simply installing `pydantic-ai` from PyPI with `pip` or `uv`.

Either way you'll need to install extra dependencies to run some examples, you just need to install the `examples` optional dependency group.

If you've cloned the repo, add the extra dependencies with:

```bash
uv sync --extra examples
```

If you've installed `pydantic-ai` via pip/uv, you can install the extra dependencies with:

```bash
pip install 'pydantic-ai[examples]'
# of if you're using uv
uv add 'pydantic-ai[examples]'
```

To run the examples, run:

```bash
uv run -m examples.<example_module_name>
python -m pydantic_ai_examples.<example_module_name>
```
(replace `python` with just `uv run` if you're using `uv`)

But you'll probably want to edit examples as well as just running them, so you can copy the examples to a new directory with:

```bash
python -m pydantic_ai_examples --copy-to examples/
```

## Examples
Expand All @@ -19,17 +44,17 @@ uv run -m examples.<example_module_name>
Simple example of using Pydantic AI to construct a Pydantic model from a text input.

```bash
uv run --extra examples -m examples.pydantic_model
(uv run/python) -m pydantic_ai_examples.pydantic_model
```

This examples uses `openai:gpt-4o` by default but it works well with other models, e.g. you can run it
This examples uses `openai:gpt-4o` by default, but it works well with other models, e.g. you can run it
with Gemini using:

```bash
PYDANTIC_AI_MODEL=gemini-1.5-pro uv run --extra examples -m examples.pydantic_model
PYDANTIC_AI_MODEL=gemini-1.5-pro (uv run/python) -m pydantic_ai_examples.pydantic_model
```

(or `PYDANTIC_AI_MODEL=gemini-1.5-flash...`)
(or `PYDANTIC_AI_MODEL=gemini-1.5-flash ...`)

### `sql_gen.py`

Expand All @@ -38,13 +63,13 @@ PYDANTIC_AI_MODEL=gemini-1.5-pro uv run --extra examples -m examples.pydantic_mo
Example demonstrating how to use Pydantic AI to generate SQL queries based on user input.

```bash
uv run --extra examples -m examples.sql_gen
(uv run/python) -m pydantic_ai_examples.sql_gen
```

or to use a custom prompt:

```bash
uv run --extra examples -m examples.sql_gen "find me whatever"
(uv run/python) -m pydantic_ai_examples.sql_gen "find me whatever"
```

This model uses `gemini-1.5-flash` by default since Gemini is good at single shot queries.
Expand All @@ -66,7 +91,7 @@ To run this example properly, you'll need two extra API keys:
**(Note if either key is missing, the code will fall back to dummy data.)**

```bash
uv run --extra examples -m examples.weather
(uv run/python) -m pydantic_ai_examples.weather
```

This example uses `openai:gpt-4o` by default. Gemini seems to be unable to handle the multiple tool
Expand Down Expand Up @@ -97,13 +122,13 @@ We also mount the postgresql `data` directory locally to persist the data if you
With that running, we can build the search database with (**WARNING**: this requires the `OPENAI_API_KEY` env variable and will calling the OpenAI embedding API around 300 times to generate embeddings for each section of the documentation):

```bash
uv run --extra examples -m examples.rag build
(uv run/python) -m pydantic_ai_examples.rag build
```

(Note building the database doesn't use Pydantic AI right now, instead it uses the OpenAI SDK directly.)

You can then ask the agent a question with:

```bash
uv run --extra examples -m examples.rag search "How do I configure logfire to work with FastAPI?"
(uv run/python) -m pydantic_ai_examples.rag search "How do I configure logfire to work with FastAPI?"
```
46 changes: 46 additions & 0 deletions pydantic_ai_examples/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Very simply CLI to aid in running the examples, and for copying examples code to a new directory.

See README.md for more information.
"""
import argparse
import sys
from pathlib import Path


def cli():
this_dir = Path(__file__).parent

parser = argparse.ArgumentParser(prog='pydantic_ai_examples', description=__doc__, formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-v', '--version', action='store_true', help='show the version and exit')
parser.add_argument('--copy-to', dest='DEST', help='Copy all examples to a new directory')

args = parser.parse_args()
if args.version:
from pydantic_ai import __version__

print(f'pydantic_ai v{__version__}')
elif args.DEST:
copy_to(this_dir, Path(args.DEST))
else:
parser.print_help()


def copy_to(this_dir: Path, dst: Path):
if dst.exists():
print(f'Error: destination path "{dst}" already exists', file=sys.stderr)
sys.exit(1)

dst.mkdir(parents=True)

count = 0
for file in this_dir.glob('*.*'):
with open(file, 'rb') as src_file:
with open(dst / file.name, 'wb') as dst_file:
dst_file.write(src_file.read())
count += 1

print(f'Copied {count} example files to "{dst}"')


if __name__ == '__main__':
cli()
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Run with:

uv run --extra examples -m examples.pydantic_model
uv run -m pydantic_ai_examples.pydantic_model
"""

import os
Expand Down
8 changes: 4 additions & 4 deletions examples/rag.py → pydantic_ai_examples/rag.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""RAG example with pydantic-ai.
"""RAG example with pydantic-ai — using vector search to augment a chat agent.

Run pgvector with:

Expand All @@ -10,11 +10,11 @@

Build the search DB with:

uv run --extra examples -m examples.rag build
uv run -m pydantic_ai_examples.rag build

Ask the agent a question with:

uv run --extra examples -m examples.rag search "How do I configure logfire to work with FastAPI?"
uv run -m pydantic_ai_examples.rag search "How do I configure logfire to work with FastAPI?"
"""

from __future__ import annotations as _annotations
Expand Down Expand Up @@ -226,5 +226,5 @@ def slugify(value: str, separator: str, unicode: bool = False) -> str:
q = 'How do I configure logfire to work with FastAPI?'
asyncio.run(run_agent(q))
else:
print('uv run --extra examples -m examples.rag build|search', file=sys.stderr)
print('uv run --extra examples -m pydantic_ai_examples.rag build|search', file=sys.stderr)
sys.exit(1)
2 changes: 1 addition & 1 deletion examples/sql_gen.py → pydantic_ai_examples/sql_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Run with:

uv run --extra examples -m examples.sql_gen "show me logs from yesterday, with level 'error'"
uv run -m pydantic_ai_examples.sql_gen "show me logs from yesterday, with level 'error'"
"""

import asyncio
Expand Down
2 changes: 1 addition & 1 deletion examples/weather.py → pydantic_ai_examples/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Run with:

uv run --extra examples -m examples.weather
uv run -m pydantic_ai_examples.weather
"""

from __future__ import annotations as _annotations
Expand Down
10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ examples = [
"logfire[asyncpg]>=1.2.0",
]

[tool.uv]
dev-dependencies = [
[dependency-groups]
dev = [
"dirty-equals>=0.8.0",
"mypy>=1.11.2",
"pyright>=1.1.384",
Expand All @@ -66,10 +66,10 @@ dev-dependencies = [
]

[tool.hatch.build.targets.wheel]
packages = ["pydantic_ai"]
packages = ["pydantic_ai", "pydantic_ai_examples"]

[tool.hatch.build.targets.sdist]
include = ["/README.md", "/Makefile", "/pydantic_ai", "/tests"]
include = ["/README.md", "/Makefile", "/pydantic_ai", "/pydantic_ai_examples", "/tests"]

[tool.ruff]
line-length = 120
Expand Down Expand Up @@ -116,7 +116,7 @@ quote-style = "single"
typeCheckingMode = "strict"
reportUnnecessaryTypeIgnoreComment = true
reportMissingTypeStubs = false
include = ["pydantic_ai", "tests", "examples"]
include = ["pydantic_ai", "tests", "pydantic_ai_examples"]
venvPath = ".venv"
# see https://github.com/microsoft/pyright/issues/7771 - we don't want to error on decorated functions in tests
# which are not otherwise used
Expand Down
Loading
Loading