Skip to content

Commit 40c3ede

Browse files
committed
chore: Remove API key usage in CI
- Remove ANTHROPIC_API_KEY, OPENAI_API_KEY, and GEMINI_API_KEY secrets from all CI workflows — tests use VCR cassettes with record_mode="none" in CI, so real API keys are never needed - Add dummy ANTHROPIC_API_KEY fallback in conftest.py (OpenAI and Google already had one) to prevent Anthropic client instantiation failures - Skip test_latest_wrappers_novcr nox session in CI since it disables VCR and requires real keys - Add CONTRIBUTING.md with repo setup, structure, testing, and CI docs - Add docs/vcr-testing.md with detailed VCR testing guide covering local vs CI differences and contributor workflow
1 parent abc8bed commit 40c3ede

11 files changed

Lines changed: 302 additions & 1298 deletions

.github/workflows/adk-py-test.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ jobs:
1515
runs-on: ${{ inputs.os }}
1616
timeout-minutes: 15
1717

18-
env:
19-
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
20-
2118
defaults:
2219
run:
2320
working-directory: integrations/adk-py

.github/workflows/langchain-py-test.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ jobs:
1919
run:
2020
working-directory: integrations/langchain-py
2121

22-
env:
23-
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
24-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
25-
2622
steps:
2723
- uses: actions/checkout@v4
2824

.github/workflows/publish-py-sdk.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ jobs:
4040
id-token: write # Required for PyPI trusted publishing
4141

4242
env:
43-
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
44-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
45-
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
4643
RELEASE_TAG: ${{ needs.validate.outputs.release_tag }}
4744

4845
steps:

.github/workflows/py.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ jobs:
2424
os: [ubuntu-latest, windows-latest]
2525
shard: [0, 1]
2626

27-
env:
28-
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
29-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
30-
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
31-
3227
steps:
3328
- uses: actions/checkout@v4
3429
- name: Set up Python
@@ -61,7 +56,6 @@ jobs:
6156
with:
6257
python-version: ${{ matrix.python-version }}
6358
os: ${{ matrix.os }}
64-
secrets: inherit
6559

6660
langchain-py:
6761
uses: ./.github/workflows/langchain-py-test.yaml
@@ -73,7 +67,6 @@ jobs:
7367
with:
7468
python-version: ${{ matrix.python-version }}
7569
os: ${{ matrix.os }}
76-
secrets: inherit
7770

7871
upload-wheel:
7972
needs: build

.github/workflows/test-publish-py-sdk.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ jobs:
2727
version: ${{ steps.get_version.outputs.version }}
2828

2929
env:
30-
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
31-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
32-
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
3330
PYPI_REPO: testpypi
3431

3532
steps:

CONTRIBUTING.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# Contributing
2+
3+
Guide for contributing to the Braintrust Python SDK.
4+
5+
## Repository Structure
6+
7+
```
8+
braintrust-sdk-python/
9+
├── py/ # Python SDK
10+
│ ├── src/braintrust/ # Source code
11+
│ │ ├── wrappers/ # Provider wrappers (OpenAI, Anthropic, Google, etc.)
12+
│ │ ├── contrib/ # Community integrations (Temporal, etc.)
13+
│ │ ├── devserver/ # Local dev server / CLI
14+
│ │ └── conftest.py # Shared test fixtures
15+
│ ├── noxfile.py # Test session definitions
16+
│ └── Makefile # Build/test commands
17+
├── integrations/
18+
│ ├── langchain-py/ # LangChain integration
19+
│ └── adk-py/ # Google ADK integration
20+
├── internal/ # Golden tests
21+
├── scripts/ # Dev scripts
22+
├── docs/ # Documentation
23+
└── Makefile # Top-level commands
24+
```
25+
26+
## Setup
27+
28+
### Prerequisites
29+
30+
- Python 3.10+ (3.9 supported but some test sessions are skipped)
31+
- [uv](https://github.com/astral-sh/uv) (installed automatically by `make install-dev`)
32+
33+
### Getting Started
34+
35+
```bash
36+
# Clone the repo
37+
git clone https://github.com/braintrustdata/braintrust-sdk-python.git
38+
cd braintrust-sdk-python
39+
40+
# Create venv and install all dependencies
41+
make develop
42+
43+
# Activate the environment
44+
source env.sh
45+
```
46+
47+
### Python SDK Development
48+
49+
```bash
50+
cd py
51+
52+
# Install dev dependencies
53+
make install-dev
54+
55+
# Install optional provider packages (for wrapper development)
56+
make install-optional
57+
```
58+
59+
## Running Tests
60+
61+
### Python SDK
62+
63+
Tests use [nox](https://nox.thea.codes/) to run across different dependency versions.
64+
65+
```bash
66+
cd py
67+
68+
# Run all test sessions
69+
make test
70+
71+
# Run core tests only (no optional dependencies)
72+
make test-core
73+
74+
# List all available sessions
75+
nox -l
76+
77+
# Run a specific session
78+
nox -s "test_openai(latest)"
79+
nox -s "test_anthropic(latest)"
80+
nox -s "test_temporal(latest)"
81+
82+
# Run a single test within a session
83+
nox -s "test_openai(latest)" -- -k "test_chat_metrics"
84+
```
85+
86+
### Integration Tests
87+
88+
```bash
89+
# LangChain
90+
cd integrations/langchain-py
91+
uv sync
92+
uv run pytest src
93+
94+
# ADK
95+
cd integrations/adk-py
96+
uv sync
97+
uv run pytest
98+
```
99+
100+
### Linting
101+
102+
```bash
103+
# From repo root — runs pre-commit hooks (formatting, etc.)
104+
make fixup
105+
106+
# Python-specific lint (pylint)
107+
cd py && make lint
108+
```
109+
110+
## VCR Cassette Testing
111+
112+
Tests for API provider wrappers use VCR.py to record and replay HTTP interactions. This means most tests run without real API keys.
113+
114+
See [docs/vcr-testing.md](docs/vcr-testing.md) for full details. Key points:
115+
116+
- **Locally:** VCR records new cassettes on first run (`record_mode="once"`). You need a real API key to record.
117+
- **In CI:** VCR only replays existing cassettes (`record_mode="none"`). No API keys needed.
118+
- **Modifying tests:** If your change alters the HTTP request a test makes, you must re-record the cassette locally with a real API key and commit it.
119+
- **New tests:** Add `@pytest.mark.vcr`, record the cassette locally, and commit the cassette file.
120+
121+
## CI Overview
122+
123+
CI runs on GitHub Actions. All workflows are in `.github/workflows/`.
124+
125+
### Workflows
126+
127+
| Workflow | File | Trigger | What it does |
128+
|---|---|---|---|
129+
| **py** | `py.yaml` | PR (py/integrations changes), push to main | Runs nox test matrix across Python 3.10–3.13 on Ubuntu + Windows, plus integration tests |
130+
| **langchain-py** | `langchain-py-test.yaml` | Called by `py.yaml` | Lint + tests for the LangChain integration |
131+
| **adk-py** | `adk-py-test.yaml` | Called by `py.yaml` | Lint + tests for the Google ADK integration |
132+
| **lint** | `lint.yaml` | PR | Pre-commit hooks and formatting checks |
133+
| **publish** | `publish-py-sdk.yaml` | Tag push (`py-sdk-v*.*.*`) | Build, test wheel, publish to PyPI, create GitHub release |
134+
| **test-publish** | `test-publish-py-sdk.yaml` | Manual dispatch | Publish to TestPyPI for pre-release validation |
135+
136+
### No API Key Secrets Required
137+
138+
CI workflows do **not** use real API key secrets (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`). Tests rely on VCR cassettes with dummy API keys provided by test fixtures. This means:
139+
140+
- Forks can run CI without configuring any secrets.
141+
- The `test_latest_wrappers_novcr` nox session (which disables VCR) is automatically skipped in CI.
142+
143+
### Test Sharding
144+
145+
The main `py.yaml` workflow shards nox sessions across 2 parallel jobs per Python version/OS combination using `scripts/nox-matrix.sh`.
146+
147+
## Test Fixtures
148+
149+
Key auto-applied fixtures defined in `py/src/braintrust/conftest.py`:
150+
151+
| Fixture | Purpose |
152+
|---|---|
153+
| `setup_braintrust` | Sets dummy API keys (OpenAI, Google, Anthropic) for VCR tests |
154+
| `override_app_url_for_tests` | Points `BRAINTRUST_APP_URL` to production for consistent behavior |
155+
| `reset_braintrust_state` | Resets global SDK state after each test |
156+
| `skip_vcr_tests_in_wheel_mode` | Skips VCR tests when testing from an installed wheel |
157+
158+
The `memory_logger` fixture (from `braintrust.test_helpers`) lets you capture logged spans in-memory without a real Braintrust connection:
159+
160+
```python
161+
def test_something(memory_logger):
162+
# ... exercise code that logs spans ...
163+
spans = memory_logger.pop()
164+
assert len(spans) == 1
165+
```
166+
167+
## Submitting Changes
168+
169+
1. Create a branch for your changes.
170+
2. Make your changes and add/update tests.
171+
3. If you modified VCR tests, re-record cassettes and commit them.
172+
4. Run `make fixup` to format and lint.
173+
5. Run relevant test sessions to verify (e.g. `nox -s "test_openai(latest)"`).
174+
6. Open a pull request against `main`.

0 commit comments

Comments
 (0)