Skip to content

Commit 0c032d6

Browse files
committed
feat(api): generate minimal Projects REST bindings
Implements step 2 of #683 by adding synchronous project create, list, get, update, and delete methods, along with their public TypedDict types. Keep the initial codegen surface intentionally narrow: select one OpenAPI tag, slice the spec to its transitive component closure, and emit one operation and binding module plus one model module. Binding and inline response names are derived mechanically from operation IDs, with normalized-name collisions rejected during generation. The generated bindings reuse the existing transport, authentication, routing, retry, and error handling. Coverage includes deterministic codegen, exact wire behavior, additive responses, typing, collision validation, and a cassette-backed end-to-end Projects flow.
1 parent c67d80d commit 0c032d6

32 files changed

Lines changed: 2331 additions & 7263 deletions

‎openapi/README.md‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
`spec.json` is a committed snapshot of the public specification from
44
[`braintrustdata/braintrust-openapi`](https://github.com/braintrustdata/braintrust-openapi).
55
`config.json` pins the full upstream commit, snapshot SHA-256, generator tools, generator flags, and
6-
explicit endpoint exclusions. The generator scripts live in `py/scripts/`. Builds and package installation use the committed generated source and never fetch or run
7-
code generation.
6+
selected endpoint tags. The generator scripts live in `py/scripts/`. Builds and package installation
7+
use the committed generated source and never fetch or run code generation.
88

99
From `py/`, validate and regenerate the private models offline with:
1010

@@ -13,7 +13,15 @@ make generate-api-client
1313
make check-api-client-codegen
1414
```
1515

16-
The check regenerates into a temporary directory and does not modify the worktree.
16+
The check regenerates into a temporary directory and does not modify the worktree. Endpoint bindings
17+
are rolled out explicitly through `endpoint_generator.generated_tags`. The current rollout supports
18+
exactly one selected OpenAPI tag and emits its operation registry and resource class together in
19+
`projects.py`, with reachable types in `models/projects.py`; unreachable models are omitted. Add
20+
explicit cross-resource model partitioning before selecting a second tag. Public resource method and
21+
inline response type names are derived mechanically from each `operationId`, and generated methods
22+
forward request fields and parameters without implicit defaults. Writes that are safe to retry are
23+
listed declaratively in `endpoint_generator.idempotent_writes`; reads and all other writes use
24+
mechanical retry defaults.
1725

1826
To fetch the configured upstream commit explicitly:
1927

@@ -29,5 +37,5 @@ BRAINTRUST_OPENAPI_ROOT=../../braintrust-openapi make fetch-openapi-spec
2937
```
3038

3139
To update the snapshot, first update the commit and SHA-256 in `config.json`, then fetch, regenerate,
32-
and review both the upstream spec diff and generated model diff. Fix specification defects upstream
33-
rather than adding Python-side normalization beyond CORS `OPTIONS` removal and configured exclusions.
40+
and review both the upstream spec diff and generated model diff. Only operations selected through
41+
`endpoint_generator.generated_tags` and their reachable schemas are validated and generated.

‎openapi/config.json‎

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,20 @@
2121
"--use-generic-container-types",
2222
"--use-field-description",
2323
"--strict-nullable",
24-
"--parent-scoped-naming",
24+
"--naming-strategy=primary-first",
2525
"--no-use-closed-typed-dict",
2626
"--disable-future-imports",
2727
"--formatters=ruff-format"
2828
]
2929
},
3030
"endpoint_generator": {
3131
"schema_version": 1,
32-
"skip_tags": {
33-
"Proxy": {
34-
"reason": "Proxy endpoints stream provider-specific payloads and remain on the specialized proxy path.",
35-
"operation_ids": [
36-
"proxychatCompletions",
37-
"proxycompletions",
38-
"proxyauto",
39-
"proxyembeddings",
40-
"proxycredentials",
41-
"proxy{path+}"
42-
]
43-
}
44-
},
32+
"generated_tags": [
33+
"Projects"
34+
],
35+
"idempotent_writes": [
36+
"postProject"
37+
],
4538
"supported_success_statuses": [
4639
"200",
4740
"201",
@@ -52,8 +45,7 @@
5245
"application/json"
5346
],
5447
"supported_response_media_types": [
55-
"application/json",
56-
"text/plain"
48+
"application/json"
5749
]
5850
}
5951
}

0 commit comments

Comments
 (0)