chore: import upstream snapshot with attribution
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Waiting to run
Test and Publish Multi-arch Docker Image / test (push) Waiting to run
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Blocked by required conditions
Validate Renovate Config / Validate Renovate Configuration (push) Waiting to run
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Waiting to run
Test and Publish Multi-arch Docker Image / test (push) Waiting to run
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Blocked by required conditions
Validate Renovate Config / Validate Renovate Configuration (push) Waiting to run
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
---
|
||||
title: Python Integration
|
||||
sidebar_label: Python
|
||||
sidebar_position: 1
|
||||
description: Use Python for promptfoo evals - providers, assertions, test generators, and prompts. Integrates with LangChain, LangGraph, CrewAI, and more.
|
||||
keywords:
|
||||
[
|
||||
promptfoo python,
|
||||
python llm testing,
|
||||
python eval,
|
||||
python provider,
|
||||
langchain testing,
|
||||
langgraph testing,
|
||||
python llm eval,
|
||||
test llm python,
|
||||
crewai testing,
|
||||
pydantic ai testing,
|
||||
openai agents sdk,
|
||||
google adk,
|
||||
strands agents,
|
||||
python agent framework,
|
||||
]
|
||||
---
|
||||
|
||||
import PythonFileViewer from '@site/src/components/PythonFileViewer';
|
||||
|
||||
# Python
|
||||
|
||||
Promptfoo is written in TypeScript and runs via Node.js, but it has first-class Python support. You can use Python for any part of your eval pipeline without writing JavaScript.
|
||||
|
||||
**Use Python for:**
|
||||
|
||||
- [**Providers**](#providers): call custom models, wrap APIs, run Hugging Face/PyTorch
|
||||
- [**Assertions**](#assertions): validate outputs with custom scoring logic
|
||||
- [**Test generators**](#test-generators): load test cases from databases, APIs, or generate them programmatically
|
||||
- [**Prompts**](#prompts): build prompts dynamically based on test variables
|
||||
- [**Framework integrations**](#framework-integrations): test LangChain, LangGraph, CrewAI, and other agent frameworks
|
||||
|
||||
The `file://` prefix tells promptfoo to execute a Python function. Promptfoo automatically detects your Python installation.
|
||||
|
||||
```yaml title="promptfooconfig.yaml"
|
||||
# yaml-language-server: $schema=https://promptfoo.dev/config-schema.json
|
||||
prompts:
|
||||
- file://prompts.py:create_prompt # Python generates the prompt
|
||||
|
||||
providers:
|
||||
- file://provider.py # Python calls the model
|
||||
|
||||
tests:
|
||||
- file://tests.py:generate_tests # Python generates test cases
|
||||
|
||||
defaultTest:
|
||||
assert:
|
||||
- type: python # Python validates the output
|
||||
value: file://assert.py:check
|
||||
```
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
<PythonFileViewer
|
||||
defaultOpen="provider.py"
|
||||
files={[
|
||||
{
|
||||
name: 'prompts.py',
|
||||
description: 'Generate prompts',
|
||||
content: `def create_prompt(context):
|
||||
return [
|
||||
{"role": "system", "content": "You are a helpful assistant."},
|
||||
{"role": "user", "content": f"Explain {context['vars']['topic']}"},
|
||||
]`,
|
||||
},
|
||||
{
|
||||
name: 'provider.py',
|
||||
description: 'Call any model',
|
||||
content: `from openai import OpenAI
|
||||
|
||||
client = OpenAI()
|
||||
|
||||
def call_api(prompt, options, context):
|
||||
# The Responses API exposes combined text through output_text.
|
||||
response = client.responses.create(
|
||||
model="gpt-5.1-mini",
|
||||
input=prompt,
|
||||
)
|
||||
return {"output": response.output_text}`,
|
||||
},
|
||||
{
|
||||
name: 'tests.py',
|
||||
description: 'Generate tests',
|
||||
content: `def generate_tests(config=None):
|
||||
return [
|
||||
{"vars": {"topic": "decorators"}},
|
||||
{"vars": {"topic": "async/await"}},
|
||||
]`,
|
||||
},
|
||||
{
|
||||
name: 'assert.py',
|
||||
description: 'Validate output',
|
||||
content: `def check(output, context):
|
||||
topic = context["vars"]["topic"]
|
||||
if topic.lower() not in output.lower():
|
||||
return {"pass": False, "score": 0, "reason": f"Missing: {topic}"}
|
||||
return {"pass": True, "score": 1.0}`,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
```bash
|
||||
npx promptfoo@latest init --example provider-python
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Providers
|
||||
|
||||
Use `file://` to reference a Python file:
|
||||
|
||||
```yaml
|
||||
providers:
|
||||
- file://provider.py # Uses call_api() by default
|
||||
- file://provider.py:custom_function # Specify a function name
|
||||
```
|
||||
|
||||
Your function receives three arguments and returns a dict:
|
||||
|
||||
```python title="provider.py"
|
||||
def call_api(prompt, options, context): # or: async def call_api(...)
|
||||
# prompt: string or JSON-encoded messages
|
||||
# options: {"config": {...}} from YAML
|
||||
# context: {"vars": {...}} from test case
|
||||
|
||||
return {
|
||||
"output": "response text",
|
||||
# Optional:
|
||||
"tokenUsage": {"total": 100, "prompt": 20, "completion": 80},
|
||||
"cost": 0.001,
|
||||
}
|
||||
```
|
||||
|
||||
→ [Provider documentation](/docs/providers/python)
|
||||
|
||||
---
|
||||
|
||||
## Assertions
|
||||
|
||||
Use `type: python` to run custom validation:
|
||||
|
||||
```yaml
|
||||
assert:
|
||||
# Inline expression (returns bool or float 0-1)
|
||||
- type: python
|
||||
value: "'keyword' in output.lower()"
|
||||
|
||||
# External file
|
||||
- type: python
|
||||
value: file://assert.py
|
||||
```
|
||||
|
||||
For external files, define a `get_assert` function:
|
||||
|
||||
```python title="assert.py"
|
||||
def get_assert(output, context):
|
||||
# Return bool, float (0-1), or detailed result
|
||||
return {
|
||||
"pass": True,
|
||||
"score": 0.9,
|
||||
"reason": "Meets criteria",
|
||||
}
|
||||
```
|
||||
|
||||
→ [Assertions documentation](/docs/configuration/expected-outputs/python)
|
||||
|
||||
---
|
||||
|
||||
## Test Generators
|
||||
|
||||
Load or generate test cases from Python:
|
||||
|
||||
```yaml
|
||||
tests:
|
||||
- file://tests.py:generate_tests
|
||||
```
|
||||
|
||||
```python title="tests.py"
|
||||
def generate_tests(config=None):
|
||||
# Load from database, API, files, etc.
|
||||
return [
|
||||
{"vars": {"input": "test 1"}, "assert": [{"type": "contains", "value": "expected"}]},
|
||||
{"vars": {"input": "test 2"}},
|
||||
]
|
||||
```
|
||||
|
||||
Pass configuration from YAML:
|
||||
|
||||
```yaml
|
||||
tests:
|
||||
- path: file://tests.py:generate_tests
|
||||
config:
|
||||
max_cases: 100
|
||||
category: 'safety'
|
||||
```
|
||||
|
||||
→ [Test case documentation](/docs/configuration/test-cases#dynamic-test-generation)
|
||||
|
||||
---
|
||||
|
||||
## Prompts
|
||||
|
||||
Build prompts dynamically:
|
||||
|
||||
```yaml
|
||||
prompts:
|
||||
- file://prompts.py:create_prompt
|
||||
```
|
||||
|
||||
```python title="prompts.py"
|
||||
def create_prompt(context):
|
||||
# Return string or chat messages
|
||||
return [
|
||||
{"role": "system", "content": "You are an expert."},
|
||||
{"role": "user", "content": f"Explain {context['vars']['topic']}"},
|
||||
]
|
||||
```
|
||||
|
||||
→ [Prompts documentation](/docs/configuration/prompts)
|
||||
|
||||
---
|
||||
|
||||
## Framework Integrations
|
||||
|
||||
Test Python agent frameworks by wrapping them as providers:
|
||||
|
||||
| Framework | Example | Guide |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
||||
| **LangGraph** | [`langgraph`](https://github.com/promptfoo/promptfoo/tree/main/examples/integration-langgraph) | [Evaluate LangGraph agents](/docs/guides/evaluate-langgraph) |
|
||||
| **LangChain** | [`langchain-python`](https://github.com/promptfoo/promptfoo/tree/main/examples/integration-langchain) | [Test LLM chains](/docs/configuration/testing-llm-chains) |
|
||||
| **CrewAI** | [`crewai`](https://github.com/promptfoo/promptfoo/tree/main/examples/integration-crewai) | [Evaluate CrewAI agents](/docs/guides/evaluate-crewai) |
|
||||
| **OpenAI Agents** | [`openai-agents`](https://github.com/promptfoo/promptfoo/tree/main/examples/openai-agents) | [OpenAI Agents Python SDK](/docs/guides/evaluate-openai-agents-python) |
|
||||
| **PydanticAI** | [`pydantic-ai`](https://github.com/promptfoo/promptfoo/tree/main/examples/integration-pydantic-ai) | Type-safe agents with Pydantic |
|
||||
| **Google ADK** | [`integration-google-adk`](https://github.com/promptfoo/promptfoo/tree/main/examples/integration-google-adk) | [Evaluate Google ADK agents](/docs/guides/evaluate-google-adk) |
|
||||
| **Strands Agents** | [`strands-agents`](https://github.com/promptfoo/promptfoo/tree/main/examples/integration-strands-agents) | AWS open-source agent framework |
|
||||
|
||||
To get started with any example:
|
||||
|
||||
```bash
|
||||
npx promptfoo@latest init --example integration-langgraph
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Jupyter / Colab
|
||||
|
||||
```python
|
||||
# Install
|
||||
!npm install -g promptfoo
|
||||
|
||||
# Create config
|
||||
%%writefile promptfooconfig.yaml
|
||||
prompts:
|
||||
- "Explain {{topic}}"
|
||||
providers:
|
||||
- openai:gpt-4.1-mini
|
||||
tests:
|
||||
- vars:
|
||||
topic: machine learning
|
||||
|
||||
# Run
|
||||
!npx promptfoo eval
|
||||
```
|
||||
|
||||
**[Open in Google Colab](https://colab.research.google.com/gist/typpo/734a5f53eb1922f90198538dbe17aa27/promptfoo-example-1.ipynb)**
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### Python Path
|
||||
|
||||
Set a custom Python executable:
|
||||
|
||||
```bash
|
||||
export PROMPTFOO_PYTHON=/path/to/python3
|
||||
```
|
||||
|
||||
Or configure per-provider in YAML:
|
||||
|
||||
```yaml
|
||||
providers:
|
||||
- id: file://provider.py
|
||||
config:
|
||||
pythonExecutable: ./venv/bin/python
|
||||
```
|
||||
|
||||
### Module Paths
|
||||
|
||||
Add directories to the Python path:
|
||||
|
||||
```bash
|
||||
export PYTHONPATH=/path/to/modules:$PYTHONPATH
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
||||
Enable debug output to see Python execution details:
|
||||
|
||||
```bash
|
||||
LOG_LEVEL=debug npx promptfoo eval
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
See [Python provider troubleshooting](/docs/providers/python#troubleshooting) for common issues like `Python not found`, module import errors, and timeout problems.
|
||||
Reference in New Issue
Block a user