Add generated control-plane client (preview)#3
Draft
njbrake wants to merge 6 commits into
Draft
Conversation
Generated control-plane client (keys, users, budgets, pricing, usage) from the otari gateway OpenAPI spec via OpenAPI Generator. Preview for review and integration design; not yet wired into the public client. Part of mozilla-ai/otari#96 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Full CRUD lifecycle tests for every control-plane endpoint (keys, users, budgets, pricing, usage) driving the generated client against a real gateway started on SQLite with a master key (no provider creds needed). Verified 22 endpoint operations pass; documents the Bearer-auth requirement and the per-language test pattern. Part of mozilla-ai/otari#96 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Regenerate the control-plane client as a clean subpackage (otari._control_plane). - Add OtariClient.control_plane: typed accessors (keys/users/budgets/pricing/usage) sharing one client authed with Authorization: Bearer using an admin credential (admin_key / GATEWAY_ADMIN_KEY / platform_token). Management endpoints require Bearer, not the Otari-Key inference header. - Add admin_key param + ControlPlane facade; export ControlPlane. - Exclude the generated subpackage from ruff/mypy; add its runtime deps. - Integration tests now drive the public control_plane surface end-to-end (full CRUD per endpoint + admin-credential guard); 6 pass against a live gateway on SQLite. Part of mozilla-ai/otari#96 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eway - Add .github/workflows/ci.yml: ruff + mypy + pytest on push/PR across Python 3.11-3.13 (the repo previously only ran checks on release). - Integration tests skip cleanly when no gateway is on PATH (set OTARI_GATEWAY_CMD to run them), so CI is green without a gateway and passes with one. - Register the 'integration' marker; per-file-ignore the subprocess/URL audit rules for the test harness. Part of mozilla-ai/otari#96 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the OpenAI-SDK delegation with a hand-written shell over the OpenAPI-generated core (otari._client), generated from the otari spec. The gateway is only OpenAI-compatible and has endpoints (notably the Anthropic-shaped /messages) the OpenAI SDK cannot represent; generating from the otari spec models the real contract. Core (unmodified generator output) replaces the old _control_plane subpackage and covers every endpoint with typed request/response models. Shell (the real work): - Auth modes preserved: platform -> Authorization: Bearer <token>; non-platform -> Otari-Key: Bearer <key>; control-plane -> Authorization: Bearer <admin/master key>. Fed into the generated ApiClient default headers and the streaming shim's httpx requests. - Ergonomic methods keep the existing public names/signatures (completion/response/embedding/moderation/rerank/list_models/batches) and add message(...) for the previously-missing /messages endpoint. control_plane accessor now backed by _client. - SSE streaming shim (_streaming.py): the generated core buffers and cannot stream, so stream=True does a raw httpx streaming POST, parses text/event-stream framing, terminates on [DONE], and yields typed ChatCompletionChunk (chat) / parsed JSON (responses, messages). - Typed error mapping: generated ApiException (.status/.body) -> the errors.py hierarchy (Authentication 401/403, InsufficientFunds 402, ModelNotFound 404, BatchNotComplete 409, RateLimit 429, GatewayTimeout 504, UpstreamProvider 502/5xx, UnsupportedCapability cross-mode, generic OtariError). The streaming path adapts failed responses through the same mapper. - Async client wraps the sync generated core via asyncio.to_thread and streams natively over httpx.AsyncClient. Drop the openai dependency from inference. Update ruff/mypy excludes to src/otari/_client. Rewrite unit tests to mock the generated transport (RESTClientObject.request) and respx for SSE; control-plane integration tests updated to import from _client and verified green against a live gateway. Note: chat streaming cannot be live-verified in this sandbox (no provider key on the gateway); the SSE shim is unit-tested over mocked chunk bytes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fail CI when the gateway OpenAPI spec exposes an endpoint the SDK's public API does not account for. A checked-in manifest (sdk-endpoints.txt) pins the covered and intentionally-excluded endpoint sets; a pytest test fetches the canonical spec and asserts spec is a subset of (covered + excluded), naming any unaccounted endpoint. Wired as a dedicated CI step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft preview. Adds the generated control-plane client (API keys, users, budgets, pricing, usage) produced from the otari gateway OpenAPI spec by OpenAPI Generator, dropped into
src/otari/_generated.Purpose: review the generated surface and design the integration that exposes these management methods through this SDK's public client. The inference and proxy surface, and batches, stay hand-written and are untouched here.
Notes:
Generated from the mozilla-ai/otari OpenAPI spec. Part of mozilla-ai/otari#96.