mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-07-06 02:52:11 +02:00
Add static OpenAPI spec and Stainless SDK config
Introduce SDK generation scaffolding: commit a static openapi.json extracted from the Utoipa annotations via a golden-file test, add Stainless workspace/config for TypeScript and Python SDKs, and clean up operation IDs for ergonomic generated method names. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9ad9d1f71f
commit
228032a4ac
6 changed files with 1887 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -16,3 +16,4 @@ __pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
demo/*.omni/
|
demo/*.omni/
|
||||||
.omnigraph-rustfs-demo/
|
.omnigraph-rustfs-demo/
|
||||||
|
sdks/
|
||||||
|
|
|
||||||
60
.stainless/stainless.yml
Normal file
60
.stainless/stainless.yml
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
edition: "2026-02-23"
|
||||||
|
|
||||||
|
organization:
|
||||||
|
name: omnigraph
|
||||||
|
docs: https://github.com/ModernRelay/omnigraph
|
||||||
|
github_org: ModernRelay
|
||||||
|
|
||||||
|
targets:
|
||||||
|
typescript:
|
||||||
|
package_name: omnigraph
|
||||||
|
production_repo: ModernRelay/omnigraph-typescript
|
||||||
|
publish:
|
||||||
|
npm: true
|
||||||
|
python:
|
||||||
|
package_name: omnigraph
|
||||||
|
production_repo: ModernRelay/omnigraph-python
|
||||||
|
publish:
|
||||||
|
pypi: true
|
||||||
|
|
||||||
|
client_settings:
|
||||||
|
opts:
|
||||||
|
api_key:
|
||||||
|
type: string
|
||||||
|
auth:
|
||||||
|
security_scheme: bearer_token
|
||||||
|
base_url:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
resources:
|
||||||
|
$client:
|
||||||
|
methods:
|
||||||
|
read: post /read
|
||||||
|
change: post /change
|
||||||
|
export: post /export
|
||||||
|
ingest: post /ingest
|
||||||
|
schema:
|
||||||
|
methods:
|
||||||
|
apply: post /schema/apply
|
||||||
|
branches:
|
||||||
|
methods:
|
||||||
|
list: get /branches
|
||||||
|
create: post /branches
|
||||||
|
delete: delete /branches/{branch}
|
||||||
|
merge: post /branches/merge
|
||||||
|
runs:
|
||||||
|
methods:
|
||||||
|
list: get /runs
|
||||||
|
retrieve: get /runs/{run_id}
|
||||||
|
publish: post /runs/{run_id}/publish
|
||||||
|
abort: post /runs/{run_id}/abort
|
||||||
|
commits:
|
||||||
|
methods:
|
||||||
|
list: get /commits
|
||||||
|
retrieve: get /commits/{commit_id}
|
||||||
|
snapshots:
|
||||||
|
methods:
|
||||||
|
retrieve: get /snapshot
|
||||||
|
|
||||||
|
settings:
|
||||||
|
license: MIT
|
||||||
13
.stainless/workspace.json
Normal file
13
.stainless/workspace.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"project": "omnigraph",
|
||||||
|
"openapi_spec": "../openapi.json",
|
||||||
|
"stainless_config": "./stainless.yml",
|
||||||
|
"targets": {
|
||||||
|
"typescript": {
|
||||||
|
"output_path": "../sdks/omnigraph-typescript"
|
||||||
|
},
|
||||||
|
"python": {
|
||||||
|
"output_path": "../sdks/omnigraph-python"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -465,6 +465,7 @@ async fn shutdown_signal() {
|
||||||
get,
|
get,
|
||||||
path = "/healthz",
|
path = "/healthz",
|
||||||
tag = "health",
|
tag = "health",
|
||||||
|
operation_id = "health",
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Server is healthy", body = HealthOutput),
|
(status = 200, description = "Server is healthy", body = HealthOutput),
|
||||||
),
|
),
|
||||||
|
|
@ -575,6 +576,7 @@ fn authorize_request(
|
||||||
get,
|
get,
|
||||||
path = "/snapshot",
|
path = "/snapshot",
|
||||||
tag = "snapshots",
|
tag = "snapshots",
|
||||||
|
operation_id = "getSnapshot",
|
||||||
params(SnapshotQuery),
|
params(SnapshotQuery),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Database snapshot", body = api::SnapshotOutput),
|
(status = 200, description = "Database snapshot", body = api::SnapshotOutput),
|
||||||
|
|
@ -615,6 +617,7 @@ async fn server_snapshot(
|
||||||
post,
|
post,
|
||||||
path = "/read",
|
path = "/read",
|
||||||
tag = "queries",
|
tag = "queries",
|
||||||
|
operation_id = "read",
|
||||||
request_body = ReadRequest,
|
request_body = ReadRequest,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Query results", body = ReadOutput),
|
(status = 200, description = "Query results", body = ReadOutput),
|
||||||
|
|
@ -684,6 +687,7 @@ async fn server_read(
|
||||||
post,
|
post,
|
||||||
path = "/export",
|
path = "/export",
|
||||||
tag = "queries",
|
tag = "queries",
|
||||||
|
operation_id = "export",
|
||||||
request_body = ExportRequest,
|
request_body = ExportRequest,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Exported data as NDJSON", content_type = "application/x-ndjson"),
|
(status = 200, description = "Exported data as NDJSON", content_type = "application/x-ndjson"),
|
||||||
|
|
@ -742,6 +746,7 @@ async fn server_export(
|
||||||
post,
|
post,
|
||||||
path = "/change",
|
path = "/change",
|
||||||
tag = "mutations",
|
tag = "mutations",
|
||||||
|
operation_id = "change",
|
||||||
request_body = ChangeRequest,
|
request_body = ChangeRequest,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Mutation results", body = ChangeOutput),
|
(status = 200, description = "Mutation results", body = ChangeOutput),
|
||||||
|
|
@ -800,6 +805,7 @@ async fn server_change(
|
||||||
post,
|
post,
|
||||||
path = "/schema/apply",
|
path = "/schema/apply",
|
||||||
tag = "mutations",
|
tag = "mutations",
|
||||||
|
operation_id = "applySchema",
|
||||||
request_body = SchemaApplyRequest,
|
request_body = SchemaApplyRequest,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Schema apply results", body = SchemaApplyOutput),
|
(status = 200, description = "Schema apply results", body = SchemaApplyOutput),
|
||||||
|
|
@ -838,6 +844,7 @@ async fn server_schema_apply(
|
||||||
post,
|
post,
|
||||||
path = "/ingest",
|
path = "/ingest",
|
||||||
tag = "mutations",
|
tag = "mutations",
|
||||||
|
operation_id = "ingest",
|
||||||
request_body = IngestRequest,
|
request_body = IngestRequest,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Ingest results", body = IngestOutput),
|
(status = 200, description = "Ingest results", body = IngestOutput),
|
||||||
|
|
@ -907,6 +914,7 @@ async fn server_ingest(
|
||||||
get,
|
get,
|
||||||
path = "/branches",
|
path = "/branches",
|
||||||
tag = "branches",
|
tag = "branches",
|
||||||
|
operation_id = "listBranches",
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "List of branches", body = BranchListOutput),
|
(status = 200, description = "List of branches", body = BranchListOutput),
|
||||||
(status = 401, description = "Unauthorized", body = ErrorOutput),
|
(status = 401, description = "Unauthorized", body = ErrorOutput),
|
||||||
|
|
@ -943,6 +951,7 @@ async fn server_branch_list(
|
||||||
post,
|
post,
|
||||||
path = "/branches",
|
path = "/branches",
|
||||||
tag = "branches",
|
tag = "branches",
|
||||||
|
operation_id = "createBranch",
|
||||||
request_body = BranchCreateRequest,
|
request_body = BranchCreateRequest,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Branch created", body = BranchCreateOutput),
|
(status = 200, description = "Branch created", body = BranchCreateOutput),
|
||||||
|
|
@ -990,6 +999,7 @@ async fn server_branch_create(
|
||||||
delete,
|
delete,
|
||||||
path = "/branches/{branch}",
|
path = "/branches/{branch}",
|
||||||
tag = "branches",
|
tag = "branches",
|
||||||
|
operation_id = "deleteBranch",
|
||||||
params(
|
params(
|
||||||
("branch" = String, Path, description = "Branch name to delete"),
|
("branch" = String, Path, description = "Branch name to delete"),
|
||||||
),
|
),
|
||||||
|
|
@ -1034,6 +1044,7 @@ async fn server_branch_delete(
|
||||||
post,
|
post,
|
||||||
path = "/branches/merge",
|
path = "/branches/merge",
|
||||||
tag = "branches",
|
tag = "branches",
|
||||||
|
operation_id = "mergeBranches",
|
||||||
request_body = BranchMergeRequest,
|
request_body = BranchMergeRequest,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Branches merged", body = BranchMergeOutput),
|
(status = 200, description = "Branches merged", body = BranchMergeOutput),
|
||||||
|
|
@ -1079,6 +1090,7 @@ async fn server_branch_merge(
|
||||||
get,
|
get,
|
||||||
path = "/runs",
|
path = "/runs",
|
||||||
tag = "runs",
|
tag = "runs",
|
||||||
|
operation_id = "listRuns",
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "List of runs", body = RunListOutput),
|
(status = 200, description = "List of runs", body = RunListOutput),
|
||||||
(status = 401, description = "Unauthorized", body = ErrorOutput),
|
(status = 401, description = "Unauthorized", body = ErrorOutput),
|
||||||
|
|
@ -1116,6 +1128,7 @@ async fn server_run_list(
|
||||||
get,
|
get,
|
||||||
path = "/runs/{run_id}",
|
path = "/runs/{run_id}",
|
||||||
tag = "runs",
|
tag = "runs",
|
||||||
|
operation_id = "getRun",
|
||||||
params(
|
params(
|
||||||
("run_id" = String, Path, description = "Run identifier"),
|
("run_id" = String, Path, description = "Run identifier"),
|
||||||
),
|
),
|
||||||
|
|
@ -1158,6 +1171,7 @@ async fn server_run_show(
|
||||||
post,
|
post,
|
||||||
path = "/runs/{run_id}/publish",
|
path = "/runs/{run_id}/publish",
|
||||||
tag = "runs",
|
tag = "runs",
|
||||||
|
operation_id = "publishRun",
|
||||||
params(
|
params(
|
||||||
("run_id" = String, Path, description = "Run identifier"),
|
("run_id" = String, Path, description = "Run identifier"),
|
||||||
),
|
),
|
||||||
|
|
@ -1207,6 +1221,7 @@ async fn server_run_publish(
|
||||||
post,
|
post,
|
||||||
path = "/runs/{run_id}/abort",
|
path = "/runs/{run_id}/abort",
|
||||||
tag = "runs",
|
tag = "runs",
|
||||||
|
operation_id = "abortRun",
|
||||||
params(
|
params(
|
||||||
("run_id" = String, Path, description = "Run identifier"),
|
("run_id" = String, Path, description = "Run identifier"),
|
||||||
),
|
),
|
||||||
|
|
@ -1255,6 +1270,7 @@ async fn server_run_abort(
|
||||||
get,
|
get,
|
||||||
path = "/commits",
|
path = "/commits",
|
||||||
tag = "commits",
|
tag = "commits",
|
||||||
|
operation_id = "listCommits",
|
||||||
params(CommitListQuery),
|
params(CommitListQuery),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "List of commits", body = CommitListOutput),
|
(status = 200, description = "List of commits", body = CommitListOutput),
|
||||||
|
|
@ -1296,6 +1312,7 @@ async fn server_commit_list(
|
||||||
get,
|
get,
|
||||||
path = "/commits/{commit_id}",
|
path = "/commits/{commit_id}",
|
||||||
tag = "commits",
|
tag = "commits",
|
||||||
|
operation_id = "getCommit",
|
||||||
params(
|
params(
|
||||||
("commit_id" = String, Path, description = "Commit identifier"),
|
("commit_id" = String, Path, description = "Commit identifier"),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -962,3 +962,28 @@ async fn auth_mode_healthz_still_has_no_security() {
|
||||||
"auth-mode: /healthz should still have no security"
|
"auth-mode: /healthz should still have no security"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn openapi_spec_is_up_to_date() {
|
||||||
|
let spec_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||||
|
.join("../../openapi.json");
|
||||||
|
|
||||||
|
let generated = serde_json::to_string_pretty(&openapi_doc()).unwrap() + "\n";
|
||||||
|
|
||||||
|
if env::var("OMNIGRAPH_UPDATE_OPENAPI").is_ok() {
|
||||||
|
fs::write(&spec_path, &generated).unwrap();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let committed = fs::read_to_string(&spec_path).unwrap_or_else(|_| {
|
||||||
|
panic!(
|
||||||
|
"openapi.json not found at {}. Run: OMNIGRAPH_UPDATE_OPENAPI=1 cargo test -p omnigraph-server --test openapi openapi_spec_is_up_to_date",
|
||||||
|
spec_path.display()
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
committed, generated,
|
||||||
|
"openapi.json is out of date. Run: OMNIGRAPH_UPDATE_OPENAPI=1 cargo test -p omnigraph-server --test openapi openapi_spec_is_up_to_date"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
1771
openapi.json
Normal file
1771
openapi.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue