Skip to content
Merged
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,7 @@ The SDK uses a standard slf4j logger and will use the default log level (or not
All Braintrust loggers will log into the `dev.braintrust` namespace. To adjust the log level, consult your logger documentation.

For example, to enable debug logging for slf4j-simple you would set the system property `org.slf4j.simpleLogger.log.dev.braintrust=DEBUG`

## See Also

- [Low-level Braintrust API client](./docs/api-client.md) — talk to the Braintrust REST API directly
40 changes: 40 additions & 0 deletions docs/api-client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Braintrust API client

The SDK ships a low-level HTTP client for the [Braintrust REST API](https://api.braintrust.dev).

> If you just want to run evals or trace AI calls, prefer
> [`dev.braintrust.eval.Eval`](../braintrust-sdk/src/main/java/dev/braintrust/eval) and
> `dev.braintrust.trace.BraintrustTracing`. Reach for the API client only when you need
> raw REST access.

The client is **generated code**. Every resource, method, and model comes from Braintrust's
public OpenAPI spec:

- Spec repo: <https://github.com/braintrustdata/braintrust-openapi>
- The exact commit we generate against is pinned as `braintrustOpenApiRef` in
[`gradle.properties`](../gradle.properties).

## Basic usage

```java
import dev.braintrust.api.BraintrustOpenApiClient;
import dev.braintrust.config.BraintrustConfig;
import dev.braintrust.openapi.api.ProjectsApi;
import dev.braintrust.openapi.model.CreateProject;
import dev.braintrust.openapi.model.Project;

var client = BraintrustOpenApiClient.of(BraintrustConfig.fromEnvironment());
var projects = new ProjectsApi(client);

// Create a project. Model classes use fluent setters (not a builder).
Project created = projects.postProject(
new CreateProject().name("my-project").description("created from java"));

System.out.println(created.getId() + " " + created.getName());
```

### Runnable example

A complete, runnable example can be found in [`examples/api-client`](../examples/api-client).

Run it with `BRAINTRUST_API_KEY=sk-... ./gradlew :examples:api-client:run`.
15 changes: 15 additions & 0 deletions examples/api-client/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
application {
mainClass = 'dev.braintrust.examples.ApiClientExample'
}

dependencies {
// The OpenAPI-generated client (dev.braintrust.openapi.*) is bundled into the published
// braintrust-sdk jar, so real consumers get it transitively. This example uses a Gradle
// project() dependency, which doesn't expose the embedded classes, so depend on the
// generated client subproject directly for compilation.
implementation project(':braintrust-api')
}

run {
description = 'Read projects, experiments, prompts, and datasets via the low-level API client'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package dev.braintrust.examples;

import dev.braintrust.api.BraintrustOpenApiClient;
import dev.braintrust.config.BraintrustConfig;
import dev.braintrust.openapi.api.DatasetsApi;
import dev.braintrust.openapi.api.ExperimentsApi;
import dev.braintrust.openapi.api.ProjectsApi;
import dev.braintrust.openapi.api.PromptsApi;
import dev.braintrust.openapi.model.Dataset;
import dev.braintrust.openapi.model.Experiment;
import dev.braintrust.openapi.model.Prompt;

/**
* Demonstrates the low-level, OpenAPI-generated Braintrust API client for raw REST access beyond
* what the {@code Eval} and {@code BraintrustTracing} helpers cover. See docs/api-client.md for the
* full walkthrough.
*
* <p>Run with:
*
* <pre>
* BRAINTRUST_API_KEY=sk-... ./gradlew :examples:api-client:run
* </pre>
*/
public class ApiClientExample {
// Cap each listing so the example prints a manageable amount.
private static final int LIMIT = 5;

public static void main(String[] args) {
// BraintrustOpenApiClient is an ApiClient with the base URL, bearer auth, and TLS
// wired up from the config. Every *Api class takes it in its constructor.
var client = BraintrustOpenApiClient.of(BraintrustConfig.fromEnvironment());

// Resolve the org name (login() is a Braintrust helper on top of the generated client)
// and grab the first project to read from.
var orgName = client.login().orgInfo().get(0).name();
var project =
new ProjectsApi(client)
.getProject(1, null, null, null, null, null)
.getObjects()
.get(0);
var projectId = project.getId();
System.out.println("Reading project " + project.getName() + " from org " + orgName);

// List endpoints share the leading pagination/filter args and return a page wrapper
// whose getObjects() holds the results. Pass null for filters you don't need; the
// first arg is the page-size limit, and here we scope each list to projectId.

// ── Experiments ───────────────────────────────────────────────────────────
var experiments = new ExperimentsApi(client);
var experimentPage =
experiments.getExperiment(LIMIT, null, null, null, null, null, projectId, null);
System.out.println("\nExperiments:");
for (Experiment e : experimentPage.getObjects()) {
System.out.println(" " + e.getName() + " (" + e.getId() + ")");
}

// ── Prompts ───────────────────────────────────────────────────────────────
var prompts = new PromptsApi(client);
var promptPage =
prompts.getPrompt(
LIMIT, null, null, null, null, null, projectId, null, null, null, null);
System.out.println("\nPrompts:");
for (Prompt p : promptPage.getObjects()) {
System.out.println(" " + p.getName() + " (" + p.getId() + ")");
}

// ── Datasets ──────────────────────────────────────────────────────────────
var datasets = new DatasetsApi(client);
var datasetPage = datasets.getDataset(LIMIT, null, null, null, null, null, projectId, null);
System.out.println("\nDatasets:");
for (Dataset d : datasetPage.getObjects()) {
System.out.println(" " + d.getName() + " (" + d.getId() + ")");
}
}
}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ include 'examples:remote-eval'
include 'examples:remote-eval-with-params'
include 'examples:trace-scoring'
include 'examples:classifiers'
include 'examples:api-client'
include 'braintrust-java-agent'
include 'braintrust-java-agent:bootstrap'
include 'braintrust-java-agent:internal'
Expand Down
Loading