diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 5701a872..2162485b 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: 48ba9f57a8739e1dc8c8cab173aad2c2 + docChecksum: 8921a22ee9a28c5cd98b924a272e809e docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 1.1.84 - configChecksum: 059fa58d21b2c4db029872d5ace90cf8 + releaseVersion: 1.1.85 + configChecksum: 056db9012f4a842d5c3fbcf891459fe3 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: bf95c823-4039-43d0-b85b-805749d1664a - pristine_commit_hash: 1213af1001443f1d78e596f6bcbb0ade102e30d4 - pristine_tree_hash: 4e6717d18e993a28ec595a08069585abf2c96e03 + generation_id: 86f35643-8d5a-4437-9448-84a67826db84 + pristine_commit_hash: 38f3a057898aac5a1b7148d458af890d5a2f8ebd + pristine_tree_hash: cc383fb366cc3db32cb2bb5e6a6492a13d9da573 features: python: acceptHeaders: 3.0.0 @@ -7032,6 +7032,14 @@ trackedFiles: id: 038d66aa4fc1 last_write_checksum: sha1:f65e16f5901c128767ab047aaeb811430c2bce3e pristine_git_object: a1fdee3160b2294a66e05f59cfd17382364c129c + docs/operations/promotecontainerfileglobals.mdx: + id: 157cfc1fe10a + last_write_checksum: sha1:05fbeea7c6d8a91974ad8ad0c869ff5a0e91b0fc + pristine_git_object: f1aa90ac480684bca770ec4c9f8b607e1b22fc42 + docs/operations/promotecontainerfilerequest.mdx: + id: ced315623746 + last_write_checksum: sha1:a81fe86e71dd07bc86e242e75df43ce8054feedd + pristine_git_object: a14427c499dccc4349e29d812671863031285866 docs/operations/prompttokensdetails.mdx: id: 346b38e82e1c last_write_checksum: sha1:ece0f5c30ccaef159981265b3ac57381289e86b3 @@ -7286,8 +7294,8 @@ trackedFiles: pristine_git_object: bed5f74e5e8269cbba66943524ffa5206c933de3 docs/sdks/containers/README.mdx: id: cc963972ad75 - last_write_checksum: sha1:b5c29b6c94661027e661293829ccfe541f56ab5b - pristine_git_object: c2d0f3257e6f5876adb5bd4c32a8ea9ce1b8e5b8 + last_write_checksum: sha1:e98902490b924d55601ebc5d6a76aa7271edaccb + pristine_git_object: 05e2d9345a19a297d29482462ca718fba4b6cc3d docs/sdks/credits/README.mdx: id: 2ba51de8de3f last_write_checksum: sha1:08de2963f78b645eaa14fa8511552bae2ddccd75 @@ -7378,8 +7386,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:0dc4c6ff50614403a21a01d9b296c7188801d9e8 - pristine_git_object: c550e3af60e52b1139ba6c5338d1748e052fe68e + last_write_checksum: sha1:d456d250d743e1fc424fe4b564385da9e801d20d + pristine_git_object: b06203b5c1c269dd0b8c45485ce66cf71e94f528 scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -7406,8 +7414,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:5ff5135d061ab60f34140aaf6c2831e382a1c570 - pristine_git_object: 1f54f6a389e5cfd98021dc7c87c03eec6fbe3d99 + last_write_checksum: sha1:c0a63eddf73b86cd05f70c11ee50271a68efc6ad + pristine_git_object: 2edbb2f02918b24e6d5135393d66d3abfb572228 src/openrouter/analytics.py: id: cb406b5aaabb last_write_checksum: sha1:1e0004d8d1d5d797e2b54cd1cabeb7f9489d08e9 @@ -9922,8 +9930,8 @@ trackedFiles: pristine_git_object: ad78361d147d2edb7b5772c14501d9c25a2000b0 src/openrouter/containers.py: id: 5edae5db57e9 - last_write_checksum: sha1:4228e5d7fd7634b5e9c53afe0fb5ec0cacf89fa1 - pristine_git_object: d26eef63014e92380c21e5a132d7e683bd0a3858 + last_write_checksum: sha1:37d4af3253f0fc119cf2414d935dc7b7cf2d9244 + pristine_git_object: 8328666b72a7f3d0c6330f02ab0268dab64070d4 src/openrouter/credits.py: id: cdc961937101 last_write_checksum: sha1:7ac37671d3de537eb98f15239d531e3ab3928a59 @@ -10066,8 +10074,8 @@ trackedFiles: pristine_git_object: 5c553b76ab24d9eaef51c3bf6d85aa74391e335e src/openrouter/operations/__init__.py: id: 9afcea1e7161 - last_write_checksum: sha1:19c99d02b7b5e77db4f93366318666cf82db6d3d - pristine_git_object: c81a9eff8a1cb74fac30f84ce8d83f6ccb6bb245 + last_write_checksum: sha1:485909820533419acf0fa1d0c8fef5acfe16bee5 + pristine_git_object: 153455463a5dffde89e5d15bc223e3aa091d4eb7 src/openrouter/operations/bulkaddworkspacemembers.py: id: e0ed56117619 last_write_checksum: sha1:5c44eb0d40fdece3ac084615f6c6082be4cf1d5a @@ -10420,6 +10428,10 @@ trackedFiles: id: fe94c6f61835 last_write_checksum: sha1:32f503f121d7ca1b10392f2615fea224ce7d5f1b pristine_git_object: cbdad12f956c5f2a8252b7f6db102f1e83c4e85a + src/openrouter/operations/promotecontainerfile.py: + id: 4303a549823d + last_write_checksum: sha1:b38c12973abf643632ac5fd2293bff383c20c0a2 + pristine_git_object: 6ab264885a9454b195955adba4b65e01f2abf223 src/openrouter/operations/queryanalytics.py: id: d76c63ff66f6 last_write_checksum: sha1:8c04150e53c68a2a7b19217f478118d12b9e27d1 @@ -12409,5 +12421,32 @@ examples: application/json: {"error": {"code": 500, "message": "Internal Server Error"}} "503": application/json: {"error": {"code": 503, "message": "Service temporarily unavailable"}} + promoteContainerFile: + speakeasy-default-promote-container-file: + parameters: + path: + container_id: "sess_abc123" + file_id: "cfile_b3V0L3JlcG9ydC5jc3Y" + responses: + "200": + application/json: {"_shape": "openrouter", "created_at": "2025-01-01T00:00:00Z", "downloadable": false, "filename": "document.pdf", "id": "or_file_011CNha8iCJcU1wXNR6q4V8w", "mime_type": "application/pdf", "size_bytes": 1024000, "type": "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"}} + "413": + application/json: {"error": {"code": 413, "message": "Request payload too large"}} + "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.chat.send()`: \n * `request.tools[].union(BashServerTool).parameters.environment` **Changed**\n* `open_router.presets.create_presets_chat_completions()`: \n * `request.tools[].union(BashServerTool).parameters.environment` **Changed**\n* `open_router.presets.create_presets_messages()`: \n * `request.tools[].union(ShellServerTool_OpenRouter).parameters.environment` **Changed**\n* `open_router.presets.create_presets_responses()`: \n * `request.input.union(Array<>)[].union(AdditionalToolsItem).tools[].union(BashServerTool).parameters.environment` **Changed**\n* `open_router.responses.send()`: \n * `request.input.union(Array<>)[].union(AdditionalToolsItem).tools[].union(BashServerTool).parameters.environment` **Changed**\n* `open_router.beta.responses.send()`: \n * `request.input.union(Array<>)[].union(AdditionalToolsItem).tools[].union(ShellServerTool_OpenRouter).parameters.environment` **Changed**\n" +releaseNotes: | + ## Python SDK Changes: + * `open_router.containers.promote_container_file()`: **Added** diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 90da99e5..f97fede7 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.1.84 + version: 1.1.85 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index 80ebbf6b..76e6bb12 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -29655,6 +29655,131 @@ paths: - $ref: "#/components/parameters/AppIdentifier" - $ref: "#/components/parameters/AppDisplayName" - $ref: "#/components/parameters/AppCategories" + /containers/{container_id}/files/{file_id}/promote: + post: + description: 'Copies a file from the container''s sandbox prefix into the workspace''s durable document storage, so it outlives the container. Returns the new document in the Files API shape, with a durable file id in the documents namespace. The copy counts against the workspace''s storage quota exactly like an upload.' + operationId: 'promoteContainerFile' + parameters: + - description: 'The canonical container id, exactly as returned in a bash/shell tool result — a restarted session has its own `-r`-suffixed id. A session-derived id is always `sess_` + the sanitized session key, which is not necessarily the raw session id that was sent.' + in: 'path' + name: 'container_id' + required: true + schema: + description: 'The canonical container id, exactly as returned in a bash/shell tool result — a restarted session has its own `-r`-suffixed id. A session-derived id is always `sess_` + the sanitized session key, which is not necessarily the raw session id that was sent.' + 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: + _shape: 'openrouter' + created_at: '2026-08-23T00:00:00Z' + downloadable: false + filename: 'out/report.csv' + id: 'or_file_011CNha8iCJcU1wXNR6q4V8w' + mime_type: 'text/csv' + size_bytes: 123 + type: 'file' + schema: + $ref: '#/components/schemas/FileResponse' + description: 'The promoted file, as a workspace document.' + '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' + '413': + content: + application/json: + example: + error: + code: 413 + message: 'Request payload too large' + schema: + $ref: '#/components/schemas/PayloadTooLargeResponse' + description: 'Payload Too Large - Request payload exceeds size limits' + '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: 'Promote a container file into workspace documents' + 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.' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 6f649066..5624bd62 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:bec3d9a23d04c2029e5a5a5d7cdd9c325dd56a298bbd9c15770bc3347db66098 - sourceBlobDigest: sha256:53f9396f5f5ff4458589931840f9bf7a8dc0a50a322e11e05659684267a1443d + sourceRevisionDigest: sha256:385f7f8d2f902977c1423ae176629a87bd05d4a60d9e7014f50056fe583436e7 + sourceBlobDigest: sha256:5a656c3be6631afcd0cc49e5dd57423299f17dc9d241ecd40752814ab8adbcc7 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:bec3d9a23d04c2029e5a5a5d7cdd9c325dd56a298bbd9c15770bc3347db66098 - sourceBlobDigest: sha256:53f9396f5f5ff4458589931840f9bf7a8dc0a50a322e11e05659684267a1443d + sourceRevisionDigest: sha256:385f7f8d2f902977c1423ae176629a87bd05d4a60d9e7014f50056fe583436e7 + sourceBlobDigest: sha256:5a656c3be6631afcd0cc49e5dd57423299f17dc9d241ecd40752814ab8adbcc7 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:61a70fc24a729a656b47de162acd80d763cd8525fe51bdc8e691d83fa1ebf320 + codeSamplesRevisionDigest: sha256:c397d9479a42226b46d1558d1033c1f9d81ac3bbce81389f1f94b85e50e4549c workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/RELEASES.md b/RELEASES.md index 2625342d..40798f5a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1629,4 +1629,14 @@ Based on: ### Generated - [python v1.1.84] . ### Releases -- [PyPI v1.1.84] https://pypi.org/project/openrouter/1.1.84 - . \ No newline at end of file +- [PyPI v1.1.84] https://pypi.org/project/openrouter/1.1.84 - . + +## 2026-08-25 08:39:17 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.1.85] . +### Releases +- [PyPI v1.1.85] https://pypi.org/project/openrouter/1.1.85 - . \ No newline at end of file diff --git a/docs/operations/promotecontainerfileglobals.mdx b/docs/operations/promotecontainerfileglobals.mdx new file mode 100644 index 00000000..f1aa90ac --- /dev/null +++ b/docs/operations/promotecontainerfileglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "PromoteContainerFileGlobals" +--- + +## 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/promotecontainerfilerequest.mdx b/docs/operations/promotecontainerfilerequest.mdx new file mode 100644 index 00000000..a14427c4 --- /dev/null +++ b/docs/operations/promotecontainerfilerequest.mdx @@ -0,0 +1,13 @@ +--- +title: "PromoteContainerFileRequest" +--- + +## 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.
| | +| `container_id` | *str* | :heavy_check_mark: | The canonical container id, exactly as returned in a bash/shell tool result — a restarted session has its own `-r`-suffixed id. A session-derived id is always `sess_` + the sanitized session key, which is not necessarily the raw session id that was sent. | 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/sdks/containers/README.mdx b/docs/sdks/containers/README.mdx index c2d0f325..05e2d934 100644 --- a/docs/sdks/containers/README.mdx +++ b/docs/sdks/containers/README.mdx @@ -12,6 +12,7 @@ Containers endpoints * [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 +* [promote_container_file](#promote_container_file) - Promote a container file into workspace documents ## list_container_files @@ -170,4 +171,58 @@ with OpenRouter( | errors.TooManyRequestsResponseError | 429 | application/json | | errors.InternalServerResponseError | 500 | application/json | | errors.ServiceUnavailableResponseError | 503 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | + +## promote_container_file + +Copies a file from the container's sandbox prefix into the workspace's durable document storage, so it outlives the container. Returns the new document in the Files API shape, with a durable file id in the documents namespace. The copy counts against the workspace's storage quota exactly like an upload. + +### 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.promote_container_file(container_id="sess_abc123", file_id="cfile_b3V0L3JlcG9ydC5jc3Y") + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `container_id` | *str* | :heavy_check_mark: | The canonical container id, exactly as returned in a bash/shell tool result — a restarted session has its own `-r`-suffixed id. A session-derived id is always `sess_` + the sanitized session key, which is not necessarily the raw session id that was sent. | 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.FileResponse](../../components/fileresponse.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.PayloadTooLargeResponseError | 413 | 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 c550e3af..b06203b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.1.84" +version = "1.1.85" 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 1f54f6a3..2edbb2f0 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.84" +__version__: str = "1.1.85" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.914.0" -__user_agent__: str = "speakeasy-sdk/python 1.1.84 2.914.0 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.1.85 2.914.0 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/containers.py b/src/openrouter/containers.py index d26eef63..8328666b 100644 --- a/src/openrouter/containers.py +++ b/src/openrouter/containers.py @@ -956,3 +956,315 @@ async def download_container_file_content_async( raise errors.OpenRouterDefaultError( "Unexpected response received", http_res, http_res_text ) + + def promote_container_file( + self, + *, + container_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.FileResponse: + r"""Promote a container file into workspace documents + + Copies a file from the container's sandbox prefix into the workspace's durable document storage, so it outlives the container. Returns the new document in the Files API shape, with a durable file id in the documents namespace. The copy counts against the workspace's storage quota exactly like an upload. + + :param container_id: The canonical container id, exactly as returned in a bash/shell tool result — a restarted session has its own `-r`-suffixed id. A session-derived id is always `sess_` + the sanitized session key, which is not necessarily the raw session id that was sent. + :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.PromoteContainerFileRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + container_id=container_id, + file_id=file_id, + ) + + req = self._build_request( + method="POST", + path="/containers/{container_id}/files/{file_id}/promote", + 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.PromoteContainerFileGlobals( + 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="promoteContainerFile", + 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.FileResponse, 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, "413", "application/json"): + response_data = unmarshal_json_response( + errors.PayloadTooLargeResponseErrorData, http_res + ) + raise errors.PayloadTooLargeResponseError(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 promote_container_file_async( + self, + *, + container_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.FileResponse: + r"""Promote a container file into workspace documents + + Copies a file from the container's sandbox prefix into the workspace's durable document storage, so it outlives the container. Returns the new document in the Files API shape, with a durable file id in the documents namespace. The copy counts against the workspace's storage quota exactly like an upload. + + :param container_id: The canonical container id, exactly as returned in a bash/shell tool result — a restarted session has its own `-r`-suffixed id. A session-derived id is always `sess_` + the sanitized session key, which is not necessarily the raw session id that was sent. + :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.PromoteContainerFileRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + container_id=container_id, + file_id=file_id, + ) + + req = self._build_request_async( + method="POST", + path="/containers/{container_id}/files/{file_id}/promote", + 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.PromoteContainerFileGlobals( + 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="promoteContainerFile", + 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.FileResponse, 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, "413", "application/json"): + response_data = unmarshal_json_response( + errors.PayloadTooLargeResponseErrorData, http_res + ) + raise errors.PayloadTooLargeResponseError(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) diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py index c81a9eff..15345546 100644 --- a/src/openrouter/operations/__init__.py +++ b/src/openrouter/operations/__init__.py @@ -729,6 +729,12 @@ ListWorkspacesResponse, ListWorkspacesResponseTypedDict, ) + from .promotecontainerfile import ( + PromoteContainerFileGlobals, + PromoteContainerFileGlobalsTypedDict, + PromoteContainerFileRequest, + PromoteContainerFileRequestTypedDict, + ) from .queryanalytics import ( ClassifierDimensions, ClassifierDimensionsTypedDict, @@ -1382,6 +1388,10 @@ "OrderBy", "OrderByTypedDict", "Period", + "PromoteContainerFileGlobals", + "PromoteContainerFileGlobalsTypedDict", + "PromoteContainerFileRequest", + "PromoteContainerFileRequestTypedDict", "PromptTokensDetails", "PromptTokensDetailsTypedDict", "Provider", @@ -2028,6 +2038,10 @@ "ListWorkspacesRequestTypedDict": ".listworkspaces", "ListWorkspacesResponse": ".listworkspaces", "ListWorkspacesResponseTypedDict": ".listworkspaces", + "PromoteContainerFileGlobals": ".promotecontainerfile", + "PromoteContainerFileGlobalsTypedDict": ".promotecontainerfile", + "PromoteContainerFileRequest": ".promotecontainerfile", + "PromoteContainerFileRequestTypedDict": ".promotecontainerfile", "ClassifierDimensions": ".queryanalytics", "ClassifierDimensionsTypedDict": ".queryanalytics", "ClassifierFilters": ".queryanalytics", diff --git a/src/openrouter/operations/promotecontainerfile.py b/src/openrouter/operations/promotecontainerfile.py new file mode 100644 index 00000000..6ab26488 --- /dev/null +++ b/src/openrouter/operations/promotecontainerfile.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 PromoteContainerFileGlobalsTypedDict(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 PromoteContainerFileGlobals(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 PromoteContainerFileRequestTypedDict(TypedDict): + container_id: str + r"""The canonical container id, exactly as returned in a bash/shell tool result — a restarted session has its own `-r`-suffixed id. A session-derived id is always `sess_` + the sanitized session key, which is not necessarily the raw session id that was sent.""" + 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 PromoteContainerFileRequest(BaseModel): + container_id: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""The canonical container id, exactly as returned in a bash/shell tool result — a restarted session has its own `-r`-suffixed id. A session-derived id is always `sess_` + the sanitized session key, which is not necessarily the raw session id that was sent.""" + + 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/uv.lock b/uv.lock index bae8896b..42538046 100644 --- a/uv.lock +++ b/uv.lock @@ -213,7 +213,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.1.84" +version = "1.1.85" source = { editable = "." } dependencies = [ { name = "httpcore" },