@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
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
# Code generated by opensdk. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import dataclasses
|
|
6
|
+
import datetime
|
|
7
|
+
import email.utils
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import random
|
|
11
|
+
import time
|
|
12
|
+
import typing
|
|
13
|
+
import urllib.error
|
|
14
|
+
import urllib.parse
|
|
15
|
+
import urllib.request
|
|
16
|
+
import uuid
|
|
17
|
+
from enum import Enum
|
|
18
|
+
from typing import Any, Optional
|
|
19
|
+
|
|
20
|
+
DEFAULT_BASE_URL = "https://api.wire.test/v1"
|
|
21
|
+
USER_AGENT = "wire_service-python/0.3.0"
|
|
22
|
+
AI_AGENT_ENV_VARS = {"CLAUDE_CODE": "claude-code", "CURSOR_AGENT": "cursor", "CLINE_ACTIVE": "cline", "WINDSURF_ACTIVE": "windsurf", "COPILOT_AGENT": "copilot"}
|
|
23
|
+
DEFAULT_TIMEOUT: Optional[float] = 60.0
|
|
24
|
+
MAX_RETRIES = 2
|
|
25
|
+
RETRYABLE_STATUS_CODES = frozenset({408, 429, 500, 502, 503, 504})
|
|
26
|
+
RETRY_CONNECTION_ERRORS = True
|
|
27
|
+
HONOR_RETRY_AFTER_HEADER = True
|
|
28
|
+
BACKOFF_INITIAL_DELAY = 0.5
|
|
29
|
+
BACKOFF_MAX_DELAY = 8.0
|
|
30
|
+
BACKOFF_MULTIPLIER = 2.0
|
|
31
|
+
BACKOFF_JITTER = 0.25
|
|
32
|
+
REQUEST_ID_HEADER = "X-Request-ID"
|
|
33
|
+
IDEMPOTENCY_HEADER = "Idempotency-Key"
|
|
34
|
+
GUARDED_OPTION_KEYS = frozenset({"api_key", "apiKey", "idempotency_key", "idempotencyKey", "extra_headers", "extraHeaders", "max_retries", "maxRetries", "base_url", "baseUrl", "timeout"})
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class APIError(Exception):
|
|
38
|
+
"""A non-2xx API response: status code, headers, raw body, request id and a best-effort message."""
|
|
39
|
+
|
|
40
|
+
kind = "API"
|
|
41
|
+
|
|
42
|
+
def __init__(self, status_code: int, headers: dict[str, str], body: bytes) -> None:
|
|
43
|
+
self.status_code = status_code
|
|
44
|
+
self.headers = headers
|
|
45
|
+
self.body = body
|
|
46
|
+
self.request_id = _header(headers, REQUEST_ID_HEADER)
|
|
47
|
+
self.message = _error_message(body) or "HTTP " + str(status_code)
|
|
48
|
+
super().__init__(self.message)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class BadRequestError(APIError):
|
|
52
|
+
"""The mapped error kind for HTTP 400 responses."""
|
|
53
|
+
|
|
54
|
+
kind = "BadRequest"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class UnauthorizedError(APIError):
|
|
58
|
+
"""The mapped error kind for HTTP 401 responses."""
|
|
59
|
+
|
|
60
|
+
kind = "Unauthorized"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class PermissionDeniedError(APIError):
|
|
64
|
+
"""The mapped error kind for HTTP 403 responses."""
|
|
65
|
+
|
|
66
|
+
kind = "PermissionDenied"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class NotFoundError(APIError):
|
|
70
|
+
"""The mapped error kind for HTTP 404 responses."""
|
|
71
|
+
|
|
72
|
+
kind = "NotFound"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class ConflictError(APIError):
|
|
76
|
+
"""The mapped error kind for HTTP 409 responses."""
|
|
77
|
+
|
|
78
|
+
kind = "Conflict"
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class UnprocessableEntityError(APIError):
|
|
82
|
+
"""The mapped error kind for HTTP 422 responses."""
|
|
83
|
+
|
|
84
|
+
kind = "UnprocessableEntity"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class RateLimitedError(APIError):
|
|
88
|
+
"""The mapped error kind for HTTP 429 responses."""
|
|
89
|
+
|
|
90
|
+
kind = "RateLimited"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class InternalError(APIError):
|
|
94
|
+
"""Catch-all for unmapped 5xx responses."""
|
|
95
|
+
|
|
96
|
+
kind = "Internal"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
_STATUS_TO_ERROR: dict[int, type] = {
|
|
100
|
+
400: BadRequestError,
|
|
101
|
+
401: UnauthorizedError,
|
|
102
|
+
403: PermissionDeniedError,
|
|
103
|
+
404: NotFoundError,
|
|
104
|
+
409: ConflictError,
|
|
105
|
+
422: UnprocessableEntityError,
|
|
106
|
+
429: RateLimitedError,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _error_for_status(status_code: int, headers: dict[str, str], body: bytes) -> APIError:
|
|
111
|
+
"""The policy-mapped exception: exact status map first, then the 5xx catch-all, then the client catch-all."""
|
|
112
|
+
cls = _STATUS_TO_ERROR.get(status_code)
|
|
113
|
+
if cls is None:
|
|
114
|
+
cls = InternalError if status_code >= 500 else APIError
|
|
115
|
+
return cls(status_code, headers, body)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _error_message(body: bytes) -> Optional[str]:
|
|
119
|
+
"""Best-effort message from a JSON error envelope ({"error": {"message": ...}} etc.)."""
|
|
120
|
+
try:
|
|
121
|
+
payload = json.loads(body.decode("utf-8"))
|
|
122
|
+
except Exception:
|
|
123
|
+
return None
|
|
124
|
+
if not isinstance(payload, dict):
|
|
125
|
+
return None
|
|
126
|
+
error = payload.get("error")
|
|
127
|
+
if isinstance(error, dict) and isinstance(error.get("message"), str):
|
|
128
|
+
return error["message"]
|
|
129
|
+
if isinstance(error, str):
|
|
130
|
+
return error
|
|
131
|
+
for key in ("message", "detail"):
|
|
132
|
+
if isinstance(payload.get(key), str):
|
|
133
|
+
return payload[key]
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _header(headers: dict[str, str], name: str) -> Optional[str]:
|
|
138
|
+
"""Case-insensitive header lookup."""
|
|
139
|
+
target = name.lower()
|
|
140
|
+
for key, value in headers.items():
|
|
141
|
+
if key.lower() == target:
|
|
142
|
+
return value
|
|
143
|
+
return None
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _user_agent() -> str:
|
|
147
|
+
"""The policy User-Agent: SDK identifier, plus an AI-agent slug when a known agent env var is set."""
|
|
148
|
+
ua = USER_AGENT
|
|
149
|
+
for env_var, slug in AI_AGENT_ENV_VARS.items():
|
|
150
|
+
if os.environ.get(env_var):
|
|
151
|
+
ua += " agent/" + slug
|
|
152
|
+
break
|
|
153
|
+
return ua
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _default_timeout() -> Optional[float]:
|
|
157
|
+
"""The policy default timeout in seconds (None = no deadline)."""
|
|
158
|
+
return DEFAULT_TIMEOUT
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _retry_delay(attempt: int, headers: Optional[dict[str, str]]) -> float:
|
|
162
|
+
"""Seconds to sleep before retry attempt (0-based): a Retry-After header
|
|
163
|
+
wins when honored; otherwise min(initial * multiplier**attempt, max) plus
|
|
164
|
+
proportional random jitter."""
|
|
165
|
+
if HONOR_RETRY_AFTER_HEADER and headers:
|
|
166
|
+
retry_after = _retry_after_seconds(headers)
|
|
167
|
+
if retry_after is not None:
|
|
168
|
+
return retry_after
|
|
169
|
+
delay = min(BACKOFF_INITIAL_DELAY * (BACKOFF_MULTIPLIER ** attempt), BACKOFF_MAX_DELAY)
|
|
170
|
+
return delay + delay * BACKOFF_JITTER * random.random()
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _retry_after_seconds(headers: dict[str, str]) -> Optional[float]:
|
|
174
|
+
"""A Retry-After header as seconds: both the integer-seconds and the HTTP-date forms."""
|
|
175
|
+
value = _header(headers, "Retry-After")
|
|
176
|
+
if value is None:
|
|
177
|
+
return None
|
|
178
|
+
value = value.strip()
|
|
179
|
+
if value.isdigit():
|
|
180
|
+
return float(value)
|
|
181
|
+
try:
|
|
182
|
+
parsed = email.utils.parsedate_to_datetime(value)
|
|
183
|
+
except (TypeError, ValueError):
|
|
184
|
+
return None
|
|
185
|
+
if parsed is None:
|
|
186
|
+
return None
|
|
187
|
+
if parsed.tzinfo is None:
|
|
188
|
+
parsed = parsed.replace(tzinfo=datetime.timezone.utc)
|
|
189
|
+
return max(0.0, (parsed - datetime.datetime.now(datetime.timezone.utc)).total_seconds())
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _guard_options(params: Optional[dict[str, Any]]) -> None:
|
|
193
|
+
"""Fail fast when a request-option key (api_key, max_retries, ...) is
|
|
194
|
+
misplaced into request params — a misplaced credential would otherwise be
|
|
195
|
+
sent on the wire and end up in provider logs."""
|
|
196
|
+
for key in params or ():
|
|
197
|
+
if key in GUARDED_OPTION_KEYS:
|
|
198
|
+
raise ValueError(
|
|
199
|
+
"request option " + repr(key) + " must be set on the client, not passed as a request parameter"
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def encode(value: Any) -> Any:
|
|
204
|
+
"""Wire-encode a request value: dataclasses -> dicts keyed by wire name
|
|
205
|
+
(None fields dropped), enums -> their values; lists/dicts recurse."""
|
|
206
|
+
if isinstance(value, Enum):
|
|
207
|
+
return encode(value.value)
|
|
208
|
+
if dataclasses.is_dataclass(value) and not isinstance(value, type):
|
|
209
|
+
out: dict[str, Any] = {}
|
|
210
|
+
for f in dataclasses.fields(value):
|
|
211
|
+
item = getattr(value, f.name)
|
|
212
|
+
if item is None:
|
|
213
|
+
continue
|
|
214
|
+
out[f.metadata.get("wire", f.name)] = encode(item)
|
|
215
|
+
return out
|
|
216
|
+
if isinstance(value, (list, tuple)):
|
|
217
|
+
return [encode(item) for item in value]
|
|
218
|
+
if isinstance(value, dict):
|
|
219
|
+
return {key: encode(item) for key, item in value.items()}
|
|
220
|
+
return value
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def decode(tp: Any, value: Any) -> Any:
|
|
224
|
+
"""Best-effort decode of parsed JSON into the generated models: dataclasses
|
|
225
|
+
are built field-by-field (honoring wire names), enums by value; unknown
|
|
226
|
+
shapes are returned as-is."""
|
|
227
|
+
if value is None or tp is None or tp is Any:
|
|
228
|
+
return value
|
|
229
|
+
origin = typing.get_origin(tp)
|
|
230
|
+
if origin is not None:
|
|
231
|
+
args = typing.get_args(tp)
|
|
232
|
+
if origin is list and isinstance(value, list):
|
|
233
|
+
item_tp = args[0] if args else Any
|
|
234
|
+
return [decode(item_tp, item) for item in value]
|
|
235
|
+
if origin is dict and isinstance(value, dict):
|
|
236
|
+
value_tp = args[1] if len(args) > 1 else Any
|
|
237
|
+
return {key: decode(value_tp, item) for key, item in value.items()}
|
|
238
|
+
if origin is typing.Union:
|
|
239
|
+
for arg in args:
|
|
240
|
+
if arg is type(None):
|
|
241
|
+
continue
|
|
242
|
+
try:
|
|
243
|
+
decoded = decode(arg, value)
|
|
244
|
+
except Exception:
|
|
245
|
+
continue
|
|
246
|
+
if decoded is not value:
|
|
247
|
+
return decoded
|
|
248
|
+
return value
|
|
249
|
+
return value
|
|
250
|
+
if isinstance(tp, type) and issubclass(tp, Enum):
|
|
251
|
+
try:
|
|
252
|
+
return tp(value)
|
|
253
|
+
except ValueError:
|
|
254
|
+
return value
|
|
255
|
+
if isinstance(tp, type) and dataclasses.is_dataclass(tp) and isinstance(value, dict):
|
|
256
|
+
try:
|
|
257
|
+
hints = typing.get_type_hints(tp)
|
|
258
|
+
except Exception:
|
|
259
|
+
hints = {}
|
|
260
|
+
kwargs: dict[str, Any] = {}
|
|
261
|
+
for f in dataclasses.fields(tp):
|
|
262
|
+
wire = f.metadata.get("wire", f.name)
|
|
263
|
+
if wire in value:
|
|
264
|
+
kwargs[f.name] = decode(hints.get(f.name, Any), value[wire])
|
|
265
|
+
elif f.default is dataclasses.MISSING and f.default_factory is dataclasses.MISSING:
|
|
266
|
+
kwargs[f.name] = None
|
|
267
|
+
return tp(**kwargs)
|
|
268
|
+
return value
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def join_csv(value: Optional[list]) -> Optional[str]:
|
|
272
|
+
"""Serialize an explode=false array parameter as one comma-joined value."""
|
|
273
|
+
if value is None:
|
|
274
|
+
return None
|
|
275
|
+
return ",".join(_text(encode(item)) for item in value)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _text(value: Any) -> str:
|
|
279
|
+
if isinstance(value, bool):
|
|
280
|
+
return "true" if value else "false"
|
|
281
|
+
if isinstance(value, (dict, list)):
|
|
282
|
+
return json.dumps(value)
|
|
283
|
+
return str(value)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def _query_value(value: Any) -> Any:
|
|
287
|
+
encoded = encode(value)
|
|
288
|
+
if isinstance(encoded, list):
|
|
289
|
+
return [_text(item) for item in encoded]
|
|
290
|
+
return _text(encoded)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def _multipart(payload: dict[str, Any]) -> tuple[bytes, str]:
|
|
294
|
+
"""Encode a multipart/form-data body (stdlib-only, manual boundary).
|
|
295
|
+
bytes / file-like values become file parts; lists become repeated parts."""
|
|
296
|
+
boundary = uuid.uuid4().hex
|
|
297
|
+
chunks: list[bytes] = []
|
|
298
|
+
for name, value in payload.items():
|
|
299
|
+
items = value if isinstance(value, list) else [value]
|
|
300
|
+
for item in items:
|
|
301
|
+
chunks.append(("--" + boundary + "\r\n").encode("utf-8"))
|
|
302
|
+
if isinstance(item, bytes) or hasattr(item, "read"):
|
|
303
|
+
content = item if isinstance(item, bytes) else item.read()
|
|
304
|
+
if isinstance(content, str):
|
|
305
|
+
content = content.encode("utf-8")
|
|
306
|
+
filename = str(getattr(item, "name", name)).replace("\\", "/").split("/")[-1] or name
|
|
307
|
+
disposition = 'Content-Disposition: form-data; name="' + name + '"; filename="' + filename + '"\r\n'
|
|
308
|
+
chunks.append(disposition.encode("utf-8"))
|
|
309
|
+
chunks.append(b"Content-Type: application/octet-stream\r\n\r\n")
|
|
310
|
+
chunks.append(content)
|
|
311
|
+
else:
|
|
312
|
+
chunks.append(('Content-Disposition: form-data; name="' + name + '"\r\n\r\n').encode("utf-8"))
|
|
313
|
+
chunks.append(_text(item).encode("utf-8"))
|
|
314
|
+
chunks.append(b"\r\n")
|
|
315
|
+
chunks.append(("--" + boundary + "--\r\n").encode("utf-8"))
|
|
316
|
+
return b"".join(chunks), "multipart/form-data; boundary=" + boundary
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
class Transport:
|
|
320
|
+
def __init__(
|
|
321
|
+
self,
|
|
322
|
+
base_url: Optional[str] = None,
|
|
323
|
+
api_key: Optional[str] = None,
|
|
324
|
+
timeout: Optional[float] = None,
|
|
325
|
+
) -> None:
|
|
326
|
+
self.base_url = (base_url or DEFAULT_BASE_URL).rstrip("/")
|
|
327
|
+
self.api_key = api_key
|
|
328
|
+
self.timeout = timeout if timeout is not None else _default_timeout()
|
|
329
|
+
self.user_agent = _user_agent()
|
|
330
|
+
|
|
331
|
+
def request(
|
|
332
|
+
self,
|
|
333
|
+
method: str,
|
|
334
|
+
path: str,
|
|
335
|
+
query: Optional[dict[str, Any]] = None,
|
|
336
|
+
body: Optional[dict[str, Any]] = None,
|
|
337
|
+
headers: Optional[dict[str, Any]] = None,
|
|
338
|
+
encoding: str = "json",
|
|
339
|
+
raw: bool = False,
|
|
340
|
+
idempotency: bool = False,
|
|
341
|
+
) -> Any:
|
|
342
|
+
_guard_options(query)
|
|
343
|
+
_guard_options(body)
|
|
344
|
+
url = self.base_url + path
|
|
345
|
+
params = {k: _query_value(v) for k, v in (query or {}).items() if v is not None}
|
|
346
|
+
request_headers: dict[str, str] = {k: _text(v) for k, v in (headers or {}).items() if v is not None}
|
|
347
|
+
request_headers.setdefault("User-Agent", self.user_agent)
|
|
348
|
+
data = None
|
|
349
|
+
if body is not None:
|
|
350
|
+
payload = {k: encode(v) for k, v in body.items() if v is not None}
|
|
351
|
+
if encoding == "multipart":
|
|
352
|
+
data, content_type = _multipart(payload)
|
|
353
|
+
request_headers["Content-Type"] = content_type
|
|
354
|
+
elif encoding == "form":
|
|
355
|
+
data = urllib.parse.urlencode(payload, doseq=True).encode("utf-8")
|
|
356
|
+
request_headers["Content-Type"] = "application/x-www-form-urlencoded"
|
|
357
|
+
else:
|
|
358
|
+
data = json.dumps(payload).encode("utf-8")
|
|
359
|
+
request_headers["Content-Type"] = "application/json"
|
|
360
|
+
if self.api_key:
|
|
361
|
+
request_headers["X-Api-Key"] = self.api_key
|
|
362
|
+
if idempotency:
|
|
363
|
+
# One key per logical call, generated before the retry loop so every
|
|
364
|
+
# retry of this request carries the SAME idempotency key.
|
|
365
|
+
request_headers.setdefault(IDEMPOTENCY_HEADER, str(uuid.uuid4()))
|
|
366
|
+
if params:
|
|
367
|
+
url += "?" + urllib.parse.urlencode(params, doseq=True)
|
|
368
|
+
attempt = 0
|
|
369
|
+
while True:
|
|
370
|
+
request = urllib.request.Request(url, data=data, method=method, headers=request_headers)
|
|
371
|
+
try:
|
|
372
|
+
with urllib.request.urlopen(request, timeout=self.timeout) as response:
|
|
373
|
+
content = response.read()
|
|
374
|
+
except urllib.error.HTTPError as error:
|
|
375
|
+
error_headers = dict(error.headers.items())
|
|
376
|
+
error_body = error.read()
|
|
377
|
+
if attempt < MAX_RETRIES and error.code in RETRYABLE_STATUS_CODES:
|
|
378
|
+
time.sleep(_retry_delay(attempt, error_headers))
|
|
379
|
+
attempt += 1
|
|
380
|
+
continue
|
|
381
|
+
raise _error_for_status(error.code, error_headers, error_body) from None
|
|
382
|
+
except OSError:
|
|
383
|
+
# Connection/timeout errors (URLError, reset, DNS failure, socket timeout).
|
|
384
|
+
if RETRY_CONNECTION_ERRORS and attempt < MAX_RETRIES:
|
|
385
|
+
time.sleep(_retry_delay(attempt, None))
|
|
386
|
+
attempt += 1
|
|
387
|
+
continue
|
|
388
|
+
raise
|
|
389
|
+
if raw:
|
|
390
|
+
return content
|
|
391
|
+
return json.loads(content.decode("utf-8")) if content else None
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Code generated by opensdk. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Any, BinaryIO, Optional, Union
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class Item:
|
|
12
|
+
id: str
|
|
13
|
+
label: str
|
|
14
|
+
kind: Optional[ItemKind] = None
|
|
15
|
+
meta_data: Optional[dict[str, Any]] = field(default=None, metadata={"wire": "metaData"})
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ItemKind(str, Enum):
|
|
19
|
+
STANDARD = "standard"
|
|
20
|
+
PREMIUM = "premium"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class CreateUploadRequest:
|
|
25
|
+
file: Union[bytes, BinaryIO]
|
|
26
|
+
label: Optional[str] = None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class UploadResult:
|
|
31
|
+
id: str
|
|
32
|
+
status: Optional[str] = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class CreateTokenRequest:
|
|
37
|
+
grant_type: str
|
|
38
|
+
scope: Optional[str] = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class Token:
|
|
43
|
+
access_token: str
|
|
44
|
+
expires_in: Optional[int] = None
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Code generated by opensdk. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import BinaryIO, Optional, Union
|
|
6
|
+
|
|
7
|
+
from ._pagination import CursorPage
|
|
8
|
+
from ._transport import Transport, decode, join_csv
|
|
9
|
+
from .models import * # noqa: F401,F403
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ItemsResource:
|
|
13
|
+
def __init__(self, transport: Transport) -> None:
|
|
14
|
+
self._transport = transport
|
|
15
|
+
|
|
16
|
+
def list(self, *, ids: Optional[list[str]] = None, tags: Optional[list[str]] = None, after: Optional[str] = None, limit: Optional[int] = None, workspace: Optional[str] = None) -> CursorPage[Item]:
|
|
17
|
+
return CursorPage.from_response(Item, self._transport.request("GET", "/items", query={"ids[]": ids, "tags": join_csv(tags), "after": after, "limit": limit}, headers={"X-Workspace": workspace}))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class UploadsResource:
|
|
21
|
+
def __init__(self, transport: Transport) -> None:
|
|
22
|
+
self._transport = transport
|
|
23
|
+
|
|
24
|
+
def create(self, *, file: Union[bytes, BinaryIO], label: Optional[str] = None) -> UploadResult:
|
|
25
|
+
return decode(UploadResult, self._transport.request("POST", "/uploads", body={"file": file, "label": label}, encoding="multipart"))
|
|
26
|
+
|
|
27
|
+
def download(self, upload_id: str) -> bytes:
|
|
28
|
+
if not upload_id:
|
|
29
|
+
raise ValueError(f"Expected a non-empty value for `upload_id` but received {upload_id!r}")
|
|
30
|
+
return self._transport.request("GET", f"/uploads/{upload_id}/content", headers={"Accept": "application/octet-stream"}, raw=True)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TokensResource:
|
|
34
|
+
def __init__(self, transport: Transport) -> None:
|
|
35
|
+
self._transport = transport
|
|
36
|
+
|
|
37
|
+
def create(self, *, grant_type: str, scope: Optional[str] = None) -> Token:
|
|
38
|
+
return decode(Token, self._transport.request("POST", "/token", body={"grant_type": grant_type, "scope": scope}, encoding="form", idempotency=True))
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
import yaml from 'js-yaml';
|
|
7
|
+
import { beforeAll, describe, expect, it } from 'vitest';
|
|
8
|
+
|
|
9
|
+
import { eachOperation, firstMethod, miniDoc } from '@xyd-js/opensdk-ci';
|
|
10
|
+
|
|
11
|
+
import { opensdkPython, writeProject } from '../index';
|
|
12
|
+
import { snakeCase } from '../src/naming';
|
|
13
|
+
|
|
14
|
+
// Generation-only dep (used when O2S_BUILD_DOCS=1); the regen-guard test below is
|
|
15
|
+
// pure (opensdk IR input.json → py).
|
|
16
|
+
import { openapi2opensdk } from '@xyd-js/openapi2opensdk';
|
|
17
|
+
|
|
18
|
+
const O2S_FIX = path.join(__dirname, '../__fixtures__/-2.complex.openai');
|
|
19
|
+
// The canonical OpenAI spec vendored in the converter's oracle is our source of truth.
|
|
20
|
+
const SPEC = path.join(__dirname, '../../xyd-openapi2opensdk/oracle/openai-openapi.yaml');
|
|
21
|
+
const GROUPING_PATH = path.join(__dirname, '../../xyd-openapi2opensdk/oracle/openai-grouping.json');
|
|
22
|
+
// oracle/* is gitignored/encrypted; guard the read so the OFFLINE regen-guard below
|
|
23
|
+
// still loads + runs when the plaintext is absent (CI without XYD_CONTENT_SECRET).
|
|
24
|
+
const GROUPING = fs.existsSync(GROUPING_PATH) ? JSON.parse(fs.readFileSync(GROUPING_PATH, 'utf8')) : {};
|
|
25
|
+
|
|
26
|
+
const BUILD = process.env.O2S_BUILD_DOCS === '1';
|
|
27
|
+
const PY_SMOKE = process.env.O2S_PY_SMOKE === '1';
|
|
28
|
+
|
|
29
|
+
/** The generated `<pkg>/resources.py` (the interesting per-method output). */
|
|
30
|
+
function resourcesKey(files: Record<string, string>): string | undefined {
|
|
31
|
+
return Object.keys(files).find((k) => k.endsWith('/resources.py'));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ---- Generator (opt-in): one CORRECT fixture per real spec operation ------
|
|
35
|
+
describe.runIf(BUILD)('generate opensdk → python fixtures (assumed-correct, for review)', () => {
|
|
36
|
+
// biome-ignore lint/suspicious/noExplicitAny: raw OpenAPI document
|
|
37
|
+
let spec: any;
|
|
38
|
+
beforeAll(() => {
|
|
39
|
+
spec = yaml.load(fs.readFileSync(SPEC, 'utf8'));
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('build __fixtures__/-2.complex.openai/<op>/{input.json, output.py}', () => {
|
|
43
|
+
fs.rmSync(O2S_FIX, { recursive: true, force: true });
|
|
44
|
+
const used = new Set<string>();
|
|
45
|
+
let n = 0;
|
|
46
|
+
for (const { path: p, method, operation } of eachOperation(spec)) {
|
|
47
|
+
let ir: ReturnType<typeof openapi2opensdk>;
|
|
48
|
+
let files: Record<string, string>;
|
|
49
|
+
try {
|
|
50
|
+
ir = openapi2opensdk(miniDoc(spec, method, p), {
|
|
51
|
+
sdkName: 'openai',
|
|
52
|
+
mountRules: GROUPING.mountRules,
|
|
53
|
+
operationHints: GROUPING.operationHints,
|
|
54
|
+
});
|
|
55
|
+
files = opensdkPython(ir);
|
|
56
|
+
} catch {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const key = resourcesKey(files);
|
|
60
|
+
const leaf = firstMethod(ir.resources);
|
|
61
|
+
if (!key || !leaf) continue;
|
|
62
|
+
|
|
63
|
+
const base = `${leaf.segments.map(snakeCase).join('__')}__${snakeCase(leaf.method.action)}`;
|
|
64
|
+
let dir = base;
|
|
65
|
+
if (used.has(dir)) dir = `${base}__${snakeCase(operation.operationId || method)}`;
|
|
66
|
+
for (let i = 2; used.has(dir); i++) dir = `${base}__${i}`;
|
|
67
|
+
used.add(dir);
|
|
68
|
+
|
|
69
|
+
const outDir = path.join(O2S_FIX, dir);
|
|
70
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
71
|
+
fs.writeFileSync(path.join(outDir, 'input.json'), `${JSON.stringify(ir, null, 2)}\n`);
|
|
72
|
+
fs.writeFileSync(path.join(outDir, 'output.py'), files[key]);
|
|
73
|
+
n++;
|
|
74
|
+
}
|
|
75
|
+
expect(n).toBeGreaterThan(200);
|
|
76
|
+
}, 300000);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// ---- Regen guard (offline; pure opensdk IR → py) -------------------------
|
|
80
|
+
const fixtures = fs.existsSync(O2S_FIX)
|
|
81
|
+
? fs.readdirSync(O2S_FIX).filter((d) => fs.existsSync(path.join(O2S_FIX, d, 'input.json')))
|
|
82
|
+
: [];
|
|
83
|
+
|
|
84
|
+
describe.skipIf(!fixtures.length || BUILD)('opensdk-python docs (IR → py, regen guard)', () => {
|
|
85
|
+
for (const dir of fixtures) {
|
|
86
|
+
it(dir, () => {
|
|
87
|
+
const ir = JSON.parse(fs.readFileSync(path.join(O2S_FIX, dir, 'input.json'), 'utf8'));
|
|
88
|
+
const files = opensdkPython(ir);
|
|
89
|
+
const key = resourcesKey(files);
|
|
90
|
+
expect(key, `no resources.py generated for ${dir}`).toBeTruthy();
|
|
91
|
+
const expected = fs.readFileSync(path.join(O2S_FIX, dir, 'output.py'), 'utf8');
|
|
92
|
+
expect(files[key as string]).toEqual(expected);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// ---- Optional: a sample of the generated projects py_compile -------------
|
|
98
|
+
describe.runIf(PY_SMOKE && fixtures.length > 0)('opensdk-python docs (py_compile smoke, sample)', () => {
|
|
99
|
+
const step = Math.max(1, Math.floor(fixtures.length / 8));
|
|
100
|
+
const sample = fixtures.filter((_, i) => i % step === 0).slice(0, 8);
|
|
101
|
+
for (const dir of sample) {
|
|
102
|
+
it(`compiles ${dir}`, async () => {
|
|
103
|
+
const ir = JSON.parse(fs.readFileSync(path.join(O2S_FIX, dir, 'input.json'), 'utf8'));
|
|
104
|
+
const files = opensdkPython(ir);
|
|
105
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'o2py-docs-'));
|
|
106
|
+
try {
|
|
107
|
+
await writeProject(files, tmp);
|
|
108
|
+
const mods = Object.keys(files).filter((f) => f.endsWith('.py'));
|
|
109
|
+
execSync(`python3 -m py_compile ${mods.map((m) => JSON.stringify(m)).join(' ')}`, { cwd: tmp, stdio: 'pipe' });
|
|
110
|
+
} finally {
|
|
111
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
112
|
+
}
|
|
113
|
+
}, 60000);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { execSync, spawn } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
import { describe, it } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import { MockServer, fullIR, hasCommand } from '@xyd-js/opensdk-ci';
|
|
9
|
+
import { writeProject } from '@xyd-js/opensdk-framework';
|
|
10
|
+
|
|
11
|
+
import { opensdkPython } from '../../index';
|
|
12
|
+
|
|
13
|
+
// The PYTHON half of the generated-SDK e2e — the analog of the opensdk-go
|
|
14
|
+
// harness's `runGeneratedTests`. The language-agnostic primitives (IR merge,
|
|
15
|
+
// spec-shaped MockServer, command probe) live in @xyd-js/opensdk-ci; this file
|
|
16
|
+
// only stands the Python SDK up in a venv and runs its OWN pytest suite. An
|
|
17
|
+
// API's whole Python e2e is one call (see e2e/openai.test.ts):
|
|
18
|
+
// runGeneratedTests({ name, sdkName, fixturesDir })
|
|
19
|
+
|
|
20
|
+
export interface ApiConfig {
|
|
21
|
+
name: string;
|
|
22
|
+
sdkName: string;
|
|
23
|
+
/** Per-method fixtures dir merged into one OpenSDK IR by `fullIR`. */
|
|
24
|
+
fixturesDir: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* (Gated E2E_SDK_TESTS=1) RUN the generated Python SDK's OWN pytest suite
|
|
29
|
+
* against a spec-shaped mock — the analog of pointing openai-python's
|
|
30
|
+
* test_*.py at a Prism mock of the OpenAPI spec. Generates the whole SDK (with
|
|
31
|
+
* its tests/test_<resource>.py), creates a venv, pip-installs pytest, stands up
|
|
32
|
+
* a MockServer that answers every method with a decodable example response, and
|
|
33
|
+
* runs `pytest tests` with TEST_API_BASE_URL pointed at it, so the emitted
|
|
34
|
+
* tests EXECUTE and PASS (not just py_compile). Gated on python3 availability.
|
|
35
|
+
*/
|
|
36
|
+
export function runGeneratedTests(cfg: ApiConfig) {
|
|
37
|
+
const RUN = process.env.E2E_SDK_TESTS === '1';
|
|
38
|
+
describe.runIf(RUN)(`${cfg.name} e2e: the SDK's own generated tests pass against a mock`, () => {
|
|
39
|
+
it('pytest tests is green against the spec-shaped mock', async () => {
|
|
40
|
+
if (!hasCommand('python3 --version')) return;
|
|
41
|
+
const spec = fullIR(cfg.fixturesDir, cfg.sdkName);
|
|
42
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'o2s-py-selftest-'));
|
|
43
|
+
const mock = new MockServer(spec);
|
|
44
|
+
await mock.start();
|
|
45
|
+
try {
|
|
46
|
+
await writeProject(opensdkPython(spec), tmpDir);
|
|
47
|
+
execSync('python3 -m venv .venv', { cwd: tmpDir, stdio: 'pipe' });
|
|
48
|
+
execSync('.venv/bin/pip install -q pytest', { cwd: tmpDir, stdio: 'pipe' });
|
|
49
|
+
// pytest via async spawn (NOT execSync): the MockServer runs in THIS
|
|
50
|
+
// Node process, so a synchronous child would block the event loop and
|
|
51
|
+
// the generated conftest's HTTP calls would deadlock. spawn keeps the
|
|
52
|
+
// loop free to serve the mock.
|
|
53
|
+
await new Promise<void>((resolve, reject) => {
|
|
54
|
+
const p = spawn('.venv/bin/python', ['-m', 'pytest', 'tests', '-q', '--no-header'], {
|
|
55
|
+
cwd: tmpDir,
|
|
56
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
57
|
+
env: {
|
|
58
|
+
...process.env,
|
|
59
|
+
PYTHONPATH: tmpDir,
|
|
60
|
+
TEST_API_BASE_URL: `http://127.0.0.1:${mock.port}`,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
let out = '';
|
|
64
|
+
p.stdout?.on('data', (d) => {
|
|
65
|
+
out += d;
|
|
66
|
+
});
|
|
67
|
+
p.stderr?.on('data', (d) => {
|
|
68
|
+
out += d;
|
|
69
|
+
});
|
|
70
|
+
p.on('exit', (code) => (code === 0 ? resolve() : reject(new Error(`pytest failed:\n${out}`))));
|
|
71
|
+
p.on('error', reject);
|
|
72
|
+
});
|
|
73
|
+
} finally {
|
|
74
|
+
mock.stop();
|
|
75
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
76
|
+
}
|
|
77
|
+
}, 600000);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { runGeneratedTests } from './harness';
|
|
4
|
+
|
|
5
|
+
// OpenAI binding for the Python generated-SDK e2e harness. The whole SDK is
|
|
6
|
+
// assembled from the committed OpenSDK IR inputs (no OpenAPI/upstream
|
|
7
|
+
// dependency) and its own pytest suite is run against a spec-shaped mock.
|
|
8
|
+
const openai = {
|
|
9
|
+
name: 'openai',
|
|
10
|
+
sdkName: 'openai',
|
|
11
|
+
fixturesDir: path.join(__dirname, '../../__fixtures__/-2.complex.openai'),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
runGeneratedTests(openai);
|