From a1280859bdd611ba1ac65bc9483209620324bd07 Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Fri, 10 Jul 2026 20:16:51 +0000 Subject: [PATCH 1/2] ## Python SDK Changes: * `open_router.beta.analytics.query_analytics()`: `request` **Changed** --- .speakeasy/gen.lock | 64 +++++++---- .speakeasy/gen.yaml | 2 +- .speakeasy/out.openapi.yaml | 72 ++++++++++++ .speakeasy/workflow.lock | 10 +- RELEASES.md | 12 +- docs/operations/classifierdimensions.mdx | 14 +++ docs/operations/classifierfilters.mdx | 13 +++ docs/operations/classifierfiltersfilter.mdx | 11 ++ docs/operations/classifierfiltersvalue.mdx | 27 +++++ docs/operations/queryanalyticsrequestbody.mdx | 2 + docs/operations/valueclassifierfilters.mdx | 18 +++ docs/sdks/betaanalytics/README.mdx | 2 + pyproject.toml | 2 +- src/openrouter/_version.py | 4 +- src/openrouter/beta_analytics.py | 34 ++++++ src/openrouter/operations/__init__.py | 30 +++++ src/openrouter/operations/queryanalytics.py | 108 ++++++++++++++++++ uv.lock | 2 +- 18 files changed, 395 insertions(+), 32 deletions(-) create mode 100644 docs/operations/classifierdimensions.mdx create mode 100644 docs/operations/classifierfilters.mdx create mode 100644 docs/operations/classifierfiltersfilter.mdx create mode 100644 docs/operations/classifierfiltersvalue.mdx create mode 100644 docs/operations/valueclassifierfilters.mdx diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 5b240863..0f009fa5 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: 5e32c54953ba574d9ee698feec69132b + docChecksum: eafdf0a15ea851c11321f795d9eaeae6 docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 0.11.19 - configChecksum: 68995e9d0f9c16d2db0f9967edfb3af3 + releaseVersion: 0.11.20 + configChecksum: 5415321126f7b1b42de92ec1c213d0d4 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: 1d141ee6-3f2d-4871-9848-c0b44ce3fc81 - pristine_commit_hash: 5d90a57f4c2fe856a5bdf25892ac7645ace722dc - pristine_tree_hash: 79eec5b9a9eebb656a47a973193134b0f2f61d67 + generation_id: 11b03c28-423b-4cf5-8a75-334f53189839 + pristine_commit_hash: 78f9f7be2b502d7c7b11ec27fd701fa26a7834b2 + pristine_tree_hash: a0a6f9597055f659340cba4c2f03acf2a76d857a features: python: acceptHeaders: 3.0.0 @@ -5312,6 +5312,22 @@ trackedFiles: id: db4a10e02011 last_write_checksum: sha1:07a2b233999d732b3559f431337d40cbfb8acb18 pristine_git_object: de22a4c7b44e291012ca85daacc77bde58afbfa4 + docs/operations/classifierdimensions.mdx: + id: 5e48dede0ae4 + last_write_checksum: sha1:9aea7af347af4565daaebcfced2f96f8957dfd1a + pristine_git_object: f7cf34faf7a89ceaeb2c20f9fd37f76e102defba + docs/operations/classifierfilters.mdx: + id: bf2b4d539ad0 + last_write_checksum: sha1:882166611599b6921a6ec342986fe18bf78cf524 + pristine_git_object: db4dbe946e875ad7189725a020f7ea2631a8adf3 + docs/operations/classifierfiltersfilter.mdx: + id: 4c60b258249e + last_write_checksum: sha1:98efc2e7262b521d268dd591b08cb90a3406fabc + pristine_git_object: f09e983a0daa403ee6d2cfca1604906f44a42ee2 + docs/operations/classifierfiltersvalue.mdx: + id: 0701a4bb73c4 + last_write_checksum: sha1:077df057506e544243ecc2e6ab055cadee049035 + pristine_git_object: 47e7dc4e537b1c7392c04f36a7c6c8f45847ee29 docs/operations/content.mdx: id: 6f64feb2d798 last_write_checksum: sha1:329d9719c9e25478666963df7b79710aa626d988 @@ -6286,8 +6302,8 @@ trackedFiles: pristine_git_object: 5b3c7c98d8cee9aa77138996c3d9af3e2bd3127a docs/operations/queryanalyticsrequestbody.mdx: id: 1b8d33b6ac1b - last_write_checksum: sha1:bd5e4998875dd2b73f5b04749ae013f108119a50 - pristine_git_object: 79876b7e840eb330cecb69b748c1dc80bbb7d14e + last_write_checksum: sha1:b100dcb3db6adf543fddf53977874d3d793c99b4 + pristine_git_object: ceec61fa2f3ad3a903475827003f6b4bbfd771c8 docs/operations/queryanalyticsresponse.mdx: id: 26c4b637ce33 last_write_checksum: sha1:3f778b3125815a89ceae9aaa735ffc846fef3de8 @@ -6452,6 +6468,10 @@ trackedFiles: id: ebf32fddf22e last_write_checksum: sha1:18f440dbfdcb2498771fe53a98b054d4d76f283c pristine_git_object: f72dd54a6f1db3e758a924691b07ec17f38bc01e + docs/operations/valueclassifierfilters.mdx: + id: 258cd046e559 + last_write_checksum: sha1:013f0a03f199fa6d2b2a256acd8af403fdd51c5a + pristine_git_object: 9280541b880980bbf528c00ea7c3eb3cc7b4f54c docs/operations/valuetype.mdx: id: 29a8210305d2 last_write_checksum: sha1:5ea5c9a100089970356c552e3d9792c6657d0143 @@ -6478,8 +6498,8 @@ trackedFiles: pristine_git_object: 072d78b5b5aedcdc34724557e76cc0fa03994fba docs/sdks/betaanalytics/README.mdx: id: 239279ebf01b - last_write_checksum: sha1:721b90a76008fa9876ce046a84a7b54bae0dcef8 - pristine_git_object: 716e4631b3b48e11081ed70ca5acc5826b8a6383 + last_write_checksum: sha1:5a76d28d77f68efe34ebbcb72850e6a87c74d3b1 + pristine_git_object: 6e4b06ff97f02da5d31d78f478094db32dfdaa6f docs/sdks/byok/README.mdx: id: 17792f3b180d last_write_checksum: sha1:18692d1b1454837b1592113fe1aaba1b1d37a805 @@ -6578,8 +6598,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:cbe4db46712b81214486e0f26d72f9384a264b7e - pristine_git_object: 9c5d4bfdf21ef61dcb7441889ce4f49cbdba7881 + last_write_checksum: sha1:8914993a8cce928e2718682d649405beb44a32de + pristine_git_object: 91166b893131a18020578ab19889176d7a128370 scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -6606,8 +6626,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:fac5e109f7e32666cc375872e0a411749b13533e - pristine_git_object: 085782e387bd5ce779b4220e2c549eb621a203f3 + last_write_checksum: sha1:2c94535d48a1494c22eff12e1255c7528b1aa324 + pristine_git_object: f5a0e56d914e266d29449c5d3e1a7ec635f26424 src/openrouter/analytics.py: id: cb406b5aaabb last_write_checksum: sha1:9e709b71dd0611056dc0cec6150b578defe32841 @@ -6630,8 +6650,8 @@ trackedFiles: pristine_git_object: 9c02cc64163adf027507af763e7b612d3b704adb src/openrouter/beta_analytics.py: id: 81988b170188 - last_write_checksum: sha1:91cc3d033be8ad49f3d2a67e9dd1ead470c4016f - pristine_git_object: bcf5829eba6df16f8984b756a46c8836b799dc98 + last_write_checksum: sha1:517ca1b0d4b94343e7728f156230e653f43c4641 + pristine_git_object: 1b01f0c081ffc8a42fa56d335f95ec3121e4b5e6 src/openrouter/byok.py: id: bec352462ae1 last_write_checksum: sha1:14ffff34cdb97e81dd5ef9d7ba0f105b09b7ba48 @@ -8982,8 +9002,8 @@ trackedFiles: pristine_git_object: a1dea9b45650cc42a6f60447c032fa46b102839a src/openrouter/operations/__init__.py: id: 9afcea1e7161 - last_write_checksum: sha1:23cba14efcf42e3a94779c6c259362a6f8a97deb - pristine_git_object: 3ee6fd4deecd7fcc382a5256db8e43c6f7e719ca + last_write_checksum: sha1:d5a5875a32fab4fc32e68a7c4036483701797944 + pristine_git_object: 134f9b320535b89c7904427ca69322f9507e7ac2 src/openrouter/operations/bulkaddworkspacemembers.py: id: e0ed56117619 last_write_checksum: sha1:5c44eb0d40fdece3ac084615f6c6082be4cf1d5a @@ -9298,8 +9318,8 @@ trackedFiles: pristine_git_object: a242ff323f23dfadad254b76440114e66db4e744 src/openrouter/operations/queryanalytics.py: id: d76c63ff66f6 - last_write_checksum: sha1:7866c71f371c0dbf9e1cda9be336bbf1d0e30ac5 - pristine_git_object: 705a3eaf0ce3e1b7cc9af6f96dbbed4fe0f67f50 + last_write_checksum: sha1:b184adfb9d438f443c1fd6c4e749aff3188e9496 + pristine_git_object: 23f2f9398884b3ab38b7e3ade20cafee40dc97f3 src/openrouter/operations/sendchatcompletionrequest.py: id: d9fee71bb577 last_write_checksum: sha1:0cba4011b8e305270ac30f88cb7ab59b6aefe619 @@ -10961,4 +10981,6 @@ examples: "500": application/json: {"error": {"code": 500, "message": "Internal Server Error"}} examplesVersion: 1.0.2 -releaseNotes: "## Python SDK Changes:\n* `open_router.beta.responses.send()`: \n * `request.input.union(Array<>)[]` **Changed**\n* `open_router.presets.create_presets_responses()`: \n * `request.input.union(Array<>)[]` **Changed**\n" +releaseNotes: | + ## Python SDK Changes: + * `open_router.beta.analytics.query_analytics()`: `request` **Changed** diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index fccd8e6f..ba5806d5 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 0.11.19 + version: 0.11.20 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index cd49a8b9..5cf1144f 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -23893,6 +23893,78 @@ paths: start: '2025-01-01T00:00:00Z' schema: properties: + classifier_dimensions: + description: >- + Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace. + properties: + classifier_id: + description: UUID of the classifier whose tags to group by. + example: 550e8400-e29b-41d4-a716-446655440000 + format: uuid + type: string + dimension_names: + items: + description: >- + Classifier dimension name (snake_case identifier). When exactly one name is provided, the response uses it as the column key; with multiple names or none, the response uses `clf_dimension_name`/`clf_dimension_value` columns. + example: department + type: string + maxItems: 10 + type: array + include_nulls: + description: >- + When true, also include generations that have no tag from this classifier. Defaults to false, which returns only classified generations. + type: boolean + required: + - classifier_id + type: object + classifier_filters: + description: >- + Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions. + properties: + classifier_id: + description: >- + UUID of the classifier whose tags to filter by. Must match classifier_dimensions.classifier_id when both are specified. + example: 550e8400-e29b-41d4-a716-446655440000 + format: uuid + type: string + filters: + items: + properties: + field: + description: >- + Classifier dimension name to filter on (snake_case identifier, e.g. "department", "work_type"). + example: department + type: string + operator: + description: >- + Filter operator. Only equality/set operators are supported (eq, neq, in, not_in) — ordered comparisons are not available because classification values are strings. + example: eq + type: string + value: + anyOf: + - type: string + - format: double + type: number + - items: + anyOf: + - type: string + - format: double + type: number + type: array + description: Filter value. Use a scalar (string or number) for eq/neq, or an array for in/not_in. + example: Engineering + required: + - field + - operator + - value + type: object + maxItems: 10 + minItems: 1 + type: array + required: + - classifier_id + - filters + type: object dimensions: items: description: Dimension to group by (up to 2). Use the /meta endpoint for available dimensions. diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index c9ecd113..c41786db 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:046e876891ba57af72f3f26e8394a517ea258cecf8c2d8f885357e7796516f2d - sourceBlobDigest: sha256:a38421ec1aa0fb81cf260b96096fb44a9f31543b4b49d700280b2b58460671d1 + sourceRevisionDigest: sha256:0244558823b6088d1e3032984eebb7034080c88012d9246accc6d9e62ff608e2 + sourceBlobDigest: sha256:639b41e906b5ebc304974d4516f56048e8243c71765c59435484287dad1a05ac tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:046e876891ba57af72f3f26e8394a517ea258cecf8c2d8f885357e7796516f2d - sourceBlobDigest: sha256:a38421ec1aa0fb81cf260b96096fb44a9f31543b4b49d700280b2b58460671d1 + sourceRevisionDigest: sha256:0244558823b6088d1e3032984eebb7034080c88012d9246accc6d9e62ff608e2 + sourceBlobDigest: sha256:639b41e906b5ebc304974d4516f56048e8243c71765c59435484287dad1a05ac codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:0eccbc2f8f6e176d5a67e24ec42aee8a70ef63fdf3da3c2a2fbb8b78587bfd8b + codeSamplesRevisionDigest: sha256:a012a1304c56f93a4aeaea74f847db642667113fb8489a88981091d34fc6e4ab workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/RELEASES.md b/RELEASES.md index 127b4ff6..f2ca288f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -298,4 +298,14 @@ Based on: ### Generated - [python v0.11.19] . ### Releases -- [PyPI v0.11.19] https://pypi.org/project/openrouter/0.11.19 - . \ No newline at end of file +- [PyPI v0.11.19] https://pypi.org/project/openrouter/0.11.19 - . + +## 2026-07-10 20:14:59 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v0.11.20] . +### Releases +- [PyPI v0.11.20] https://pypi.org/project/openrouter/0.11.20 - . \ No newline at end of file diff --git a/docs/operations/classifierdimensions.mdx b/docs/operations/classifierdimensions.mdx new file mode 100644 index 00000000..f7cf34fa --- /dev/null +++ b/docs/operations/classifierdimensions.mdx @@ -0,0 +1,14 @@ +--- +title: "ClassifierDimensions" +--- + +Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace. + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `classifier_id` | *str* | :heavy_check_mark: | UUID of the classifier whose tags to group by. | 550e8400-e29b-41d4-a716-446655440000 | +| `dimension_names` | List[*str*] | :heavy_minus_sign: | N/A | | +| `include_nulls` | *Optional[bool]* | :heavy_minus_sign: | When true, also include generations that have no tag from this classifier. Defaults to false, which returns only classified generations. | | \ No newline at end of file diff --git a/docs/operations/classifierfilters.mdx b/docs/operations/classifierfilters.mdx new file mode 100644 index 00000000..db4dbe94 --- /dev/null +++ b/docs/operations/classifierfilters.mdx @@ -0,0 +1,13 @@ +--- +title: "ClassifierFilters" +--- + +Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions. + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `classifier_id` | *str* | :heavy_check_mark: | UUID of the classifier whose tags to filter by. Must match classifier_dimensions.classifier_id when both are specified. | 550e8400-e29b-41d4-a716-446655440000 | +| `filters` | List[[operations.ClassifierFiltersFilter](../operations/classifierfiltersfilter.mdx)] | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/operations/classifierfiltersfilter.mdx b/docs/operations/classifierfiltersfilter.mdx new file mode 100644 index 00000000..f09e983a --- /dev/null +++ b/docs/operations/classifierfiltersfilter.mdx @@ -0,0 +1,11 @@ +--- +title: "ClassifierFiltersFilter" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `field` | *str* | :heavy_check_mark: | Classifier dimension name to filter on (snake_case identifier, e.g. "department", "work_type"). | department | +| `operator` | *str* | :heavy_check_mark: | Filter operator. Only equality/set operators are supported (eq, neq, in, not_in) — ordered comparisons are not available because classification values are strings. | eq | +| `value` | [operations.ClassifierFiltersValue](../operations/classifierfiltersvalue.mdx) | :heavy_check_mark: | Filter value. Use a scalar (string or number) for eq/neq, or an array for in/not_in. | Engineering | \ No newline at end of file diff --git a/docs/operations/classifierfiltersvalue.mdx b/docs/operations/classifierfiltersvalue.mdx new file mode 100644 index 00000000..47e7dc4e --- /dev/null +++ b/docs/operations/classifierfiltersvalue.mdx @@ -0,0 +1,27 @@ +--- +title: "ClassifierFiltersValue" +--- + +Filter value. Use a scalar (string or number) for eq/neq, or an array for in/not_in. + + +## Supported Types + +### `str` + +```python +value: str = /* values here */ +``` + +### `float` + +```python +value: float = /* values here */ +``` + +### `List[operations.ValueClassifierFilters]` + +```python +value: List[operations.ValueClassifierFilters] = /* values here */ +``` + diff --git a/docs/operations/queryanalyticsrequestbody.mdx b/docs/operations/queryanalyticsrequestbody.mdx index 79876b7e..ceec61fa 100644 --- a/docs/operations/queryanalyticsrequestbody.mdx +++ b/docs/operations/queryanalyticsrequestbody.mdx @@ -6,6 +6,8 @@ title: "QueryAnalyticsRequestBody" | Field | Type | Required | Description | Example | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `classifier_dimensions` | [Optional[operations.ClassifierDimensions]](../operations/classifierdimensions.mdx) | :heavy_minus_sign: | Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace. | | +| `classifier_filters` | [Optional[operations.ClassifierFilters]](../operations/classifierfilters.mdx) | :heavy_minus_sign: | Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions. | | | `dimensions` | List[*str*] | :heavy_minus_sign: | N/A | | | `filters` | List[[operations.Filter](../operations/filter_.mdx)] | :heavy_minus_sign: | N/A | | | `granularity` | *Optional[str]* | :heavy_minus_sign: | Time granularity | day | diff --git a/docs/operations/valueclassifierfilters.mdx b/docs/operations/valueclassifierfilters.mdx new file mode 100644 index 00000000..9280541b --- /dev/null +++ b/docs/operations/valueclassifierfilters.mdx @@ -0,0 +1,18 @@ +--- +title: "ValueClassifierFilters" +--- + +## Supported Types + +### `str` + +```python +value: str = /* values here */ +``` + +### `float` + +```python +value: float = /* values here */ +``` + diff --git a/docs/sdks/betaanalytics/README.mdx b/docs/sdks/betaanalytics/README.mdx index 716e4631..6e4b06ff 100644 --- a/docs/sdks/betaanalytics/README.mdx +++ b/docs/sdks/betaanalytics/README.mdx @@ -100,6 +100,8 @@ with OpenRouter( | `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.
| | +| `classifier_dimensions` | [Optional[operations.ClassifierDimensions]](../../operations/classifierdimensions.mdx) | :heavy_minus_sign: | Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace. | | +| `classifier_filters` | [Optional[operations.ClassifierFilters]](../../operations/classifierfilters.mdx) | :heavy_minus_sign: | Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions. | | | `dimensions` | List[*str*] | :heavy_minus_sign: | N/A | | | `filters` | List[[operations.Filter](../../operations/filter_.mdx)] | :heavy_minus_sign: | N/A | | | `granularity` | *Optional[str]* | :heavy_minus_sign: | Time granularity | day | diff --git a/pyproject.toml b/pyproject.toml index 9c5d4bfd..91166b89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "0.11.19" +version = "0.11.20" 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 085782e3..f5a0e56d 100644 --- a/src/openrouter/_version.py +++ b/src/openrouter/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "openrouter" -__version__: str = "0.11.19" +__version__: str = "0.11.20" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.914.0" -__user_agent__: str = "speakeasy-sdk/python 0.11.19 2.914.0 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 0.11.20 2.914.0 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/beta_analytics.py b/src/openrouter/beta_analytics.py index bcf5829e..1b01f0c0 100644 --- a/src/openrouter/beta_analytics.py +++ b/src/openrouter/beta_analytics.py @@ -273,6 +273,15 @@ def query_analytics( http_referer: Optional[str] = None, x_open_router_title: Optional[str] = None, x_open_router_categories: Optional[str] = None, + classifier_dimensions: Optional[ + Union[ + operations.ClassifierDimensions, + operations.ClassifierDimensionsTypedDict, + ] + ] = None, + classifier_filters: Optional[ + Union[operations.ClassifierFilters, operations.ClassifierFiltersTypedDict] + ] = None, dimensions: Optional[Iterable[str]] = None, filters: Optional[ Union[Iterable[operations.Filter], Iterable[operations.FilterTypedDict]] @@ -303,6 +312,8 @@ def query_analytics( :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + :param classifier_dimensions: Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace. + :param classifier_filters: Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions. :param dimensions: :param filters: :param granularity: Time granularity @@ -330,6 +341,12 @@ def query_analytics( x_open_router_title=x_open_router_title, x_open_router_categories=x_open_router_categories, request_body=operations.QueryAnalyticsRequestBody( + classifier_dimensions=utils.get_pydantic_model( + classifier_dimensions, Optional[operations.ClassifierDimensions] + ), + classifier_filters=utils.get_pydantic_model( + classifier_filters, Optional[operations.ClassifierFilters] + ), dimensions=utils.unmarshal(dimensions, Optional[List[str]]), filters=utils.get_pydantic_model( filters, Optional[List[operations.Filter]] @@ -453,6 +470,15 @@ async def query_analytics_async( http_referer: Optional[str] = None, x_open_router_title: Optional[str] = None, x_open_router_categories: Optional[str] = None, + classifier_dimensions: Optional[ + Union[ + operations.ClassifierDimensions, + operations.ClassifierDimensionsTypedDict, + ] + ] = None, + classifier_filters: Optional[ + Union[operations.ClassifierFilters, operations.ClassifierFiltersTypedDict] + ] = None, dimensions: Optional[Iterable[str]] = None, filters: Optional[ Union[Iterable[operations.Filter], Iterable[operations.FilterTypedDict]] @@ -483,6 +509,8 @@ async def query_analytics_async( :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + :param classifier_dimensions: Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace. + :param classifier_filters: Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions. :param dimensions: :param filters: :param granularity: Time granularity @@ -510,6 +538,12 @@ async def query_analytics_async( x_open_router_title=x_open_router_title, x_open_router_categories=x_open_router_categories, request_body=operations.QueryAnalyticsRequestBody( + classifier_dimensions=utils.get_pydantic_model( + classifier_dimensions, Optional[operations.ClassifierDimensions] + ), + classifier_filters=utils.get_pydantic_model( + classifier_filters, Optional[operations.ClassifierFilters] + ), dimensions=utils.unmarshal(dimensions, Optional[List[str]]), filters=utils.get_pydantic_model( filters, Optional[List[operations.Filter]] diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py index 3ee6fd4d..134f9b32 100644 --- a/src/openrouter/operations/__init__.py +++ b/src/openrouter/operations/__init__.py @@ -652,6 +652,14 @@ ListWorkspacesResponseTypedDict, ) from .queryanalytics import ( + ClassifierDimensions, + ClassifierDimensionsTypedDict, + ClassifierFilters, + ClassifierFiltersFilter, + ClassifierFiltersFilterTypedDict, + ClassifierFiltersTypedDict, + ClassifierFiltersValue, + ClassifierFiltersValueTypedDict, Direction, Filter, FilterTypedDict, @@ -677,6 +685,8 @@ Value1TypedDict, Value2, Value2TypedDict, + ValueClassifierFilters, + ValueClassifierFiltersTypedDict, ) from .sendchatcompletionrequest import ( SendChatCompletionRequestGlobals, @@ -772,6 +782,14 @@ "BulkUnassignMembersFromGuardrailGlobalsTypedDict", "BulkUnassignMembersFromGuardrailRequest", "BulkUnassignMembersFromGuardrailRequestTypedDict", + "ClassifierDimensions", + "ClassifierDimensionsTypedDict", + "ClassifierFilters", + "ClassifierFiltersFilter", + "ClassifierFiltersFilterTypedDict", + "ClassifierFiltersTypedDict", + "ClassifierFiltersValue", + "ClassifierFiltersValueTypedDict", "Content", "ContentImageURL", "ContentImageURLTypedDict", @@ -1308,6 +1326,8 @@ "Value1TypedDict", "Value2", "Value2TypedDict", + "ValueClassifierFilters", + "ValueClassifierFiltersTypedDict", "ValueType", "Window", "Zdr", @@ -1804,6 +1824,14 @@ "ListWorkspacesRequestTypedDict": ".listworkspaces", "ListWorkspacesResponse": ".listworkspaces", "ListWorkspacesResponseTypedDict": ".listworkspaces", + "ClassifierDimensions": ".queryanalytics", + "ClassifierDimensionsTypedDict": ".queryanalytics", + "ClassifierFilters": ".queryanalytics", + "ClassifierFiltersFilter": ".queryanalytics", + "ClassifierFiltersFilterTypedDict": ".queryanalytics", + "ClassifierFiltersTypedDict": ".queryanalytics", + "ClassifierFiltersValue": ".queryanalytics", + "ClassifierFiltersValueTypedDict": ".queryanalytics", "Direction": ".queryanalytics", "Filter": ".queryanalytics", "FilterTypedDict": ".queryanalytics", @@ -1829,6 +1857,8 @@ "Value1TypedDict": ".queryanalytics", "Value2": ".queryanalytics", "Value2TypedDict": ".queryanalytics", + "ValueClassifierFilters": ".queryanalytics", + "ValueClassifierFiltersTypedDict": ".queryanalytics", "SendChatCompletionRequestGlobals": ".sendchatcompletionrequest", "SendChatCompletionRequestGlobalsTypedDict": ".sendchatcompletionrequest", "SendChatCompletionRequestRequest": ".sendchatcompletionrequest", diff --git a/src/openrouter/operations/queryanalytics.py b/src/openrouter/operations/queryanalytics.py index 705a3eaf..23f2f939 100644 --- a/src/openrouter/operations/queryanalytics.py +++ b/src/openrouter/operations/queryanalytics.py @@ -74,6 +74,102 @@ def serialize_model(self, handler): return m +class ClassifierDimensionsTypedDict(TypedDict): + r"""Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace.""" + + classifier_id: str + r"""UUID of the classifier whose tags to group by.""" + dimension_names: NotRequired[List[str]] + include_nulls: NotRequired[bool] + r"""When true, also include generations that have no tag from this classifier. Defaults to false, which returns only classified generations.""" + + +class ClassifierDimensions(BaseModel): + r"""Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace.""" + + classifier_id: str + r"""UUID of the classifier whose tags to group by.""" + + dimension_names: Optional[List[str]] = None + + include_nulls: Optional[bool] = None + r"""When true, also include generations that have no tag from this classifier. Defaults to false, which returns only classified generations.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["dimension_names", "include_nulls"]) + 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 + + +ValueClassifierFiltersTypedDict = TypeAliasType( + "ValueClassifierFiltersTypedDict", Union[str, float] +) + + +ValueClassifierFilters = TypeAliasType("ValueClassifierFilters", Union[str, float]) + + +ClassifierFiltersValueTypedDict = TypeAliasType( + "ClassifierFiltersValueTypedDict", + Union[str, float, List[ValueClassifierFiltersTypedDict]], +) +r"""Filter value. Use a scalar (string or number) for eq/neq, or an array for in/not_in.""" + + +ClassifierFiltersValue = TypeAliasType( + "ClassifierFiltersValue", Union[str, float, List[ValueClassifierFilters]] +) +r"""Filter value. Use a scalar (string or number) for eq/neq, or an array for in/not_in.""" + + +class ClassifierFiltersFilterTypedDict(TypedDict): + field: str + r"""Classifier dimension name to filter on (snake_case identifier, e.g. \"department\", \"work_type\").""" + operator: str + r"""Filter operator. Only equality/set operators are supported (eq, neq, in, not_in) — ordered comparisons are not available because classification values are strings.""" + value: ClassifierFiltersValueTypedDict + r"""Filter value. Use a scalar (string or number) for eq/neq, or an array for in/not_in.""" + + +class ClassifierFiltersFilter(BaseModel): + field: str + r"""Classifier dimension name to filter on (snake_case identifier, e.g. \"department\", \"work_type\").""" + + operator: str + r"""Filter operator. Only equality/set operators are supported (eq, neq, in, not_in) — ordered comparisons are not available because classification values are strings.""" + + value: ClassifierFiltersValue + r"""Filter value. Use a scalar (string or number) for eq/neq, or an array for in/not_in.""" + + +class ClassifierFiltersTypedDict(TypedDict): + r"""Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions.""" + + classifier_id: str + r"""UUID of the classifier whose tags to filter by. Must match classifier_dimensions.classifier_id when both are specified.""" + filters: List[ClassifierFiltersFilterTypedDict] + + +class ClassifierFilters(BaseModel): + r"""Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions.""" + + classifier_id: str + r"""UUID of the classifier whose tags to filter by. Must match classifier_dimensions.classifier_id when both are specified.""" + + filters: List[ClassifierFiltersFilter] + + Value2TypedDict = TypeAliasType("Value2TypedDict", Union[str, float]) @@ -145,6 +241,10 @@ class TimeRange(BaseModel): class QueryAnalyticsRequestBodyTypedDict(TypedDict): metrics: List[str] + classifier_dimensions: NotRequired[ClassifierDimensionsTypedDict] + r"""Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace.""" + classifier_filters: NotRequired[ClassifierFiltersTypedDict] + r"""Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions.""" dimensions: NotRequired[List[str]] filters: NotRequired[List[FilterTypedDict]] granularity: NotRequired[str] @@ -160,6 +260,12 @@ class QueryAnalyticsRequestBodyTypedDict(TypedDict): class QueryAnalyticsRequestBody(BaseModel): metrics: List[str] + classifier_dimensions: Optional[ClassifierDimensions] = None + r"""Group results by custom classifier tags, breaking down metrics by the specified dimension values. Requires an active classifier on the workspace.""" + + classifier_filters: Optional[ClassifierFilters] = None + r"""Filter results to generations with specific classifier tag values. Can be combined with classifier_dimensions (must use the same classifier_id) or used independently with standard dimensions.""" + dimensions: Optional[List[str]] = None filters: Optional[List[Filter]] = None @@ -181,6 +287,8 @@ class QueryAnalyticsRequestBody(BaseModel): def serialize_model(self, handler): optional_fields = set( [ + "classifier_dimensions", + "classifier_filters", "dimensions", "filters", "granularity", diff --git a/uv.lock b/uv.lock index 405c5a67..783d413e 100644 --- a/uv.lock +++ b/uv.lock @@ -213,7 +213,7 @@ wheels = [ [[package]] name = "openrouter" -version = "0.11.19" +version = "0.11.20" source = { editable = "." } dependencies = [ { name = "httpcore" }, From cfc2810f3b99217dad3632f543b43f7022d1c2ab Mon Sep 17 00:00:00 2001 From: "speakeasy-github[bot]" <128539517+speakeasy-github[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 20:16:57 +0000 Subject: [PATCH 2/2] empty commit to trigger [run-tests] workflow