@xyd-js/opensdk-python 0.0.0-build-f0c10f6-20260703195526
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/LICENSE +21 -0
- package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__create/input.json +325 -0
- package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__create/output.py +26 -0
- package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__delete/input.json +201 -0
- package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__delete/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__list/input.json +400 -0
- package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__retrieve/input.json +304 -0
- package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__retrieve/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__audit_logs__list/input.json +2602 -0
- package/__fixtures__/-2.complex.openai/admin__organization__audit_logs__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__activate__create/input.json +308 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__activate__create/output.py +32 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__create/input.json +308 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__create/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__deactivate__create/input.json +308 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__deactivate__create/output.py +32 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__delete/input.json +196 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__delete/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__list/input.json +356 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__retrieve/input.json +300 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__retrieve/output.py +30 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__update/input.json +310 -0
- package/__fixtures__/-2.complex.openai/admin__organization__certificates__update/output.py +30 -0
- package/__fixtures__/-2.complex.openai/admin__organization__costs__list/input.json +1062 -0
- package/__fixtures__/-2.complex.openai/admin__organization__costs__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__create/input.json +239 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__create/output.py +26 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__delete/input.json +206 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__delete/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__list/input.json +316 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__create/input.json +364 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__create/output.py +34 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__delete/input.json +210 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__delete/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__list/input.json +398 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__list/output.py +37 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__update/input.json +241 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__update/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__users__create/input.json +237 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__users__create/output.py +34 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__users__delete/input.json +211 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__users__delete/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__users__list/input.json +314 -0
- package/__fixtures__/-2.complex.openai/admin__organization__groups__users__list/output.py +37 -0
- package/__fixtures__/-2.complex.openai/admin__organization__invites__create/input.json +386 -0
- package/__fixtures__/-2.complex.openai/admin__organization__invites__create/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__invites__delete/input.json +203 -0
- package/__fixtures__/-2.complex.openai/admin__organization__invites__delete/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__invites__list/input.json +414 -0
- package/__fixtures__/-2.complex.openai/admin__organization__invites__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/admin__organization__invites__retrieve/input.json +337 -0
- package/__fixtures__/-2.complex.openai/admin__organization__invites__retrieve/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__delete/input.json +279 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__delete/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__list/input.json +475 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__list/output.py +37 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__retrieve/input.json +400 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__retrieve/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__archive/input.json +247 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__archive/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__activate__create/input.json +324 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__activate__create/output.py +40 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__deactivate__create/input.json +324 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__deactivate__create/output.py +40 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__list/input.json +372 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__list/output.py +37 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__create/input.json +281 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__create/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__create/input.json +274 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__create/output.py +34 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__delete/input.json +211 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__delete/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__list/input.json +342 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__list/output.py +37 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__list/input.json +330 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__rate_limits__list_rate_limits/input.json +358 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__rate_limits__list_rate_limits/output.py +37 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__rate_limits__update_rate_limit/input.json +407 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__rate_limits__update_rate_limit/output.py +38 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__retrieve/input.json +247 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__retrieve/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__create/input.json +372 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__create/output.py +34 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__delete/input.json +216 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__delete/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__list/input.json +391 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__list/output.py +37 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__retrieve/input.json +253 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__retrieve/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__update/input.json +356 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__update/output.py +30 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__create/input.json +349 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__create/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__delete/input.json +279 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__delete/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__list/input.json +387 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__list/output.py +37 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__retrieve/input.json +250 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__retrieve/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__update/input.json +339 -0
- package/__fixtures__/-2.complex.openai/admin__organization__projects__users__update/output.py +38 -0
- package/__fixtures__/-2.complex.openai/admin__organization__roles__create/input.json +283 -0
- package/__fixtures__/-2.complex.openai/admin__organization__roles__create/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__roles__delete/input.json +206 -0
- package/__fixtures__/-2.complex.openai/admin__organization__roles__delete/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__roles__list/input.json +338 -0
- package/__fixtures__/-2.complex.openai/admin__organization__roles__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/admin__organization__roles__update/input.json +296 -0
- package/__fixtures__/-2.complex.openai/admin__organization__roles__update/output.py +30 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__audio_speeches__list/input.json +1108 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__audio_speeches__list/output.py +35 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__audio_transcriptions__list/input.json +1108 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__audio_transcriptions__list/output.py +35 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__code_interpreter_sessions__list/input.json +1054 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__code_interpreter_sessions__list/output.py +35 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__completions__list/input.json +1123 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__completions__list/output.py +35 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__embeddings__list/input.json +1108 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__embeddings__list/output.py +35 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__images__list/input.json +1176 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__images__list/output.py +35 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__moderations__list/input.json +1108 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__moderations__list/output.py +35 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__vector_stores__list/input.json +1054 -0
- package/__fixtures__/-2.complex.openai/admin__organization__usage__vector_stores__list/output.py +35 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__delete/input.json +202 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__delete/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__list/input.json +557 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__retrieve/input.json +472 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__retrieve/output.py +28 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__roles__create/input.json +611 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__roles__create/output.py +34 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__roles__delete/input.json +210 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__roles__delete/output.py +36 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__roles__list/input.json +398 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__roles__list/output.py +37 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__update/input.json +528 -0
- package/__fixtures__/-2.complex.openai/admin__organization__users__update/output.py +30 -0
- package/__fixtures__/-2.complex.openai/audio__speech__create/input.json +388 -0
- package/__fixtures__/-2.complex.openai/audio__speech__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/audio__transcriptions__create/input.json +999 -0
- package/__fixtures__/-2.complex.openai/audio__transcriptions__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/audio__translations__create/input.json +430 -0
- package/__fixtures__/-2.complex.openai/audio__translations__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__create/input.json +244 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__delete/input.json +190 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__delete/output.py +22 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__list/input.json +285 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__list/output.py +23 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__retrieve/input.json +212 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__retrieve/output.py +22 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__update/input.json +236 -0
- package/__fixtures__/-2.complex.openai/audio__voice_consents__update/output.py +22 -0
- package/__fixtures__/-2.complex.openai/audio__voices__create/input.json +235 -0
- package/__fixtures__/-2.complex.openai/audio__voices__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/batches__cancel/input.json +594 -0
- package/__fixtures__/-2.complex.openai/batches__cancel/output.py +16 -0
- package/__fixtures__/-2.complex.openai/batches__create/input.json +701 -0
- package/__fixtures__/-2.complex.openai/batches__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/batches__list/input.json +665 -0
- package/__fixtures__/-2.complex.openai/batches__list/output.py +17 -0
- package/__fixtures__/-2.complex.openai/batches__retrieve/input.json +594 -0
- package/__fixtures__/-2.complex.openai/batches__retrieve/output.py +16 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__create/input.json +1029 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__delete/input.json +190 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__delete/output.py +22 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__list/input.json +796 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__list/output.py +23 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__retrieve/input.json +694 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__retrieve/output.py +22 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__update/input.json +1045 -0
- package/__fixtures__/-2.complex.openai/beta__assistants__update/output.py +24 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__sessions__cancel/input.json +482 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__sessions__cancel/output.py +28 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__sessions__create/input.json +738 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__sessions__create/output.py +28 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__delete/input.json +200 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__delete/output.py +28 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__items__list/input.json +1218 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__items__list/output.py +37 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__list/input.json +444 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__list/output.py +29 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__retrieve/input.json +328 -0
- package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__retrieve/output.py +28 -0
- package/__fixtures__/-2.complex.openai/beta__threads__create/input.json +665 -0
- package/__fixtures__/-2.complex.openai/beta__threads__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/beta__threads__delete/input.json +189 -0
- package/__fixtures__/-2.complex.openai/beta__threads__delete/output.py +22 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__create/input.json +938 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__create/output.py +30 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__delete/input.json +203 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__delete/output.py +30 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__list/input.json +945 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__list/output.py +31 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__retrieve/input.json +832 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__retrieve/output.py +30 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__update/input.json +855 -0
- package/__fixtures__/-2.complex.openai/beta__threads__messages__update/output.py +32 -0
- package/__fixtures__/-2.complex.openai/beta__threads__new_and_run/input.json +1899 -0
- package/__fixtures__/-2.complex.openai/beta__threads__new_and_run/output.py +22 -0
- package/__fixtures__/-2.complex.openai/beta__threads__retrieve/input.json +283 -0
- package/__fixtures__/-2.complex.openai/beta__threads__retrieve/output.py +22 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__cancel/input.json +1181 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__cancel/output.py +30 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__create/input.json +1851 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__create/output.py +30 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__list/input.json +1285 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__list/output.py +31 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__retrieve/input.json +1181 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__retrieve/output.py +30 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__steps__list/input.json +1066 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__steps__list/output.py +39 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__steps__retrieve/input.json +964 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__steps__retrieve/output.py +40 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__submit_tool_outputs__create/input.json +1246 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__submit_tool_outputs__create/output.py +38 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__update/input.json +1204 -0
- package/__fixtures__/-2.complex.openai/beta__threads__runs__update/output.py +32 -0
- package/__fixtures__/-2.complex.openai/beta__threads__update/input.json +315 -0
- package/__fixtures__/-2.complex.openai/beta__threads__update/output.py +24 -0
- package/__fixtures__/-2.complex.openai/chat__completions__create/input.json +3325 -0
- package/__fixtures__/-2.complex.openai/chat__completions__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/chat__completions__delete/input.json +192 -0
- package/__fixtures__/-2.complex.openai/chat__completions__delete/output.py +22 -0
- package/__fixtures__/-2.complex.openai/chat__completions__list/input.json +1069 -0
- package/__fixtures__/-2.complex.openai/chat__completions__list/output.py +23 -0
- package/__fixtures__/-2.complex.openai/chat__completions__messages__list/input.json +770 -0
- package/__fixtures__/-2.complex.openai/chat__completions__messages__list/output.py +31 -0
- package/__fixtures__/-2.complex.openai/chat__completions__retrieve/input.json +938 -0
- package/__fixtures__/-2.complex.openai/chat__completions__retrieve/output.py +22 -0
- package/__fixtures__/-2.complex.openai/chat__completions__update/input.json +973 -0
- package/__fixtures__/-2.complex.openai/chat__completions__update/output.py +22 -0
- package/__fixtures__/-2.complex.openai/completions__create/input.json +788 -0
- package/__fixtures__/-2.complex.openai/completions__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/containers__create/input.json +671 -0
- package/__fixtures__/-2.complex.openai/containers__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/containers__delete/input.json +142 -0
- package/__fixtures__/-2.complex.openai/containers__delete/output.py +16 -0
- package/__fixtures__/-2.complex.openai/containers__files__content/input.json +154 -0
- package/__fixtures__/-2.complex.openai/containers__files__content/output.py +24 -0
- package/__fixtures__/-2.complex.openai/containers__files__create/input.json +261 -0
- package/__fixtures__/-2.complex.openai/containers__files__create/output.py +24 -0
- package/__fixtures__/-2.complex.openai/containers__files__delete/input.json +154 -0
- package/__fixtures__/-2.complex.openai/containers__files__delete/output.py +24 -0
- package/__fixtures__/-2.complex.openai/containers__files__list/input.json +337 -0
- package/__fixtures__/-2.complex.openai/containers__files__list/output.py +25 -0
- package/__fixtures__/-2.complex.openai/containers__files__retrieve/input.json +235 -0
- package/__fixtures__/-2.complex.openai/containers__files__retrieve/output.py +24 -0
- package/__fixtures__/-2.complex.openai/containers__list/input.json +438 -0
- package/__fixtures__/-2.complex.openai/containers__list/output.py +17 -0
- package/__fixtures__/-2.complex.openai/containers__retrieve/input.json +329 -0
- package/__fixtures__/-2.complex.openai/containers__retrieve/output.py +16 -0
- package/__fixtures__/-2.complex.openai/conversations__create/input.json +6737 -0
- package/__fixtures__/-2.complex.openai/conversations__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/conversations__delete/input.json +186 -0
- package/__fixtures__/-2.complex.openai/conversations__delete/output.py +16 -0
- package/__fixtures__/-2.complex.openai/conversations__items__create/input.json +8352 -0
- package/__fixtures__/-2.complex.openai/conversations__items__create/output.py +25 -0
- package/__fixtures__/-2.complex.openai/conversations__items__delete/input.json +213 -0
- package/__fixtures__/-2.complex.openai/conversations__items__delete/output.py +24 -0
- package/__fixtures__/-2.complex.openai/conversations__items__list/input.json +6695 -0
- package/__fixtures__/-2.complex.openai/conversations__items__list/output.py +25 -0
- package/__fixtures__/-2.complex.openai/conversations__items__retrieve/input.json +6597 -0
- package/__fixtures__/-2.complex.openai/conversations__items__retrieve/output.py +26 -0
- package/__fixtures__/-2.complex.openai/conversations__retrieve/input.json +198 -0
- package/__fixtures__/-2.complex.openai/conversations__retrieve/output.py +16 -0
- package/__fixtures__/-2.complex.openai/conversations__update/input.json +233 -0
- package/__fixtures__/-2.complex.openai/conversations__update/output.py +16 -0
- package/__fixtures__/-2.complex.openai/embeddings__create/input.json +395 -0
- package/__fixtures__/-2.complex.openai/embeddings__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/evals__create/input.json +1424 -0
- package/__fixtures__/-2.complex.openai/evals__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/evals__delete/input.json +232 -0
- package/__fixtures__/-2.complex.openai/evals__delete/output.py +16 -0
- package/__fixtures__/-2.complex.openai/evals__list/input.json +1251 -0
- package/__fixtures__/-2.complex.openai/evals__list/output.py +17 -0
- package/__fixtures__/-2.complex.openai/evals__retrieve/input.json +1127 -0
- package/__fixtures__/-2.complex.openai/evals__retrieve/output.py +16 -0
- package/__fixtures__/-2.complex.openai/evals__runs__cancel/input.json +4445 -0
- package/__fixtures__/-2.complex.openai/evals__runs__cancel/output.py +24 -0
- package/__fixtures__/-2.complex.openai/evals__runs__create/input.json +4526 -0
- package/__fixtures__/-2.complex.openai/evals__runs__create/output.py +24 -0
- package/__fixtures__/-2.complex.openai/evals__runs__delete/input.json +246 -0
- package/__fixtures__/-2.complex.openai/evals__runs__delete/output.py +24 -0
- package/__fixtures__/-2.complex.openai/evals__runs__list/input.json +4579 -0
- package/__fixtures__/-2.complex.openai/evals__runs__list/output.py +25 -0
- package/__fixtures__/-2.complex.openai/evals__runs__output_items__list/input.json +685 -0
- package/__fixtures__/-2.complex.openai/evals__runs__output_items__list/output.py +33 -0
- package/__fixtures__/-2.complex.openai/evals__runs__output_items__retrieve/input.json +560 -0
- package/__fixtures__/-2.complex.openai/evals__runs__output_items__retrieve/output.py +32 -0
- package/__fixtures__/-2.complex.openai/evals__runs__retrieve/input.json +4445 -0
- package/__fixtures__/-2.complex.openai/evals__runs__retrieve/output.py +24 -0
- package/__fixtures__/-2.complex.openai/evals__update/input.json +1160 -0
- package/__fixtures__/-2.complex.openai/evals__update/output.py +18 -0
- package/__fixtures__/-2.complex.openai/files__content/input.json +151 -0
- package/__fixtures__/-2.complex.openai/files__content/output.py +16 -0
- package/__fixtures__/-2.complex.openai/files__create/input.json +379 -0
- package/__fixtures__/-2.complex.openai/files__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/files__delete/input.json +184 -0
- package/__fixtures__/-2.complex.openai/files__delete/output.py +16 -0
- package/__fixtures__/-2.complex.openai/files__list/input.json +397 -0
- package/__fixtures__/-2.complex.openai/files__list/output.py +17 -0
- package/__fixtures__/-2.complex.openai/files__retrieve/input.json +295 -0
- package/__fixtures__/-2.complex.openai/files__retrieve/output.py +16 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__alpha__graders__run__create/input.json +1225 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__alpha__graders__run__create/output.py +34 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__alpha__graders__validate__create/input.json +991 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__alpha__graders__validate__create/output.py +32 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__create/input.json +297 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__create/output.py +29 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__delete/input.json +208 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__delete/output.py +30 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__list/input.json +325 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__list/output.py +31 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__cancel/input.json +1645 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__cancel/output.py +22 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__checkpoints__list/input.json +383 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__checkpoints__list/output.py +31 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__create/input.json +1887 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__list/input.json +1714 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__list/output.py +23 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__list_events/input.json +330 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__list_events/output.py +25 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__pause/input.json +1645 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__pause/output.py +22 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__resume/input.json +1645 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__resume/output.py +22 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__retrieve/input.json +1645 -0
- package/__fixtures__/-2.complex.openai/fine_tuning__jobs__retrieve/output.py +22 -0
- package/__fixtures__/-2.complex.openai/images__edits__create/input.json +744 -0
- package/__fixtures__/-2.complex.openai/images__edits__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/images__generations__create/input.json +789 -0
- package/__fixtures__/-2.complex.openai/images__generations__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/images__variations__create/input.json +550 -0
- package/__fixtures__/-2.complex.openai/images__variations__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/models__delete/input.json +184 -0
- package/__fixtures__/-2.complex.openai/models__delete/output.py +16 -0
- package/__fixtures__/-2.complex.openai/models__list/input.json +221 -0
- package/__fixtures__/-2.complex.openai/models__list/output.py +15 -0
- package/__fixtures__/-2.complex.openai/models__retrieve/input.json +199 -0
- package/__fixtures__/-2.complex.openai/models__retrieve/output.py +16 -0
- package/__fixtures__/-2.complex.openai/moderations__create/input.json +831 -0
- package/__fixtures__/-2.complex.openai/moderations__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/projects__groups__roles__create/input.json +368 -0
- package/__fixtures__/-2.complex.openai/projects__groups__roles__create/output.py +30 -0
- package/__fixtures__/-2.complex.openai/projects__groups__roles__delete/input.json +214 -0
- package/__fixtures__/-2.complex.openai/projects__groups__roles__delete/output.py +32 -0
- package/__fixtures__/-2.complex.openai/projects__groups__roles__list/input.json +402 -0
- package/__fixtures__/-2.complex.openai/projects__groups__roles__list/output.py +33 -0
- package/__fixtures__/-2.complex.openai/projects__roles__create/input.json +289 -0
- package/__fixtures__/-2.complex.openai/projects__roles__create/output.py +24 -0
- package/__fixtures__/-2.complex.openai/projects__roles__delete/input.json +210 -0
- package/__fixtures__/-2.complex.openai/projects__roles__delete/output.py +24 -0
- package/__fixtures__/-2.complex.openai/projects__roles__list/input.json +344 -0
- package/__fixtures__/-2.complex.openai/projects__roles__list/output.py +25 -0
- package/__fixtures__/-2.complex.openai/projects__roles__update/input.json +300 -0
- package/__fixtures__/-2.complex.openai/projects__roles__update/output.py +26 -0
- package/__fixtures__/-2.complex.openai/projects__users__roles__create/input.json +615 -0
- package/__fixtures__/-2.complex.openai/projects__users__roles__create/output.py +30 -0
- package/__fixtures__/-2.complex.openai/projects__users__roles__delete/input.json +214 -0
- package/__fixtures__/-2.complex.openai/projects__users__roles__delete/output.py +32 -0
- package/__fixtures__/-2.complex.openai/projects__users__roles__list/input.json +402 -0
- package/__fixtures__/-2.complex.openai/projects__users__roles__list/output.py +33 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__accept/input.json +1768 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__accept/output.py +24 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__create/input.json +1790 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__hangup/input.json +147 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__hangup/output.py +22 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__refer/input.json +175 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__refer/output.py +22 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__reject/input.json +175 -0
- package/__fixtures__/-2.complex.openai/realtime__calls__reject/output.py +24 -0
- package/__fixtures__/-2.complex.openai/realtime__client_secrets__create/input.json +2407 -0
- package/__fixtures__/-2.complex.openai/realtime__client_secrets__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/realtime__sessions__create/input.json +1400 -0
- package/__fixtures__/-2.complex.openai/realtime__sessions__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/realtime__transcription_sessions__create/input.json +562 -0
- package/__fixtures__/-2.complex.openai/realtime__transcription_sessions__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/realtime__translations__client_secrets__create/input.json +498 -0
- package/__fixtures__/-2.complex.openai/realtime__translations__client_secrets__create/output.py +28 -0
- package/__fixtures__/-2.complex.openai/responses__cancel/input.json +9526 -0
- package/__fixtures__/-2.complex.openai/responses__cancel/output.py +16 -0
- package/__fixtures__/-2.complex.openai/responses__compact__create/input.json +8721 -0
- package/__fixtures__/-2.complex.openai/responses__compact__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/responses__create/input.json +9862 -0
- package/__fixtures__/-2.complex.openai/responses__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/responses__delete/input.json +194 -0
- package/__fixtures__/-2.complex.openai/responses__delete/output.py +16 -0
- package/__fixtures__/-2.complex.openai/responses__input_items__list/input.json +6686 -0
- package/__fixtures__/-2.complex.openai/responses__input_items__list/output.py +25 -0
- package/__fixtures__/-2.complex.openai/responses__input_tokens__count/input.json +7368 -0
- package/__fixtures__/-2.complex.openai/responses__input_tokens__count/output.py +22 -0
- package/__fixtures__/-2.complex.openai/responses__retrieve/input.json +9550 -0
- package/__fixtures__/-2.complex.openai/responses__retrieve/output.py +18 -0
- package/__fixtures__/-2.complex.openai/skills__content/input.json +152 -0
- package/__fixtures__/-2.complex.openai/skills__content/output.py +16 -0
- package/__fixtures__/-2.complex.openai/skills__create/input.json +258 -0
- package/__fixtures__/-2.complex.openai/skills__create/output.py +14 -0
- package/__fixtures__/-2.complex.openai/skills__delete/input.json +186 -0
- package/__fixtures__/-2.complex.openai/skills__delete/output.py +16 -0
- package/__fixtures__/-2.complex.openai/skills__list/input.json +323 -0
- package/__fixtures__/-2.complex.openai/skills__list/output.py +17 -0
- package/__fixtures__/-2.complex.openai/skills__retrieve/input.json +226 -0
- package/__fixtures__/-2.complex.openai/skills__retrieve/output.py +16 -0
- package/__fixtures__/-2.complex.openai/skills__update/input.json +251 -0
- package/__fixtures__/-2.complex.openai/skills__update/output.py +16 -0
- package/__fixtures__/-2.complex.openai/skills__versions__content/input.json +166 -0
- package/__fixtures__/-2.complex.openai/skills__versions__content/output.py +24 -0
- package/__fixtures__/-2.complex.openai/skills__versions__create/input.json +284 -0
- package/__fixtures__/-2.complex.openai/skills__versions__create/output.py +24 -0
- package/__fixtures__/-2.complex.openai/skills__versions__delete/input.json +209 -0
- package/__fixtures__/-2.complex.openai/skills__versions__delete/output.py +24 -0
- package/__fixtures__/-2.complex.openai/skills__versions__list/input.json +341 -0
- package/__fixtures__/-2.complex.openai/skills__versions__list/output.py +25 -0
- package/__fixtures__/-2.complex.openai/skills__versions__retrieve/input.json +240 -0
- package/__fixtures__/-2.complex.openai/skills__versions__retrieve/output.py +24 -0
- package/__fixtures__/-2.complex.openai/uploads__cancel/input.json +407 -0
- package/__fixtures__/-2.complex.openai/uploads__cancel/output.py +16 -0
- package/__fixtures__/-2.complex.openai/uploads__complete/input.json +443 -0
- package/__fixtures__/-2.complex.openai/uploads__complete/output.py +18 -0
- package/__fixtures__/-2.complex.openai/uploads__create/input.json +501 -0
- package/__fixtures__/-2.complex.openai/uploads__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/uploads__parts__create/input.json +229 -0
- package/__fixtures__/-2.complex.openai/uploads__parts__create/output.py +24 -0
- package/__fixtures__/-2.complex.openai/vector_stores__create/input.json +507 -0
- package/__fixtures__/-2.complex.openai/vector_stores__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/vector_stores__delete/input.json +184 -0
- package/__fixtures__/-2.complex.openai/vector_stores__delete/output.py +16 -0
- package/__fixtures__/-2.complex.openai/vector_stores__file_batches__cancel/input.json +300 -0
- package/__fixtures__/-2.complex.openai/vector_stores__file_batches__cancel/output.py +24 -0
- package/__fixtures__/-2.complex.openai/vector_stores__file_batches__create/input.json +314 -0
- package/__fixtures__/-2.complex.openai/vector_stores__file_batches__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/vector_stores__file_batches__list_files/input.json +571 -0
- package/__fixtures__/-2.complex.openai/vector_stores__file_batches__list_files/output.py +27 -0
- package/__fixtures__/-2.complex.openai/vector_stores__file_batches__retrieve/input.json +302 -0
- package/__fixtures__/-2.complex.openai/vector_stores__file_batches__retrieve/output.py +24 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__content/input.json +249 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__content/output.py +25 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__create/input.json +527 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__create/output.py +24 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__delete/input.json +198 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__delete/output.py +24 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__list/input.json +562 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__list/output.py +25 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__retrieve/input.json +432 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__retrieve/output.py +24 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__update/input.json +455 -0
- package/__fixtures__/-2.complex.openai/vector_stores__files__update/output.py +24 -0
- package/__fixtures__/-2.complex.openai/vector_stores__list/input.json +468 -0
- package/__fixtures__/-2.complex.openai/vector_stores__list/output.py +17 -0
- package/__fixtures__/-2.complex.openai/vector_stores__retrieve/input.json +366 -0
- package/__fixtures__/-2.complex.openai/vector_stores__retrieve/output.py +16 -0
- package/__fixtures__/-2.complex.openai/vector_stores__search/input.json +637 -0
- package/__fixtures__/-2.complex.openai/vector_stores__search/output.py +19 -0
- package/__fixtures__/-2.complex.openai/vector_stores__update/input.json +409 -0
- package/__fixtures__/-2.complex.openai/vector_stores__update/output.py +18 -0
- package/__fixtures__/-2.complex.openai/videos__characters__create/input.json +216 -0
- package/__fixtures__/-2.complex.openai/videos__characters__create/output.py +22 -0
- package/__fixtures__/-2.complex.openai/videos__characters__retrieve/input.json +193 -0
- package/__fixtures__/-2.complex.openai/videos__characters__retrieve/output.py +22 -0
- package/__fixtures__/-2.complex.openai/videos__create/input.json +465 -0
- package/__fixtures__/-2.complex.openai/videos__create/output.py +16 -0
- package/__fixtures__/-2.complex.openai/videos__delete/input.json +190 -0
- package/__fixtures__/-2.complex.openai/videos__delete/output.py +16 -0
- package/__fixtures__/-2.complex.openai/videos__download_content/input.json +181 -0
- package/__fixtures__/-2.complex.openai/videos__download_content/output.py +18 -0
- package/__fixtures__/-2.complex.openai/videos__edits__create/input.json +422 -0
- package/__fixtures__/-2.complex.openai/videos__edits__create/output.py +20 -0
- package/__fixtures__/-2.complex.openai/videos__extensions__create/input.json +446 -0
- package/__fixtures__/-2.complex.openai/videos__extensions__create/output.py +20 -0
- package/__fixtures__/-2.complex.openai/videos__list/input.json +477 -0
- package/__fixtures__/-2.complex.openai/videos__list/output.py +17 -0
- package/__fixtures__/-2.complex.openai/videos__remix/input.json +405 -0
- package/__fixtures__/-2.complex.openai/videos__remix/output.py +16 -0
- package/__fixtures__/-2.complex.openai/videos__retrieve/input.json +380 -0
- package/__fixtures__/-2.complex.openai/videos__retrieve/output.py +16 -0
- package/__fixtures__/1.basic/input.json +249 -0
- package/__fixtures__/1.basic/output/petstore/__init__.py +6 -0
- package/__fixtures__/1.basic/output/petstore/_client.py +21 -0
- package/__fixtures__/1.basic/output/petstore/_pagination.py +42 -0
- package/__fixtures__/1.basic/output/petstore/_transport.py +391 -0
- package/__fixtures__/1.basic/output/petstore/models.py +33 -0
- package/__fixtures__/1.basic/output/petstore/resources.py +25 -0
- package/__fixtures__/1.basic/output/pyproject.toml +12 -0
- package/__fixtures__/1.basic/output/tests/conftest.py +16 -0
- package/__fixtures__/1.basic/output/tests/test_pets.py +36 -0
- package/__fixtures__/1.basic/output/tests/utils.py +28 -0
- package/__fixtures__/2.wire/input.json +351 -0
- package/__fixtures__/2.wire/output/pyproject.toml +12 -0
- package/__fixtures__/2.wire/output/tests/conftest.py +16 -0
- package/__fixtures__/2.wire/output/tests/test_items.py +18 -0
- package/__fixtures__/2.wire/output/tests/test_tokens.py +17 -0
- package/__fixtures__/2.wire/output/tests/test_uploads.py +27 -0
- package/__fixtures__/2.wire/output/tests/utils.py +28 -0
- package/__fixtures__/2.wire/output/wire_service/__init__.py +6 -0
- package/__fixtures__/2.wire/output/wire_service/_client.py +23 -0
- package/__fixtures__/2.wire/output/wire_service/_pagination.py +42 -0
- package/__fixtures__/2.wire/output/wire_service/_transport.py +391 -0
- package/__fixtures__/2.wire/output/wire_service/models.py +44 -0
- package/__fixtures__/2.wire/output/wire_service/resources.py +38 -0
- package/__tests__/docs.test.ts +115 -0
- package/__tests__/e2e/harness.ts +79 -0
- package/__tests__/e2e/openai.test.ts +14 -0
- package/__tests__/e2e/publish.test.ts +19 -0
- package/__tests__/opensdk-python.test.ts +134 -0
- package/__tests__/utils.ts +117 -0
- package/biome.json +25 -0
- package/dist/index.cjs +1274 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +1246 -0
- package/dist/index.js.map +1 -0
- package/index.ts +1 -0
- package/package.json +30 -0
- package/src/emitter.ts +95 -0
- package/src/example-py.ts +60 -0
- package/src/index.ts +4 -0
- package/src/method.ts +13 -0
- package/src/naming.ts +45 -0
- package/src/project.ts +446 -0
- package/src/publish.ts +22 -0
- package/src/pytype.ts +86 -0
- package/src/runtime.ts +551 -0
- package/src/tests-py.ts +197 -0
- package/src/types.ts +8 -0
- package/tsconfig.json +18 -0
- package/tsup.config.ts +19 -0
- package/vitest.config.ts +8 -0
package/src/runtime.ts
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
import { type OpensdkSpecJson, type ResolvedSdkBehavior, sdkBehavior } from '@xyd-js/opensdk-core';
|
|
2
|
+
|
|
3
|
+
// The generated Python runtime, mirroring the Go emitter's vendored runtime at
|
|
4
|
+
// its minimum bar: a stdlib-only transport (urllib) with structured APIError,
|
|
5
|
+
// wire-correct query/form/multipart encoding, best-effort typed decode into
|
|
6
|
+
// the generated dataclasses, and (only when a method pages) generic
|
|
7
|
+
// CursorPage/Page containers.
|
|
8
|
+
//
|
|
9
|
+
// Runtime BEHAVIOR (retry loop, timeout, User-Agent, error kinds, request
|
|
10
|
+
// guard, idempotency) is policy-driven: every constant below is interpolated
|
|
11
|
+
// from the IR's `sdk` block via opensdk-core's `sdkBehavior(spec)`, so the
|
|
12
|
+
// Python and Go runtimes encode the same declared values instead of drifting.
|
|
13
|
+
|
|
14
|
+
// ---- Python literal helpers ------------------------------------------------
|
|
15
|
+
|
|
16
|
+
function pyStr(value: string): string {
|
|
17
|
+
return JSON.stringify(value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function pyBool(value: boolean): string {
|
|
21
|
+
return value ? 'True' : 'False';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** A float literal (Python): integers render as `60.0` so units read as seconds. */
|
|
25
|
+
function pyFloat(value: number): string {
|
|
26
|
+
return Number.isInteger(value) ? `${value}.0` : String(value);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function pyFrozenset(items: string[]): string {
|
|
30
|
+
return items.length ? `frozenset({${items.join(', ')}})` : 'frozenset()';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function pyStrDict(record: Record<string, string>): string {
|
|
34
|
+
const entries = Object.entries(record).map(([key, value]) => `${pyStr(key)}: ${pyStr(value)}`);
|
|
35
|
+
return `{${entries.join(', ')}}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ---- error-kind classes (sdk.errors) --------------------------------------
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The Python exception class for a policy error kind: `NotFound` ->
|
|
42
|
+
* `NotFoundError`; the canonical client kind `API` IS the `APIError` base.
|
|
43
|
+
*/
|
|
44
|
+
function errorClassName(kind: string): string {
|
|
45
|
+
if (kind === 'API') return 'APIError';
|
|
46
|
+
return kind.endsWith('Error') ? kind : `${kind}Error`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The generated `APIError` subclass names (sorted), for the package
|
|
51
|
+
* `__init__` exports. `APIError` itself is not included.
|
|
52
|
+
*/
|
|
53
|
+
export function errorClassNames(spec: OpensdkSpecJson): string[] {
|
|
54
|
+
const behavior = sdkBehavior(spec);
|
|
55
|
+
const names = new Set<string>();
|
|
56
|
+
for (const kind of Object.values(behavior.errors.statusCodeMap)) names.add(errorClassName(kind));
|
|
57
|
+
names.add(errorClassName(behavior.errors.serverErrorKind));
|
|
58
|
+
names.add(errorClassName(behavior.errors.clientErrorKind));
|
|
59
|
+
names.delete('APIError');
|
|
60
|
+
return [...names].sort();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The per-kind exception classes plus the status -> class dispatch table. */
|
|
64
|
+
function errorClassesBlock(behavior: ResolvedSdkBehavior): string {
|
|
65
|
+
const mapped = Object.entries(behavior.errors.statusCodeMap)
|
|
66
|
+
.map(([status, kind]) => [Number(status), kind] as const)
|
|
67
|
+
.sort((a, b) => a[0] - b[0]);
|
|
68
|
+
|
|
69
|
+
// Class -> its policy kind + the statuses it maps (several statuses may share a kind).
|
|
70
|
+
const byClass = new Map<string, { kind: string; statuses: number[] }>();
|
|
71
|
+
for (const [status, kind] of mapped) {
|
|
72
|
+
const cls = errorClassName(kind);
|
|
73
|
+
if (cls === 'APIError') continue;
|
|
74
|
+
const entry = byClass.get(cls) || { kind, statuses: [] };
|
|
75
|
+
entry.statuses.push(status);
|
|
76
|
+
byClass.set(cls, entry);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const serverClass = errorClassName(behavior.errors.serverErrorKind);
|
|
80
|
+
const clientClass = errorClassName(behavior.errors.clientErrorKind);
|
|
81
|
+
|
|
82
|
+
const errorClass = (cls: string, kind: string, doc: string): string =>
|
|
83
|
+
`class ${cls}(APIError):\n """${doc}"""\n\n kind = ${pyStr(kind)}`;
|
|
84
|
+
|
|
85
|
+
const classes: string[] = [];
|
|
86
|
+
for (const [cls, { kind, statuses }] of byClass) {
|
|
87
|
+
classes.push(errorClass(cls, kind, `The mapped error kind for HTTP ${statuses.join('/')} responses.`));
|
|
88
|
+
}
|
|
89
|
+
if (serverClass !== 'APIError' && !byClass.has(serverClass)) {
|
|
90
|
+
classes.push(errorClass(serverClass, behavior.errors.serverErrorKind, 'Catch-all for unmapped 5xx responses.'));
|
|
91
|
+
}
|
|
92
|
+
if (clientClass !== 'APIError' && !byClass.has(clientClass) && clientClass !== serverClass) {
|
|
93
|
+
classes.push(
|
|
94
|
+
errorClass(clientClass, behavior.errors.clientErrorKind, 'Catch-all for unmapped non-5xx error responses.'),
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const tableEntries = mapped.map(([status, kind]) => ` ${status}: ${errorClassName(kind)},`);
|
|
99
|
+
const table = tableEntries.length
|
|
100
|
+
? `_STATUS_TO_ERROR: dict[int, type] = {\n${tableEntries.join('\n')}\n}`
|
|
101
|
+
: '_STATUS_TO_ERROR: dict[int, type] = {}';
|
|
102
|
+
|
|
103
|
+
return `${classes.join('\n\n\n')}\n\n\n${table}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _error_for_status(status_code: int, headers: dict[str, str], body: bytes) -> APIError:
|
|
107
|
+
"""The policy-mapped exception: exact status map first, then the 5xx catch-all, then the client catch-all."""
|
|
108
|
+
cls = _STATUS_TO_ERROR.get(status_code)
|
|
109
|
+
if cls is None:
|
|
110
|
+
cls = ${serverClass} if status_code >= 500 else ${clientClass}
|
|
111
|
+
return cls(status_code, headers, body)`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ---- _transport.py (auth + behavior policies baked from the spec) ----------
|
|
115
|
+
|
|
116
|
+
export function transportPy(spec: OpensdkSpecJson, pkg: string, baseURL: string): string {
|
|
117
|
+
const behavior = sdkBehavior(spec);
|
|
118
|
+
|
|
119
|
+
const security = spec.security?.[0];
|
|
120
|
+
let authLine = '';
|
|
121
|
+
if (security) {
|
|
122
|
+
const name = security.name || '';
|
|
123
|
+
switch (security.kind) {
|
|
124
|
+
case 'apiKey-header':
|
|
125
|
+
authLine = ` request_headers[${JSON.stringify(name)}] = self.api_key\n`;
|
|
126
|
+
break;
|
|
127
|
+
case 'apiKey-query':
|
|
128
|
+
authLine = ` params[${JSON.stringify(name)}] = self.api_key\n`;
|
|
129
|
+
break;
|
|
130
|
+
default:
|
|
131
|
+
authLine = ` request_headers["Authorization"] = "Bearer " + self.api_key\n`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const authBlock = authLine ? ` if self.api_key:\n${authLine}` : '';
|
|
135
|
+
|
|
136
|
+
// sdk.userAgent: the identifier is assembled at generation time from the
|
|
137
|
+
// template; the runtime-version suffix and AI-agent sniff run at runtime.
|
|
138
|
+
const userAgent = behavior.userAgent.sdkIdentifierTemplate
|
|
139
|
+
.replace(/\{package\}/g, pkg)
|
|
140
|
+
.replace(/\{language\}/g, 'python')
|
|
141
|
+
.replace(/\{version\}/g, spec.info.version || '0.0.0');
|
|
142
|
+
|
|
143
|
+
// sdk.timeout: milliseconds in the IR, seconds on urlopen; 0 = no deadline.
|
|
144
|
+
const timeoutMs = behavior.timeout.defaultTimeoutMs;
|
|
145
|
+
const defaultTimeout = timeoutMs > 0 ? pyFloat(timeoutMs / 1000) : 'None';
|
|
146
|
+
const timeoutEnvVar = behavior.timeout.timeoutEnvVar;
|
|
147
|
+
|
|
148
|
+
const retry = behavior.retry;
|
|
149
|
+
const errorDocUrlTemplate = behavior.errors.errorDocUrlTemplate;
|
|
150
|
+
const includeRuntimeVersion = behavior.userAgent.includeRuntimeVersion;
|
|
151
|
+
|
|
152
|
+
const constants = [
|
|
153
|
+
`DEFAULT_BASE_URL = ${pyStr(baseURL)}`,
|
|
154
|
+
`USER_AGENT = ${pyStr(userAgent)}`,
|
|
155
|
+
`AI_AGENT_ENV_VARS = ${pyStrDict(behavior.userAgent.aiAgentEnvVars)}`,
|
|
156
|
+
`DEFAULT_TIMEOUT: Optional[float] = ${defaultTimeout}`,
|
|
157
|
+
...(timeoutEnvVar ? [`TIMEOUT_ENV_VAR = ${pyStr(timeoutEnvVar)}`] : []),
|
|
158
|
+
`MAX_RETRIES = ${retry.maxRetries}`,
|
|
159
|
+
`RETRYABLE_STATUS_CODES = ${pyFrozenset(retry.retryableStatusCodes.map(String))}`,
|
|
160
|
+
`RETRY_CONNECTION_ERRORS = ${pyBool(retry.retryConnectionErrors)}`,
|
|
161
|
+
`HONOR_RETRY_AFTER_HEADER = ${pyBool(retry.honorRetryAfterHeader)}`,
|
|
162
|
+
`BACKOFF_INITIAL_DELAY = ${pyFloat(retry.backoff.initialDelayMs / 1000)}`,
|
|
163
|
+
`BACKOFF_MAX_DELAY = ${pyFloat(retry.backoff.maxDelayMs / 1000)}`,
|
|
164
|
+
`BACKOFF_MULTIPLIER = ${pyFloat(retry.backoff.multiplier)}`,
|
|
165
|
+
`BACKOFF_JITTER = ${pyFloat(retry.backoff.jitter)}`,
|
|
166
|
+
`REQUEST_ID_HEADER = ${pyStr(behavior.telemetry.requestIdHeader)}`,
|
|
167
|
+
`IDEMPOTENCY_HEADER = ${pyStr(behavior.idempotency.headerName)}`,
|
|
168
|
+
...(errorDocUrlTemplate ? [`ERROR_DOC_URL_TEMPLATE = ${pyStr(errorDocUrlTemplate)}`] : []),
|
|
169
|
+
`GUARDED_OPTION_KEYS = ${pyFrozenset(behavior.requestGuard.optionKeys.map(pyStr))}`,
|
|
170
|
+
].join('\n');
|
|
171
|
+
|
|
172
|
+
// sdk.errors.errorDocUrlTemplate ({kind}/{status} placeholders) is appended
|
|
173
|
+
// to the error's string form only when the policy declares it.
|
|
174
|
+
const errorDocStr = errorDocUrlTemplate
|
|
175
|
+
? `
|
|
176
|
+
|
|
177
|
+
def __str__(self) -> str:
|
|
178
|
+
url = ERROR_DOC_URL_TEMPLATE.replace("{kind}", self.kind).replace("{status}", str(self.status_code))
|
|
179
|
+
return self.message + " (" + url + ")"`
|
|
180
|
+
: '';
|
|
181
|
+
|
|
182
|
+
const runtimeVersionLine = includeRuntimeVersion ? '\n ua += " python/" + platform.python_version()' : '';
|
|
183
|
+
|
|
184
|
+
return `from __future__ import annotations
|
|
185
|
+
|
|
186
|
+
import dataclasses
|
|
187
|
+
import datetime
|
|
188
|
+
import email.utils
|
|
189
|
+
import json
|
|
190
|
+
import os${includeRuntimeVersion ? '\nimport platform' : ''}
|
|
191
|
+
import random
|
|
192
|
+
import time
|
|
193
|
+
import typing
|
|
194
|
+
import urllib.error
|
|
195
|
+
import urllib.parse
|
|
196
|
+
import urllib.request
|
|
197
|
+
import uuid
|
|
198
|
+
from enum import Enum
|
|
199
|
+
from typing import Any, Optional
|
|
200
|
+
|
|
201
|
+
${constants}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class APIError(Exception):
|
|
205
|
+
"""A non-2xx API response: status code, headers, raw body, request id and a best-effort message."""
|
|
206
|
+
|
|
207
|
+
kind = "API"
|
|
208
|
+
|
|
209
|
+
def __init__(self, status_code: int, headers: dict[str, str], body: bytes) -> None:
|
|
210
|
+
self.status_code = status_code
|
|
211
|
+
self.headers = headers
|
|
212
|
+
self.body = body
|
|
213
|
+
self.request_id = _header(headers, REQUEST_ID_HEADER)
|
|
214
|
+
self.message = _error_message(body) or "HTTP " + str(status_code)
|
|
215
|
+
super().__init__(self.message)${errorDocStr}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
${errorClassesBlock(behavior)}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def _error_message(body: bytes) -> Optional[str]:
|
|
222
|
+
"""Best-effort message from a JSON error envelope ({"error": {"message": ...}} etc.)."""
|
|
223
|
+
try:
|
|
224
|
+
payload = json.loads(body.decode("utf-8"))
|
|
225
|
+
except Exception:
|
|
226
|
+
return None
|
|
227
|
+
if not isinstance(payload, dict):
|
|
228
|
+
return None
|
|
229
|
+
error = payload.get("error")
|
|
230
|
+
if isinstance(error, dict) and isinstance(error.get("message"), str):
|
|
231
|
+
return error["message"]
|
|
232
|
+
if isinstance(error, str):
|
|
233
|
+
return error
|
|
234
|
+
for key in ("message", "detail"):
|
|
235
|
+
if isinstance(payload.get(key), str):
|
|
236
|
+
return payload[key]
|
|
237
|
+
return None
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def _header(headers: dict[str, str], name: str) -> Optional[str]:
|
|
241
|
+
"""Case-insensitive header lookup."""
|
|
242
|
+
target = name.lower()
|
|
243
|
+
for key, value in headers.items():
|
|
244
|
+
if key.lower() == target:
|
|
245
|
+
return value
|
|
246
|
+
return None
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _user_agent() -> str:
|
|
250
|
+
"""The policy User-Agent: SDK identifier, plus an AI-agent slug when a known agent env var is set."""
|
|
251
|
+
ua = USER_AGENT${runtimeVersionLine}
|
|
252
|
+
for env_var, slug in AI_AGENT_ENV_VARS.items():
|
|
253
|
+
if os.environ.get(env_var):
|
|
254
|
+
ua += " agent/" + slug
|
|
255
|
+
break
|
|
256
|
+
return ua
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def _default_timeout() -> Optional[float]:
|
|
260
|
+
${
|
|
261
|
+
timeoutEnvVar
|
|
262
|
+
? ` """The policy default timeout in seconds; TIMEOUT_ENV_VAR (milliseconds) overrides it when set."""
|
|
263
|
+
raw = os.environ.get(TIMEOUT_ENV_VAR)
|
|
264
|
+
if raw:
|
|
265
|
+
try:
|
|
266
|
+
return float(raw) / 1000.0
|
|
267
|
+
except ValueError:
|
|
268
|
+
pass
|
|
269
|
+
return DEFAULT_TIMEOUT`
|
|
270
|
+
: ` """The policy default timeout in seconds (None = no deadline)."""
|
|
271
|
+
return DEFAULT_TIMEOUT`
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def _retry_delay(attempt: int, headers: Optional[dict[str, str]]) -> float:
|
|
276
|
+
"""Seconds to sleep before retry attempt (0-based): a Retry-After header
|
|
277
|
+
wins when honored; otherwise min(initial * multiplier**attempt, max) plus
|
|
278
|
+
proportional random jitter."""
|
|
279
|
+
if HONOR_RETRY_AFTER_HEADER and headers:
|
|
280
|
+
retry_after = _retry_after_seconds(headers)
|
|
281
|
+
if retry_after is not None:
|
|
282
|
+
return retry_after
|
|
283
|
+
delay = min(BACKOFF_INITIAL_DELAY * (BACKOFF_MULTIPLIER ** attempt), BACKOFF_MAX_DELAY)
|
|
284
|
+
return delay + delay * BACKOFF_JITTER * random.random()
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def _retry_after_seconds(headers: dict[str, str]) -> Optional[float]:
|
|
288
|
+
"""A Retry-After header as seconds: both the integer-seconds and the HTTP-date forms."""
|
|
289
|
+
value = _header(headers, "Retry-After")
|
|
290
|
+
if value is None:
|
|
291
|
+
return None
|
|
292
|
+
value = value.strip()
|
|
293
|
+
if value.isdigit():
|
|
294
|
+
return float(value)
|
|
295
|
+
try:
|
|
296
|
+
parsed = email.utils.parsedate_to_datetime(value)
|
|
297
|
+
except (TypeError, ValueError):
|
|
298
|
+
return None
|
|
299
|
+
if parsed is None:
|
|
300
|
+
return None
|
|
301
|
+
if parsed.tzinfo is None:
|
|
302
|
+
parsed = parsed.replace(tzinfo=datetime.timezone.utc)
|
|
303
|
+
return max(0.0, (parsed - datetime.datetime.now(datetime.timezone.utc)).total_seconds())
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def _guard_options(params: Optional[dict[str, Any]]) -> None:
|
|
307
|
+
"""Fail fast when a request-option key (api_key, max_retries, ...) is
|
|
308
|
+
misplaced into request params — a misplaced credential would otherwise be
|
|
309
|
+
sent on the wire and end up in provider logs."""
|
|
310
|
+
for key in params or ():
|
|
311
|
+
if key in GUARDED_OPTION_KEYS:
|
|
312
|
+
raise ValueError(
|
|
313
|
+
"request option " + repr(key) + " must be set on the client, not passed as a request parameter"
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def encode(value: Any) -> Any:
|
|
318
|
+
"""Wire-encode a request value: dataclasses -> dicts keyed by wire name
|
|
319
|
+
(None fields dropped), enums -> their values; lists/dicts recurse."""
|
|
320
|
+
if isinstance(value, Enum):
|
|
321
|
+
return encode(value.value)
|
|
322
|
+
if dataclasses.is_dataclass(value) and not isinstance(value, type):
|
|
323
|
+
out: dict[str, Any] = {}
|
|
324
|
+
for f in dataclasses.fields(value):
|
|
325
|
+
item = getattr(value, f.name)
|
|
326
|
+
if item is None:
|
|
327
|
+
continue
|
|
328
|
+
out[f.metadata.get("wire", f.name)] = encode(item)
|
|
329
|
+
return out
|
|
330
|
+
if isinstance(value, (list, tuple)):
|
|
331
|
+
return [encode(item) for item in value]
|
|
332
|
+
if isinstance(value, dict):
|
|
333
|
+
return {key: encode(item) for key, item in value.items()}
|
|
334
|
+
return value
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def decode(tp: Any, value: Any) -> Any:
|
|
338
|
+
"""Best-effort decode of parsed JSON into the generated models: dataclasses
|
|
339
|
+
are built field-by-field (honoring wire names), enums by value; unknown
|
|
340
|
+
shapes are returned as-is."""
|
|
341
|
+
if value is None or tp is None or tp is Any:
|
|
342
|
+
return value
|
|
343
|
+
origin = typing.get_origin(tp)
|
|
344
|
+
if origin is not None:
|
|
345
|
+
args = typing.get_args(tp)
|
|
346
|
+
if origin is list and isinstance(value, list):
|
|
347
|
+
item_tp = args[0] if args else Any
|
|
348
|
+
return [decode(item_tp, item) for item in value]
|
|
349
|
+
if origin is dict and isinstance(value, dict):
|
|
350
|
+
value_tp = args[1] if len(args) > 1 else Any
|
|
351
|
+
return {key: decode(value_tp, item) for key, item in value.items()}
|
|
352
|
+
if origin is typing.Union:
|
|
353
|
+
for arg in args:
|
|
354
|
+
if arg is type(None):
|
|
355
|
+
continue
|
|
356
|
+
try:
|
|
357
|
+
decoded = decode(arg, value)
|
|
358
|
+
except Exception:
|
|
359
|
+
continue
|
|
360
|
+
if decoded is not value:
|
|
361
|
+
return decoded
|
|
362
|
+
return value
|
|
363
|
+
return value
|
|
364
|
+
if isinstance(tp, type) and issubclass(tp, Enum):
|
|
365
|
+
try:
|
|
366
|
+
return tp(value)
|
|
367
|
+
except ValueError:
|
|
368
|
+
return value
|
|
369
|
+
if isinstance(tp, type) and dataclasses.is_dataclass(tp) and isinstance(value, dict):
|
|
370
|
+
try:
|
|
371
|
+
hints = typing.get_type_hints(tp)
|
|
372
|
+
except Exception:
|
|
373
|
+
hints = {}
|
|
374
|
+
kwargs: dict[str, Any] = {}
|
|
375
|
+
for f in dataclasses.fields(tp):
|
|
376
|
+
wire = f.metadata.get("wire", f.name)
|
|
377
|
+
if wire in value:
|
|
378
|
+
kwargs[f.name] = decode(hints.get(f.name, Any), value[wire])
|
|
379
|
+
elif f.default is dataclasses.MISSING and f.default_factory is dataclasses.MISSING:
|
|
380
|
+
kwargs[f.name] = None
|
|
381
|
+
return tp(**kwargs)
|
|
382
|
+
return value
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def join_csv(value: Optional[list]) -> Optional[str]:
|
|
386
|
+
"""Serialize an explode=false array parameter as one comma-joined value."""
|
|
387
|
+
if value is None:
|
|
388
|
+
return None
|
|
389
|
+
return ",".join(_text(encode(item)) for item in value)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def _text(value: Any) -> str:
|
|
393
|
+
if isinstance(value, bool):
|
|
394
|
+
return "true" if value else "false"
|
|
395
|
+
if isinstance(value, (dict, list)):
|
|
396
|
+
return json.dumps(value)
|
|
397
|
+
return str(value)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def _query_value(value: Any) -> Any:
|
|
401
|
+
encoded = encode(value)
|
|
402
|
+
if isinstance(encoded, list):
|
|
403
|
+
return [_text(item) for item in encoded]
|
|
404
|
+
return _text(encoded)
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def _multipart(payload: dict[str, Any]) -> tuple[bytes, str]:
|
|
408
|
+
"""Encode a multipart/form-data body (stdlib-only, manual boundary).
|
|
409
|
+
bytes / file-like values become file parts; lists become repeated parts."""
|
|
410
|
+
boundary = uuid.uuid4().hex
|
|
411
|
+
chunks: list[bytes] = []
|
|
412
|
+
for name, value in payload.items():
|
|
413
|
+
items = value if isinstance(value, list) else [value]
|
|
414
|
+
for item in items:
|
|
415
|
+
chunks.append(("--" + boundary + "\\r\\n").encode("utf-8"))
|
|
416
|
+
if isinstance(item, bytes) or hasattr(item, "read"):
|
|
417
|
+
content = item if isinstance(item, bytes) else item.read()
|
|
418
|
+
if isinstance(content, str):
|
|
419
|
+
content = content.encode("utf-8")
|
|
420
|
+
filename = str(getattr(item, "name", name)).replace("\\\\", "/").split("/")[-1] or name
|
|
421
|
+
disposition = 'Content-Disposition: form-data; name="' + name + '"; filename="' + filename + '"\\r\\n'
|
|
422
|
+
chunks.append(disposition.encode("utf-8"))
|
|
423
|
+
chunks.append(b"Content-Type: application/octet-stream\\r\\n\\r\\n")
|
|
424
|
+
chunks.append(content)
|
|
425
|
+
else:
|
|
426
|
+
chunks.append(('Content-Disposition: form-data; name="' + name + '"\\r\\n\\r\\n').encode("utf-8"))
|
|
427
|
+
chunks.append(_text(item).encode("utf-8"))
|
|
428
|
+
chunks.append(b"\\r\\n")
|
|
429
|
+
chunks.append(("--" + boundary + "--\\r\\n").encode("utf-8"))
|
|
430
|
+
return b"".join(chunks), "multipart/form-data; boundary=" + boundary
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
class Transport:
|
|
434
|
+
def __init__(
|
|
435
|
+
self,
|
|
436
|
+
base_url: Optional[str] = None,
|
|
437
|
+
api_key: Optional[str] = None,
|
|
438
|
+
timeout: Optional[float] = None,
|
|
439
|
+
) -> None:
|
|
440
|
+
self.base_url = (base_url or DEFAULT_BASE_URL).rstrip("/")
|
|
441
|
+
self.api_key = api_key
|
|
442
|
+
self.timeout = timeout if timeout is not None else _default_timeout()
|
|
443
|
+
self.user_agent = _user_agent()
|
|
444
|
+
|
|
445
|
+
def request(
|
|
446
|
+
self,
|
|
447
|
+
method: str,
|
|
448
|
+
path: str,
|
|
449
|
+
query: Optional[dict[str, Any]] = None,
|
|
450
|
+
body: Optional[dict[str, Any]] = None,
|
|
451
|
+
headers: Optional[dict[str, Any]] = None,
|
|
452
|
+
encoding: str = "json",
|
|
453
|
+
raw: bool = False,
|
|
454
|
+
idempotency: bool = False,
|
|
455
|
+
) -> Any:
|
|
456
|
+
_guard_options(query)
|
|
457
|
+
_guard_options(body)
|
|
458
|
+
url = self.base_url + path
|
|
459
|
+
params = {k: _query_value(v) for k, v in (query or {}).items() if v is not None}
|
|
460
|
+
request_headers: dict[str, str] = {k: _text(v) for k, v in (headers or {}).items() if v is not None}
|
|
461
|
+
request_headers.setdefault("User-Agent", self.user_agent)
|
|
462
|
+
data = None
|
|
463
|
+
if body is not None:
|
|
464
|
+
payload = {k: encode(v) for k, v in body.items() if v is not None}
|
|
465
|
+
if encoding == "multipart":
|
|
466
|
+
data, content_type = _multipart(payload)
|
|
467
|
+
request_headers["Content-Type"] = content_type
|
|
468
|
+
elif encoding == "form":
|
|
469
|
+
data = urllib.parse.urlencode(payload, doseq=True).encode("utf-8")
|
|
470
|
+
request_headers["Content-Type"] = "application/x-www-form-urlencoded"
|
|
471
|
+
else:
|
|
472
|
+
data = json.dumps(payload).encode("utf-8")
|
|
473
|
+
request_headers["Content-Type"] = "application/json"
|
|
474
|
+
${authBlock} if idempotency:
|
|
475
|
+
# One key per logical call, generated before the retry loop so every
|
|
476
|
+
# retry of this request carries the SAME idempotency key.
|
|
477
|
+
request_headers.setdefault(IDEMPOTENCY_HEADER, str(uuid.uuid4()))
|
|
478
|
+
if params:
|
|
479
|
+
url += "?" + urllib.parse.urlencode(params, doseq=True)
|
|
480
|
+
attempt = 0
|
|
481
|
+
while True:
|
|
482
|
+
request = urllib.request.Request(url, data=data, method=method, headers=request_headers)
|
|
483
|
+
try:
|
|
484
|
+
with urllib.request.urlopen(request, timeout=self.timeout) as response:
|
|
485
|
+
content = response.read()
|
|
486
|
+
except urllib.error.HTTPError as error:
|
|
487
|
+
error_headers = dict(error.headers.items())
|
|
488
|
+
error_body = error.read()
|
|
489
|
+
if attempt < MAX_RETRIES and error.code in RETRYABLE_STATUS_CODES:
|
|
490
|
+
time.sleep(_retry_delay(attempt, error_headers))
|
|
491
|
+
attempt += 1
|
|
492
|
+
continue
|
|
493
|
+
raise _error_for_status(error.code, error_headers, error_body) from None
|
|
494
|
+
except OSError:
|
|
495
|
+
# Connection/timeout errors (URLError, reset, DNS failure, socket timeout).
|
|
496
|
+
if RETRY_CONNECTION_ERRORS and attempt < MAX_RETRIES:
|
|
497
|
+
time.sleep(_retry_delay(attempt, None))
|
|
498
|
+
attempt += 1
|
|
499
|
+
continue
|
|
500
|
+
raise
|
|
501
|
+
if raw:
|
|
502
|
+
return content
|
|
503
|
+
return json.loads(content.decode("utf-8")) if content else None
|
|
504
|
+
`;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// ---- _pagination.py (only emitted when some method returns a page) -------
|
|
508
|
+
|
|
509
|
+
export function paginationPy(): string {
|
|
510
|
+
return `from __future__ import annotations
|
|
511
|
+
|
|
512
|
+
from dataclasses import dataclass, field
|
|
513
|
+
from typing import Any, Generic, Iterator, TypeVar
|
|
514
|
+
|
|
515
|
+
from ._transport import decode
|
|
516
|
+
|
|
517
|
+
T = TypeVar("T")
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
@dataclass
|
|
521
|
+
class CursorPage(Generic[T]):
|
|
522
|
+
"""One page of a cursor-paginated list: \`data\` plus a \`has_more\` marker."""
|
|
523
|
+
|
|
524
|
+
data: list[T] = field(default_factory=list)
|
|
525
|
+
has_more: bool = False
|
|
526
|
+
|
|
527
|
+
def __iter__(self) -> Iterator[T]:
|
|
528
|
+
return iter(self.data)
|
|
529
|
+
|
|
530
|
+
@classmethod
|
|
531
|
+
def from_response(cls, item_type: Any, raw: Any) -> CursorPage[T]:
|
|
532
|
+
payload = raw if isinstance(raw, dict) else {}
|
|
533
|
+
data = [decode(item_type, item) for item in payload.get("data") or []]
|
|
534
|
+
return cls(data=data, has_more=bool(payload.get("has_more") or False))
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
@dataclass
|
|
538
|
+
class Page(Generic[T]):
|
|
539
|
+
"""One page of a marker-less list: the whole collection in one \`data\` envelope."""
|
|
540
|
+
|
|
541
|
+
data: list[T] = field(default_factory=list)
|
|
542
|
+
|
|
543
|
+
def __iter__(self) -> Iterator[T]:
|
|
544
|
+
return iter(self.data)
|
|
545
|
+
|
|
546
|
+
@classmethod
|
|
547
|
+
def from_response(cls, item_type: Any, raw: Any) -> Page[T]:
|
|
548
|
+
payload = raw if isinstance(raw, dict) else {}
|
|
549
|
+
return cls(data=[decode(item_type, item) for item in payload.get("data") or []])
|
|
550
|
+
`;
|
|
551
|
+
}
|