From 3660844501cada3e797dd0ba6e612b780d5436dd Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Mon, 24 Aug 2026 01:56:26 +0000 Subject: [PATCH 1/3] ## Python SDK Changes: * `open_router.containers.list_container_files()`: **Added** * `open_router.containers.get_container_file()`: **Added** * `open_router.containers.download_container_file_content()`: **Added** --- .speakeasy/gen.lock | 178 +++- .speakeasy/gen.yaml | 2 +- .speakeasy/out.openapi.yaml | 418 ++++++++ .speakeasy/workflow.lock | 10 +- RELEASES.md | 12 +- docs/components/containerfile.mdx | 15 + docs/components/containerfilelistresponse.mdx | 13 + .../containerfilelistresponseobject.mdx | 15 + docs/components/containerfileobject.mdx | 15 + docs/components/containerfilesource.mdx | 17 + .../downloadcontainerfilecontentglobals.mdx | 11 + .../downloadcontainerfilecontentrequest.mdx | 13 + docs/operations/getcontainerfileglobals.mdx | 11 + docs/operations/getcontainerfilerequest.mdx | 13 + docs/operations/listcontainerfilesglobals.mdx | 11 + docs/operations/listcontainerfilesrequest.mdx | 14 + docs/sdks/containers/README.mdx | 173 ++++ pyproject.toml | 2 +- src/openrouter/_version.py | 4 +- src/openrouter/components/__init__.py | 25 + src/openrouter/components/containerfile.py | 58 ++ .../components/containerfilelistresponse.py | 47 + src/openrouter/containers.py | 958 ++++++++++++++++++ src/openrouter/operations/__init__.py | 42 + .../downloadcontainerfilecontent.py | 151 +++ src/openrouter/operations/getcontainerfile.py | 151 +++ .../operations/listcontainerfiles.py | 171 ++++ src/openrouter/sdk.py | 4 + uv.lock | 2 +- 29 files changed, 2528 insertions(+), 28 deletions(-) create mode 100644 docs/components/containerfile.mdx create mode 100644 docs/components/containerfilelistresponse.mdx create mode 100644 docs/components/containerfilelistresponseobject.mdx create mode 100644 docs/components/containerfileobject.mdx create mode 100644 docs/components/containerfilesource.mdx create mode 100644 docs/operations/downloadcontainerfilecontentglobals.mdx create mode 100644 docs/operations/downloadcontainerfilecontentrequest.mdx create mode 100644 docs/operations/getcontainerfileglobals.mdx create mode 100644 docs/operations/getcontainerfilerequest.mdx create mode 100644 docs/operations/listcontainerfilesglobals.mdx create mode 100644 docs/operations/listcontainerfilesrequest.mdx create mode 100644 docs/sdks/containers/README.mdx create mode 100644 src/openrouter/components/containerfile.py create mode 100644 src/openrouter/components/containerfilelistresponse.py create mode 100644 src/openrouter/containers.py create mode 100644 src/openrouter/operations/downloadcontainerfilecontent.py create mode 100644 src/openrouter/operations/getcontainerfile.py create mode 100644 src/openrouter/operations/listcontainerfiles.py diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 42ee5833..15caf42d 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,19 +1,19 @@ lockVersion: 2.0.0 id: c48cf606-fb42-4a45-9c23-8f0555307828 management: - docChecksum: 9fb12aaa50aac47d52de2be119794664 + docChecksum: 8096d9b7f5871c9137b4ebcd2cd8970f docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 1.1.74 - configChecksum: a61a95459185f7b05d7d7e2145aca63a + releaseVersion: 1.1.75 + configChecksum: 80430cc7e9cd260533f3d6554dd73c49 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: 77268ed9-3648-48e6-b202-d01ffe5f50a7 - pristine_commit_hash: 605b3e3652e82e2bda19d3067379af1ae22902b2 - pristine_tree_hash: 9bcdabb4954b7400973ed08c699093481edfa53b + generation_id: 766187d4-2e93-4aae-8175-5fdfdbb5ff78 + pristine_commit_hash: 942ad6ab28dcb8f92462dc9e2f2648a6d001d333 + pristine_tree_hash: adce8e873a0cad4602ba69bc37add3a3dc405b94 features: python: acceptHeaders: 3.0.0 @@ -1360,6 +1360,26 @@ trackedFiles: id: 1e247d70245d last_write_checksum: sha1:66636ec50e7863bc4c8f9fb4f95b1e895f429b97 pristine_git_object: 1c99ecd1ca87bb0ff50f541f157ab9c1db071372 + docs/components/containerfile.mdx: + id: 293da6a8ffaf + last_write_checksum: sha1:952b39aaf049938a8c08167687287f763afe77b5 + pristine_git_object: 7afa4e43e6e82ab7b84a89840d1137ef5b47e0da + docs/components/containerfilelistresponse.mdx: + id: 1e09ddf3473c + last_write_checksum: sha1:efcc514ed1a2090ed2c7c1a383fa8949fe87e412 + pristine_git_object: b1a1d9ad5a961fd06abd7e5377130034b714d768 + docs/components/containerfilelistresponseobject.mdx: + id: bd9847deeba3 + last_write_checksum: sha1:76c4e51ee62059e3e234142d1d8ba71773d5a9c6 + pristine_git_object: c229ca305df5157fc3a11fbe024a612a057b0a1d + docs/components/containerfileobject.mdx: + id: 38415dcef5a7 + last_write_checksum: sha1:8e22571e6de97937b7d9209154a71c354b19f16b + pristine_git_object: 5e9797cde4d7b3b3674f30327093d8af26c4d561 + docs/components/containerfilesource.mdx: + id: 3a64638e26d2 + last_write_checksum: sha1:24d370611c20eaae07bbe4d65d76eacf3bc03cf9 + pristine_git_object: d202c01bb7fea9b2ccc19803a9c36ed5e3354930 docs/components/containerreferenceenvironment.mdx: id: 80d581804fd7 last_write_checksum: sha1:525283f0d016b0385786264f87e2a1257c53b9a9 @@ -6228,6 +6248,14 @@ trackedFiles: id: 341c9e73a4c7 last_write_checksum: sha1:847b221d2a019253796dfef6fab0ee5da1422834 pristine_git_object: 5dc0d7b0cd5f93f218882f150500b4fe4ae6b4f4 + docs/operations/downloadcontainerfilecontentglobals.mdx: + id: 7184cf67e7a3 + last_write_checksum: sha1:db6eedb42515002aac657b233d53a70ee985cdd3 + pristine_git_object: 630f5406beadd34b2e97bb5272a8206b6af22d99 + docs/operations/downloadcontainerfilecontentrequest.mdx: + id: b2a618019b09 + last_write_checksum: sha1:5d4c014cc84471e0911cb6e889a505f019fc124d + pristine_git_object: 2ea989b85476b58f816a01ca0e828deb8a5e5400 docs/operations/downloadfilecontentglobals.mdx: id: 0ada32f1640c last_write_checksum: sha1:ed4bbd8ccded9c65480b84fdfb54582b5e606516 @@ -6320,6 +6348,14 @@ trackedFiles: id: 13473d1c826b last_write_checksum: sha1:c504ae8e40669d44dfa9b33a59b17dbe041dc7c6 pristine_git_object: 7c25821298233727884352b886699753c83868a9 + docs/operations/getcontainerfileglobals.mdx: + id: 168ff6e69a10 + last_write_checksum: sha1:a40229e83e7ab4c1bf3b6fdf4d80dea35fb7f2e7 + pristine_git_object: 8343594f88ed238341e618f3d6bace3b3141411e + docs/operations/getcontainerfilerequest.mdx: + id: 727fad4bbdcd + last_write_checksum: sha1:d5d464622f343f774282862e9514e151726f25b8 + pristine_git_object: 1fba45782a76236212195b32a6ba8e82a46d2d54 docs/operations/getcreditsdata.mdx: id: 24936b7229aa last_write_checksum: sha1:04c170b75b9f943bcf4143ff49bffbace613744b @@ -6568,6 +6604,14 @@ trackedFiles: id: ad2f5a3c160a last_write_checksum: sha1:8496c7f3080cd0ec5a42401a6cccfbd1be87968d pristine_git_object: 213ea97a6bf34351ada3b72a70b7f7dcedfafe5a + docs/operations/listcontainerfilesglobals.mdx: + id: 89c4df41f2bf + last_write_checksum: sha1:0aaf5478ab48cac7f3c7dc011b5b7fdf0f040491 + pristine_git_object: 3bd312de040f562fc4b66811f89db0b06483ec1d + docs/operations/listcontainerfilesrequest.mdx: + id: 54073da72503 + last_write_checksum: sha1:7159b36d582af022a0f183dace41a4fb4b7a4103 + pristine_git_object: 560e080fb596ac66029dfb7937c55b638e89ed5d docs/operations/listdata.mdx: id: 949d8d9f5ac7 last_write_checksum: sha1:5f8b3da3cfe52a23525dd37725dcec786a295704 @@ -7176,6 +7220,10 @@ trackedFiles: id: 4786130ef02a last_write_checksum: sha1:87ea3518b4147ae7833b01da7be92d41a4b49df7 pristine_git_object: bed5f74e5e8269cbba66943524ffa5206c933de3 + docs/sdks/containers/README.mdx: + id: cc963972ad75 + last_write_checksum: sha1:e869aab492e8f05097531617fc0a03c5bb157f0e + pristine_git_object: 2d69e9d1da84deabd7f2e51df92cdf95476bc236 docs/sdks/credits/README.mdx: id: 2ba51de8de3f last_write_checksum: sha1:08de2963f78b645eaa14fa8511552bae2ddccd75 @@ -7266,8 +7314,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:c3437c95d22e45f3befad9d4bc702dee50f3049f - pristine_git_object: 5770dd83565f8791e800a993f6a53bc37474459a + last_write_checksum: sha1:65253019d332e7c935f904d79e5c22e372596110 + pristine_git_object: 13a459680e6ee996aa7899b36bdd4fb3aabfaa6b scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -7294,8 +7342,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:2af0372a8794ec342f03e2eba4a878262eec658b - pristine_git_object: c24e3acab130d362ad77dbd34bab17cae0dc643a + last_write_checksum: sha1:2c1d87963e0158700d5fec4670a083f2a7d21742 + pristine_git_object: 1fb15c54a812778b6ba8556f2fbf4a7d163b38ec src/openrouter/analytics.py: id: cb406b5aaabb last_write_checksum: sha1:1e0004d8d1d5d797e2b54cd1cabeb7f9489d08e9 @@ -7334,8 +7382,8 @@ trackedFiles: pristine_git_object: ad3d247954547814054c01989a2dff3d12b3e4e1 src/openrouter/components/__init__.py: id: 81754e97b3f4 - last_write_checksum: sha1:10eb5b4457c1df6ac3e5c5a6b7dd17219aef5bf7 - pristine_git_object: 668446597628e5005477ca7db4f3f709cf9d6d7a + last_write_checksum: sha1:1731a042a9572abd629db06f85f5318e89cd4893 + pristine_git_object: 3be5de516ae707b3e739e702bf2749b6c5f7dcc3 src/openrouter/components/aabenchmarkentry.py: id: e2e0f0b48c82 last_write_checksum: sha1:fab4d9a24d2cea937bb749d46c5f83941e99d65c @@ -7936,6 +7984,14 @@ trackedFiles: id: 0c41c2609d28 last_write_checksum: sha1:d6b8b06b51d5f0ffc28b1644843a8fa8a576d31b pristine_git_object: 78d8937bcdaf636d1df431e7fe868ae820b5f40c + src/openrouter/components/containerfile.py: + id: 2dc442adcee4 + last_write_checksum: sha1:b342aec85fee498ad94a63b71e5580e2a2d67d3c + pristine_git_object: ea5d9eb47b93a7a81ea02edb9a226b51acf9436f + src/openrouter/components/containerfilelistresponse.py: + id: f1d494b9a4e9 + last_write_checksum: sha1:cfcee9763748a5ad9ea44d0da222e2ecca8635b5 + pristine_git_object: a2593a4d8fab2fda41f2476015a4f60f9898da2f src/openrouter/components/containerreferenceenvironment.py: id: deb4c42c7020 last_write_checksum: sha1:4436d0c57e31a64e27e5fae97702c16b355ecfca @@ -9796,6 +9852,10 @@ trackedFiles: id: b510f727fe9c last_write_checksum: sha1:cc6c8880763f294494616a3daa84c8822d4e3f08 pristine_git_object: ad78361d147d2edb7b5772c14501d9c25a2000b0 + src/openrouter/containers.py: + id: 5edae5db57e9 + last_write_checksum: sha1:81138d9e61f2745d59485fcc12558e6abae657df + pristine_git_object: e6907e07b5b5583694d57773adbb7f76ef0c6202 src/openrouter/credits.py: id: cdc961937101 last_write_checksum: sha1:7ac37671d3de537eb98f15239d531e3ab3928a59 @@ -9938,8 +9998,8 @@ trackedFiles: pristine_git_object: 5c553b76ab24d9eaef51c3bf6d85aa74391e335e src/openrouter/operations/__init__.py: id: 9afcea1e7161 - last_write_checksum: sha1:040182e46f2248a17818facd01e0596af6f33a95 - pristine_git_object: 76ee91671dc2984195055b18c7bf1e49969e14bc + last_write_checksum: sha1:19c99d02b7b5e77db4f93366318666cf82db6d3d + pristine_git_object: c81a9eff8a1cb74fac30f84ce8d83f6ccb6bb245 src/openrouter/operations/bulkaddworkspacemembers.py: id: e0ed56117619 last_write_checksum: sha1:5c44eb0d40fdece3ac084615f6c6082be4cf1d5a @@ -10068,6 +10128,10 @@ trackedFiles: id: 4043f35925db last_write_checksum: sha1:1b6fd5acfd6b53525c8dcff26148535d5acf0401 pristine_git_object: b61191d8c3c9ab9da453e46c871231bda0e2628c + src/openrouter/operations/downloadcontainerfilecontent.py: + id: 6cbf0cdcba2b + last_write_checksum: sha1:f230411229419fb32eeec926132fb1af4d5cb887 + pristine_git_object: ca3b009ceb0d29e95e1ba5a73f97682d8f798a17 src/openrouter/operations/downloadfilecontent.py: id: 6ff3d391a23f last_write_checksum: sha1:a1152e6af4d5a47bdaaab7ef35dfed739f1abff4 @@ -10092,6 +10156,10 @@ trackedFiles: id: d141452bd88a last_write_checksum: sha1:d6d391b230d90f51945144e63e9c53772650bd7b pristine_git_object: 6021faa4de45bfaf200eca955b62f4b5b3113804 + src/openrouter/operations/getcontainerfile.py: + id: 7b8249f30861 + last_write_checksum: sha1:7e6d37e9f52c7a5e4f6bfcec9a18c989827d0862 + pristine_git_object: 953ef093e4a803543295ed83b2500d30b202bbe1 src/openrouter/operations/getcredits.py: id: 83155df53da5 last_write_checksum: sha1:89afe99cd26e560d8dabb211bfe37f97e0f80f45 @@ -10176,6 +10244,10 @@ trackedFiles: id: b6dd42b3e05f last_write_checksum: sha1:6fc66f3b5e9d1e73b0395f93a9c0bf1821cec29c pristine_git_object: 5f14df3f94fc6e57cfcc2ff5514dca5a835de897 + src/openrouter/operations/listcontainerfiles.py: + id: 7a30b9291c76 + last_write_checksum: sha1:409c7d73b6de34dd6b9c554d6cf028539bf02916 + pristine_git_object: 9aff2f128db9f4150ca53904d87f2d02aa2de29c src/openrouter/operations/listembeddingsmodels.py: id: bf749a1f23d6 last_write_checksum: sha1:938440c9b9df0c3d8430792f262bffced0207d13 @@ -10354,8 +10426,8 @@ trackedFiles: pristine_git_object: f6ad93a8202863708520f9fdb7043eeb4f1f1fc6 src/openrouter/sdk.py: id: ee9846c4c9c5 - last_write_checksum: sha1:78519ae3116f7cdc82ed2c757f019a663f216baa - pristine_git_object: 4dca8972da6ac87832ef3c3c8dcca9001256197e + last_write_checksum: sha1:d8eeaa771b4d51749dc9f3390793903e842fc0af + pristine_git_object: 98847019888bb61e4ed50f189d7c22107e0541a6 src/openrouter/sdkconfiguration.py: id: 55773bb98d7c last_write_checksum: sha1:c01826125c31a8b8bc99d9d679782c8758fae001 @@ -12198,5 +12270,77 @@ examples: application/json: {"error": {"code": 429, "message": "Rate limit exceeded"}} "500": application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + listContainerFiles: + speakeasy-default-list-container-files: + parameters: + path: + session_id: "sess-abc123" + query: + limit: 100 + responses: + "200": + application/json: {"data": [], "first_id": "cfile_b3V0L3JlcG9ydC5jc3Y", "has_more": false, "last_id": "cfile_b3V0L3JlcG9ydC5jc3Y", "object": "list"} + "400": + application/json: {"error": {"code": 400, "message": "Invalid request parameters"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "403": + application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}} + "429": + application/json: {"error": {"code": 429, "message": "Rate limit exceeded"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + "503": + application/json: {"error": {"code": 503, "message": "Service temporarily unavailable"}} + getContainerFile: + speakeasy-default-get-container-file: + parameters: + path: + session_id: "sess-abc123" + file_id: "cfile_b3V0L3JlcG9ydC5jc3Y" + responses: + "200": + application/json: {"bytes": 123, "container_id": "sess-abc123", "created_at": 1755640000, "id": "cfile_b3V0L3JlcG9ydC5jc3Y", "object": "container.file", "path": "out/report.csv", "source": "assistant"} + "400": + application/json: {"error": {"code": 400, "message": "Invalid request parameters"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "403": + application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "429": + application/json: {"error": {"code": 429, "message": "Rate limit exceeded"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + "503": + application/json: {"error": {"code": 503, "message": "Service temporarily unavailable"}} + downloadContainerFileContent: + speakeasy-default-download-container-file-content: + parameters: + path: + session_id: "sess-abc123" + file_id: "cfile_b3V0L3JlcG9ydC5jc3Y" + responses: + "200": + application/octet-stream: "x-file: example.file" + "400": + application/json: {"error": {"code": 400, "message": "Invalid request parameters"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "403": + application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "429": + application/json: {"error": {"code": 429, "message": "Rate limit exceeded"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + "503": + application/json: {"error": {"code": 503, "message": "Service temporarily unavailable"}} examplesVersion: 1.0.2 -releaseNotes: "## Python SDK Changes:\n* `open_router.presets.create_presets_responses()`: `request` **Changed** (Breaking ⚠️)\n* `open_router.responses.send()`: \n * `request` **Changed** (Breaking ⚠️)\n * `response` **Changed**\n* `open_router.beta.responses.send()`: \n * `request` **Changed** (Breaking ⚠️)\n * `response` **Changed**\n* `open_router.presets.create_presets_messages()`: \n * `request.tools[].union(ToolSearchServerTool)` **Added**\n" +releaseNotes: | + ## Python SDK Changes: + * `open_router.containers.list_container_files()`: **Added** + * `open_router.containers.get_container_file()`: **Added** + * `open_router.containers.download_container_file_content()`: **Added** diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 447ad8e4..1e29b068 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.1.74 + version: 1.1.75 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index 6e3c5977..d7a0e9db 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -6631,6 +6631,80 @@ components: required: - 'type' type: 'object' + ContainerFile: + properties: + bytes: + description: 'File size in bytes.' + example: 123 + type: 'integer' + container_id: + description: 'The container the file belongs to — echoes the `session_id` path parameter (OpenAI field name).' + example: 'sess-abc123' + type: 'string' + created_at: + description: 'Unix timestamp (seconds) when the file was last synced.' + example: 1755640000 + type: 'integer' + id: + description: 'Container file id: `cfile_` + base64url of the file path.' + example: 'cfile_b3V0L3JlcG9ydC5jc3Y' + type: 'string' + object: + enum: + - 'container.file' + example: 'container.file' + type: 'string' + path: + description: 'Session-relative file path inside the container.' + example: 'out/report.csv' + type: 'string' + source: + description: 'Container files are always produced by the assistant sandbox.' + enum: + - 'assistant' + example: 'assistant' + type: 'string' + required: + - 'id' + - 'object' + - 'container_id' + - 'bytes' + - 'created_at' + - 'path' + - 'source' + type: 'object' + ContainerFileListResponse: + properties: + data: + items: + $ref: '#/components/schemas/ContainerFile' + type: 'array' + first_id: + example: 'cfile_b3V0L3JlcG9ydC5jc3Y' + type: + - 'string' + - 'null' + has_more: + description: 'True when another page can be fetched by passing `after=last_id`.' + example: false + type: 'boolean' + last_id: + example: 'cfile_b3V0L3JlcG9ydC5jc3Y' + type: + - 'string' + - 'null' + object: + enum: + - 'list' + example: 'list' + type: 'string' + required: + - 'object' + - 'data' + - 'first_id' + - 'last_id' + - 'has_more' + type: 'object' ContainerReferenceEnvironment: description: 'Reference to a previously created container to reuse.' example: @@ -28957,6 +29031,348 @@ paths: - $ref: "#/components/parameters/AppIdentifier" - $ref: "#/components/parameters/AppDisplayName" - $ref: "#/components/parameters/AppCategories" + /containers/{session_id}/files: + get: + description: 'Lists the files under a sandbox session prefix, in lexicographic path order. A restarted session is a separate container with its own session id. Paginate with `limit` and `after` (pass the previous page’s `last_id`); `has_more: true` always means the next page is fetchable that way.' + operationId: 'listContainerFiles' + parameters: + - description: 'The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.' + in: 'path' + name: 'session_id' + required: true + schema: + description: 'The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.' + example: 'sess-abc123' + type: 'string' + - description: 'Maximum number of files to return (1-1000). Defaults to 100 when absent.' + in: 'query' + name: 'limit' + required: false + schema: + default: 100 + description: 'Maximum number of files to return (1-1000). Defaults to 100 when absent.' + example: 100 + maximum: 1000 + minimum: 1 + type: 'integer' + - description: 'Forward cursor: a container file id from a previous page (typically `last_id`); listing resumes strictly after that file.' + in: 'query' + name: 'after' + required: false + schema: + description: 'Forward cursor: a container file id from a previous page (typically `last_id`); listing resumes strictly after that file.' + example: 'cfile_b3V0L3JlcG9ydC5jc3Y' + type: 'string' + responses: + '200': + content: + application/json: + example: + data: + - bytes: 123 + container_id: 'sess-abc123' + created_at: 1755640000 + id: 'cfile_b3V0L3JlcG9ydC5jc3Y' + object: 'container.file' + path: 'out/report.csv' + source: 'assistant' + first_id: 'cfile_b3V0L3JlcG9ydC5jc3Y' + has_more: false + last_id: 'cfile_b3V0L3JlcG9ydC5jc3Y' + object: 'list' + schema: + $ref: '#/components/schemas/ContainerFileListResponse' + description: 'The files in the container.' + '400': + content: + application/json: + example: + error: + code: 400 + message: 'Invalid request parameters' + schema: + $ref: '#/components/schemas/BadRequestResponse' + description: 'Bad Request - Invalid request parameters or malformed input' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '403': + content: + application/json: + example: + error: + code: 403 + message: 'Only management keys can perform this operation' + schema: + $ref: '#/components/schemas/ForbiddenResponse' + description: 'Forbidden - Authentication successful but insufficient permissions' + '429': + content: + application/json: + example: + error: + code: 429 + message: 'Rate limit exceeded' + schema: + $ref: '#/components/schemas/TooManyRequestsResponse' + description: 'Too Many Requests - Rate limit exceeded' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + '503': + content: + application/json: + example: + error: + code: 503 + message: 'Service temporarily unavailable' + schema: + $ref: '#/components/schemas/ServiceUnavailableResponse' + description: 'Service Unavailable - Service temporarily unavailable' + summary: 'List container files' + tags: + - 'Containers' + x-hidden: true + parameters: + - $ref: "#/components/parameters/AppIdentifier" + - $ref: "#/components/parameters/AppDisplayName" + - $ref: "#/components/parameters/AppCategories" + /containers/{session_id}/files/{file_id}: + get: + description: 'Returns the metadata of a single file under a sandbox session prefix.' + operationId: 'getContainerFile' + parameters: + - description: 'The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.' + in: 'path' + name: 'session_id' + required: true + schema: + description: 'The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.' + example: 'sess-abc123' + type: 'string' + - description: 'Container file id (`cfile_` + base64url of the file path).' + in: 'path' + name: 'file_id' + required: true + schema: + description: 'Container file id (`cfile_` + base64url of the file path).' + example: 'cfile_b3V0L3JlcG9ydC5jc3Y' + type: 'string' + responses: + '200': + content: + application/json: + example: + bytes: 123 + container_id: 'sess-abc123' + created_at: 1755640000 + id: 'cfile_b3V0L3JlcG9ydC5jc3Y' + object: 'container.file' + path: 'out/report.csv' + source: 'assistant' + schema: + $ref: '#/components/schemas/ContainerFile' + description: 'The container file.' + '400': + content: + application/json: + example: + error: + code: 400 + message: 'Invalid request parameters' + schema: + $ref: '#/components/schemas/BadRequestResponse' + description: 'Bad Request - Invalid request parameters or malformed input' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '403': + content: + application/json: + example: + error: + code: 403 + message: 'Only management keys can perform this operation' + schema: + $ref: '#/components/schemas/ForbiddenResponse' + description: 'Forbidden - Authentication successful but insufficient permissions' + '404': + content: + application/json: + example: + error: + code: 404 + message: 'Resource not found' + schema: + $ref: '#/components/schemas/NotFoundResponse' + description: 'Not Found - Resource does not exist' + '429': + content: + application/json: + example: + error: + code: 429 + message: 'Rate limit exceeded' + schema: + $ref: '#/components/schemas/TooManyRequestsResponse' + description: 'Too Many Requests - Rate limit exceeded' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + '503': + content: + application/json: + example: + error: + code: 503 + message: 'Service temporarily unavailable' + schema: + $ref: '#/components/schemas/ServiceUnavailableResponse' + description: 'Service Unavailable - Service temporarily unavailable' + summary: 'Retrieve a container file' + tags: + - 'Containers' + x-hidden: true + parameters: + - $ref: "#/components/parameters/AppIdentifier" + - $ref: "#/components/parameters/AppDisplayName" + - $ref: "#/components/parameters/AppCategories" + /containers/{session_id}/files/{file_id}/content: + get: + description: 'Streams the raw bytes of a file under a sandbox session prefix.' + operationId: 'downloadContainerFileContent' + parameters: + - description: 'The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.' + in: 'path' + name: 'session_id' + required: true + schema: + description: 'The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.' + example: 'sess-abc123' + type: 'string' + - description: 'Container file id (`cfile_` + base64url of the file path).' + in: 'path' + name: 'file_id' + required: true + schema: + description: 'Container file id (`cfile_` + base64url of the file path).' + example: 'cfile_b3V0L3JlcG9ydC5jc3Y' + type: 'string' + responses: + '200': + content: + application/octet-stream: + example: 'binary file contents' + schema: + format: 'binary' + type: 'string' + description: 'The raw file content.' + '400': + content: + application/json: + example: + error: + code: 400 + message: 'Invalid request parameters' + schema: + $ref: '#/components/schemas/BadRequestResponse' + description: 'Bad Request - Invalid request parameters or malformed input' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '403': + content: + application/json: + example: + error: + code: 403 + message: 'Only management keys can perform this operation' + schema: + $ref: '#/components/schemas/ForbiddenResponse' + description: 'Forbidden - Authentication successful but insufficient permissions' + '404': + content: + application/json: + example: + error: + code: 404 + message: 'Resource not found' + schema: + $ref: '#/components/schemas/NotFoundResponse' + description: 'Not Found - Resource does not exist' + '429': + content: + application/json: + example: + error: + code: 429 + message: 'Rate limit exceeded' + schema: + $ref: '#/components/schemas/TooManyRequestsResponse' + description: 'Too Many Requests - Rate limit exceeded' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + '503': + content: + application/json: + example: + error: + code: 503 + message: 'Service temporarily unavailable' + schema: + $ref: '#/components/schemas/ServiceUnavailableResponse' + description: 'Service Unavailable - Service temporarily unavailable' + summary: 'Download container file content' + tags: + - 'Containers' + x-hidden: true + parameters: + - $ref: "#/components/parameters/AppIdentifier" + - $ref: "#/components/parameters/AppDisplayName" + - $ref: "#/components/parameters/AppCategories" /credits: get: description: 'Get total credits purchased and used for the authenticated user. [Management key](/docs/guides/overview/auth/management-api-keys) required.' @@ -39550,6 +39966,8 @@ tags: name: 'Chat' - description: 'Task classification market-share endpoints' name: 'Classifications' + - description: 'Containers endpoints' + name: 'Containers' - description: 'Credit management endpoints' name: 'Credits' - description: 'Public OpenRouter usage datasets. Data returned by these endpoints is licensed under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/): reuse and republish it, including commercially, with attribution to OpenRouter.' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index ee8884a9..63ba6607 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -2,8 +2,8 @@ speakeasyVersion: 1.787.0 sources: OpenRouter API: sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:d938807249c4b04e2aa3e426d81beedfb2d8204bd8c5eddb9e144ee9c969c295 - sourceBlobDigest: sha256:1f896360285d829673d1a92c48e1ed7ad2382a0c8c59f823a11cf275e4861b1e + sourceRevisionDigest: sha256:bf5cb8b155fdc50b0699b68828ae28f42a757dfb66ad956275d2706fdecff569 + sourceBlobDigest: sha256:2a524a9436cc91ff2c06c562f6971a7c638a48881611d7d8627bb0a075e17745 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:d938807249c4b04e2aa3e426d81beedfb2d8204bd8c5eddb9e144ee9c969c295 - sourceBlobDigest: sha256:1f896360285d829673d1a92c48e1ed7ad2382a0c8c59f823a11cf275e4861b1e + sourceRevisionDigest: sha256:bf5cb8b155fdc50b0699b68828ae28f42a757dfb66ad956275d2706fdecff569 + sourceBlobDigest: sha256:2a524a9436cc91ff2c06c562f6971a7c638a48881611d7d8627bb0a075e17745 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:1521a78c388b312f5f76799e2fc3ad010b754e359cdd3f401afd2ea52eea0f62 + codeSamplesRevisionDigest: sha256:98396f67aa7e2da3e21791589b6c51c4e487c0eab41f9602228ad155140eb808 workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/RELEASES.md b/RELEASES.md index 1cd05a1e..8b4df116 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1529,4 +1529,14 @@ Based on: ### Generated - [python v1.1.74] . ### Releases -- [PyPI v1.1.74] https://pypi.org/project/openrouter/1.1.74 - . \ No newline at end of file +- [PyPI v1.1.74] https://pypi.org/project/openrouter/1.1.74 - . + +## 2026-08-24 01:54:18 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.1.75] . +### Releases +- [PyPI v1.1.75] https://pypi.org/project/openrouter/1.1.75 - . \ No newline at end of file diff --git a/docs/components/containerfile.mdx b/docs/components/containerfile.mdx new file mode 100644 index 00000000..7afa4e43 --- /dev/null +++ b/docs/components/containerfile.mdx @@ -0,0 +1,15 @@ +--- +title: "ContainerFile" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | +| `bytes_` | *int* | :heavy_check_mark: | File size in bytes. | 123 | +| `container_id` | *str* | :heavy_check_mark: | The container the file belongs to — echoes the `session_id` path parameter (OpenAI field name). | sess-abc123 | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp (seconds) when the file was last synced. | 1755640000 | +| `id` | *str* | :heavy_check_mark: | Container file id: `cfile_` + base64url of the file path. | cfile_b3V0L3JlcG9ydC5jc3Y | +| `object` | [components.ContainerFileObject](../components/containerfileobject.mdx) | :heavy_check_mark: | N/A | container.file | +| `path` | *str* | :heavy_check_mark: | Session-relative file path inside the container. | out/report.csv | +| `source` | [components.ContainerFileSource](../components/containerfilesource.mdx) | :heavy_check_mark: | Container files are always produced by the assistant sandbox. | assistant | \ No newline at end of file diff --git a/docs/components/containerfilelistresponse.mdx b/docs/components/containerfilelistresponse.mdx new file mode 100644 index 00000000..b1a1d9ad --- /dev/null +++ b/docs/components/containerfilelistresponse.mdx @@ -0,0 +1,13 @@ +--- +title: "ContainerFileListResponse" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `data` | List[[components.ContainerFile](../components/containerfile.mdx)] | :heavy_check_mark: | N/A | | +| `first_id` | *Nullable[str]* | :heavy_check_mark: | N/A | cfile_b3V0L3JlcG9ydC5jc3Y | +| `has_more` | *bool* | :heavy_check_mark: | True when another page can be fetched by passing `after=last_id`. | false | +| `last_id` | *Nullable[str]* | :heavy_check_mark: | N/A | cfile_b3V0L3JlcG9ydC5jc3Y | +| `object` | [components.ContainerFileListResponseObject](../components/containerfilelistresponseobject.mdx) | :heavy_check_mark: | N/A | list | \ No newline at end of file diff --git a/docs/components/containerfilelistresponseobject.mdx b/docs/components/containerfilelistresponseobject.mdx new file mode 100644 index 00000000..c229ca30 --- /dev/null +++ b/docs/components/containerfilelistresponseobject.mdx @@ -0,0 +1,15 @@ +--- +title: "ContainerFileListResponseObject" +--- + +## Example Usage + +```python +from openrouter.components import ContainerFileListResponseObject +value: ContainerFileListResponseObject = "list" +``` + + +## Values + +- `"list"` diff --git a/docs/components/containerfileobject.mdx b/docs/components/containerfileobject.mdx new file mode 100644 index 00000000..5e9797cd --- /dev/null +++ b/docs/components/containerfileobject.mdx @@ -0,0 +1,15 @@ +--- +title: "ContainerFileObject" +--- + +## Example Usage + +```python +from openrouter.components import ContainerFileObject +value: ContainerFileObject = "container.file" +``` + + +## Values + +- `"container.file"` diff --git a/docs/components/containerfilesource.mdx b/docs/components/containerfilesource.mdx new file mode 100644 index 00000000..d202c01b --- /dev/null +++ b/docs/components/containerfilesource.mdx @@ -0,0 +1,17 @@ +--- +title: "ContainerFileSource" +--- + +Container files are always produced by the assistant sandbox. + +## Example Usage + +```python +from openrouter.components import ContainerFileSource +value: ContainerFileSource = "assistant" +``` + + +## Values + +- `"assistant"` diff --git a/docs/operations/downloadcontainerfilecontentglobals.mdx b/docs/operations/downloadcontainerfilecontentglobals.mdx new file mode 100644 index 00000000..630f5406 --- /dev/null +++ b/docs/operations/downloadcontainerfilecontentglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "DownloadContainerFileContentGlobals" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| \ No newline at end of file diff --git a/docs/operations/downloadcontainerfilecontentrequest.mdx b/docs/operations/downloadcontainerfilecontentrequest.mdx new file mode 100644 index 00000000..2ea989b8 --- /dev/null +++ b/docs/operations/downloadcontainerfilecontentrequest.mdx @@ -0,0 +1,13 @@ +--- +title: "DownloadContainerFileContentRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `session_id` | *str* | :heavy_check_mark: | The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. | sess-abc123 | +| `file_id` | *str* | :heavy_check_mark: | Container file id (`cfile_` + base64url of the file path). | cfile_b3V0L3JlcG9ydC5jc3Y | \ No newline at end of file diff --git a/docs/operations/getcontainerfileglobals.mdx b/docs/operations/getcontainerfileglobals.mdx new file mode 100644 index 00000000..8343594f --- /dev/null +++ b/docs/operations/getcontainerfileglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "GetContainerFileGlobals" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| \ No newline at end of file diff --git a/docs/operations/getcontainerfilerequest.mdx b/docs/operations/getcontainerfilerequest.mdx new file mode 100644 index 00000000..1fba4578 --- /dev/null +++ b/docs/operations/getcontainerfilerequest.mdx @@ -0,0 +1,13 @@ +--- +title: "GetContainerFileRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `session_id` | *str* | :heavy_check_mark: | The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. | sess-abc123 | +| `file_id` | *str* | :heavy_check_mark: | Container file id (`cfile_` + base64url of the file path). | cfile_b3V0L3JlcG9ydC5jc3Y | \ No newline at end of file diff --git a/docs/operations/listcontainerfilesglobals.mdx b/docs/operations/listcontainerfilesglobals.mdx new file mode 100644 index 00000000..3bd312de --- /dev/null +++ b/docs/operations/listcontainerfilesglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "ListContainerFilesGlobals" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| \ No newline at end of file diff --git a/docs/operations/listcontainerfilesrequest.mdx b/docs/operations/listcontainerfilesrequest.mdx new file mode 100644 index 00000000..560e080f --- /dev/null +++ b/docs/operations/listcontainerfilesrequest.mdx @@ -0,0 +1,14 @@ +--- +title: "ListContainerFilesRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `session_id` | *str* | :heavy_check_mark: | The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. | sess-abc123 | +| `limit` | *Optional[int]* | :heavy_minus_sign: | Maximum number of files to return (1-1000). Defaults to 100 when absent. | 100 | +| `after` | *Optional[str]* | :heavy_minus_sign: | Forward cursor: a container file id from a previous page (typically `last_id`); listing resumes strictly after that file. | cfile_b3V0L3JlcG9ydC5jc3Y | \ No newline at end of file diff --git a/docs/sdks/containers/README.mdx b/docs/sdks/containers/README.mdx new file mode 100644 index 00000000..2d69e9d1 --- /dev/null +++ b/docs/sdks/containers/README.mdx @@ -0,0 +1,173 @@ +--- +title: "Containers" +description: "Containers endpoints" +--- + +## Overview + +Containers endpoints + +### Available Operations + +* [list_container_files](#list_container_files) - List container files +* [get_container_file](#get_container_file) - Retrieve a container file +* [download_container_file_content](#download_container_file_content) - Download container file content + +## list_container_files + +Lists the files under a sandbox session prefix, in lexicographic path order. A restarted session is a separate container with its own session id. Paginate with `limit` and `after` (pass the previous page’s `last_id`); `has_more: true` always means the next page is fetchable that way. + +### Example Usage + +```python +from openrouter import OpenRouter +import os + + +with OpenRouter( + http_referer="", + x_open_router_title="", + x_open_router_categories="", + api_key=os.getenv("OPENROUTER_API_KEY", ""), +) as open_router: + + res = open_router.containers.list_container_files(session_id="sess-abc123", limit=100) + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `session_id` | *str* | :heavy_check_mark: | The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. | sess-abc123 | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `limit` | *Optional[int]* | :heavy_minus_sign: | Maximum number of files to return (1-1000). Defaults to 100 when absent. | 100 | +| `after` | *Optional[str]* | :heavy_minus_sign: | Forward cursor: a container file id from a previous page (typically `last_id`); listing resumes strictly after that file. | cfile_b3V0L3JlcG9ydC5jc3Y | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[components.ContainerFileListResponse](../../components/containerfilelistresponse.mdx)** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | +| errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.ForbiddenResponseError | 403 | application/json | +| errors.TooManyRequestsResponseError | 429 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.ServiceUnavailableResponseError | 503 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | + +## get_container_file + +Returns the metadata of a single file under a sandbox session prefix. + +### Example Usage + +```python +from openrouter import OpenRouter +import os + + +with OpenRouter( + http_referer="", + x_open_router_title="", + x_open_router_categories="", + api_key=os.getenv("OPENROUTER_API_KEY", ""), +) as open_router: + + res = open_router.containers.get_container_file(session_id="sess-abc123", file_id="cfile_b3V0L3JlcG9ydC5jc3Y") + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `session_id` | *str* | :heavy_check_mark: | The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. | sess-abc123 | +| `file_id` | *str* | :heavy_check_mark: | Container file id (`cfile_` + base64url of the file path). | cfile_b3V0L3JlcG9ydC5jc3Y | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[components.ContainerFile](../../components/containerfile.mdx)** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | +| errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.ForbiddenResponseError | 403 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.TooManyRequestsResponseError | 429 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.ServiceUnavailableResponseError | 503 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | + +## download_container_file_content + +Streams the raw bytes of a file under a sandbox session prefix. + +### Example Usage + +```python +from openrouter import OpenRouter +import os + + +with OpenRouter( + http_referer="", + x_open_router_title="", + x_open_router_categories="", + api_key=os.getenv("OPENROUTER_API_KEY", ""), +) as open_router: + + res = open_router.containers.download_container_file_content(session_id="sess-abc123", file_id="cfile_b3V0L3JlcG9ydC5jc3Y") + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `session_id` | *str* | :heavy_check_mark: | The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. | sess-abc123 | +| `file_id` | *str* | :heavy_check_mark: | Container file id (`cfile_` + base64url of the file path). | cfile_b3V0L3JlcG9ydC5jc3Y | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[httpx.Response](../../models/.mdx)** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | +| errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.ForbiddenResponseError | 403 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.TooManyRequestsResponseError | 429 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.ServiceUnavailableResponseError | 503 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 5770dd83..13a45968 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.1.74" +version = "1.1.75" description = "Official Python Client SDK for OpenRouter." authors = [{ name = "OpenRouter" },] readme = "README-PYPI.md" diff --git a/src/openrouter/_version.py b/src/openrouter/_version.py index c24e3aca..1fb15c54 100644 --- a/src/openrouter/_version.py +++ b/src/openrouter/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "openrouter" -__version__: str = "1.1.74" +__version__: str = "1.1.75" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.914.0" -__user_agent__: str = "speakeasy-sdk/python 1.1.74 2.914.0 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.1.75 2.914.0 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/components/__init__.py b/src/openrouter/components/__init__.py index 66844659..3be5de51 100644 --- a/src/openrouter/components/__init__.py +++ b/src/openrouter/components/__init__.py @@ -740,6 +740,17 @@ ContainerAutoEnvironmentType, ContainerAutoEnvironmentTypedDict, ) + from .containerfile import ( + ContainerFile, + ContainerFileObject, + ContainerFileSource, + ContainerFileTypedDict, + ) + from .containerfilelistresponse import ( + ContainerFileListResponse, + ContainerFileListResponseObject, + ContainerFileListResponseTypedDict, + ) from .containerreferenceenvironment import ( ContainerReferenceEnvironment, ContainerReferenceEnvironmentType, @@ -3635,6 +3646,13 @@ "ContainerAutoEnvironmentType", "ContainerAutoEnvironmentTypedDict", "ContainerAutoTypedDict", + "ContainerFile", + "ContainerFileListResponse", + "ContainerFileListResponseObject", + "ContainerFileListResponseTypedDict", + "ContainerFileObject", + "ContainerFileSource", + "ContainerFileTypedDict", "ContainerReferenceEnvironment", "ContainerReferenceEnvironmentType", "ContainerReferenceEnvironmentTypedDict", @@ -5904,6 +5922,13 @@ "ContainerAutoEnvironment": ".containerautoenvironment", "ContainerAutoEnvironmentType": ".containerautoenvironment", "ContainerAutoEnvironmentTypedDict": ".containerautoenvironment", + "ContainerFile": ".containerfile", + "ContainerFileObject": ".containerfile", + "ContainerFileSource": ".containerfile", + "ContainerFileTypedDict": ".containerfile", + "ContainerFileListResponse": ".containerfilelistresponse", + "ContainerFileListResponseObject": ".containerfilelistresponse", + "ContainerFileListResponseTypedDict": ".containerfilelistresponse", "ContainerReferenceEnvironment": ".containerreferenceenvironment", "ContainerReferenceEnvironmentType": ".containerreferenceenvironment", "ContainerReferenceEnvironmentTypedDict": ".containerreferenceenvironment", diff --git a/src/openrouter/components/containerfile.py b/src/openrouter/components/containerfile.py new file mode 100644 index 00000000..ea5d9eb4 --- /dev/null +++ b/src/openrouter/components/containerfile.py @@ -0,0 +1,58 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel +import pydantic +from typing import Literal +from typing_extensions import Annotated, TypedDict + + +ContainerFileObject = Literal["container.file",] + + +ContainerFileSource = Literal["assistant",] +r"""Container files are always produced by the assistant sandbox.""" + + +class ContainerFileTypedDict(TypedDict): + bytes_: int + r"""File size in bytes.""" + container_id: str + r"""The container the file belongs to — echoes the `session_id` path parameter (OpenAI field name).""" + created_at: int + r"""Unix timestamp (seconds) when the file was last synced.""" + id: str + r"""Container file id: `cfile_` + base64url of the file path.""" + object: ContainerFileObject + path: str + r"""Session-relative file path inside the container.""" + source: ContainerFileSource + r"""Container files are always produced by the assistant sandbox.""" + + +class ContainerFile(BaseModel): + bytes_: Annotated[int, pydantic.Field(alias="bytes")] + r"""File size in bytes.""" + + container_id: str + r"""The container the file belongs to — echoes the `session_id` path parameter (OpenAI field name).""" + + created_at: int + r"""Unix timestamp (seconds) when the file was last synced.""" + + id: str + r"""Container file id: `cfile_` + base64url of the file path.""" + + object: ContainerFileObject + + path: str + r"""Session-relative file path inside the container.""" + + source: ContainerFileSource + r"""Container files are always produced by the assistant sandbox.""" + + +try: + ContainerFile.model_rebuild() +except NameError: + pass diff --git a/src/openrouter/components/containerfilelistresponse.py b/src/openrouter/components/containerfilelistresponse.py new file mode 100644 index 00000000..a2593a4d --- /dev/null +++ b/src/openrouter/components/containerfilelistresponse.py @@ -0,0 +1,47 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .containerfile import ContainerFile, ContainerFileTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing import List, Literal +from typing_extensions import TypedDict + + +ContainerFileListResponseObject = Literal["list",] + + +class ContainerFileListResponseTypedDict(TypedDict): + data: List[ContainerFileTypedDict] + first_id: Nullable[str] + has_more: bool + r"""True when another page can be fetched by passing `after=last_id`.""" + last_id: Nullable[str] + object: ContainerFileListResponseObject + + +class ContainerFileListResponse(BaseModel): + data: List[ContainerFile] + + first_id: Nullable[str] + + has_more: bool + r"""True when another page can be fetched by passing `after=last_id`.""" + + last_id: Nullable[str] + + object: ContainerFileListResponseObject + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/containers.py b/src/openrouter/containers.py new file mode 100644 index 00000000..e6907e07 --- /dev/null +++ b/src/openrouter/containers.py @@ -0,0 +1,958 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from .basesdk import BaseSDK +import httpx +from openrouter import components, errors, operations, utils +from openrouter._hooks import HookContext +from openrouter.types import OptionalNullable, UNSET +from openrouter.utils import get_security_from_env +from openrouter.utils.unmarshal_json_response import unmarshal_json_response +from typing import Any, Mapping, Optional + + +class Containers(BaseSDK): + r"""Containers endpoints""" + + def list_container_files( + self, + *, + session_id: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + limit: Optional[int] = 100, + after: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.ContainerFileListResponse: + r"""List container files + + Lists the files under a sandbox session prefix, in lexicographic path order. A restarted session is a separate container with its own session id. Paginate with `limit` and `after` (pass the previous page’s `last_id`); `has_more: true` always means the next page is fetchable that way. + + :param session_id: The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param limit: Maximum number of files to return (1-1000). Defaults to 100 when absent. + :param after: Forward cursor: a container file id from a previous page (typically `last_id`); listing resumes strictly after that file. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.ListContainerFilesRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + session_id=session_id, + limit=limit, + after=after, + ) + + req = self._build_request( + method="GET", + path="/containers/{session_id}/files", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.ListContainerFilesGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="listContainerFiles", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["Containers"], + extensions={"x-hidden": True}, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response( + components.ContainerFileListResponse, http_res + ) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "403", "application/json"): + response_data = unmarshal_json_response( + errors.ForbiddenResponseErrorData, http_res + ) + raise errors.ForbiddenResponseError(response_data, http_res) + if utils.match_response(http_res, "429", "application/json"): + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res + ) + raise errors.TooManyRequestsResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "503", "application/json"): + response_data = unmarshal_json_response( + errors.ServiceUnavailableResponseErrorData, http_res + ) + raise errors.ServiceUnavailableResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + async def list_container_files_async( + self, + *, + session_id: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + limit: Optional[int] = 100, + after: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.ContainerFileListResponse: + r"""List container files + + Lists the files under a sandbox session prefix, in lexicographic path order. A restarted session is a separate container with its own session id. Paginate with `limit` and `after` (pass the previous page’s `last_id`); `has_more: true` always means the next page is fetchable that way. + + :param session_id: The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param limit: Maximum number of files to return (1-1000). Defaults to 100 when absent. + :param after: Forward cursor: a container file id from a previous page (typically `last_id`); listing resumes strictly after that file. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.ListContainerFilesRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + session_id=session_id, + limit=limit, + after=after, + ) + + req = self._build_request_async( + method="GET", + path="/containers/{session_id}/files", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.ListContainerFilesGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="listContainerFiles", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["Containers"], + extensions={"x-hidden": True}, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response( + components.ContainerFileListResponse, http_res + ) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "403", "application/json"): + response_data = unmarshal_json_response( + errors.ForbiddenResponseErrorData, http_res + ) + raise errors.ForbiddenResponseError(response_data, http_res) + if utils.match_response(http_res, "429", "application/json"): + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res + ) + raise errors.TooManyRequestsResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "503", "application/json"): + response_data = unmarshal_json_response( + errors.ServiceUnavailableResponseErrorData, http_res + ) + raise errors.ServiceUnavailableResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + def get_container_file( + self, + *, + session_id: str, + file_id: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.ContainerFile: + r"""Retrieve a container file + + Returns the metadata of a single file under a sandbox session prefix. + + :param session_id: The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. + :param file_id: Container file id (`cfile_` + base64url of the file path). + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.GetContainerFileRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + session_id=session_id, + file_id=file_id, + ) + + req = self._build_request( + method="GET", + path="/containers/{session_id}/files/{file_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.GetContainerFileGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="getContainerFile", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["Containers"], + extensions={"x-hidden": True}, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response(components.ContainerFile, http_res) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "403", "application/json"): + response_data = unmarshal_json_response( + errors.ForbiddenResponseErrorData, http_res + ) + raise errors.ForbiddenResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "429", "application/json"): + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res + ) + raise errors.TooManyRequestsResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "503", "application/json"): + response_data = unmarshal_json_response( + errors.ServiceUnavailableResponseErrorData, http_res + ) + raise errors.ServiceUnavailableResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + async def get_container_file_async( + self, + *, + session_id: str, + file_id: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.ContainerFile: + r"""Retrieve a container file + + Returns the metadata of a single file under a sandbox session prefix. + + :param session_id: The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. + :param file_id: Container file id (`cfile_` + base64url of the file path). + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.GetContainerFileRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + session_id=session_id, + file_id=file_id, + ) + + req = self._build_request_async( + method="GET", + path="/containers/{session_id}/files/{file_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.GetContainerFileGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="getContainerFile", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["Containers"], + extensions={"x-hidden": True}, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response(components.ContainerFile, http_res) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "403", "application/json"): + response_data = unmarshal_json_response( + errors.ForbiddenResponseErrorData, http_res + ) + raise errors.ForbiddenResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "429", "application/json"): + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res + ) + raise errors.TooManyRequestsResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "503", "application/json"): + response_data = unmarshal_json_response( + errors.ServiceUnavailableResponseErrorData, http_res + ) + raise errors.ServiceUnavailableResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + def download_container_file_content( + self, + *, + session_id: str, + file_id: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> httpx.Response: + r"""Download container file content + + Streams the raw bytes of a file under a sandbox session prefix. + + :param session_id: The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. + :param file_id: Container file id (`cfile_` + base64url of the file path). + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.DownloadContainerFileContentRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + session_id=session_id, + file_id=file_id, + ) + + req = self._build_request( + method="GET", + path="/containers/{session_id}/files/{file_id}/content", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/octet-stream", + http_headers=http_headers, + _globals=operations.DownloadContainerFileContentGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="downloadContainerFileContent", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["Containers"], + extensions={"x-hidden": True}, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + stream=True, + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/octet-stream"): + return http_res + if utils.match_response(http_res, "400", "application/json"): + http_res_text = utils.stream_to_text(http_res) + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res, http_res_text + ) + raise errors.BadRequestResponseError(response_data, http_res, http_res_text) + if utils.match_response(http_res, "401", "application/json"): + http_res_text = utils.stream_to_text(http_res) + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res, http_res_text + ) + raise errors.UnauthorizedResponseError( + response_data, http_res, http_res_text + ) + if utils.match_response(http_res, "403", "application/json"): + http_res_text = utils.stream_to_text(http_res) + response_data = unmarshal_json_response( + errors.ForbiddenResponseErrorData, http_res, http_res_text + ) + raise errors.ForbiddenResponseError(response_data, http_res, http_res_text) + if utils.match_response(http_res, "404", "application/json"): + http_res_text = utils.stream_to_text(http_res) + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res, http_res_text + ) + raise errors.NotFoundResponseError(response_data, http_res, http_res_text) + if utils.match_response(http_res, "429", "application/json"): + http_res_text = utils.stream_to_text(http_res) + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res, http_res_text + ) + raise errors.TooManyRequestsResponseError( + response_data, http_res, http_res_text + ) + if utils.match_response(http_res, "500", "application/json"): + http_res_text = utils.stream_to_text(http_res) + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res, http_res_text + ) + raise errors.InternalServerResponseError( + response_data, http_res, http_res_text + ) + if utils.match_response(http_res, "503", "application/json"): + http_res_text = utils.stream_to_text(http_res) + response_data = unmarshal_json_response( + errors.ServiceUnavailableResponseErrorData, http_res, http_res_text + ) + raise errors.ServiceUnavailableResponseError( + response_data, http_res, http_res_text + ) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "Unexpected response received", http_res, http_res_text + ) + + async def download_container_file_content_async( + self, + *, + session_id: str, + file_id: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> httpx.Response: + r"""Download container file content + + Streams the raw bytes of a file under a sandbox session prefix. + + :param session_id: The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id. + :param file_id: Container file id (`cfile_` + base64url of the file path). + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.DownloadContainerFileContentRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + session_id=session_id, + file_id=file_id, + ) + + req = self._build_request_async( + method="GET", + path="/containers/{session_id}/files/{file_id}/content", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/octet-stream", + http_headers=http_headers, + _globals=operations.DownloadContainerFileContentGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="downloadContainerFileContent", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["Containers"], + extensions={"x-hidden": True}, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + stream=True, + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/octet-stream"): + return http_res + if utils.match_response(http_res, "400", "application/json"): + http_res_text = await utils.stream_to_text_async(http_res) + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res, http_res_text + ) + raise errors.BadRequestResponseError(response_data, http_res, http_res_text) + if utils.match_response(http_res, "401", "application/json"): + http_res_text = await utils.stream_to_text_async(http_res) + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res, http_res_text + ) + raise errors.UnauthorizedResponseError( + response_data, http_res, http_res_text + ) + if utils.match_response(http_res, "403", "application/json"): + http_res_text = await utils.stream_to_text_async(http_res) + response_data = unmarshal_json_response( + errors.ForbiddenResponseErrorData, http_res, http_res_text + ) + raise errors.ForbiddenResponseError(response_data, http_res, http_res_text) + if utils.match_response(http_res, "404", "application/json"): + http_res_text = await utils.stream_to_text_async(http_res) + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res, http_res_text + ) + raise errors.NotFoundResponseError(response_data, http_res, http_res_text) + if utils.match_response(http_res, "429", "application/json"): + http_res_text = await utils.stream_to_text_async(http_res) + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res, http_res_text + ) + raise errors.TooManyRequestsResponseError( + response_data, http_res, http_res_text + ) + if utils.match_response(http_res, "500", "application/json"): + http_res_text = await utils.stream_to_text_async(http_res) + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res, http_res_text + ) + raise errors.InternalServerResponseError( + response_data, http_res, http_res_text + ) + if utils.match_response(http_res, "503", "application/json"): + http_res_text = await utils.stream_to_text_async(http_res) + response_data = unmarshal_json_response( + errors.ServiceUnavailableResponseErrorData, http_res, http_res_text + ) + raise errors.ServiceUnavailableResponseError( + response_data, http_res, http_res_text + ) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "Unexpected response received", http_res, http_res_text + ) diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py index 76ee9167..c81a9eff 100644 --- a/src/openrouter/operations/__init__.py +++ b/src/openrouter/operations/__init__.py @@ -274,6 +274,12 @@ DeleteWorkspaceBudgetRequest, DeleteWorkspaceBudgetRequestTypedDict, ) + from .downloadcontainerfilecontent import ( + DownloadContainerFileContentGlobals, + DownloadContainerFileContentGlobalsTypedDict, + DownloadContainerFileContentRequest, + DownloadContainerFileContentRequestTypedDict, + ) from .downloadfilecontent import ( DownloadFileContentGlobals, DownloadFileContentGlobalsTypedDict, @@ -341,6 +347,12 @@ GetBYOKKeyRequest, GetBYOKKeyRequestTypedDict, ) + from .getcontainerfile import ( + GetContainerFileGlobals, + GetContainerFileGlobalsTypedDict, + GetContainerFileRequest, + GetContainerFileRequestTypedDict, + ) from .getcredits import ( GetCreditsData, GetCreditsDataTypedDict, @@ -505,6 +517,12 @@ ListBYOKKeysResponseTypedDict, Provider, ) + from .listcontainerfiles import ( + ListContainerFilesGlobals, + ListContainerFilesGlobalsTypedDict, + ListContainerFilesRequest, + ListContainerFilesRequestTypedDict, + ) from .listembeddingsmodels import ( ListEmbeddingsModelsGlobals, ListEmbeddingsModelsGlobalsTypedDict, @@ -1022,6 +1040,10 @@ "DocumentResponse", "DocumentResponseTypedDict", "DocumentTypedDict", + "DownloadContainerFileContentGlobals", + "DownloadContainerFileContentGlobalsTypedDict", + "DownloadContainerFileContentRequest", + "DownloadContainerFileContentRequestTypedDict", "DownloadFileContentGlobals", "DownloadFileContentGlobalsTypedDict", "DownloadFileContentRequest", @@ -1064,6 +1086,10 @@ "GetBenchmarksGlobalsTypedDict", "GetBenchmarksRequest", "GetBenchmarksRequestTypedDict", + "GetContainerFileGlobals", + "GetContainerFileGlobalsTypedDict", + "GetContainerFileRequest", + "GetContainerFileRequestTypedDict", "GetCreditsData", "GetCreditsDataTypedDict", "GetCreditsGlobals", @@ -1180,6 +1206,10 @@ "ListBYOKKeysRequestTypedDict", "ListBYOKKeysResponse", "ListBYOKKeysResponseTypedDict", + "ListContainerFilesGlobals", + "ListContainerFilesGlobalsTypedDict", + "ListContainerFilesRequest", + "ListContainerFilesRequestTypedDict", "ListData", "ListDataTypedDict", "ListEmbeddingsModelsGlobals", @@ -1655,6 +1685,10 @@ "DeleteWorkspaceBudgetGlobalsTypedDict": ".deleteworkspacebudget", "DeleteWorkspaceBudgetRequest": ".deleteworkspacebudget", "DeleteWorkspaceBudgetRequestTypedDict": ".deleteworkspacebudget", + "DownloadContainerFileContentGlobals": ".downloadcontainerfilecontent", + "DownloadContainerFileContentGlobalsTypedDict": ".downloadcontainerfilecontent", + "DownloadContainerFileContentRequest": ".downloadcontainerfilecontent", + "DownloadContainerFileContentRequestTypedDict": ".downloadcontainerfilecontent", "DownloadFileContentGlobals": ".downloadfilecontent", "DownloadFileContentGlobalsTypedDict": ".downloadfilecontent", "DownloadFileContentRequest": ".downloadfilecontent", @@ -1710,6 +1744,10 @@ "GetBYOKKeyGlobalsTypedDict": ".getbyokkey", "GetBYOKKeyRequest": ".getbyokkey", "GetBYOKKeyRequestTypedDict": ".getbyokkey", + "GetContainerFileGlobals": ".getcontainerfile", + "GetContainerFileGlobalsTypedDict": ".getcontainerfile", + "GetContainerFileRequest": ".getcontainerfile", + "GetContainerFileRequestTypedDict": ".getcontainerfile", "GetCreditsData": ".getcredits", "GetCreditsDataTypedDict": ".getcredits", "GetCreditsGlobals": ".getcredits", @@ -1832,6 +1870,10 @@ "ListBYOKKeysResponse": ".listbyokkeys", "ListBYOKKeysResponseTypedDict": ".listbyokkeys", "Provider": ".listbyokkeys", + "ListContainerFilesGlobals": ".listcontainerfiles", + "ListContainerFilesGlobalsTypedDict": ".listcontainerfiles", + "ListContainerFilesRequest": ".listcontainerfiles", + "ListContainerFilesRequestTypedDict": ".listcontainerfiles", "ListEmbeddingsModelsGlobals": ".listembeddingsmodels", "ListEmbeddingsModelsGlobalsTypedDict": ".listembeddingsmodels", "ListEmbeddingsModelsRequest": ".listembeddingsmodels", diff --git a/src/openrouter/operations/downloadcontainerfilecontent.py b/src/openrouter/operations/downloadcontainerfilecontent.py new file mode 100644 index 00000000..ca3b009c --- /dev/null +++ b/src/openrouter/operations/downloadcontainerfilecontent.py @@ -0,0 +1,151 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.utils import FieldMetadata, HeaderMetadata, PathParamMetadata +import pydantic +from pydantic import model_serializer +from typing import Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class DownloadContainerFileContentGlobalsTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class DownloadContainerFileContentGlobals(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class DownloadContainerFileContentRequestTypedDict(TypedDict): + session_id: str + r"""The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.""" + file_id: str + r"""Container file id (`cfile_` + base64url of the file path).""" + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class DownloadContainerFileContentRequest(BaseModel): + session_id: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.""" + + file_id: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""Container file id (`cfile_` + base64url of the file path).""" + + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/openrouter/operations/getcontainerfile.py b/src/openrouter/operations/getcontainerfile.py new file mode 100644 index 00000000..953ef093 --- /dev/null +++ b/src/openrouter/operations/getcontainerfile.py @@ -0,0 +1,151 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.utils import FieldMetadata, HeaderMetadata, PathParamMetadata +import pydantic +from pydantic import model_serializer +from typing import Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class GetContainerFileGlobalsTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class GetContainerFileGlobals(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class GetContainerFileRequestTypedDict(TypedDict): + session_id: str + r"""The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.""" + file_id: str + r"""Container file id (`cfile_` + base64url of the file path).""" + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class GetContainerFileRequest(BaseModel): + session_id: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.""" + + file_id: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""Container file id (`cfile_` + base64url of the file path).""" + + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/openrouter/operations/listcontainerfiles.py b/src/openrouter/operations/listcontainerfiles.py new file mode 100644 index 00000000..9aff2f12 --- /dev/null +++ b/src/openrouter/operations/listcontainerfiles.py @@ -0,0 +1,171 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.utils import ( + FieldMetadata, + HeaderMetadata, + PathParamMetadata, + QueryParamMetadata, +) +import pydantic +from pydantic import model_serializer +from typing import Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class ListContainerFilesGlobalsTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class ListContainerFilesGlobals(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class ListContainerFilesRequestTypedDict(TypedDict): + session_id: str + r"""The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.""" + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + limit: NotRequired[int] + r"""Maximum number of files to return (1-1000). Defaults to 100 when absent.""" + after: NotRequired[str] + r"""Forward cursor: a container file id from a previous page (typically `last_id`); listing resumes strictly after that file.""" + + +class ListContainerFilesRequest(BaseModel): + session_id: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""The sandbox session id, exactly as stored — a restarted session has its own `-r`-suffixed id.""" + + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + limit: Annotated[ + Optional[int], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = 100 + r"""Maximum number of files to return (1-1000). Defaults to 100 when absent.""" + + after: Annotated[ + Optional[str], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = None + r"""Forward cursor: a container file id from a previous page (typically `last_id`); listing resumes strictly after that file.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + [ + "HTTP-Referer", + "X-OpenRouter-Title", + "X-OpenRouter-Categories", + "limit", + "after", + ] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/openrouter/sdk.py b/src/openrouter/sdk.py index 4dca8972..98847019 100644 --- a/src/openrouter/sdk.py +++ b/src/openrouter/sdk.py @@ -23,6 +23,7 @@ from openrouter.byok import BYOK from openrouter.chat import Chat from openrouter.classifications import Classifications + from openrouter.containers import Containers from openrouter.credits import Credits from openrouter.datasets import Datasets from openrouter.embeddings import Embeddings @@ -66,6 +67,8 @@ class OpenRouter(BaseSDK): chat: "Chat" classifications: "Classifications" r"""Task classification market-share endpoints""" + containers: "Containers" + r"""Containers endpoints""" credits: "Credits" r"""Credit management endpoints""" datasets: "Datasets" @@ -114,6 +117,7 @@ class OpenRouter(BaseSDK): "byok": ("openrouter.byok", "BYOK"), "chat": ("openrouter.chat", "Chat"), "classifications": ("openrouter.classifications", "Classifications"), + "containers": ("openrouter.containers", "Containers"), "credits": ("openrouter.credits", "Credits"), "datasets": ("openrouter.datasets", "Datasets"), "embeddings": ("openrouter.embeddings", "Embeddings"), diff --git a/uv.lock b/uv.lock index 1104693d..df512212 100644 --- a/uv.lock +++ b/uv.lock @@ -213,7 +213,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.1.74" +version = "1.1.75" source = { editable = "." } dependencies = [ { name = "httpcore" }, From 319540621da5ed824a5eb6e5cb48002f0f6a5f01 Mon Sep 17 00:00:00 2001 From: "speakeasy-github[bot]" <128539517+speakeasy-github[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 01:56:34 +0000 Subject: [PATCH 2/3] empty commit to trigger [run-tests] workflow From 901777f2cfc9eae7b0e979d27b8ccce224d448ea Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 01:56:47 +0000 Subject: [PATCH 3/3] Chore: regenerate docs navigation Auto-generated-by: update-generated-files-action; https://github.com/OpenRouterTeam/python-sdk/actions/runs/32681404822 --- docs/docs.json | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs.json b/docs/docs.json index 0e245732..c0ca1903 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -17,6 +17,7 @@ "sdks/byok/README", "sdks/chat/README", "sdks/classifications/README", + "sdks/containers/README", "sdks/credits/README", "sdks/datasets/README", "sdks/embeddings/README",