Skip to content
Closed
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
33 changes: 33 additions & 0 deletions py/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,39 @@ Then run:
BRAINTRUST_API_KEY=<YOUR_API_KEY> braintrust eval tutorial_eval.py
```

## Logging With an Ingestion Key

Ingestion keys let apps that run on your users' machines, like a desktop app or a CLI, send traces to a single project without an API key.
Pass the ingestion key URL from your project settings to `init_logger`, or set `BRAINTRUST_INGESTION_KEY`:

```python
import braintrust

logger = braintrust.init_logger(ingestion_key="https://dp.example.com/ingest?ingestKey=bt-ik-...")
logger.log(input="question", output="answer")
```

The logger sends rows and attachments straight to the data plane in the URL, with the key in the `Authorization` header.
It never logs in, so it ignores `BRAINTRUST_API_KEY` and any earlier `braintrust.login()`, and it doesn't register or look up the project.
Passing an explicit `api_key` to `init_logger` uses that key instead of `BRAINTRUST_INGESTION_KEY`, and passing both `api_key` and `ingestion_key` is an error.
Feedback logged with an ingestion key can only include scores, expected values, and tags.
`Attachment` works as usual, but `ExternalAttachment` isn't supported, since its URL can point at content outside the project.

Ingestion keys don't own the rows they write.
Anyone holding the key can update any row of the project whose ID they know, including rows logged with an API key or with another ingestion key.
Row IDs aren't secrets, so treat every row in the project as writable by whoever holds the key.

To export OpenTelemetry spans with an ingestion key, point a standard OTLP exporter at the `/otel/v1/traces` path under the ingestion URL and drop the query string:

```python
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

exporter = OTLPSpanExporter(
endpoint="https://dp.example.com/ingest/otel/v1/traces",
headers={"Authorization": "Bearer bt-ik-..."},
)
```

## Optional Extras

Install extras as needed for specific workflows:
Expand Down
1 change: 1 addition & 0 deletions py/src/braintrust/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ def __get__(self, instance: object, owner: type | None = None) -> bool:

class BraintrustEnv:
API_KEY = EnvVar("BRAINTRUST_API_KEY", EnvParser.STRING)
INGESTION_KEY = EnvVar("BRAINTRUST_INGESTION_KEY", EnvParser.STRING)
API_URL = EnvVar("BRAINTRUST_API_URL", EnvParser.STRING)
PROXY_URL = EnvVar("BRAINTRUST_PROXY_URL", EnvParser.STRING)
HTTP_TIMEOUT = EnvVar("BRAINTRUST_HTTP_TIMEOUT", EnvParser.FLOAT)
Expand Down
Loading
Loading