From 71ac5e20eaa2cd18747d3edefc20a0995f1eb5f3 Mon Sep 17 00:00:00 2001 From: "Nova (SFK)" Date: Tue, 28 Apr 2026 23:09:33 +0000 Subject: [PATCH 1/5] docs(examples): convert to per-integration uv projects using auto_instrument Restructure py/examples/ so every example is an isolated uv project that clones/copies cleanly. Each one consists of a pyproject.toml (with a local editable braintrust source), a short README, and a tiny example script. Every provider example now uses braintrust.auto_instrument() + init_logger() as the canonical setup pattern instead of integration-specific setup_*() / wrap_*() helpers, matching the direction of the integrations API. - 13 new examples for previously uncovered integrations: agentscope, autogen, claude_agent_sdk, cohere, crewai, google_genai, langchain, litellm, llamaindex, mistral, openai_agents, openrouter, strands. - Existing top-level scripts moved into their own directories (openai_example.py -> openai/, anthropic_*.py -> anthropic/, etc.) with git history preserved. - temporal/: requirements.txt -> pyproject.toml; Procfile/mise.toml updated to use uv run / uv sync. - langsmith/: drop committed uv.lock for consistency. - adk/: drop manual_patching.py since auto_instrument supersedes it. - Drop the dedicated auto_instrument/ showcase since every provider example now demonstrates auto_instrument by default. - Top-level examples/README.md explains the layout, the canonical auto_instrument() pattern, and lists every example. - uv.lock files are gitignored: examples target current PyPI, not pinned snapshots, so each clone resolves fresh. Verified by running `uv sync` and `braintrust.auto_instrument()` in every example dir; each integration reports `instrumented: True`. Co-Authored-By: Claude Opus 4.7 --- py/examples/.gitignore | 7 + py/examples/README.md | 95 ++ py/examples/adk/README.md | 13 + py/examples/adk/{auto.py => example.py} | 10 +- py/examples/adk/manual_patching.py | 52 - py/examples/adk/pyproject.toml | 13 + py/examples/agentscope/README.md | 13 + py/examples/agentscope/example.py | 35 + py/examples/agentscope/pyproject.toml | 13 + py/examples/agno/README.md | 21 + py/examples/agno/async_simple_agent_stream.py | 5 +- py/examples/agno/async_team_agent.py | 8 +- py/examples/agno/pyproject.toml | 14 + py/examples/agno/simple_agent.py | 6 +- py/examples/agno/simple_agent_stream.py | 6 +- py/examples/agno/team_agent.py | 8 +- py/examples/anthropic/README.md | 14 + .../async_example.py} | 32 +- py/examples/anthropic/pyproject.toml | 12 + .../{anthropic_sync.py => anthropic/sync.py} | 16 +- py/examples/auto_instrument.py | 71 -- py/examples/autogen/README.md | 13 + py/examples/autogen/example.py | 29 + py/examples/autogen/pyproject.toml | 13 + py/examples/claude_agent_sdk/README.md | 15 + py/examples/claude_agent_sdk/example.py | 25 + py/examples/claude_agent_sdk/pyproject.toml | 12 + py/examples/cohere/README.md | 13 + py/examples/cohere/example.py | 19 + py/examples/cohere/pyproject.toml | 12 + py/examples/crewai/README.md | 13 + py/examples/crewai/example.py | 29 + py/examples/crewai/pyproject.toml | 12 + py/examples/dspy/README.md | 15 + py/examples/dspy/example.py | 53 +- py/examples/dspy/pyproject.toml | 14 + py/examples/evals/README.md | 18 + py/examples/evals/pyproject.toml | 11 + py/examples/google_genai/README.md | 13 + py/examples/google_genai/example.py | 19 + py/examples/google_genai/pyproject.toml | 12 + py/examples/langchain/README.md | 13 + py/examples/langchain/example.py | 25 + py/examples/langchain/pyproject.toml | 13 + py/examples/langsmith/uv.lock | 966 ------------------ py/examples/litellm/README.md | 15 + py/examples/litellm/example.py | 17 + py/examples/litellm/pyproject.toml | 12 + py/examples/llamaindex/README.md | 13 + py/examples/llamaindex/example.py | 15 + py/examples/llamaindex/pyproject.toml | 13 + py/examples/mistral/README.md | 13 + py/examples/mistral/example.py | 22 + py/examples/mistral/pyproject.toml | 12 + py/examples/openai/README.md | 13 + .../{openai_example.py => openai/example.py} | 12 +- py/examples/openai/pyproject.toml | 12 + py/examples/openai_agents/README.md | 13 + py/examples/openai_agents/example.py | 27 + py/examples/openai_agents/pyproject.toml | 12 + py/examples/openrouter/README.md | 13 + py/examples/openrouter/example.py | 20 + py/examples/openrouter/pyproject.toml | 12 + py/examples/otel/README.md | 21 + py/examples/otel/pyproject.toml | 14 + py/examples/pydantic_ai/README.md | 13 + .../example.py} | 0 py/examples/pydantic_ai/pyproject.toml | 12 + py/examples/strands/README.md | 13 + py/examples/strands/example.py | 29 + py/examples/strands/pyproject.toml | 13 + py/examples/temporal/Procfile | 6 +- py/examples/temporal/README.md | 7 +- py/examples/temporal/mise.toml | 4 +- py/examples/temporal/pyproject.toml | 11 + py/examples/temporal/requirements.txt | 2 - 76 files changed, 1051 insertions(+), 1201 deletions(-) create mode 100644 py/examples/README.md create mode 100644 py/examples/adk/README.md rename py/examples/adk/{auto.py => example.py} (82%) delete mode 100644 py/examples/adk/manual_patching.py create mode 100644 py/examples/adk/pyproject.toml create mode 100644 py/examples/agentscope/README.md create mode 100644 py/examples/agentscope/example.py create mode 100644 py/examples/agentscope/pyproject.toml create mode 100644 py/examples/agno/README.md create mode 100644 py/examples/agno/pyproject.toml create mode 100644 py/examples/anthropic/README.md rename py/examples/{anthropic_async.py => anthropic/async_example.py} (60%) create mode 100644 py/examples/anthropic/pyproject.toml rename py/examples/{anthropic_sync.py => anthropic/sync.py} (78%) delete mode 100644 py/examples/auto_instrument.py create mode 100644 py/examples/autogen/README.md create mode 100644 py/examples/autogen/example.py create mode 100644 py/examples/autogen/pyproject.toml create mode 100644 py/examples/claude_agent_sdk/README.md create mode 100644 py/examples/claude_agent_sdk/example.py create mode 100644 py/examples/claude_agent_sdk/pyproject.toml create mode 100644 py/examples/cohere/README.md create mode 100644 py/examples/cohere/example.py create mode 100644 py/examples/cohere/pyproject.toml create mode 100644 py/examples/crewai/README.md create mode 100644 py/examples/crewai/example.py create mode 100644 py/examples/crewai/pyproject.toml create mode 100644 py/examples/dspy/README.md create mode 100644 py/examples/dspy/pyproject.toml create mode 100644 py/examples/evals/README.md create mode 100644 py/examples/evals/pyproject.toml create mode 100644 py/examples/google_genai/README.md create mode 100644 py/examples/google_genai/example.py create mode 100644 py/examples/google_genai/pyproject.toml create mode 100644 py/examples/langchain/README.md create mode 100644 py/examples/langchain/example.py create mode 100644 py/examples/langchain/pyproject.toml delete mode 100644 py/examples/langsmith/uv.lock create mode 100644 py/examples/litellm/README.md create mode 100644 py/examples/litellm/example.py create mode 100644 py/examples/litellm/pyproject.toml create mode 100644 py/examples/llamaindex/README.md create mode 100644 py/examples/llamaindex/example.py create mode 100644 py/examples/llamaindex/pyproject.toml create mode 100644 py/examples/mistral/README.md create mode 100644 py/examples/mistral/example.py create mode 100644 py/examples/mistral/pyproject.toml create mode 100644 py/examples/openai/README.md rename py/examples/{openai_example.py => openai/example.py} (83%) create mode 100644 py/examples/openai/pyproject.toml create mode 100644 py/examples/openai_agents/README.md create mode 100644 py/examples/openai_agents/example.py create mode 100644 py/examples/openai_agents/pyproject.toml create mode 100644 py/examples/openrouter/README.md create mode 100644 py/examples/openrouter/example.py create mode 100644 py/examples/openrouter/pyproject.toml create mode 100644 py/examples/otel/README.md create mode 100644 py/examples/otel/pyproject.toml create mode 100644 py/examples/pydantic_ai/README.md rename py/examples/{pydantic_ai_example.py => pydantic_ai/example.py} (100%) create mode 100644 py/examples/pydantic_ai/pyproject.toml create mode 100644 py/examples/strands/README.md create mode 100644 py/examples/strands/example.py create mode 100644 py/examples/strands/pyproject.toml create mode 100644 py/examples/temporal/pyproject.toml delete mode 100644 py/examples/temporal/requirements.txt diff --git a/py/examples/.gitignore b/py/examples/.gitignore index 245773fb..f0dac40e 100644 --- a/py/examples/.gitignore +++ b/py/examples/.gitignore @@ -1 +1,8 @@ run.sh + +# Examples install fresh against current PyPI; locks aren't checked in. +uv.lock +.venv/ +__pycache__/ +*.pyc +.env diff --git a/py/examples/README.md b/py/examples/README.md new file mode 100644 index 00000000..16454093 --- /dev/null +++ b/py/examples/README.md @@ -0,0 +1,95 @@ +# Braintrust Python SDK Examples + +Each subdirectory in this folder is a self-contained [`uv`](https://docs.astral.sh/uv/) project demonstrating one Braintrust integration or feature. They are designed to be cloned, copied, or run as-is without affecting the rest of the repository. + +## Layout + +Every example has the same shape: + +``` +examples// +├── pyproject.toml # declares deps + a local `path` source for braintrust +├── README.md # what it shows + how to run it +└── *.py # the example script(s) +``` + +The `pyproject.toml` in each example pins `braintrust` to the local checkout via: + +```toml +[tool.uv.sources] +braintrust = { path = "../..", editable = true } +``` + +That means `uv sync` inside any example installs the version of the SDK currently on disk — edits to `py/src/braintrust/` are picked up immediately. + +## Running an example + +From the repo root: + +```bash +cd py/examples/ +uv sync +uv run python