From 20e0124a2ecdb04a2afa4c83da830a8835fdf2ac Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 11:18:11 -0500 Subject: [PATCH 01/10] note about jupyter --- .ipynb_checkpoints/Untitled-checkpoint.ipynb | 6 ++++++ Untitled.ipynb | 6 ++++++ docs/agents.md | 10 ++++++++++ 3 files changed, 22 insertions(+) create mode 100644 .ipynb_checkpoints/Untitled-checkpoint.ipynb create mode 100644 Untitled.ipynb diff --git a/.ipynb_checkpoints/Untitled-checkpoint.ipynb b/.ipynb_checkpoints/Untitled-checkpoint.ipynb new file mode 100644 index 0000000000..363fcab7ed --- /dev/null +++ b/.ipynb_checkpoints/Untitled-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Untitled.ipynb b/Untitled.ipynb new file mode 100644 index 0000000000..363fcab7ed --- /dev/null +++ b/Untitled.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/agents.md b/docs/agents.md index af42c3a95c..db86518022 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -90,6 +90,16 @@ _(This example is complete, it can be run "as is")_ You can also pass messages from previous runs to continue a conversation or provide context, as described in [Messages and Chat History](message-history.md). +!!! note "jupyter notebooks" + If you're running `pydantic-ai` in a jupyter notebook, you might consider using [`nest-asyncio`](https://pypi.org/project/nest-asyncio/) + to manage conflicts between event loops that occur between jupyter's event loops and `pydantic-ai`'s. + + Before you execute any agent runs, do the following: + ```py + import nest_asyncio + nest_asyncio.apply() + ``` + ## Runs vs. Conversations An agent **run** might represent an entire conversation — there's no limit to how many messages can be exchanged in a single run. However, a **conversation** might also be composed of multiple runs, especially if you need to maintain state between separate interactions or API calls. From f7906af884e2d797415f89bd9f1b50c8bcbdc11e Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 11:18:38 -0500 Subject: [PATCH 02/10] remove jupyter stuff --- .ipynb_checkpoints/Untitled-checkpoint.ipynb | 6 ------ Untitled.ipynb | 6 ------ 2 files changed, 12 deletions(-) delete mode 100644 .ipynb_checkpoints/Untitled-checkpoint.ipynb delete mode 100644 Untitled.ipynb diff --git a/.ipynb_checkpoints/Untitled-checkpoint.ipynb b/.ipynb_checkpoints/Untitled-checkpoint.ipynb deleted file mode 100644 index 363fcab7ed..0000000000 --- a/.ipynb_checkpoints/Untitled-checkpoint.ipynb +++ /dev/null @@ -1,6 +0,0 @@ -{ - "cells": [], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/Untitled.ipynb b/Untitled.ipynb deleted file mode 100644 index 363fcab7ed..0000000000 --- a/Untitled.ipynb +++ /dev/null @@ -1,6 +0,0 @@ -{ - "cells": [], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 5 -} From 1c05506d2937d321422883abf9d695f59d8b1356 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 11:20:21 -0500 Subject: [PATCH 03/10] formatting --- docs/agents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/agents.md b/docs/agents.md index db86518022..2fe867f1a6 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -97,6 +97,7 @@ You can also pass messages from previous runs to continue a conversation or prov Before you execute any agent runs, do the following: ```py import nest_asyncio + nest_asyncio.apply() ``` From 3a12bbeb6fcb57071f2a07fd8b96d78dfcd84929 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 11:24:04 -0500 Subject: [PATCH 04/10] skip linting and testing --- docs/agents.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/agents.md b/docs/agents.md index 2fe867f1a6..b71f5ee96c 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -95,9 +95,8 @@ You can also pass messages from previous runs to continue a conversation or prov to manage conflicts between event loops that occur between jupyter's event loops and `pydantic-ai`'s. Before you execute any agent runs, do the following: - ```py + ```py {test=skip, lint=skip} import nest_asyncio - nest_asyncio.apply() ``` From dccbbdc97a9d8c813e92c4f8b9537213e4d85937 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 11:26:27 -0500 Subject: [PATCH 05/10] update comment --- docs/agents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/agents.md b/docs/agents.md index b71f5ee96c..b0668e8ea0 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -62,7 +62,7 @@ print(result.data) There are three ways to run an agent: 1. [`agent.run()`][pydantic_ai.Agent.run] — a coroutine which returns a [`RunResult`][pydantic_ai.result.RunResult] containing a completed response -2. [`agent.run_sync()`][pydantic_ai.Agent.run_sync] — a plain, synchronous function which returns a [`RunResult`][pydantic_ai.result.RunResult] containing a completed response (internally, this just calls `asyncio.run(self.run())`) +2. [`agent.run_sync()`][pydantic_ai.Agent.run_sync] — a plain, synchronous function which returns a [`RunResult`][pydantic_ai.result.RunResult] containing a completed response (internally, this just calls `loop.run_until_complete(self.run())`) 3. [`agent.run_stream()`][pydantic_ai.Agent.run_stream] — a coroutine which returns a [`StreamedRunResult`][pydantic_ai.result.StreamedRunResult], which contains methods to stream a response as an async iterable Here's a simple example demonstrating all three: From bc934995b118eb86ce7f388d4358714aa20d0c11 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 11:29:09 -0500 Subject: [PATCH 06/10] more formatting --- docs/agents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/agents.md b/docs/agents.md index b0668e8ea0..b99b0df8e5 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -95,7 +95,7 @@ You can also pass messages from previous runs to continue a conversation or prov to manage conflicts between event loops that occur between jupyter's event loops and `pydantic-ai`'s. Before you execute any agent runs, do the following: - ```py {test=skip, lint=skip} + ```py {test="skip", lint="skip"} import nest_asyncio nest_asyncio.apply() ``` From 06cfcb67657849795205317a0f143e794493be61 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 11:34:48 -0500 Subject: [PATCH 07/10] do it the old way --- docs/agents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/agents.md b/docs/agents.md index b99b0df8e5..06d02108f2 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -95,7 +95,7 @@ You can also pass messages from previous runs to continue a conversation or prov to manage conflicts between event loops that occur between jupyter's event loops and `pydantic-ai`'s. Before you execute any agent runs, do the following: - ```py {test="skip", lint="skip"} + ```py test="skip", lint="skip" import nest_asyncio nest_asyncio.apply() ``` From 5dcb4ad78b52f0f5e9ef5a660cb5ffef1b023c98 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 11:45:15 -0500 Subject: [PATCH 08/10] get test examples working --- docs/agents.md | 2 +- docs/index.md | 2 +- tests/test_examples.py | 23 ++++++++++++++--------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/docs/agents.md b/docs/agents.md index 06d02108f2..b99b0df8e5 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -95,7 +95,7 @@ You can also pass messages from previous runs to continue a conversation or prov to manage conflicts between event loops that occur between jupyter's event loops and `pydantic-ai`'s. Before you execute any agent runs, do the following: - ```py test="skip", lint="skip" + ```py {test="skip", lint="skip"} import nest_asyncio nest_asyncio.apply() ``` diff --git a/docs/index.md b/docs/index.md index 69d7e14f52..d954d1feff 100644 --- a/docs/index.md +++ b/docs/index.md @@ -144,7 +144,7 @@ To understand the flow of the above runs, we can watch the agent in action using To do this, we need to set up logfire, and add the following to our code: -```py title="bank_support_with_logfire.py" hl_lines="4-6" +```py title="bank_support_with_logfire.py" hl_lines="4-6" test="skip" lint="skip" ... from bank_database import DatabaseConn diff --git a/tests/test_examples.py b/tests/test_examples.py index d6aa7aab0b..daa0e3f2df 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -81,11 +81,12 @@ def test_docs_examples( prefix_settings = example.prefix_settings() opt_title = prefix_settings.get('title') + opt_test = prefix_settings.get('test', '') + opt_lint = prefix_settings.get('lint', '') cwd = Path.cwd() - if opt_title == 'bank_support_with_logfire.py': - # don't format and no need to run - return + if opt_test.startswith('skip') and opt_lint.startswith('skip'): + pytest.skip('both running code and lint skipped') if opt_title == 'sql_app_evals.py': os.chdir(tmp_path) @@ -116,12 +117,16 @@ def test_docs_examples( call_name = name break - if eval_example.update_examples: # pragma: no cover - eval_example.format(example) - module_dict = eval_example.run_print_update(example, call=call_name) - else: - eval_example.lint(example) - module_dict = eval_example.run_print_check(example, call=call_name) + if not opt_lint.startswith('skip'): + if eval_example.update_examples: # pragma: no cover + eval_example.format(example) + module_dict = eval_example.run_print_update(example, call=call_name) + else: + eval_example.lint(example) + module_dict = eval_example.run_print_check(example, call=call_name) + + if opt_test.startswith('skip'): + pytest.skip(opt_test[4:].lstrip(' -') or 'running code skipped') os.chdir(cwd) if title := opt_title: From c159f6fd3e00178cd29c61f556a9936036856905 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 12:01:28 -0500 Subject: [PATCH 09/10] fix linting issue --- tests/test_examples.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_examples.py b/tests/test_examples.py index daa0e3f2df..691bfc4327 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -125,16 +125,16 @@ def test_docs_examples( eval_example.lint(example) module_dict = eval_example.run_print_check(example, call=call_name) + os.chdir(cwd) + if title := opt_title: + if title.endswith('.py'): + module_name = title[:-3] + sys.modules[module_name] = module = ModuleType(module_name) + module.__dict__.update(module_dict) + if opt_test.startswith('skip'): pytest.skip(opt_test[4:].lstrip(' -') or 'running code skipped') - os.chdir(cwd) - if title := opt_title: - if title.endswith('.py'): - module_name = title[:-3] - sys.modules[module_name] = module = ModuleType(module_name) - module.__dict__.update(module_dict) - def print_callback(s: str) -> str: s = re.sub(r'datetime\.datetime\(.+?\)', 'datetime.datetime(...)', s, flags=re.DOTALL) From 82214caa5ba41cd17173d917dd9f867f3f0c0a43 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 11 Dec 2024 12:08:07 -0500 Subject: [PATCH 10/10] reformat test examples --- tests/test_examples.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/test_examples.py b/tests/test_examples.py index 691bfc4327..db89a1eaa4 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -108,7 +108,6 @@ def test_docs_examples( line_length = 120 eval_example.set_config(ruff_ignore=ruff_ignore, target_version='py39', line_length=line_length) - eval_example.print_callback = print_callback call_name = 'main' @@ -120,9 +119,15 @@ def test_docs_examples( if not opt_lint.startswith('skip'): if eval_example.update_examples: # pragma: no cover eval_example.format(example) - module_dict = eval_example.run_print_update(example, call=call_name) else: eval_example.lint(example) + + if opt_test.startswith('skip'): + pytest.skip(opt_test[4:].lstrip(' -') or 'running code skipped') + else: + if eval_example.update_examples: + module_dict = eval_example.run_print_update(example, call=call_name) + else: module_dict = eval_example.run_print_check(example, call=call_name) os.chdir(cwd) @@ -132,9 +137,6 @@ def test_docs_examples( sys.modules[module_name] = module = ModuleType(module_name) module.__dict__.update(module_dict) - if opt_test.startswith('skip'): - pytest.skip(opt_test[4:].lstrip(' -') or 'running code skipped') - def print_callback(s: str) -> str: s = re.sub(r'datetime\.datetime\(.+?\)', 'datetime.datetime(...)', s, flags=re.DOTALL)