diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 52eceb37..47b869c8 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: 1b3480b82990a39f968571a292695e01 + docChecksum: 9ce928049e3e28d0a94005ba9f3feae0 docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 0.11.3 - configChecksum: 9580963049895d84eccfc135025854cb + releaseVersion: 0.11.4 + configChecksum: 4bdce4423724fbc3e27157c1593f7b74 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: 00a7dc9a-a2f7-46bb-898f-e804c87aa438 - pristine_commit_hash: 22206487f7eccf058be8483fb016c65abc71aef9 - pristine_tree_hash: c724440db515750df210411562157b40257083ef + generation_id: 050680d0-830b-4b43-af34-44a6c0807b04 + pristine_commit_hash: 7115aa4a60edab70391136ff35b553ee7d958e42 + pristine_tree_hash: 361cb3b699fe64a78518445b7184f4a488605777 features: python: acceptHeaders: 3.0.0 @@ -2070,8 +2070,8 @@ trackedFiles: pristine_git_object: df5a9a53d2ea20bb548913c902b0bffdf2dc5d15 docs/components/imagegenerationrequest.mdx: id: b093cb0f5e81 - last_write_checksum: sha1:68096752052ef76c094d2e49782962a0facad4d8 - pristine_git_object: 1d6369db6d2d6de74df8a6d7366ba627a5389a70 + last_write_checksum: sha1:4a0e2091a23f660c3e706c0e695504fb090e94d1 + pristine_git_object: f9b74f407b1fbc065f271341d42c94142b2e2503 docs/components/imagegenerationrequestaspectratio.mdx: id: bda89377f32d last_write_checksum: sha1:9cc231ee222c01ce471ecff3804a9e5acb8a054f @@ -3658,8 +3658,8 @@ trackedFiles: pristine_git_object: eef5a5c4a33f4a956032328641888fc336a5a55d docs/components/paretorouterplugin.mdx: id: 92e7a1e63fd0 - last_write_checksum: sha1:0d27d564e181cecd6570c92ce027afd447518536 - pristine_git_object: c7ff4bd17a8c4fa61b9a02abad2257ce6c931dc6 + last_write_checksum: sha1:493693e42545592735e9103c9c0a343911a3ac55 + pristine_git_object: 072b9b7e8859caae7e50577a4ed7a2efff48a3b8 docs/components/paretorouterpluginid.mdx: id: 1142f2f64cc8 last_write_checksum: sha1:6e5b2bd86e73db92a9b4b93f014acb57cc61e1ae @@ -3776,6 +3776,10 @@ trackedFiles: id: 35ac43fbcda0 last_write_checksum: sha1:ac447a848769901eb347e8d4ab81494a79d4101f pristine_git_object: 414a5204c691ee0766f05498ff467eeaddebcb6c + docs/components/pricesource.mdx: + id: 815a5cfaf906 + last_write_checksum: sha1:7a7ed23b3c6a5feb64f8428c7e62eab575883a7f + pristine_git_object: 3d340325d192b54a5d039336cce2bd35d12445ac docs/components/pricing.mdx: id: 6816d700f8b1 last_write_checksum: sha1:ac5c56af4e56eb98da5686e33a224950dfbb8207 @@ -5192,6 +5196,22 @@ trackedFiles: id: 3a50c3fec9de last_write_checksum: sha1:df0aebe1971befd5930236620a6ea94dbec73898 pristine_git_object: 2427dcaa5a305401e2e863eaaa6a99bb53183c51 + docs/operations/createaudiotranscriptionsmultipartfile.mdx: + id: 7a553e03f3a1 + last_write_checksum: sha1:47da0d067b733b676fdd0ed535620d7a5b4b5ee6 + pristine_git_object: 3fa3d99a9db518b810a86f06448b3a2f32b37f0a + docs/operations/createaudiotranscriptionsmultipartglobals.mdx: + id: 6f8d9ab67625 + last_write_checksum: sha1:2de6739adb69660e9b1e85090bcc8fbd73ea822d + pristine_git_object: 40d3f1222273b0f940344f051d1184c551ff3002 + docs/operations/createaudiotranscriptionsmultipartrequest.mdx: + id: 31e7948635e6 + last_write_checksum: sha1:00af643224e329cb890449f62f4ee6d350b30db1 + pristine_git_object: b5031668ec1156a4157609e4812b7a3937b802a2 + docs/operations/createaudiotranscriptionsmultipartrequestbody.mdx: + id: 0550cc56c73a + last_write_checksum: sha1:c377fd998af4c7cb2bae44e1a41c3bce02367a18 + pristine_git_object: 70f754bbc14e7fe9754309837b419705c622dfb6 docs/operations/createaudiotranscriptionsrequest.mdx: id: 68a813383936 last_write_checksum: sha1:a3ad7e4691917927539d6c614788da7f4d6b4892 @@ -5512,10 +5532,6 @@ trackedFiles: id: 64162c7ece40 last_write_checksum: sha1:ab0c02f32ff39de1f3da9604432708878cc932c6 pristine_git_object: 2642f99d77ceb5007b1b863028d73c07e48dac67 - docs/operations/file.mdx: - id: 262d5e5a2457 - last_write_checksum: sha1:bb735203bac5677c946bf404bf1e516635d39efd - pristine_git_object: 0c3c666ca80b93b693bd9b4798d8f511738bf269 docs/operations/filter_.mdx: id: 79b9c7c02d3b last_write_checksum: sha1:210f8d87b466cf10785abbd4cb2f9eb2c3e8576e @@ -6120,6 +6136,10 @@ trackedFiles: id: bff19f8bb679 last_write_checksum: sha1:1a743e8a62051c433127a609e131187a74e2a240 pristine_git_object: 051bb4d1cdb3bdbcd87b29419a4a408f10bb1555 + docs/operations/responseformat.mdx: + id: 363fb8a0ddd6 + last_write_checksum: sha1:69ffb401451c435882706846f68465b58324f02f + pristine_git_object: 83b1634e4f243f00c539d436c9defb32eee0f466 docs/operations/result.mdx: id: b68db2e6b7af last_write_checksum: sha1:3ca42544567f285e78aa012de25ac52b5d082314 @@ -6220,6 +6240,10 @@ trackedFiles: id: f2e782002c04 last_write_checksum: sha1:f04d312af9e3ccc5ce53deb68cb6ade27c300dec pristine_git_object: 086cdf63dfdacf09da11a66301f90245ac7cbb0b + docs/operations/uploadfilefile.mdx: + id: fd906268ce4a + last_write_checksum: sha1:31e686522b460fe22dff0c71c996d34b56947c70 + pristine_git_object: f07c77ddfac359392f50d0b9c2f1919bcb043bc4 docs/operations/uploadfileglobals.mdx: id: ec9ebdf283f8 last_write_checksum: sha1:50f87018f87e3b469cd1f8a0795fc186faa0daa4 @@ -6230,8 +6254,8 @@ trackedFiles: pristine_git_object: 70188129763ff300a0f3faa45134f7299c9bdf39 docs/operations/uploadfilerequestbody.mdx: id: fde4cc558d95 - last_write_checksum: sha1:74a28c6834102e4511000ad118bb2892aa0d11cc - pristine_git_object: 4a9975fed03ab1d97c880283bedde17ce90906f9 + last_write_checksum: sha1:84cd9ecf7c776cba269dbc3c6b970b906bd0030d + pristine_git_object: e91f2d3752b54fa3fe8fd469c1e452aa99f5f6b8 docs/operations/upsertworkspacebudgetglobals.mdx: id: 08d7f90d9b03 last_write_checksum: sha1:3fff3f45d7170916f5c4d12557a97cd9693bbac4 @@ -6310,8 +6334,8 @@ trackedFiles: pristine_git_object: 741c77c1982e1f7fc1c2352ce5199c921f9ee82f docs/sdks/files/README.mdx: id: 1a0c257e330c - last_write_checksum: sha1:475d99ba1b2bb8b2826cb43cc729753fbfc0acf8 - pristine_git_object: 5327882a8d7463846af3285afa1bd38432cec275 + last_write_checksum: sha1:e21cb3c8c0e1c48ca7bc6799e764f45790578d3d + pristine_git_object: 8ed39ab511e8430389a8cb92bed10b088a586006 docs/sdks/generations/README.mdx: id: a754fecc8514 last_write_checksum: sha1:e4276fe2f85be0fbafaf573fe58d17b7236d0652 @@ -6322,8 +6346,8 @@ trackedFiles: pristine_git_object: d164a1da79b0838bd68f0a6560a0317eb86e0226 docs/sdks/images/README.mdx: id: 534a6c102c4f - last_write_checksum: sha1:cdebfe56dd55af4bf9248c8a61366d1a6c6b894b - pristine_git_object: cb61de85f54743e18a3e9ff2a861ffc510af713f + last_write_checksum: sha1:fd7a87a3091a9cc65b1f6785fff8f3b278da1660 + pristine_git_object: 77f3172dabafbaa192b258382074cb34cfd55a5e docs/sdks/models/README.mdx: id: 58f1ca464e0b last_write_checksum: sha1:13cd9e4631b4e19a7db5ad93ce63d66358ffb935 @@ -6358,8 +6382,8 @@ trackedFiles: pristine_git_object: 03281f8cf709ebb9a81700ade4cf9bc0db665eb6 docs/sdks/stt/README.mdx: id: 190b0dc9a5d1 - last_write_checksum: sha1:7647525772ccfd7b3b3653eaca748e0e785941b0 - pristine_git_object: a5097c97cbefb52415e2c830b7869525e994a9da + last_write_checksum: sha1:b07ff598e0d3cf542021bff66790ce97ceef6686 + pristine_git_object: 4ca736501a4c14a79710585ab460ea224f95918d docs/sdks/tts/README.mdx: id: cd1132543884 last_write_checksum: sha1:8930237642313a1db6fdce5f7ea2b0680dc7c5ac @@ -6378,8 +6402,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:77dc4bb23124c68a4514773255a6be898795a345 - pristine_git_object: 0ee40fce00c555f4ae902fe221bccbc7bc2cf960 + last_write_checksum: sha1:e63ee1edc31eba7748772e0f9d9f1239abe84b72 + pristine_git_object: 63126319baf5f2bd6c915b590f02eb5b4b8cb1e1 scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -6406,8 +6430,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:07a6785b54ea278e7f66f25b16dc131011c8fbd6 - pristine_git_object: c2263273c453c720d864cf483e26066fd7edb1e2 + last_write_checksum: sha1:55bbac3c115b285a81d9826cc0f69c37e1195456 + pristine_git_object: 578264d267742981dc5c7268ff378621572831dd src/openrouter/analytics.py: id: cb406b5aaabb last_write_checksum: sha1:9e709b71dd0611056dc0cec6150b578defe32841 @@ -6446,8 +6470,8 @@ trackedFiles: pristine_git_object: ad3d247954547814054c01989a2dff3d12b3e4e1 src/openrouter/components/__init__.py: id: 81754e97b3f4 - last_write_checksum: sha1:08af0c2202383ec06d9bc58553df3ceb68272edd - pristine_git_object: 192d30802850b8d05e199dade47c0e86deb3c689 + last_write_checksum: sha1:fd8a64c71c4edc63a92eec32343fef06f743dd1b + pristine_git_object: 6e6304237012f2f5eaa9d96e5fde8ee13bc7096d src/openrouter/components/aabenchmarkentry.py: id: e2e0f0b48c82 last_write_checksum: sha1:fab4d9a24d2cea937bb749d46c5f83941e99d65c @@ -6878,8 +6902,8 @@ trackedFiles: pristine_git_object: 8bbde153b53887e426989fd5b0486b6dc1122810 src/openrouter/components/chatrequest.py: id: 5e39eaefa9cf - last_write_checksum: sha1:795fe5c66c8e44878d3769d1068d5591bd0a7a40 - pristine_git_object: 3ab5ba1d64a4f1cb214ff2428a6cfa31054d8774 + last_write_checksum: sha1:ca664d330b0d2904c1479cb63e7b5b7d4e4f0961 + pristine_git_object: fe89789eca242903d019c9d9dd2e50c1069a452d src/openrouter/components/chatresult.py: id: 9062fe2935fe last_write_checksum: sha1:2ff1963c54e7e79500115c8549c8d395f4e336d1 @@ -7382,8 +7406,8 @@ trackedFiles: pristine_git_object: ca3f68a4504570acfdc9c095ccdecfbb636c30f1 src/openrouter/components/imagegenerationrequest.py: id: f8291a7be9a0 - last_write_checksum: sha1:5332c2cd26dbb93e94c927f20babe1d060388242 - pristine_git_object: 5d2a7e6371e56cfadd302a67a10d00deef0373cc + last_write_checksum: sha1:179a0b7ea9363fa826749e8bb6fb21074433e43e + pristine_git_object: fbb59ab7c3ea49aa774b4fc917eb9ed9d4484d32 src/openrouter/components/imagegenerationresponse.py: id: 53354cd0cbfc last_write_checksum: sha1:8c42a25c58b589aad6031d2c1734eabcf1a1b143 @@ -7606,8 +7630,8 @@ trackedFiles: pristine_git_object: 9b033dd8570e1d71ddb61a63a4b320d3003bd3ef src/openrouter/components/messagesrequest.py: id: 72b1f339024d - last_write_checksum: sha1:ea318958da35e90201812d01dfb04608212533b3 - pristine_git_object: e87ddbde100b658e3d6378cca6b123c8e162b3a9 + last_write_checksum: sha1:85812e6b546d59d8788ea1a30766a01510ea57a9 + pristine_git_object: e69fe1fc961d93b9cfcfacce426937b34fd53b42 src/openrouter/components/metadatalevel.py: id: 0eede47eef62 last_write_checksum: sha1:b4e7e6fc4e9016b65008e9ebbfcc6f018fe89ced @@ -7942,8 +7966,8 @@ trackedFiles: pristine_git_object: 9aaebc4cb7eefdce97f37e89d6d719e524d148e5 src/openrouter/components/paretorouterplugin.py: id: b239c8e11899 - last_write_checksum: sha1:683d7762d520e3b9d08a3e976bc3bfd3ceca931f - pristine_git_object: f010e7df96d242b4b636a3112416a28b7a5845ac + last_write_checksum: sha1:b40a6f823553cd1602d0ccc3d163c19b2b4dbb8a + pristine_git_object: 68114efa832af6afe4dc86cb3e7daa2a2517620b src/openrouter/components/payloadtoolargeresponseerrordata.py: id: 5209b3a61cc9 last_write_checksum: sha1:41c9cfe04f098a0f8c3971e6dfe490c27e783413 @@ -8178,8 +8202,8 @@ trackedFiles: pristine_git_object: 1c7f8a0ef6bc011cd6196c4a4c77a94b1cbb6b73 src/openrouter/components/responsesrequest.py: id: 8c850080ec5d - last_write_checksum: sha1:101e67249f64b2d28693f05935aa964a94109467 - pristine_git_object: 53cacf214278aeecf2d9219374316ebde6c1c726 + last_write_checksum: sha1:a473bffe268a505095e26b83c4eb52cf1ebe3b4b + pristine_git_object: 9a98af5bc71c7be9fd3ec851cebce9b806b384a7 src/openrouter/components/responsesstreamingresponse.py: id: 142379f3bd90 last_write_checksum: sha1:a48d6f3610f5d15248ef4d25a0d88a0a4a1a9db7 @@ -8682,8 +8706,8 @@ trackedFiles: pristine_git_object: d858f3b578b189d20b89d0dfc1a6b829ff5897ff src/openrouter/files.py: id: 7baf7ee1f5b3 - last_write_checksum: sha1:0835637e39ff5f43fd04f2b428c861c87d1963be - pristine_git_object: 0c46d08795e4f68a47d310d5636e004fd9088208 + last_write_checksum: sha1:d06e5c382e420e3ffb5892e08088844e69f7a8d7 + pristine_git_object: 1c20e7d6a4837053dac23f3d7985ef6910217589 src/openrouter/generations.py: id: 70e1c21042bc last_write_checksum: sha1:c513500d0aecefad46e4e791094672dd8a31e6f2 @@ -8698,8 +8722,8 @@ trackedFiles: pristine_git_object: 89560b566073785535643e694c112bedbd3db13d src/openrouter/images.py: id: c4d7adf63ae0 - last_write_checksum: sha1:00ec5394bd5507e972b99d119ce27e8b3a0d47b4 - pristine_git_object: ebdec2dfff7323a1abe95b3143396cc0a91deb6d + last_write_checksum: sha1:17dfa465ebb0408aff811872149f6ecda426a050 + pristine_git_object: 6f5c7bad3913610dbe97f5bd03837deff83faa6b src/openrouter/models/__init__.py: id: ed73b93abb3f last_write_checksum: sha1:932a790ae66ccd7d7022b39c659bcf72a664ebea @@ -8726,8 +8750,8 @@ trackedFiles: pristine_git_object: a1dea9b45650cc42a6f60447c032fa46b102839a src/openrouter/operations/__init__.py: id: 9afcea1e7161 - last_write_checksum: sha1:58c06e81675a137ec84b13517f78cf1020874f2d - pristine_git_object: fc51690a99a6041a78762af05e43da30f15875da + last_write_checksum: sha1:86fa5bd8f963caf8257ef28d618202fdb56e0b8f + pristine_git_object: 737838dfcd39c8a590ca5058aeffb8fe85311665 src/openrouter/operations/bulkaddworkspacemembers.py: id: e0ed56117619 last_write_checksum: sha1:5c44eb0d40fdece3ac084615f6c6082be4cf1d5a @@ -8760,6 +8784,10 @@ trackedFiles: id: 53f76e1550e4 last_write_checksum: sha1:80072ad426adddceec1d13756ba0c239cbad7014 pristine_git_object: 4e8414f223370bff1e4f060919f36f70da6ec40c + src/openrouter/operations/createaudiotranscriptions_multipart.py: + id: da07d463225a + last_write_checksum: sha1:340621e278cff6ac1537e4d7e3b2c116a4193ee8 + pristine_git_object: 2697d1e94c6a76e751575bc6f6f626f3e3149f3d src/openrouter/operations/createauthkeyscode.py: id: 4253a437de22 last_write_checksum: sha1:874492b64266fcdc5a7f3cd988d71326b7796a5c @@ -9066,8 +9094,8 @@ trackedFiles: pristine_git_object: 4441056786e1495816e8dc057a29795e86380ab1 src/openrouter/operations/uploadfile.py: id: f9dc565da045 - last_write_checksum: sha1:d73fad089275b4d32a718e63baf48926899f6bca - pristine_git_object: 29a37b944dfd1855409f064503e348ce50d13cf0 + last_write_checksum: sha1:fba1a6cb4299c240b32bae8628b5e583e914182a + pristine_git_object: fa8f9261c002709027180b7db501f3c6face90ea src/openrouter/operations/upsertworkspacebudget.py: id: 67d4a2962257 last_write_checksum: sha1:e251aa9f18cef5e265ef4d65cfbda42af411d2a3 @@ -9106,8 +9134,8 @@ trackedFiles: pristine_git_object: 26433165a0b1c25d7bd3115b9b129b18f2dc9387 src/openrouter/stt.py: id: fc0c2f669423 - last_write_checksum: sha1:da4bb584de8f5e54ae6d9b6a5d07c3bc6cf41558 - pristine_git_object: a5f03a72b9dd5ad769366fb71c07c57d7510fc56 + last_write_checksum: sha1:d9821e49378f4ceba290fcfd17f7c9b68311fecc + pristine_git_object: b5895f3b688cde2b19bcef498e4992761bbdd58d src/openrouter/tts.py: id: 5055d4b95f1d last_write_checksum: sha1:727a19a0df768153cbe2d8351394a2e254f680ea @@ -9942,6 +9970,32 @@ examples: application/json: {"error": {"code": 524, "message": "Request timed out. Please try again later."}} "529": application/json: {"error": {"code": 529, "message": "Provider returned error"}} + speakeasy-default-create-audio-transcriptions-multipart: + requestBody: + multipart/form-data: {"file": "x-file: example.file", "model": "Escalade"} + responses: + "200": + application/json: {"text": "Hello, this is a test of OpenAI speech-to-text transcription."} + "400": + application/json: {"error": {"code": 400, "message": "Invalid request parameters"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "402": + application/json: {"error": {"code": 402, "message": "Insufficient credits. Add more using https://openrouter.ai/credits"}} + "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"}} + "502": + application/json: {"error": {"code": 502, "message": "Provider returned error"}} + "503": + application/json: {"error": {"code": 503, "message": "Service temporarily unavailable"}} + "524": + application/json: {"error": {"code": 524, "message": "Request timed out. Please try again later."}} + "529": + application/json: {"error": {"code": 529, "message": "Provider returned error"}} listBYOKKeys: speakeasy-default-list-BYOK-keys: responses: @@ -10652,4 +10706,4 @@ 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<>)[].union(OutputFilesServerToolItem)` **Added**\n * `response` **Changed**\n* `open_router.presets.create_presets_responses()`: \n * `request.input.union(Array<>)[].union(OutputFilesServerToolItem)` **Added**\n" +releaseNotes: "## Python SDK Changes:\n* `open_router.stt.create_transcription_multipart()`: **Added**\n* `open_router.beta.responses.send()`: \n * `request.plugins[].union(pareto-router).price_source` **Added**\n* `open_router.chat.send()`: \n * `request.plugins[].union(pareto-router).price_source` **Added**\n* `open_router.presets.create_presets_chat_completions()`: \n * `request.plugins[].union(pareto-router).price_source` **Added**\n* `open_router.presets.create_presets_messages()`: \n * `request.plugins[].union(pareto-router).price_source` **Added**\n* `open_router.presets.create_presets_responses()`: \n * `request.plugins[].union(pareto-router).price_source` **Added**\n" diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index c997d33f..abe3ec93 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 0.11.3 + version: 0.11.4 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index dfb21f3d..47f2f0b0 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -9434,7 +9434,7 @@ components: type: integer size: description: >- - Optional. A convenience shorthand for output dimensions — pass a tier ("2K", "4K") or explicit pixels ("2048x2048") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. + Optional. A convenience shorthand for output dimensions — pass a tier ("2K", "4K") or explicit pixels ("2048x2048") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. example: 2K type: string stream: @@ -17356,6 +17356,7 @@ components: enabled: true id: pareto-router min_coding_score: 0.8 + price_source: prompt properties: enabled: description: Set to false to disable the pareto-router plugin for this request. Defaults to true. @@ -17366,12 +17367,20 @@ components: type: string min_coding_score: description: >- - Minimum desired coding score between 0 and 1, where 1 is best. Higher values select from stronger coding models (sourced from Artificial Analysis coding percentiles). Maps internally to one of three tiers (low, medium, high). Omit to use the router default tier. + Minimum coding quality score between 0 and 1. Maps to internal quality tiers: >= 0.66 → high (top coding models), >= 0.33 → medium (strong modern flagships), < 0.33 → low (capable coders above the median). Omit to default to the highest tier (equivalent to >= 0.66). example: 0.8 format: double maximum: 1 minimum: 0 type: number + price_source: + description: >- + Price source for the Pareto frontier cost axis. "prompt" uses catalog list price (endpoint.pricing.prompt). "weighted_avg" uses traffic-weighted effective input price from ClickHouse, falling back to prompt price for models without traffic data. Defaults to "prompt". + enum: + - prompt + - weighted_avg + type: string + x-speakeasy-unknown-values: allow required: - id type: object @@ -23705,7 +23714,8 @@ paths: - $ref: "#/components/parameters/AppCategories" /audio/transcriptions: post: - description: Transcribes audio into text. Accepts base64-encoded audio input and returns the transcribed text. + description: >- + Transcribes audio into text. Accepts base64-encoded audio input as JSON or an OpenAI-style multipart/form-data file upload, and returns the transcribed text. operationId: createAudioTranscriptions requestBody: content: @@ -23718,6 +23728,36 @@ paths: model: openai/whisper-large-v3 schema: $ref: '#/components/schemas/STTRequest' + multipart/form-data: + example: + file: audio.wav + language: en + model: openai/whisper-large-v3 + schema: + properties: + file: + description: >- + The audio file to transcribe. The format is derived from the filename extension or the file part content type. Max 25 MB; send larger files as base64 JSON via input_audio. + format: binary + type: string + language: + description: The language of the input audio (ISO-639-1). + type: string + model: + description: The model to use for transcription. + type: string + response_format: + description: The response format. Only "json" is supported. + enum: + - json + type: string + temperature: + description: The sampling temperature. + type: number + required: + - file + - model + type: object required: true responses: '200': diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 2b0692f1..38cf9a51 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:5381277309ba2f3a4a3e0719b00425be3f93c3103717316e6625bd5caf15b277 - sourceBlobDigest: sha256:def8d29511aca594e11c3367b7013a64c8733cc8050e23deae98d9cc5df55c93 + sourceRevisionDigest: sha256:d2c2c3e13ad669361c25f68fad9ec7eecb75ce8225fe04163163192c1c7fe1f6 + sourceBlobDigest: sha256:22a034c7168faf862dc49ec1eb11cabe3f7b5405fffae3881c02000a4f0ec55b tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:5381277309ba2f3a4a3e0719b00425be3f93c3103717316e6625bd5caf15b277 - sourceBlobDigest: sha256:def8d29511aca594e11c3367b7013a64c8733cc8050e23deae98d9cc5df55c93 + sourceRevisionDigest: sha256:d2c2c3e13ad669361c25f68fad9ec7eecb75ce8225fe04163163192c1c7fe1f6 + sourceBlobDigest: sha256:22a034c7168faf862dc49ec1eb11cabe3f7b5405fffae3881c02000a4f0ec55b codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:18d6fc594c9338480cbc65842c3f276ad0a58f2ceda311aff3d70ea33dbd6e6d + codeSamplesRevisionDigest: sha256:9b19c83c1b20193106f585b755a4d639540a4884675a9336cdf199776093c4bc workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/README-PYPI.md b/README-PYPI.md index 9fdbe277..6b6e72cf 100644 --- a/README-PYPI.md +++ b/README-PYPI.md @@ -221,10 +221,10 @@ with OpenRouter( api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: - res = open_router.files.upload(file={ + res = open_router.stt.create_transcription_multipart(file={ "file_name": "example.file", "content": open("example.file", "rb"), - }) + }, model="openai/whisper-large-v3", language="en") # Handle response print(res) diff --git a/README.md b/README.md index 9fdbe277..6b6e72cf 100644 --- a/README.md +++ b/README.md @@ -221,10 +221,10 @@ with OpenRouter( api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: - res = open_router.files.upload(file={ + res = open_router.stt.create_transcription_multipart(file={ "file_name": "example.file", "content": open("example.file", "rb"), - }) + }, model="openai/whisper-large-v3", language="en") # Handle response print(res) diff --git a/RELEASES.md b/RELEASES.md index cb586587..c2bff2d2 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -138,4 +138,14 @@ Based on: ### Generated - [python v0.11.3] . ### Releases -- [PyPI v0.11.3] https://pypi.org/project/openrouter/0.11.3 - . \ No newline at end of file +- [PyPI v0.11.3] https://pypi.org/project/openrouter/0.11.3 - . + +## 2026-07-07 14:30:37 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v0.11.4] . +### Releases +- [PyPI v0.11.4] https://pypi.org/project/openrouter/0.11.4 - . \ No newline at end of file diff --git a/docs/components/imagegenerationrequest.mdx b/docs/components/imagegenerationrequest.mdx index 1d6369db..f9b74f40 100644 --- a/docs/components/imagegenerationrequest.mdx +++ b/docs/components/imagegenerationrequest.mdx @@ -7,19 +7,19 @@ Image generation request input ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `aspect_ratio` | [Optional[components.ImageGenerationRequestAspectRatio]](../components/imagegenerationrequestaspectratio.mdx) | :heavy_minus_sign: | Normalized aspect ratio of the generated image. Providers clamp to their supported subset. | 16:9 | -| `background` | [Optional[components.ImageGenerationRequestBackground]](../components/imagegenerationrequestbackground.mdx) | :heavy_minus_sign: | Background treatment. `transparent` requires an output_format that supports alpha (png or webp). | auto | -| `input_references` | List[[components.ContentPartImage](../components/contentpartimage.mdx)] | :heavy_minus_sign: | Reference images to guide image-to-image generation, as base64 data URLs or HTTP(S) URLs. | | -| `model` | *str* | :heavy_check_mark: | The image generation model to use | bytedance-seed/seedream-4.5 | -| `n` | *Optional[int]* | :heavy_minus_sign: | Number of images to generate (1-10). Providers that only support single-image generation reject n > 1. | 1 | -| `output_compression` | *Optional[int]* | :heavy_minus_sign: | Compression level (0-100) for webp/jpeg output. Ignored for png and by providers without a compression knob. | 100 | -| `output_format` | [Optional[components.ImageGenerationRequestOutputFormat]](../components/imagegenerationrequestoutputformat.mdx) | :heavy_minus_sign: | Encoding of the returned image bytes. Most models produce raster formats (png, jpeg, webp). SVG is supported by vectorization models (e.g. Quiver) — the SVG markup is UTF-8 base64-encoded in `b64_json`. | png | -| `prompt` | *str* | :heavy_check_mark: | Text description of the desired image | a red panda astronaut floating in space, studio lighting | -| `provider` | [Optional[components.ImageGenerationRequestProvider]](../components/imagegenerationrequestprovider.mdx) | :heavy_minus_sign: | Provider-specific passthrough configuration | | -| `quality` | [Optional[components.ImageGenerationRequestQuality]](../components/imagegenerationrequestquality.mdx) | :heavy_minus_sign: | Rendering quality. Providers without a quality knob ignore this. | high | -| `resolution` | [Optional[components.ImageGenerationRequestResolution]](../components/imagegenerationrequestresolution.mdx) | :heavy_minus_sign: | Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. | 2K | -| `seed` | *Optional[int]* | :heavy_minus_sign: | If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. | | -| `size` | *Optional[str]* | :heavy_minus_sign: | Optional. A convenience shorthand for output dimensions — pass a tier ("2K", "4K") or explicit pixels ("2048x2048") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. | 2K | -| `stream` | *Optional[bool]* | :heavy_minus_sign: | If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `aspect_ratio` | [Optional[components.ImageGenerationRequestAspectRatio]](../components/imagegenerationrequestaspectratio.mdx) | :heavy_minus_sign: | Normalized aspect ratio of the generated image. Providers clamp to their supported subset. | 16:9 | +| `background` | [Optional[components.ImageGenerationRequestBackground]](../components/imagegenerationrequestbackground.mdx) | :heavy_minus_sign: | Background treatment. `transparent` requires an output_format that supports alpha (png or webp). | auto | +| `input_references` | List[[components.ContentPartImage](../components/contentpartimage.mdx)] | :heavy_minus_sign: | Reference images to guide image-to-image generation, as base64 data URLs or HTTP(S) URLs. | | +| `model` | *str* | :heavy_check_mark: | The image generation model to use | bytedance-seed/seedream-4.5 | +| `n` | *Optional[int]* | :heavy_minus_sign: | Number of images to generate (1-10). Providers that only support single-image generation reject n > 1. | 1 | +| `output_compression` | *Optional[int]* | :heavy_minus_sign: | Compression level (0-100) for webp/jpeg output. Ignored for png and by providers without a compression knob. | 100 | +| `output_format` | [Optional[components.ImageGenerationRequestOutputFormat]](../components/imagegenerationrequestoutputformat.mdx) | :heavy_minus_sign: | Encoding of the returned image bytes. Most models produce raster formats (png, jpeg, webp). SVG is supported by vectorization models (e.g. Quiver) — the SVG markup is UTF-8 base64-encoded in `b64_json`. | png | +| `prompt` | *str* | :heavy_check_mark: | Text description of the desired image | a red panda astronaut floating in space, studio lighting | +| `provider` | [Optional[components.ImageGenerationRequestProvider]](../components/imagegenerationrequestprovider.mdx) | :heavy_minus_sign: | Provider-specific passthrough configuration | | +| `quality` | [Optional[components.ImageGenerationRequestQuality]](../components/imagegenerationrequestquality.mdx) | :heavy_minus_sign: | Rendering quality. Providers without a quality knob ignore this. | high | +| `resolution` | [Optional[components.ImageGenerationRequestResolution]](../components/imagegenerationrequestresolution.mdx) | :heavy_minus_sign: | Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. | 2K | +| `seed` | *Optional[int]* | :heavy_minus_sign: | If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. | | +| `size` | *Optional[str]* | :heavy_minus_sign: | Optional. A convenience shorthand for output dimensions — pass a tier ("2K", "4K") or explicit pixels ("2048x2048") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. | 2K | +| `stream` | *Optional[bool]* | :heavy_minus_sign: | If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. | | \ No newline at end of file diff --git a/docs/components/paretorouterplugin.mdx b/docs/components/paretorouterplugin.mdx index c7ff4bd1..072b9b7e 100644 --- a/docs/components/paretorouterplugin.mdx +++ b/docs/components/paretorouterplugin.mdx @@ -4,8 +4,9 @@ title: "ParetoRouterPlugin" ## Fields -| Field | Type | Required | Description | Example | -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `enabled` | *Optional[bool]* | :heavy_minus_sign: | Set to false to disable the pareto-router plugin for this request. Defaults to true. | | -| `id` | [components.ParetoRouterPluginID](../components/paretorouterpluginid.mdx) | :heavy_check_mark: | N/A | | -| `min_coding_score` | *Optional[float]* | :heavy_minus_sign: | Minimum desired coding score between 0 and 1, where 1 is best. Higher values select from stronger coding models (sourced from Artificial Analysis coding percentiles). Maps internally to one of three tiers (low, medium, high). Omit to use the router default tier. | 0.8 | \ No newline at end of file +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `enabled` | *Optional[bool]* | :heavy_minus_sign: | Set to false to disable the pareto-router plugin for this request. Defaults to true. | | +| `id` | [components.ParetoRouterPluginID](../components/paretorouterpluginid.mdx) | :heavy_check_mark: | N/A | | +| `min_coding_score` | *Optional[float]* | :heavy_minus_sign: | Minimum coding quality score between 0 and 1. Maps to internal quality tiers: >= 0.66 → high (top coding models), >= 0.33 → medium (strong modern flagships), < 0.33 → low (capable coders above the median). Omit to default to the highest tier (equivalent to >= 0.66). | 0.8 | +| `price_source` | [Optional[components.PriceSource]](../components/pricesource.mdx) | :heavy_minus_sign: | Price source for the Pareto frontier cost axis. "prompt" uses catalog list price (endpoint.pricing.prompt). "weighted_avg" uses traffic-weighted effective input price from ClickHouse, falling back to prompt price for models without traffic data. Defaults to "prompt". | | \ No newline at end of file diff --git a/docs/components/pricesource.mdx b/docs/components/pricesource.mdx new file mode 100644 index 00000000..3d340325 --- /dev/null +++ b/docs/components/pricesource.mdx @@ -0,0 +1,22 @@ +--- +title: "PriceSource" +--- + +Price source for the Pareto frontier cost axis. "prompt" uses catalog list price (endpoint.pricing.prompt). "weighted_avg" uses traffic-weighted effective input price from ClickHouse, falling back to prompt price for models without traffic data. Defaults to "prompt". + +## Example Usage + +```python +from openrouter.components import PriceSource + +# Open enum: unrecognized values are captured as UnrecognizedStr +value: PriceSource = "prompt" +``` + + +## Values + +This is an open enum. Unrecognized values will not fail type checks. + +- `"prompt"` +- `"weighted_avg"` diff --git a/docs/operations/createaudiotranscriptionsmultipartfile.mdx b/docs/operations/createaudiotranscriptionsmultipartfile.mdx new file mode 100644 index 00000000..3fa3d99a --- /dev/null +++ b/docs/operations/createaudiotranscriptionsmultipartfile.mdx @@ -0,0 +1,11 @@ +--- +title: "CreateAudioTranscriptionsMultipartFile" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | +| `file_name` | *str* | :heavy_check_mark: | N/A | +| `content` | *Union[bytes, IO[bytes], io.IOBase]* | :heavy_check_mark: | N/A | +| `content_type` | *Optional[str]* | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/operations/createaudiotranscriptionsmultipartglobals.mdx b/docs/operations/createaudiotranscriptionsmultipartglobals.mdx new file mode 100644 index 00000000..40d3f122 --- /dev/null +++ b/docs/operations/createaudiotranscriptionsmultipartglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "CreateAudioTranscriptionsMultipartGlobals" +--- + +## 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/createaudiotranscriptionsmultipartrequest.mdx b/docs/operations/createaudiotranscriptionsmultipartrequest.mdx new file mode 100644 index 00000000..b5031668 --- /dev/null +++ b/docs/operations/createaudiotranscriptionsmultipartrequest.mdx @@ -0,0 +1,12 @@ +--- +title: "CreateAudioTranscriptionsMultipartRequest" +--- + +## 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.
| +| `request_body` | [operations.CreateAudioTranscriptionsMultipartRequestBody](../operations/createaudiotranscriptionsmultipartrequestbody.mdx) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/operations/createaudiotranscriptionsmultipartrequestbody.mdx b/docs/operations/createaudiotranscriptionsmultipartrequestbody.mdx new file mode 100644 index 00000000..70f754bb --- /dev/null +++ b/docs/operations/createaudiotranscriptionsmultipartrequestbody.mdx @@ -0,0 +1,13 @@ +--- +title: "CreateAudioTranscriptionsMultipartRequestBody" +--- + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `file` | [operations.CreateAudioTranscriptionsMultipartFile](../operations/createaudiotranscriptionsmultipartfile.mdx) | :heavy_check_mark: | The audio file to transcribe. The format is derived from the filename extension or the file part content type. Max 25 MB; send larger files as base64 JSON via input_audio. | +| `language` | *Optional[str]* | :heavy_minus_sign: | The language of the input audio (ISO-639-1). | +| `model` | *str* | :heavy_check_mark: | The model to use for transcription. | +| `response_format` | [Optional[operations.ResponseFormat]](../operations/responseformat.mdx) | :heavy_minus_sign: | The response format. Only "json" is supported. | +| `temperature` | *Optional[float]* | :heavy_minus_sign: | The sampling temperature. | \ No newline at end of file diff --git a/docs/operations/responseformat.mdx b/docs/operations/responseformat.mdx new file mode 100644 index 00000000..83b1634e --- /dev/null +++ b/docs/operations/responseformat.mdx @@ -0,0 +1,17 @@ +--- +title: "ResponseFormat" +--- + +The response format. Only "json" is supported. + +## Example Usage + +```python +from openrouter.operations import ResponseFormat +value: ResponseFormat = "json" +``` + + +## Values + +- `"json"` diff --git a/docs/operations/file.mdx b/docs/operations/uploadfilefile.mdx similarity index 97% rename from docs/operations/file.mdx rename to docs/operations/uploadfilefile.mdx index 0c3c666c..f07c77dd 100644 --- a/docs/operations/file.mdx +++ b/docs/operations/uploadfilefile.mdx @@ -1,5 +1,5 @@ --- -title: "File" +title: "UploadFileFile" --- ## Fields diff --git a/docs/operations/uploadfilerequestbody.mdx b/docs/operations/uploadfilerequestbody.mdx index 4a9975fe..e91f2d37 100644 --- a/docs/operations/uploadfilerequestbody.mdx +++ b/docs/operations/uploadfilerequestbody.mdx @@ -4,6 +4,6 @@ title: "UploadFileRequestBody" ## Fields -| Field | Type | Required | Description | -| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | -| `file` | [operations.File](../operations/file.mdx) | :heavy_check_mark: | N/A | \ No newline at end of file +| Field | Type | Required | Description | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| `file` | [operations.UploadFileFile](../operations/uploadfilefile.mdx) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/sdks/files/README.mdx b/docs/sdks/files/README.mdx index 5327882a..8ed39ab5 100644 --- a/docs/sdks/files/README.mdx +++ b/docs/sdks/files/README.mdx @@ -100,7 +100,7 @@ with OpenRouter( | Parameter | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| `file` | [operations.File](../../operations/file.mdx) | :heavy_check_mark: | N/A | | +| `file` | [operations.UploadFileFile](../../operations/uploadfilefile.mdx) | :heavy_check_mark: | N/A | | | `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.
| | diff --git a/docs/sdks/images/README.mdx b/docs/sdks/images/README.mdx index cb61de85..77f3172d 100644 --- a/docs/sdks/images/README.mdx +++ b/docs/sdks/images/README.mdx @@ -42,26 +42,26 @@ with OpenRouter( ### Parameters -| Parameter | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `model` | *str* | :heavy_check_mark: | The image generation model to use | bytedance-seed/seedream-4.5 | -| `prompt` | *str* | :heavy_check_mark: | Text description of the desired image | a red panda astronaut floating in space, studio lighting | -| `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.
| | -| `aspect_ratio` | [Optional[components.ImageGenerationRequestAspectRatio]](../../components/imagegenerationrequestaspectratio.mdx) | :heavy_minus_sign: | Normalized aspect ratio of the generated image. Providers clamp to their supported subset. | 16:9 | -| `background` | [Optional[components.ImageGenerationRequestBackground]](../../components/imagegenerationrequestbackground.mdx) | :heavy_minus_sign: | Background treatment. `transparent` requires an output_format that supports alpha (png or webp). | auto | -| `input_references` | List[[components.ContentPartImage](../../components/contentpartimage.mdx)] | :heavy_minus_sign: | Reference images to guide image-to-image generation, as base64 data URLs or HTTP(S) URLs. | | -| `n` | *Optional[int]* | :heavy_minus_sign: | Number of images to generate (1-10). Providers that only support single-image generation reject n > 1. | 1 | -| `output_compression` | *Optional[int]* | :heavy_minus_sign: | Compression level (0-100) for webp/jpeg output. Ignored for png and by providers without a compression knob. | 100 | -| `output_format` | [Optional[components.ImageGenerationRequestOutputFormat]](../../components/imagegenerationrequestoutputformat.mdx) | :heavy_minus_sign: | Encoding of the returned image bytes. Most models produce raster formats (png, jpeg, webp). SVG is supported by vectorization models (e.g. Quiver) — the SVG markup is UTF-8 base64-encoded in `b64_json`. | png | -| `provider` | [Optional[components.ImageGenerationRequestProvider]](../../components/imagegenerationrequestprovider.mdx) | :heavy_minus_sign: | Provider-specific passthrough configuration | | -| `quality` | [Optional[components.ImageGenerationRequestQuality]](../../components/imagegenerationrequestquality.mdx) | :heavy_minus_sign: | Rendering quality. Providers without a quality knob ignore this. | high | -| `resolution` | [Optional[components.ImageGenerationRequestResolution]](../../components/imagegenerationrequestresolution.mdx) | :heavy_minus_sign: | Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. | 2K | -| `seed` | *Optional[int]* | :heavy_minus_sign: | If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. | | -| `size` | *Optional[str]* | :heavy_minus_sign: | Optional. A convenience shorthand for output dimensions — pass a tier ("2K", "4K") or explicit pixels ("2048x2048") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. | 2K | -| `stream` | *Optional[bool]* | :heavy_minus_sign: | If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. | | -| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `model` | *str* | :heavy_check_mark: | The image generation model to use | bytedance-seed/seedream-4.5 | +| `prompt` | *str* | :heavy_check_mark: | Text description of the desired image | a red panda astronaut floating in space, studio lighting | +| `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.
| | +| `aspect_ratio` | [Optional[components.ImageGenerationRequestAspectRatio]](../../components/imagegenerationrequestaspectratio.mdx) | :heavy_minus_sign: | Normalized aspect ratio of the generated image. Providers clamp to their supported subset. | 16:9 | +| `background` | [Optional[components.ImageGenerationRequestBackground]](../../components/imagegenerationrequestbackground.mdx) | :heavy_minus_sign: | Background treatment. `transparent` requires an output_format that supports alpha (png or webp). | auto | +| `input_references` | List[[components.ContentPartImage](../../components/contentpartimage.mdx)] | :heavy_minus_sign: | Reference images to guide image-to-image generation, as base64 data URLs or HTTP(S) URLs. | | +| `n` | *Optional[int]* | :heavy_minus_sign: | Number of images to generate (1-10). Providers that only support single-image generation reject n > 1. | 1 | +| `output_compression` | *Optional[int]* | :heavy_minus_sign: | Compression level (0-100) for webp/jpeg output. Ignored for png and by providers without a compression knob. | 100 | +| `output_format` | [Optional[components.ImageGenerationRequestOutputFormat]](../../components/imagegenerationrequestoutputformat.mdx) | :heavy_minus_sign: | Encoding of the returned image bytes. Most models produce raster formats (png, jpeg, webp). SVG is supported by vectorization models (e.g. Quiver) — the SVG markup is UTF-8 base64-encoded in `b64_json`. | png | +| `provider` | [Optional[components.ImageGenerationRequestProvider]](../../components/imagegenerationrequestprovider.mdx) | :heavy_minus_sign: | Provider-specific passthrough configuration | | +| `quality` | [Optional[components.ImageGenerationRequestQuality]](../../components/imagegenerationrequestquality.mdx) | :heavy_minus_sign: | Rendering quality. Providers without a quality knob ignore this. | high | +| `resolution` | [Optional[components.ImageGenerationRequestResolution]](../../components/imagegenerationrequestresolution.mdx) | :heavy_minus_sign: | Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. | 2K | +| `seed` | *Optional[int]* | :heavy_minus_sign: | If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. | | +| `size` | *Optional[str]* | :heavy_minus_sign: | Optional. A convenience shorthand for output dimensions — pass a tier ("2K", "4K") or explicit pixels ("2048x2048") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. | 2K | +| `stream` | *Optional[bool]* | :heavy_minus_sign: | If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. | | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | ### Response diff --git a/docs/sdks/stt/README.mdx b/docs/sdks/stt/README.mdx index a5097c97..4ca73650 100644 --- a/docs/sdks/stt/README.mdx +++ b/docs/sdks/stt/README.mdx @@ -10,10 +10,11 @@ Speech-to-text endpoints ### Available Operations * [create_transcription](#create_transcription) - Create transcription +* [create_transcription_multipart](#create_transcription_multipart) - Create transcription ## create_transcription -Transcribes audio into text. Accepts base64-encoded audio input and returns the transcribed text. +Transcribes audio into text. Accepts base64-encoded audio input as JSON or an OpenAI-style multipart/form-data file upload, and returns the transcribed text. ### Example Usage @@ -59,6 +60,68 @@ with OpenRouter( ### Errors +| Error Type | Status Code | Content Type | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | +| errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.PaymentRequiredResponseError | 402 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.TooManyRequestsResponseError | 429 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.BadGatewayResponseError | 502 | application/json | +| errors.ServiceUnavailableResponseError | 503 | application/json | +| errors.EdgeNetworkTimeoutResponseError | 524 | application/json | +| errors.ProviderOverloadedResponseError | 529 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | + +## create_transcription_multipart + +Transcribes audio into text. Accepts base64-encoded audio input as JSON or an OpenAI-style multipart/form-data file upload, and returns the transcribed text. + +### 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.stt.create_transcription_multipart(file={ + "file_name": "example.file", + "content": open("example.file", "rb"), + }, model="openai/whisper-large-v3", language="en") + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `file` | [operations.CreateAudioTranscriptionsMultipartFile](../../operations/createaudiotranscriptionsmultipartfile.mdx) | :heavy_check_mark: | The audio file to transcribe. The format is derived from the filename extension or the file part content type. Max 25 MB; send larger files as base64 JSON via input_audio. | +| `model` | *str* | :heavy_check_mark: | The model to use for transcription. | +| `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.
| +| `language` | *Optional[str]* | :heavy_minus_sign: | The language of the input audio (ISO-639-1). | +| `response_format` | [Optional[operations.ResponseFormat]](../../operations/responseformat.mdx) | :heavy_minus_sign: | The response format. Only "json" is supported. | +| `temperature` | *Optional[float]* | :heavy_minus_sign: | The sampling temperature. | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + +### Response + +**[components.STTResponse](../../components/sttresponse.mdx)** + +### Errors + | Error Type | Status Code | Content Type | | -------------------------------------- | -------------------------------------- | -------------------------------------- | | errors.BadRequestResponseError | 400 | application/json | diff --git a/pyproject.toml b/pyproject.toml index 0ee40fce..63126319 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "0.11.3" +version = "0.11.4" 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 c2263273..578264d2 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.3" +__version__: str = "0.11.4" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.914.0" -__user_agent__: str = "speakeasy-sdk/python 0.11.3 2.914.0 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 0.11.4 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 192d3080..6e630423 100644 --- a/src/openrouter/components/__init__.py +++ b/src/openrouter/components/__init__.py @@ -2074,6 +2074,7 @@ ParetoRouterPlugin, ParetoRouterPluginID, ParetoRouterPluginTypedDict, + PriceSource, ) from .payloadtoolargeresponseerrordata import ( PayloadTooLargeResponseErrorData, @@ -4192,6 +4193,7 @@ "PreviewWebSearchUserLocation", "PreviewWebSearchUserLocationType", "PreviewWebSearchUserLocationTypedDict", + "PriceSource", "Pricing", "PricingTypedDict", "PromptInjectionScanScope", @@ -6262,6 +6264,7 @@ "ParetoRouterPlugin": ".paretorouterplugin", "ParetoRouterPluginID": ".paretorouterplugin", "ParetoRouterPluginTypedDict": ".paretorouterplugin", + "PriceSource": ".paretorouterplugin", "PayloadTooLargeResponseErrorData": ".payloadtoolargeresponseerrordata", "PayloadTooLargeResponseErrorDataTypedDict": ".payloadtoolargeresponseerrordata", "PaymentRequiredResponseErrorData": ".paymentrequiredresponseerrordata", diff --git a/src/openrouter/components/chatrequest.py b/src/openrouter/components/chatrequest.py index 3ab5ba1d..fe89789e 100644 --- a/src/openrouter/components/chatrequest.py +++ b/src/openrouter/components/chatrequest.py @@ -78,8 +78,8 @@ ResponseHealingPluginTypedDict, FileParserPluginTypedDict, ContextCompressionPluginTypedDict, - ParetoRouterPluginTypedDict, AutoRouterPluginTypedDict, + ParetoRouterPluginTypedDict, WebFetchPluginTypedDict, FusionPluginTypedDict, WebSearchPluginTypedDict, diff --git a/src/openrouter/components/imagegenerationrequest.py b/src/openrouter/components/imagegenerationrequest.py index 5d2a7e63..fbb59ab7 100644 --- a/src/openrouter/components/imagegenerationrequest.py +++ b/src/openrouter/components/imagegenerationrequest.py @@ -698,7 +698,7 @@ class ImageGenerationRequestTypedDict(TypedDict): seed: NotRequired[int] r"""If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers.""" size: NotRequired[str] - r"""Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected.""" + r"""Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400.""" stream: NotRequired[bool] r"""If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response.""" @@ -743,7 +743,7 @@ class ImageGenerationRequest(BaseModel): r"""If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers.""" size: Optional[str] = None - r"""Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected.""" + r"""Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400.""" stream: Optional[bool] = None r"""If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response.""" diff --git a/src/openrouter/components/messagesrequest.py b/src/openrouter/components/messagesrequest.py index e87ddbde..e69fe1fc 100644 --- a/src/openrouter/components/messagesrequest.py +++ b/src/openrouter/components/messagesrequest.py @@ -355,8 +355,8 @@ def serialize_model(self, handler): ResponseHealingPluginTypedDict, FileParserPluginTypedDict, ContextCompressionPluginTypedDict, - ParetoRouterPluginTypedDict, AutoRouterPluginTypedDict, + ParetoRouterPluginTypedDict, WebFetchPluginTypedDict, FusionPluginTypedDict, WebSearchPluginTypedDict, diff --git a/src/openrouter/components/paretorouterplugin.py b/src/openrouter/components/paretorouterplugin.py index f010e7df..68114efa 100644 --- a/src/openrouter/components/paretorouterplugin.py +++ b/src/openrouter/components/paretorouterplugin.py @@ -1,21 +1,33 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.types import BaseModel, UNSET_SENTINEL, UnrecognizedStr from pydantic import model_serializer -from typing import Literal, Optional +from typing import Literal, Optional, Union from typing_extensions import NotRequired, TypedDict ParetoRouterPluginID = Literal["pareto-router",] +PriceSource = Union[ + Literal[ + "prompt", + "weighted_avg", + ], + UnrecognizedStr, +] +r"""Price source for the Pareto frontier cost axis. \"prompt\" uses catalog list price (endpoint.pricing.prompt). \"weighted_avg\" uses traffic-weighted effective input price from ClickHouse, falling back to prompt price for models without traffic data. Defaults to \"prompt\".""" + + class ParetoRouterPluginTypedDict(TypedDict): id: ParetoRouterPluginID enabled: NotRequired[bool] r"""Set to false to disable the pareto-router plugin for this request. Defaults to true.""" min_coding_score: NotRequired[float] - r"""Minimum desired coding score between 0 and 1, where 1 is best. Higher values select from stronger coding models (sourced from Artificial Analysis coding percentiles). Maps internally to one of three tiers (low, medium, high). Omit to use the router default tier.""" + r"""Minimum coding quality score between 0 and 1. Maps to internal quality tiers: >= 0.66 → high (top coding models), >= 0.33 → medium (strong modern flagships), < 0.33 → low (capable coders above the median). Omit to default to the highest tier (equivalent to >= 0.66).""" + price_source: NotRequired[PriceSource] + r"""Price source for the Pareto frontier cost axis. \"prompt\" uses catalog list price (endpoint.pricing.prompt). \"weighted_avg\" uses traffic-weighted effective input price from ClickHouse, falling back to prompt price for models without traffic data. Defaults to \"prompt\".""" class ParetoRouterPlugin(BaseModel): @@ -25,11 +37,14 @@ class ParetoRouterPlugin(BaseModel): r"""Set to false to disable the pareto-router plugin for this request. Defaults to true.""" min_coding_score: Optional[float] = None - r"""Minimum desired coding score between 0 and 1, where 1 is best. Higher values select from stronger coding models (sourced from Artificial Analysis coding percentiles). Maps internally to one of three tiers (low, medium, high). Omit to use the router default tier.""" + r"""Minimum coding quality score between 0 and 1. Maps to internal quality tiers: >= 0.66 → high (top coding models), >= 0.33 → medium (strong modern flagships), < 0.33 → low (capable coders above the median). Omit to default to the highest tier (equivalent to >= 0.66).""" + + price_source: Optional[PriceSource] = None + r"""Price source for the Pareto frontier cost axis. \"prompt\" uses catalog list price (endpoint.pricing.prompt). \"weighted_avg\" uses traffic-weighted effective input price from ClickHouse, falling back to prompt price for models without traffic data. Defaults to \"prompt\".""" @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["enabled", "min_coding_score"]) + optional_fields = set(["enabled", "min_coding_score", "price_source"]) serialized = handler(self) m = {} diff --git a/src/openrouter/components/responsesrequest.py b/src/openrouter/components/responsesrequest.py index 53cacf21..9a98af5b 100644 --- a/src/openrouter/components/responsesrequest.py +++ b/src/openrouter/components/responsesrequest.py @@ -123,8 +123,8 @@ ResponseHealingPluginTypedDict, FileParserPluginTypedDict, ContextCompressionPluginTypedDict, - ParetoRouterPluginTypedDict, AutoRouterPluginTypedDict, + ParetoRouterPluginTypedDict, WebFetchPluginTypedDict, FusionPluginTypedDict, WebSearchPluginTypedDict, diff --git a/src/openrouter/files.py b/src/openrouter/files.py index 0c46d087..1c20e7d6 100644 --- a/src/openrouter/files.py +++ b/src/openrouter/files.py @@ -360,7 +360,7 @@ async def empty_result(): def upload( self, *, - file: Union[operations.File, operations.FileTypedDict], + file: Union[operations.UploadFileFile, operations.UploadFileFileTypedDict], http_referer: Optional[str] = None, x_open_router_title: Optional[str] = None, x_open_router_categories: Optional[str] = None, @@ -404,7 +404,7 @@ def upload( x_open_router_categories=x_open_router_categories, workspace_id=workspace_id, request_body=operations.UploadFileRequestBody( - file=utils.get_pydantic_model(file, operations.File), + file=utils.get_pydantic_model(file, operations.UploadFileFile), ), ) @@ -515,7 +515,7 @@ def upload( async def upload_async( self, *, - file: Union[operations.File, operations.FileTypedDict], + file: Union[operations.UploadFileFile, operations.UploadFileFileTypedDict], http_referer: Optional[str] = None, x_open_router_title: Optional[str] = None, x_open_router_categories: Optional[str] = None, @@ -559,7 +559,7 @@ async def upload_async( x_open_router_categories=x_open_router_categories, workspace_id=workspace_id, request_body=operations.UploadFileRequestBody( - file=utils.get_pydantic_model(file, operations.File), + file=utils.get_pydantic_model(file, operations.UploadFileFile), ), ) diff --git a/src/openrouter/images.py b/src/openrouter/images.py index ebdec2df..6f5c7bad 100644 --- a/src/openrouter/images.py +++ b/src/openrouter/images.py @@ -71,7 +71,7 @@ def generate( :param quality: Rendering quality. Providers without a quality knob ignore this. :param resolution: Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. :param seed: If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. - :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. + :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. :param stream: If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method @@ -138,7 +138,7 @@ def generate( :param quality: Rendering quality. Providers without a quality knob ignore this. :param resolution: Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. :param seed: If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. - :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. + :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. :param stream: If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method @@ -208,7 +208,7 @@ def generate( :param quality: Rendering quality. Providers without a quality knob ignore this. :param resolution: Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. :param seed: If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. - :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. + :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. :param stream: If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method @@ -277,7 +277,7 @@ def generate( :param quality: Rendering quality. Providers without a quality knob ignore this. :param resolution: Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. :param seed: If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. - :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. + :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. :param stream: If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method @@ -543,7 +543,7 @@ async def generate_async( :param quality: Rendering quality. Providers without a quality knob ignore this. :param resolution: Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. :param seed: If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. - :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. + :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. :param stream: If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method @@ -610,7 +610,7 @@ async def generate_async( :param quality: Rendering quality. Providers without a quality knob ignore this. :param resolution: Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. :param seed: If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. - :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. + :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. :param stream: If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method @@ -680,7 +680,7 @@ async def generate_async( :param quality: Rendering quality. Providers without a quality knob ignore this. :param resolution: Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. :param seed: If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. - :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. + :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. :param stream: If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method @@ -749,7 +749,7 @@ async def generate_async( :param quality: Rendering quality. Providers without a quality knob ignore this. :param resolution: Normalized resolution tier of the generated image. Concrete pixel dimensions are derived per-provider. :param seed: If specified, the generation will sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed for all providers. - :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. Interchangeable with resolution + aspect_ratio; use those directly for enumerated, per-model discoverable values. Conflicting size + resolution/aspect_ratio is rejected. + :param size: Optional. A convenience shorthand for output dimensions — pass a tier (\"2K\", \"4K\") or explicit pixels (\"2048x2048\") and we normalize it to the right dimensions for the chosen provider. A tier size is equivalent to setting `resolution` and combines with `aspect_ratio`. An explicit pixel size is authoritative: a mismatched `resolution` or `aspect_ratio` alongside it is rejected with a 400. :param stream: If true, partial images are streamed as SSE events as they become available. Only supported by providers with native streaming (currently OpenAI). Non-streaming providers ignore this flag and return a buffered response. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py index fc51690a..737838df 100644 --- a/src/openrouter/operations/__init__.py +++ b/src/openrouter/operations/__init__.py @@ -53,6 +53,17 @@ CreateAudioTranscriptionsRequest, CreateAudioTranscriptionsRequestTypedDict, ) + from .createaudiotranscriptions_multipart import ( + CreateAudioTranscriptionsMultipartFile, + CreateAudioTranscriptionsMultipartFileTypedDict, + CreateAudioTranscriptionsMultipartGlobals, + CreateAudioTranscriptionsMultipartGlobalsTypedDict, + CreateAudioTranscriptionsMultipartRequest, + CreateAudioTranscriptionsMultipartRequestBody, + CreateAudioTranscriptionsMultipartRequestBodyTypedDict, + CreateAudioTranscriptionsMultipartRequestTypedDict, + ResponseFormat, + ) from .createauthkeyscode import ( CreateAuthKeysCodeCodeChallengeMethod, CreateAuthKeysCodeData, @@ -707,8 +718,8 @@ UpdateWorkspaceRequestTypedDict, ) from .uploadfile import ( - File, - FileTypedDict, + UploadFileFile, + UploadFileFileTypedDict, UploadFileGlobals, UploadFileGlobalsTypedDict, UploadFileRequest, @@ -763,6 +774,14 @@ "CreateAudioSpeechRequestTypedDict", "CreateAudioTranscriptionsGlobals", "CreateAudioTranscriptionsGlobalsTypedDict", + "CreateAudioTranscriptionsMultipartFile", + "CreateAudioTranscriptionsMultipartFileTypedDict", + "CreateAudioTranscriptionsMultipartGlobals", + "CreateAudioTranscriptionsMultipartGlobalsTypedDict", + "CreateAudioTranscriptionsMultipartRequest", + "CreateAudioTranscriptionsMultipartRequestBody", + "CreateAudioTranscriptionsMultipartRequestBodyTypedDict", + "CreateAudioTranscriptionsMultipartRequestTypedDict", "CreateAudioTranscriptionsRequest", "CreateAudioTranscriptionsRequestTypedDict", "CreateAuthKeysCodeCodeChallengeMethod", @@ -915,8 +934,6 @@ "ExchangeAuthCodeForAPIKeyRequestTypedDict", "ExchangeAuthCodeForAPIKeyResponse", "ExchangeAuthCodeForAPIKeyResponseTypedDict", - "File", - "FileTypedDict", "Filter", "FilterTypedDict", "GetAnalyticsMetaData", @@ -1208,6 +1225,7 @@ "RateLimit", "RateLimitTypedDict", "Region", + "ResponseFormat", "Result", "ResultTypedDict", "Role", @@ -1251,6 +1269,8 @@ "UpdateWorkspaceGlobalsTypedDict", "UpdateWorkspaceRequest", "UpdateWorkspaceRequestTypedDict", + "UploadFileFile", + "UploadFileFileTypedDict", "UploadFileGlobals", "UploadFileGlobalsTypedDict", "UploadFileRequest", @@ -1304,6 +1324,15 @@ "CreateAudioTranscriptionsGlobalsTypedDict": ".createaudiotranscriptions", "CreateAudioTranscriptionsRequest": ".createaudiotranscriptions", "CreateAudioTranscriptionsRequestTypedDict": ".createaudiotranscriptions", + "CreateAudioTranscriptionsMultipartFile": ".createaudiotranscriptions_multipart", + "CreateAudioTranscriptionsMultipartFileTypedDict": ".createaudiotranscriptions_multipart", + "CreateAudioTranscriptionsMultipartGlobals": ".createaudiotranscriptions_multipart", + "CreateAudioTranscriptionsMultipartGlobalsTypedDict": ".createaudiotranscriptions_multipart", + "CreateAudioTranscriptionsMultipartRequest": ".createaudiotranscriptions_multipart", + "CreateAudioTranscriptionsMultipartRequestBody": ".createaudiotranscriptions_multipart", + "CreateAudioTranscriptionsMultipartRequestBodyTypedDict": ".createaudiotranscriptions_multipart", + "CreateAudioTranscriptionsMultipartRequestTypedDict": ".createaudiotranscriptions_multipart", + "ResponseFormat": ".createaudiotranscriptions_multipart", "CreateAuthKeysCodeCodeChallengeMethod": ".createauthkeyscode", "CreateAuthKeysCodeData": ".createauthkeyscode", "CreateAuthKeysCodeDataTypedDict": ".createauthkeyscode", @@ -1805,8 +1834,8 @@ "UpdateWorkspaceGlobalsTypedDict": ".updateworkspace", "UpdateWorkspaceRequest": ".updateworkspace", "UpdateWorkspaceRequestTypedDict": ".updateworkspace", - "File": ".uploadfile", - "FileTypedDict": ".uploadfile", + "UploadFileFile": ".uploadfile", + "UploadFileFileTypedDict": ".uploadfile", "UploadFileGlobals": ".uploadfile", "UploadFileGlobalsTypedDict": ".uploadfile", "UploadFileRequest": ".uploadfile", diff --git a/src/openrouter/operations/createaudiotranscriptions_multipart.py b/src/openrouter/operations/createaudiotranscriptions_multipart.py new file mode 100644 index 00000000..2697d1e9 --- /dev/null +++ b/src/openrouter/operations/createaudiotranscriptions_multipart.py @@ -0,0 +1,244 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +import io +from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.utils import ( + FieldMetadata, + HeaderMetadata, + MultipartFormMetadata, + RequestMetadata, +) +import pydantic +from pydantic import model_serializer +from typing import IO, Literal, Optional, Union +from typing_extensions import Annotated, NotRequired, TypedDict + + +class CreateAudioTranscriptionsMultipartGlobalsTypedDict(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 CreateAudioTranscriptionsMultipartGlobals(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 CreateAudioTranscriptionsMultipartFileTypedDict(TypedDict): + file_name: str + content: Union[bytes, IO[bytes], io.IOBase] + content_type: NotRequired[str] + + +class CreateAudioTranscriptionsMultipartFile(BaseModel): + file_name: Annotated[ + str, pydantic.Field(alias="fileName"), FieldMetadata(multipart=True) + ] + + content: Annotated[ + Union[bytes, IO[bytes], io.IOBase], + pydantic.Field(alias=""), + FieldMetadata(multipart=MultipartFormMetadata(content=True)), + ] + + content_type: Annotated[ + Optional[str], + pydantic.Field(alias="Content-Type"), + FieldMetadata(multipart=True), + ] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["contentType"]) + 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 + + +ResponseFormat = Literal["json",] +r"""The response format. Only \"json\" is supported.""" + + +class CreateAudioTranscriptionsMultipartRequestBodyTypedDict(TypedDict): + file: CreateAudioTranscriptionsMultipartFileTypedDict + r"""The audio file to transcribe. The format is derived from the filename extension or the file part content type. Max 25 MB; send larger files as base64 JSON via input_audio.""" + model: str + r"""The model to use for transcription.""" + language: NotRequired[str] + r"""The language of the input audio (ISO-639-1).""" + response_format: NotRequired[ResponseFormat] + r"""The response format. Only \"json\" is supported.""" + temperature: NotRequired[float] + r"""The sampling temperature.""" + + +class CreateAudioTranscriptionsMultipartRequestBody(BaseModel): + file: Annotated[ + CreateAudioTranscriptionsMultipartFile, + FieldMetadata(multipart=MultipartFormMetadata(file=True)), + ] + r"""The audio file to transcribe. The format is derived from the filename extension or the file part content type. Max 25 MB; send larger files as base64 JSON via input_audio.""" + + model: Annotated[str, FieldMetadata(multipart=True)] + r"""The model to use for transcription.""" + + language: Annotated[Optional[str], FieldMetadata(multipart=True)] = None + r"""The language of the input audio (ISO-639-1).""" + + response_format: Annotated[ + Optional[ResponseFormat], FieldMetadata(multipart=True) + ] = None + r"""The response format. Only \"json\" is supported.""" + + temperature: Annotated[Optional[float], FieldMetadata(multipart=True)] = None + r"""The sampling temperature.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["language", "response_format", "temperature"]) + 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 CreateAudioTranscriptionsMultipartRequestTypedDict(TypedDict): + request_body: CreateAudioTranscriptionsMultipartRequestBodyTypedDict + 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 CreateAudioTranscriptionsMultipartRequest(BaseModel): + request_body: Annotated[ + CreateAudioTranscriptionsMultipartRequestBody, + FieldMetadata(request=RequestMetadata(media_type="multipart/form-data")), + ] + + 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/uploadfile.py b/src/openrouter/operations/uploadfile.py index 29a37b94..fa8f9261 100644 --- a/src/openrouter/operations/uploadfile.py +++ b/src/openrouter/operations/uploadfile.py @@ -80,13 +80,13 @@ def serialize_model(self, handler): return m -class FileTypedDict(TypedDict): +class UploadFileFileTypedDict(TypedDict): file_name: str content: Union[bytes, IO[bytes], io.IOBase] content_type: NotRequired[str] -class File(BaseModel): +class UploadFileFile(BaseModel): file_name: Annotated[ str, pydantic.Field(alias="fileName"), FieldMetadata(multipart=True) ] @@ -121,11 +121,13 @@ def serialize_model(self, handler): class UploadFileRequestBodyTypedDict(TypedDict): - file: FileTypedDict + file: UploadFileFileTypedDict class UploadFileRequestBody(BaseModel): - file: Annotated[File, FieldMetadata(multipart=MultipartFormMetadata(file=True))] + file: Annotated[ + UploadFileFile, FieldMetadata(multipart=MultipartFormMetadata(file=True)) + ] class UploadFileRequestTypedDict(TypedDict): diff --git a/src/openrouter/stt.py b/src/openrouter/stt.py index a5f03a72..b5895f3b 100644 --- a/src/openrouter/stt.py +++ b/src/openrouter/stt.py @@ -32,7 +32,7 @@ def create_transcription( ) -> components.STTResponse: r"""Create transcription - Transcribes audio into text. Accepts base64-encoded audio input and returns the transcribed text. + Transcribes audio into text. Accepts base64-encoded audio input as JSON or an OpenAI-style multipart/form-data file upload, and returns the transcribed text. :param input_audio: Base64-encoded audio to transcribe :param model: STT model identifier @@ -218,7 +218,7 @@ async def create_transcription_async( ) -> components.STTResponse: r"""Create transcription - Transcribes audio into text. Accepts base64-encoded audio input and returns the transcribed text. + Transcribes audio into text. Accepts base64-encoded audio input as JSON or an OpenAI-style multipart/form-data file upload, and returns the transcribed text. :param input_audio: Base64-encoded audio to transcribe :param model: STT model identifier @@ -383,3 +383,381 @@ async def create_transcription_async( ) raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + def create_transcription_multipart( + self, + *, + file: Union[ + operations.CreateAudioTranscriptionsMultipartFile, + operations.CreateAudioTranscriptionsMultipartFileTypedDict, + ], + model: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + language: Optional[str] = None, + response_format: Optional[operations.ResponseFormat] = None, + temperature: Optional[float] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.STTResponse: + r"""Create transcription + + Transcribes audio into text. Accepts base64-encoded audio input as JSON or an OpenAI-style multipart/form-data file upload, and returns the transcribed text. + + :param file: The audio file to transcribe. The format is derived from the filename extension or the file part content type. Max 25 MB; send larger files as base64 JSON via input_audio. + :param model: The model to use for transcription. + :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 language: The language of the input audio (ISO-639-1). + :param response_format: The response format. Only \"json\" is supported. + :param temperature: The sampling temperature. + :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.CreateAudioTranscriptionsMultipartRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + request_body=operations.CreateAudioTranscriptionsMultipartRequestBody( + file=utils.get_pydantic_model( + file, operations.CreateAudioTranscriptionsMultipartFile + ), + language=language, + model=model, + response_format=response_format, + temperature=temperature, + ), + ) + + req = self._build_request( + method="POST", + path="/audio/transcriptions", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.CreateAudioTranscriptionsMultipartGlobals( + 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, + get_serialized_body=lambda: utils.serialize_request_body( + request.request_body, + False, + False, + "multipart", + operations.CreateAudioTranscriptionsMultipartRequestBody, + ), + 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="createAudioTranscriptions_multipart", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["STT"], + extensions=None, + ), + 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.STTResponse, 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, "402", "application/json"): + response_data = unmarshal_json_response( + errors.PaymentRequiredResponseErrorData, http_res + ) + raise errors.PaymentRequiredResponseError(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, "502", "application/json"): + response_data = unmarshal_json_response( + errors.BadGatewayResponseErrorData, http_res + ) + raise errors.BadGatewayResponseError(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, "524", "application/json"): + response_data = unmarshal_json_response( + errors.EdgeNetworkTimeoutResponseErrorData, http_res + ) + raise errors.EdgeNetworkTimeoutResponseError(response_data, http_res) + if utils.match_response(http_res, "529", "application/json"): + response_data = unmarshal_json_response( + errors.ProviderOverloadedResponseErrorData, http_res + ) + raise errors.ProviderOverloadedResponseError(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 create_transcription_multipart_async( + self, + *, + file: Union[ + operations.CreateAudioTranscriptionsMultipartFile, + operations.CreateAudioTranscriptionsMultipartFileTypedDict, + ], + model: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + language: Optional[str] = None, + response_format: Optional[operations.ResponseFormat] = None, + temperature: Optional[float] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.STTResponse: + r"""Create transcription + + Transcribes audio into text. Accepts base64-encoded audio input as JSON or an OpenAI-style multipart/form-data file upload, and returns the transcribed text. + + :param file: The audio file to transcribe. The format is derived from the filename extension or the file part content type. Max 25 MB; send larger files as base64 JSON via input_audio. + :param model: The model to use for transcription. + :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 language: The language of the input audio (ISO-639-1). + :param response_format: The response format. Only \"json\" is supported. + :param temperature: The sampling temperature. + :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.CreateAudioTranscriptionsMultipartRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + request_body=operations.CreateAudioTranscriptionsMultipartRequestBody( + file=utils.get_pydantic_model( + file, operations.CreateAudioTranscriptionsMultipartFile + ), + language=language, + model=model, + response_format=response_format, + temperature=temperature, + ), + ) + + req = self._build_request_async( + method="POST", + path="/audio/transcriptions", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.CreateAudioTranscriptionsMultipartGlobals( + 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, + get_serialized_body=lambda: utils.serialize_request_body( + request.request_body, + False, + False, + "multipart", + operations.CreateAudioTranscriptionsMultipartRequestBody, + ), + 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="createAudioTranscriptions_multipart", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["STT"], + extensions=None, + ), + 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.STTResponse, 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, "402", "application/json"): + response_data = unmarshal_json_response( + errors.PaymentRequiredResponseErrorData, http_res + ) + raise errors.PaymentRequiredResponseError(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, "502", "application/json"): + response_data = unmarshal_json_response( + errors.BadGatewayResponseErrorData, http_res + ) + raise errors.BadGatewayResponseError(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, "524", "application/json"): + response_data = unmarshal_json_response( + errors.EdgeNetworkTimeoutResponseErrorData, http_res + ) + raise errors.EdgeNetworkTimeoutResponseError(response_data, http_res) + if utils.match_response(http_res, "529", "application/json"): + response_data = unmarshal_json_response( + errors.ProviderOverloadedResponseErrorData, http_res + ) + raise errors.ProviderOverloadedResponseError(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/uv.lock b/uv.lock index 9f421ae8..cae74d09 100644 --- a/uv.lock +++ b/uv.lock @@ -213,7 +213,7 @@ wheels = [ [[package]] name = "openrouter" -version = "0.11.3" +version = "0.11.4" source = { editable = "." } dependencies = [ { name = "httpcore" },