@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.
Files changed (539) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/LICENSE +21 -0
  3. package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__create/input.json +325 -0
  4. package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__create/output.py +26 -0
  5. package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__delete/input.json +201 -0
  6. package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__delete/output.py +28 -0
  7. package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__list/input.json +400 -0
  8. package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__list/output.py +29 -0
  9. package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__retrieve/input.json +304 -0
  10. package/__fixtures__/-2.complex.openai/admin__organization__admin_api_keys__retrieve/output.py +28 -0
  11. package/__fixtures__/-2.complex.openai/admin__organization__audit_logs__list/input.json +2602 -0
  12. package/__fixtures__/-2.complex.openai/admin__organization__audit_logs__list/output.py +29 -0
  13. package/__fixtures__/-2.complex.openai/admin__organization__certificates__activate__create/input.json +308 -0
  14. package/__fixtures__/-2.complex.openai/admin__organization__certificates__activate__create/output.py +32 -0
  15. package/__fixtures__/-2.complex.openai/admin__organization__certificates__create/input.json +308 -0
  16. package/__fixtures__/-2.complex.openai/admin__organization__certificates__create/output.py +28 -0
  17. package/__fixtures__/-2.complex.openai/admin__organization__certificates__deactivate__create/input.json +308 -0
  18. package/__fixtures__/-2.complex.openai/admin__organization__certificates__deactivate__create/output.py +32 -0
  19. package/__fixtures__/-2.complex.openai/admin__organization__certificates__delete/input.json +196 -0
  20. package/__fixtures__/-2.complex.openai/admin__organization__certificates__delete/output.py +28 -0
  21. package/__fixtures__/-2.complex.openai/admin__organization__certificates__list/input.json +356 -0
  22. package/__fixtures__/-2.complex.openai/admin__organization__certificates__list/output.py +29 -0
  23. package/__fixtures__/-2.complex.openai/admin__organization__certificates__retrieve/input.json +300 -0
  24. package/__fixtures__/-2.complex.openai/admin__organization__certificates__retrieve/output.py +30 -0
  25. package/__fixtures__/-2.complex.openai/admin__organization__certificates__update/input.json +310 -0
  26. package/__fixtures__/-2.complex.openai/admin__organization__certificates__update/output.py +30 -0
  27. package/__fixtures__/-2.complex.openai/admin__organization__costs__list/input.json +1062 -0
  28. package/__fixtures__/-2.complex.openai/admin__organization__costs__list/output.py +29 -0
  29. package/__fixtures__/-2.complex.openai/admin__organization__groups__create/input.json +239 -0
  30. package/__fixtures__/-2.complex.openai/admin__organization__groups__create/output.py +26 -0
  31. package/__fixtures__/-2.complex.openai/admin__organization__groups__delete/input.json +206 -0
  32. package/__fixtures__/-2.complex.openai/admin__organization__groups__delete/output.py +28 -0
  33. package/__fixtures__/-2.complex.openai/admin__organization__groups__list/input.json +316 -0
  34. package/__fixtures__/-2.complex.openai/admin__organization__groups__list/output.py +29 -0
  35. package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__create/input.json +364 -0
  36. package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__create/output.py +34 -0
  37. package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__delete/input.json +210 -0
  38. package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__delete/output.py +36 -0
  39. package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__list/input.json +398 -0
  40. package/__fixtures__/-2.complex.openai/admin__organization__groups__roles__list/output.py +37 -0
  41. package/__fixtures__/-2.complex.openai/admin__organization__groups__update/input.json +241 -0
  42. package/__fixtures__/-2.complex.openai/admin__organization__groups__update/output.py +28 -0
  43. package/__fixtures__/-2.complex.openai/admin__organization__groups__users__create/input.json +237 -0
  44. package/__fixtures__/-2.complex.openai/admin__organization__groups__users__create/output.py +34 -0
  45. package/__fixtures__/-2.complex.openai/admin__organization__groups__users__delete/input.json +211 -0
  46. package/__fixtures__/-2.complex.openai/admin__organization__groups__users__delete/output.py +36 -0
  47. package/__fixtures__/-2.complex.openai/admin__organization__groups__users__list/input.json +314 -0
  48. package/__fixtures__/-2.complex.openai/admin__organization__groups__users__list/output.py +37 -0
  49. package/__fixtures__/-2.complex.openai/admin__organization__invites__create/input.json +386 -0
  50. package/__fixtures__/-2.complex.openai/admin__organization__invites__create/output.py +28 -0
  51. package/__fixtures__/-2.complex.openai/admin__organization__invites__delete/input.json +203 -0
  52. package/__fixtures__/-2.complex.openai/admin__organization__invites__delete/output.py +28 -0
  53. package/__fixtures__/-2.complex.openai/admin__organization__invites__list/input.json +414 -0
  54. package/__fixtures__/-2.complex.openai/admin__organization__invites__list/output.py +29 -0
  55. package/__fixtures__/-2.complex.openai/admin__organization__invites__retrieve/input.json +337 -0
  56. package/__fixtures__/-2.complex.openai/admin__organization__invites__retrieve/output.py +28 -0
  57. package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__delete/input.json +279 -0
  58. package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__delete/output.py +36 -0
  59. package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__list/input.json +475 -0
  60. package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__list/output.py +37 -0
  61. package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__retrieve/input.json +400 -0
  62. package/__fixtures__/-2.complex.openai/admin__organization__projects__api_keys__retrieve/output.py +36 -0
  63. package/__fixtures__/-2.complex.openai/admin__organization__projects__archive/input.json +247 -0
  64. package/__fixtures__/-2.complex.openai/admin__organization__projects__archive/output.py +28 -0
  65. package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__activate__create/input.json +324 -0
  66. package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__activate__create/output.py +40 -0
  67. package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__deactivate__create/input.json +324 -0
  68. package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__deactivate__create/output.py +40 -0
  69. package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__list/input.json +372 -0
  70. package/__fixtures__/-2.complex.openai/admin__organization__projects__certificates__list/output.py +37 -0
  71. package/__fixtures__/-2.complex.openai/admin__organization__projects__create/input.json +281 -0
  72. package/__fixtures__/-2.complex.openai/admin__organization__projects__create/output.py +28 -0
  73. package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__create/input.json +274 -0
  74. package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__create/output.py +34 -0
  75. package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__delete/input.json +211 -0
  76. package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__delete/output.py +36 -0
  77. package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__list/input.json +342 -0
  78. package/__fixtures__/-2.complex.openai/admin__organization__projects__groups__list/output.py +37 -0
  79. package/__fixtures__/-2.complex.openai/admin__organization__projects__list/input.json +330 -0
  80. package/__fixtures__/-2.complex.openai/admin__organization__projects__list/output.py +29 -0
  81. package/__fixtures__/-2.complex.openai/admin__organization__projects__rate_limits__list_rate_limits/input.json +358 -0
  82. package/__fixtures__/-2.complex.openai/admin__organization__projects__rate_limits__list_rate_limits/output.py +37 -0
  83. package/__fixtures__/-2.complex.openai/admin__organization__projects__rate_limits__update_rate_limit/input.json +407 -0
  84. package/__fixtures__/-2.complex.openai/admin__organization__projects__rate_limits__update_rate_limit/output.py +38 -0
  85. package/__fixtures__/-2.complex.openai/admin__organization__projects__retrieve/input.json +247 -0
  86. package/__fixtures__/-2.complex.openai/admin__organization__projects__retrieve/output.py +28 -0
  87. package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__create/input.json +372 -0
  88. package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__create/output.py +34 -0
  89. package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__delete/input.json +216 -0
  90. package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__delete/output.py +36 -0
  91. package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__list/input.json +391 -0
  92. package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__list/output.py +37 -0
  93. package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__retrieve/input.json +253 -0
  94. package/__fixtures__/-2.complex.openai/admin__organization__projects__service_accounts__retrieve/output.py +36 -0
  95. package/__fixtures__/-2.complex.openai/admin__organization__projects__update/input.json +356 -0
  96. package/__fixtures__/-2.complex.openai/admin__organization__projects__update/output.py +30 -0
  97. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__create/input.json +349 -0
  98. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__create/output.py +36 -0
  99. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__delete/input.json +279 -0
  100. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__delete/output.py +36 -0
  101. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__list/input.json +387 -0
  102. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__list/output.py +37 -0
  103. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__retrieve/input.json +250 -0
  104. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__retrieve/output.py +36 -0
  105. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__update/input.json +339 -0
  106. package/__fixtures__/-2.complex.openai/admin__organization__projects__users__update/output.py +38 -0
  107. package/__fixtures__/-2.complex.openai/admin__organization__roles__create/input.json +283 -0
  108. package/__fixtures__/-2.complex.openai/admin__organization__roles__create/output.py +28 -0
  109. package/__fixtures__/-2.complex.openai/admin__organization__roles__delete/input.json +206 -0
  110. package/__fixtures__/-2.complex.openai/admin__organization__roles__delete/output.py +28 -0
  111. package/__fixtures__/-2.complex.openai/admin__organization__roles__list/input.json +338 -0
  112. package/__fixtures__/-2.complex.openai/admin__organization__roles__list/output.py +29 -0
  113. package/__fixtures__/-2.complex.openai/admin__organization__roles__update/input.json +296 -0
  114. package/__fixtures__/-2.complex.openai/admin__organization__roles__update/output.py +30 -0
  115. package/__fixtures__/-2.complex.openai/admin__organization__usage__audio_speeches__list/input.json +1108 -0
  116. package/__fixtures__/-2.complex.openai/admin__organization__usage__audio_speeches__list/output.py +35 -0
  117. package/__fixtures__/-2.complex.openai/admin__organization__usage__audio_transcriptions__list/input.json +1108 -0
  118. package/__fixtures__/-2.complex.openai/admin__organization__usage__audio_transcriptions__list/output.py +35 -0
  119. package/__fixtures__/-2.complex.openai/admin__organization__usage__code_interpreter_sessions__list/input.json +1054 -0
  120. package/__fixtures__/-2.complex.openai/admin__organization__usage__code_interpreter_sessions__list/output.py +35 -0
  121. package/__fixtures__/-2.complex.openai/admin__organization__usage__completions__list/input.json +1123 -0
  122. package/__fixtures__/-2.complex.openai/admin__organization__usage__completions__list/output.py +35 -0
  123. package/__fixtures__/-2.complex.openai/admin__organization__usage__embeddings__list/input.json +1108 -0
  124. package/__fixtures__/-2.complex.openai/admin__organization__usage__embeddings__list/output.py +35 -0
  125. package/__fixtures__/-2.complex.openai/admin__organization__usage__images__list/input.json +1176 -0
  126. package/__fixtures__/-2.complex.openai/admin__organization__usage__images__list/output.py +35 -0
  127. package/__fixtures__/-2.complex.openai/admin__organization__usage__moderations__list/input.json +1108 -0
  128. package/__fixtures__/-2.complex.openai/admin__organization__usage__moderations__list/output.py +35 -0
  129. package/__fixtures__/-2.complex.openai/admin__organization__usage__vector_stores__list/input.json +1054 -0
  130. package/__fixtures__/-2.complex.openai/admin__organization__usage__vector_stores__list/output.py +35 -0
  131. package/__fixtures__/-2.complex.openai/admin__organization__users__delete/input.json +202 -0
  132. package/__fixtures__/-2.complex.openai/admin__organization__users__delete/output.py +28 -0
  133. package/__fixtures__/-2.complex.openai/admin__organization__users__list/input.json +557 -0
  134. package/__fixtures__/-2.complex.openai/admin__organization__users__list/output.py +29 -0
  135. package/__fixtures__/-2.complex.openai/admin__organization__users__retrieve/input.json +472 -0
  136. package/__fixtures__/-2.complex.openai/admin__organization__users__retrieve/output.py +28 -0
  137. package/__fixtures__/-2.complex.openai/admin__organization__users__roles__create/input.json +611 -0
  138. package/__fixtures__/-2.complex.openai/admin__organization__users__roles__create/output.py +34 -0
  139. package/__fixtures__/-2.complex.openai/admin__organization__users__roles__delete/input.json +210 -0
  140. package/__fixtures__/-2.complex.openai/admin__organization__users__roles__delete/output.py +36 -0
  141. package/__fixtures__/-2.complex.openai/admin__organization__users__roles__list/input.json +398 -0
  142. package/__fixtures__/-2.complex.openai/admin__organization__users__roles__list/output.py +37 -0
  143. package/__fixtures__/-2.complex.openai/admin__organization__users__update/input.json +528 -0
  144. package/__fixtures__/-2.complex.openai/admin__organization__users__update/output.py +30 -0
  145. package/__fixtures__/-2.complex.openai/audio__speech__create/input.json +388 -0
  146. package/__fixtures__/-2.complex.openai/audio__speech__create/output.py +22 -0
  147. package/__fixtures__/-2.complex.openai/audio__transcriptions__create/input.json +999 -0
  148. package/__fixtures__/-2.complex.openai/audio__transcriptions__create/output.py +22 -0
  149. package/__fixtures__/-2.complex.openai/audio__translations__create/input.json +430 -0
  150. package/__fixtures__/-2.complex.openai/audio__translations__create/output.py +22 -0
  151. package/__fixtures__/-2.complex.openai/audio__voice_consents__create/input.json +244 -0
  152. package/__fixtures__/-2.complex.openai/audio__voice_consents__create/output.py +22 -0
  153. package/__fixtures__/-2.complex.openai/audio__voice_consents__delete/input.json +190 -0
  154. package/__fixtures__/-2.complex.openai/audio__voice_consents__delete/output.py +22 -0
  155. package/__fixtures__/-2.complex.openai/audio__voice_consents__list/input.json +285 -0
  156. package/__fixtures__/-2.complex.openai/audio__voice_consents__list/output.py +23 -0
  157. package/__fixtures__/-2.complex.openai/audio__voice_consents__retrieve/input.json +212 -0
  158. package/__fixtures__/-2.complex.openai/audio__voice_consents__retrieve/output.py +22 -0
  159. package/__fixtures__/-2.complex.openai/audio__voice_consents__update/input.json +236 -0
  160. package/__fixtures__/-2.complex.openai/audio__voice_consents__update/output.py +22 -0
  161. package/__fixtures__/-2.complex.openai/audio__voices__create/input.json +235 -0
  162. package/__fixtures__/-2.complex.openai/audio__voices__create/output.py +22 -0
  163. package/__fixtures__/-2.complex.openai/batches__cancel/input.json +594 -0
  164. package/__fixtures__/-2.complex.openai/batches__cancel/output.py +16 -0
  165. package/__fixtures__/-2.complex.openai/batches__create/input.json +701 -0
  166. package/__fixtures__/-2.complex.openai/batches__create/output.py +16 -0
  167. package/__fixtures__/-2.complex.openai/batches__list/input.json +665 -0
  168. package/__fixtures__/-2.complex.openai/batches__list/output.py +17 -0
  169. package/__fixtures__/-2.complex.openai/batches__retrieve/input.json +594 -0
  170. package/__fixtures__/-2.complex.openai/batches__retrieve/output.py +16 -0
  171. package/__fixtures__/-2.complex.openai/beta__assistants__create/input.json +1029 -0
  172. package/__fixtures__/-2.complex.openai/beta__assistants__create/output.py +22 -0
  173. package/__fixtures__/-2.complex.openai/beta__assistants__delete/input.json +190 -0
  174. package/__fixtures__/-2.complex.openai/beta__assistants__delete/output.py +22 -0
  175. package/__fixtures__/-2.complex.openai/beta__assistants__list/input.json +796 -0
  176. package/__fixtures__/-2.complex.openai/beta__assistants__list/output.py +23 -0
  177. package/__fixtures__/-2.complex.openai/beta__assistants__retrieve/input.json +694 -0
  178. package/__fixtures__/-2.complex.openai/beta__assistants__retrieve/output.py +22 -0
  179. package/__fixtures__/-2.complex.openai/beta__assistants__update/input.json +1045 -0
  180. package/__fixtures__/-2.complex.openai/beta__assistants__update/output.py +24 -0
  181. package/__fixtures__/-2.complex.openai/beta__chat_kit__sessions__cancel/input.json +482 -0
  182. package/__fixtures__/-2.complex.openai/beta__chat_kit__sessions__cancel/output.py +28 -0
  183. package/__fixtures__/-2.complex.openai/beta__chat_kit__sessions__create/input.json +738 -0
  184. package/__fixtures__/-2.complex.openai/beta__chat_kit__sessions__create/output.py +28 -0
  185. package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__delete/input.json +200 -0
  186. package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__delete/output.py +28 -0
  187. package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__items__list/input.json +1218 -0
  188. package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__items__list/output.py +37 -0
  189. package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__list/input.json +444 -0
  190. package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__list/output.py +29 -0
  191. package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__retrieve/input.json +328 -0
  192. package/__fixtures__/-2.complex.openai/beta__chat_kit__threads__retrieve/output.py +28 -0
  193. package/__fixtures__/-2.complex.openai/beta__threads__create/input.json +665 -0
  194. package/__fixtures__/-2.complex.openai/beta__threads__create/output.py +22 -0
  195. package/__fixtures__/-2.complex.openai/beta__threads__delete/input.json +189 -0
  196. package/__fixtures__/-2.complex.openai/beta__threads__delete/output.py +22 -0
  197. package/__fixtures__/-2.complex.openai/beta__threads__messages__create/input.json +938 -0
  198. package/__fixtures__/-2.complex.openai/beta__threads__messages__create/output.py +30 -0
  199. package/__fixtures__/-2.complex.openai/beta__threads__messages__delete/input.json +203 -0
  200. package/__fixtures__/-2.complex.openai/beta__threads__messages__delete/output.py +30 -0
  201. package/__fixtures__/-2.complex.openai/beta__threads__messages__list/input.json +945 -0
  202. package/__fixtures__/-2.complex.openai/beta__threads__messages__list/output.py +31 -0
  203. package/__fixtures__/-2.complex.openai/beta__threads__messages__retrieve/input.json +832 -0
  204. package/__fixtures__/-2.complex.openai/beta__threads__messages__retrieve/output.py +30 -0
  205. package/__fixtures__/-2.complex.openai/beta__threads__messages__update/input.json +855 -0
  206. package/__fixtures__/-2.complex.openai/beta__threads__messages__update/output.py +32 -0
  207. package/__fixtures__/-2.complex.openai/beta__threads__new_and_run/input.json +1899 -0
  208. package/__fixtures__/-2.complex.openai/beta__threads__new_and_run/output.py +22 -0
  209. package/__fixtures__/-2.complex.openai/beta__threads__retrieve/input.json +283 -0
  210. package/__fixtures__/-2.complex.openai/beta__threads__retrieve/output.py +22 -0
  211. package/__fixtures__/-2.complex.openai/beta__threads__runs__cancel/input.json +1181 -0
  212. package/__fixtures__/-2.complex.openai/beta__threads__runs__cancel/output.py +30 -0
  213. package/__fixtures__/-2.complex.openai/beta__threads__runs__create/input.json +1851 -0
  214. package/__fixtures__/-2.complex.openai/beta__threads__runs__create/output.py +30 -0
  215. package/__fixtures__/-2.complex.openai/beta__threads__runs__list/input.json +1285 -0
  216. package/__fixtures__/-2.complex.openai/beta__threads__runs__list/output.py +31 -0
  217. package/__fixtures__/-2.complex.openai/beta__threads__runs__retrieve/input.json +1181 -0
  218. package/__fixtures__/-2.complex.openai/beta__threads__runs__retrieve/output.py +30 -0
  219. package/__fixtures__/-2.complex.openai/beta__threads__runs__steps__list/input.json +1066 -0
  220. package/__fixtures__/-2.complex.openai/beta__threads__runs__steps__list/output.py +39 -0
  221. package/__fixtures__/-2.complex.openai/beta__threads__runs__steps__retrieve/input.json +964 -0
  222. package/__fixtures__/-2.complex.openai/beta__threads__runs__steps__retrieve/output.py +40 -0
  223. package/__fixtures__/-2.complex.openai/beta__threads__runs__submit_tool_outputs__create/input.json +1246 -0
  224. package/__fixtures__/-2.complex.openai/beta__threads__runs__submit_tool_outputs__create/output.py +38 -0
  225. package/__fixtures__/-2.complex.openai/beta__threads__runs__update/input.json +1204 -0
  226. package/__fixtures__/-2.complex.openai/beta__threads__runs__update/output.py +32 -0
  227. package/__fixtures__/-2.complex.openai/beta__threads__update/input.json +315 -0
  228. package/__fixtures__/-2.complex.openai/beta__threads__update/output.py +24 -0
  229. package/__fixtures__/-2.complex.openai/chat__completions__create/input.json +3325 -0
  230. package/__fixtures__/-2.complex.openai/chat__completions__create/output.py +22 -0
  231. package/__fixtures__/-2.complex.openai/chat__completions__delete/input.json +192 -0
  232. package/__fixtures__/-2.complex.openai/chat__completions__delete/output.py +22 -0
  233. package/__fixtures__/-2.complex.openai/chat__completions__list/input.json +1069 -0
  234. package/__fixtures__/-2.complex.openai/chat__completions__list/output.py +23 -0
  235. package/__fixtures__/-2.complex.openai/chat__completions__messages__list/input.json +770 -0
  236. package/__fixtures__/-2.complex.openai/chat__completions__messages__list/output.py +31 -0
  237. package/__fixtures__/-2.complex.openai/chat__completions__retrieve/input.json +938 -0
  238. package/__fixtures__/-2.complex.openai/chat__completions__retrieve/output.py +22 -0
  239. package/__fixtures__/-2.complex.openai/chat__completions__update/input.json +973 -0
  240. package/__fixtures__/-2.complex.openai/chat__completions__update/output.py +22 -0
  241. package/__fixtures__/-2.complex.openai/completions__create/input.json +788 -0
  242. package/__fixtures__/-2.complex.openai/completions__create/output.py +16 -0
  243. package/__fixtures__/-2.complex.openai/containers__create/input.json +671 -0
  244. package/__fixtures__/-2.complex.openai/containers__create/output.py +16 -0
  245. package/__fixtures__/-2.complex.openai/containers__delete/input.json +142 -0
  246. package/__fixtures__/-2.complex.openai/containers__delete/output.py +16 -0
  247. package/__fixtures__/-2.complex.openai/containers__files__content/input.json +154 -0
  248. package/__fixtures__/-2.complex.openai/containers__files__content/output.py +24 -0
  249. package/__fixtures__/-2.complex.openai/containers__files__create/input.json +261 -0
  250. package/__fixtures__/-2.complex.openai/containers__files__create/output.py +24 -0
  251. package/__fixtures__/-2.complex.openai/containers__files__delete/input.json +154 -0
  252. package/__fixtures__/-2.complex.openai/containers__files__delete/output.py +24 -0
  253. package/__fixtures__/-2.complex.openai/containers__files__list/input.json +337 -0
  254. package/__fixtures__/-2.complex.openai/containers__files__list/output.py +25 -0
  255. package/__fixtures__/-2.complex.openai/containers__files__retrieve/input.json +235 -0
  256. package/__fixtures__/-2.complex.openai/containers__files__retrieve/output.py +24 -0
  257. package/__fixtures__/-2.complex.openai/containers__list/input.json +438 -0
  258. package/__fixtures__/-2.complex.openai/containers__list/output.py +17 -0
  259. package/__fixtures__/-2.complex.openai/containers__retrieve/input.json +329 -0
  260. package/__fixtures__/-2.complex.openai/containers__retrieve/output.py +16 -0
  261. package/__fixtures__/-2.complex.openai/conversations__create/input.json +6737 -0
  262. package/__fixtures__/-2.complex.openai/conversations__create/output.py +16 -0
  263. package/__fixtures__/-2.complex.openai/conversations__delete/input.json +186 -0
  264. package/__fixtures__/-2.complex.openai/conversations__delete/output.py +16 -0
  265. package/__fixtures__/-2.complex.openai/conversations__items__create/input.json +8352 -0
  266. package/__fixtures__/-2.complex.openai/conversations__items__create/output.py +25 -0
  267. package/__fixtures__/-2.complex.openai/conversations__items__delete/input.json +213 -0
  268. package/__fixtures__/-2.complex.openai/conversations__items__delete/output.py +24 -0
  269. package/__fixtures__/-2.complex.openai/conversations__items__list/input.json +6695 -0
  270. package/__fixtures__/-2.complex.openai/conversations__items__list/output.py +25 -0
  271. package/__fixtures__/-2.complex.openai/conversations__items__retrieve/input.json +6597 -0
  272. package/__fixtures__/-2.complex.openai/conversations__items__retrieve/output.py +26 -0
  273. package/__fixtures__/-2.complex.openai/conversations__retrieve/input.json +198 -0
  274. package/__fixtures__/-2.complex.openai/conversations__retrieve/output.py +16 -0
  275. package/__fixtures__/-2.complex.openai/conversations__update/input.json +233 -0
  276. package/__fixtures__/-2.complex.openai/conversations__update/output.py +16 -0
  277. package/__fixtures__/-2.complex.openai/embeddings__create/input.json +395 -0
  278. package/__fixtures__/-2.complex.openai/embeddings__create/output.py +16 -0
  279. package/__fixtures__/-2.complex.openai/evals__create/input.json +1424 -0
  280. package/__fixtures__/-2.complex.openai/evals__create/output.py +16 -0
  281. package/__fixtures__/-2.complex.openai/evals__delete/input.json +232 -0
  282. package/__fixtures__/-2.complex.openai/evals__delete/output.py +16 -0
  283. package/__fixtures__/-2.complex.openai/evals__list/input.json +1251 -0
  284. package/__fixtures__/-2.complex.openai/evals__list/output.py +17 -0
  285. package/__fixtures__/-2.complex.openai/evals__retrieve/input.json +1127 -0
  286. package/__fixtures__/-2.complex.openai/evals__retrieve/output.py +16 -0
  287. package/__fixtures__/-2.complex.openai/evals__runs__cancel/input.json +4445 -0
  288. package/__fixtures__/-2.complex.openai/evals__runs__cancel/output.py +24 -0
  289. package/__fixtures__/-2.complex.openai/evals__runs__create/input.json +4526 -0
  290. package/__fixtures__/-2.complex.openai/evals__runs__create/output.py +24 -0
  291. package/__fixtures__/-2.complex.openai/evals__runs__delete/input.json +246 -0
  292. package/__fixtures__/-2.complex.openai/evals__runs__delete/output.py +24 -0
  293. package/__fixtures__/-2.complex.openai/evals__runs__list/input.json +4579 -0
  294. package/__fixtures__/-2.complex.openai/evals__runs__list/output.py +25 -0
  295. package/__fixtures__/-2.complex.openai/evals__runs__output_items__list/input.json +685 -0
  296. package/__fixtures__/-2.complex.openai/evals__runs__output_items__list/output.py +33 -0
  297. package/__fixtures__/-2.complex.openai/evals__runs__output_items__retrieve/input.json +560 -0
  298. package/__fixtures__/-2.complex.openai/evals__runs__output_items__retrieve/output.py +32 -0
  299. package/__fixtures__/-2.complex.openai/evals__runs__retrieve/input.json +4445 -0
  300. package/__fixtures__/-2.complex.openai/evals__runs__retrieve/output.py +24 -0
  301. package/__fixtures__/-2.complex.openai/evals__update/input.json +1160 -0
  302. package/__fixtures__/-2.complex.openai/evals__update/output.py +18 -0
  303. package/__fixtures__/-2.complex.openai/files__content/input.json +151 -0
  304. package/__fixtures__/-2.complex.openai/files__content/output.py +16 -0
  305. package/__fixtures__/-2.complex.openai/files__create/input.json +379 -0
  306. package/__fixtures__/-2.complex.openai/files__create/output.py +16 -0
  307. package/__fixtures__/-2.complex.openai/files__delete/input.json +184 -0
  308. package/__fixtures__/-2.complex.openai/files__delete/output.py +16 -0
  309. package/__fixtures__/-2.complex.openai/files__list/input.json +397 -0
  310. package/__fixtures__/-2.complex.openai/files__list/output.py +17 -0
  311. package/__fixtures__/-2.complex.openai/files__retrieve/input.json +295 -0
  312. package/__fixtures__/-2.complex.openai/files__retrieve/output.py +16 -0
  313. package/__fixtures__/-2.complex.openai/fine_tuning__alpha__graders__run__create/input.json +1225 -0
  314. package/__fixtures__/-2.complex.openai/fine_tuning__alpha__graders__run__create/output.py +34 -0
  315. package/__fixtures__/-2.complex.openai/fine_tuning__alpha__graders__validate__create/input.json +991 -0
  316. package/__fixtures__/-2.complex.openai/fine_tuning__alpha__graders__validate__create/output.py +32 -0
  317. package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__create/input.json +297 -0
  318. package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__create/output.py +29 -0
  319. package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__delete/input.json +208 -0
  320. package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__delete/output.py +30 -0
  321. package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__list/input.json +325 -0
  322. package/__fixtures__/-2.complex.openai/fine_tuning__checkpoints__permissions__list/output.py +31 -0
  323. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__cancel/input.json +1645 -0
  324. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__cancel/output.py +22 -0
  325. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__checkpoints__list/input.json +383 -0
  326. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__checkpoints__list/output.py +31 -0
  327. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__create/input.json +1887 -0
  328. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__create/output.py +22 -0
  329. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__list/input.json +1714 -0
  330. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__list/output.py +23 -0
  331. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__list_events/input.json +330 -0
  332. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__list_events/output.py +25 -0
  333. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__pause/input.json +1645 -0
  334. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__pause/output.py +22 -0
  335. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__resume/input.json +1645 -0
  336. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__resume/output.py +22 -0
  337. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__retrieve/input.json +1645 -0
  338. package/__fixtures__/-2.complex.openai/fine_tuning__jobs__retrieve/output.py +22 -0
  339. package/__fixtures__/-2.complex.openai/images__edits__create/input.json +744 -0
  340. package/__fixtures__/-2.complex.openai/images__edits__create/output.py +22 -0
  341. package/__fixtures__/-2.complex.openai/images__generations__create/input.json +789 -0
  342. package/__fixtures__/-2.complex.openai/images__generations__create/output.py +22 -0
  343. package/__fixtures__/-2.complex.openai/images__variations__create/input.json +550 -0
  344. package/__fixtures__/-2.complex.openai/images__variations__create/output.py +22 -0
  345. package/__fixtures__/-2.complex.openai/models__delete/input.json +184 -0
  346. package/__fixtures__/-2.complex.openai/models__delete/output.py +16 -0
  347. package/__fixtures__/-2.complex.openai/models__list/input.json +221 -0
  348. package/__fixtures__/-2.complex.openai/models__list/output.py +15 -0
  349. package/__fixtures__/-2.complex.openai/models__retrieve/input.json +199 -0
  350. package/__fixtures__/-2.complex.openai/models__retrieve/output.py +16 -0
  351. package/__fixtures__/-2.complex.openai/moderations__create/input.json +831 -0
  352. package/__fixtures__/-2.complex.openai/moderations__create/output.py +16 -0
  353. package/__fixtures__/-2.complex.openai/projects__groups__roles__create/input.json +368 -0
  354. package/__fixtures__/-2.complex.openai/projects__groups__roles__create/output.py +30 -0
  355. package/__fixtures__/-2.complex.openai/projects__groups__roles__delete/input.json +214 -0
  356. package/__fixtures__/-2.complex.openai/projects__groups__roles__delete/output.py +32 -0
  357. package/__fixtures__/-2.complex.openai/projects__groups__roles__list/input.json +402 -0
  358. package/__fixtures__/-2.complex.openai/projects__groups__roles__list/output.py +33 -0
  359. package/__fixtures__/-2.complex.openai/projects__roles__create/input.json +289 -0
  360. package/__fixtures__/-2.complex.openai/projects__roles__create/output.py +24 -0
  361. package/__fixtures__/-2.complex.openai/projects__roles__delete/input.json +210 -0
  362. package/__fixtures__/-2.complex.openai/projects__roles__delete/output.py +24 -0
  363. package/__fixtures__/-2.complex.openai/projects__roles__list/input.json +344 -0
  364. package/__fixtures__/-2.complex.openai/projects__roles__list/output.py +25 -0
  365. package/__fixtures__/-2.complex.openai/projects__roles__update/input.json +300 -0
  366. package/__fixtures__/-2.complex.openai/projects__roles__update/output.py +26 -0
  367. package/__fixtures__/-2.complex.openai/projects__users__roles__create/input.json +615 -0
  368. package/__fixtures__/-2.complex.openai/projects__users__roles__create/output.py +30 -0
  369. package/__fixtures__/-2.complex.openai/projects__users__roles__delete/input.json +214 -0
  370. package/__fixtures__/-2.complex.openai/projects__users__roles__delete/output.py +32 -0
  371. package/__fixtures__/-2.complex.openai/projects__users__roles__list/input.json +402 -0
  372. package/__fixtures__/-2.complex.openai/projects__users__roles__list/output.py +33 -0
  373. package/__fixtures__/-2.complex.openai/realtime__calls__accept/input.json +1768 -0
  374. package/__fixtures__/-2.complex.openai/realtime__calls__accept/output.py +24 -0
  375. package/__fixtures__/-2.complex.openai/realtime__calls__create/input.json +1790 -0
  376. package/__fixtures__/-2.complex.openai/realtime__calls__create/output.py +22 -0
  377. package/__fixtures__/-2.complex.openai/realtime__calls__hangup/input.json +147 -0
  378. package/__fixtures__/-2.complex.openai/realtime__calls__hangup/output.py +22 -0
  379. package/__fixtures__/-2.complex.openai/realtime__calls__refer/input.json +175 -0
  380. package/__fixtures__/-2.complex.openai/realtime__calls__refer/output.py +22 -0
  381. package/__fixtures__/-2.complex.openai/realtime__calls__reject/input.json +175 -0
  382. package/__fixtures__/-2.complex.openai/realtime__calls__reject/output.py +24 -0
  383. package/__fixtures__/-2.complex.openai/realtime__client_secrets__create/input.json +2407 -0
  384. package/__fixtures__/-2.complex.openai/realtime__client_secrets__create/output.py +22 -0
  385. package/__fixtures__/-2.complex.openai/realtime__sessions__create/input.json +1400 -0
  386. package/__fixtures__/-2.complex.openai/realtime__sessions__create/output.py +22 -0
  387. package/__fixtures__/-2.complex.openai/realtime__transcription_sessions__create/input.json +562 -0
  388. package/__fixtures__/-2.complex.openai/realtime__transcription_sessions__create/output.py +22 -0
  389. package/__fixtures__/-2.complex.openai/realtime__translations__client_secrets__create/input.json +498 -0
  390. package/__fixtures__/-2.complex.openai/realtime__translations__client_secrets__create/output.py +28 -0
  391. package/__fixtures__/-2.complex.openai/responses__cancel/input.json +9526 -0
  392. package/__fixtures__/-2.complex.openai/responses__cancel/output.py +16 -0
  393. package/__fixtures__/-2.complex.openai/responses__compact__create/input.json +8721 -0
  394. package/__fixtures__/-2.complex.openai/responses__compact__create/output.py +22 -0
  395. package/__fixtures__/-2.complex.openai/responses__create/input.json +9862 -0
  396. package/__fixtures__/-2.complex.openai/responses__create/output.py +16 -0
  397. package/__fixtures__/-2.complex.openai/responses__delete/input.json +194 -0
  398. package/__fixtures__/-2.complex.openai/responses__delete/output.py +16 -0
  399. package/__fixtures__/-2.complex.openai/responses__input_items__list/input.json +6686 -0
  400. package/__fixtures__/-2.complex.openai/responses__input_items__list/output.py +25 -0
  401. package/__fixtures__/-2.complex.openai/responses__input_tokens__count/input.json +7368 -0
  402. package/__fixtures__/-2.complex.openai/responses__input_tokens__count/output.py +22 -0
  403. package/__fixtures__/-2.complex.openai/responses__retrieve/input.json +9550 -0
  404. package/__fixtures__/-2.complex.openai/responses__retrieve/output.py +18 -0
  405. package/__fixtures__/-2.complex.openai/skills__content/input.json +152 -0
  406. package/__fixtures__/-2.complex.openai/skills__content/output.py +16 -0
  407. package/__fixtures__/-2.complex.openai/skills__create/input.json +258 -0
  408. package/__fixtures__/-2.complex.openai/skills__create/output.py +14 -0
  409. package/__fixtures__/-2.complex.openai/skills__delete/input.json +186 -0
  410. package/__fixtures__/-2.complex.openai/skills__delete/output.py +16 -0
  411. package/__fixtures__/-2.complex.openai/skills__list/input.json +323 -0
  412. package/__fixtures__/-2.complex.openai/skills__list/output.py +17 -0
  413. package/__fixtures__/-2.complex.openai/skills__retrieve/input.json +226 -0
  414. package/__fixtures__/-2.complex.openai/skills__retrieve/output.py +16 -0
  415. package/__fixtures__/-2.complex.openai/skills__update/input.json +251 -0
  416. package/__fixtures__/-2.complex.openai/skills__update/output.py +16 -0
  417. package/__fixtures__/-2.complex.openai/skills__versions__content/input.json +166 -0
  418. package/__fixtures__/-2.complex.openai/skills__versions__content/output.py +24 -0
  419. package/__fixtures__/-2.complex.openai/skills__versions__create/input.json +284 -0
  420. package/__fixtures__/-2.complex.openai/skills__versions__create/output.py +24 -0
  421. package/__fixtures__/-2.complex.openai/skills__versions__delete/input.json +209 -0
  422. package/__fixtures__/-2.complex.openai/skills__versions__delete/output.py +24 -0
  423. package/__fixtures__/-2.complex.openai/skills__versions__list/input.json +341 -0
  424. package/__fixtures__/-2.complex.openai/skills__versions__list/output.py +25 -0
  425. package/__fixtures__/-2.complex.openai/skills__versions__retrieve/input.json +240 -0
  426. package/__fixtures__/-2.complex.openai/skills__versions__retrieve/output.py +24 -0
  427. package/__fixtures__/-2.complex.openai/uploads__cancel/input.json +407 -0
  428. package/__fixtures__/-2.complex.openai/uploads__cancel/output.py +16 -0
  429. package/__fixtures__/-2.complex.openai/uploads__complete/input.json +443 -0
  430. package/__fixtures__/-2.complex.openai/uploads__complete/output.py +18 -0
  431. package/__fixtures__/-2.complex.openai/uploads__create/input.json +501 -0
  432. package/__fixtures__/-2.complex.openai/uploads__create/output.py +16 -0
  433. package/__fixtures__/-2.complex.openai/uploads__parts__create/input.json +229 -0
  434. package/__fixtures__/-2.complex.openai/uploads__parts__create/output.py +24 -0
  435. package/__fixtures__/-2.complex.openai/vector_stores__create/input.json +507 -0
  436. package/__fixtures__/-2.complex.openai/vector_stores__create/output.py +16 -0
  437. package/__fixtures__/-2.complex.openai/vector_stores__delete/input.json +184 -0
  438. package/__fixtures__/-2.complex.openai/vector_stores__delete/output.py +16 -0
  439. package/__fixtures__/-2.complex.openai/vector_stores__file_batches__cancel/input.json +300 -0
  440. package/__fixtures__/-2.complex.openai/vector_stores__file_batches__cancel/output.py +24 -0
  441. package/__fixtures__/-2.complex.openai/vector_stores__file_batches__create/input.json +314 -0
  442. package/__fixtures__/-2.complex.openai/vector_stores__file_batches__create/output.py +22 -0
  443. package/__fixtures__/-2.complex.openai/vector_stores__file_batches__list_files/input.json +571 -0
  444. package/__fixtures__/-2.complex.openai/vector_stores__file_batches__list_files/output.py +27 -0
  445. package/__fixtures__/-2.complex.openai/vector_stores__file_batches__retrieve/input.json +302 -0
  446. package/__fixtures__/-2.complex.openai/vector_stores__file_batches__retrieve/output.py +24 -0
  447. package/__fixtures__/-2.complex.openai/vector_stores__files__content/input.json +249 -0
  448. package/__fixtures__/-2.complex.openai/vector_stores__files__content/output.py +25 -0
  449. package/__fixtures__/-2.complex.openai/vector_stores__files__create/input.json +527 -0
  450. package/__fixtures__/-2.complex.openai/vector_stores__files__create/output.py +24 -0
  451. package/__fixtures__/-2.complex.openai/vector_stores__files__delete/input.json +198 -0
  452. package/__fixtures__/-2.complex.openai/vector_stores__files__delete/output.py +24 -0
  453. package/__fixtures__/-2.complex.openai/vector_stores__files__list/input.json +562 -0
  454. package/__fixtures__/-2.complex.openai/vector_stores__files__list/output.py +25 -0
  455. package/__fixtures__/-2.complex.openai/vector_stores__files__retrieve/input.json +432 -0
  456. package/__fixtures__/-2.complex.openai/vector_stores__files__retrieve/output.py +24 -0
  457. package/__fixtures__/-2.complex.openai/vector_stores__files__update/input.json +455 -0
  458. package/__fixtures__/-2.complex.openai/vector_stores__files__update/output.py +24 -0
  459. package/__fixtures__/-2.complex.openai/vector_stores__list/input.json +468 -0
  460. package/__fixtures__/-2.complex.openai/vector_stores__list/output.py +17 -0
  461. package/__fixtures__/-2.complex.openai/vector_stores__retrieve/input.json +366 -0
  462. package/__fixtures__/-2.complex.openai/vector_stores__retrieve/output.py +16 -0
  463. package/__fixtures__/-2.complex.openai/vector_stores__search/input.json +637 -0
  464. package/__fixtures__/-2.complex.openai/vector_stores__search/output.py +19 -0
  465. package/__fixtures__/-2.complex.openai/vector_stores__update/input.json +409 -0
  466. package/__fixtures__/-2.complex.openai/vector_stores__update/output.py +18 -0
  467. package/__fixtures__/-2.complex.openai/videos__characters__create/input.json +216 -0
  468. package/__fixtures__/-2.complex.openai/videos__characters__create/output.py +22 -0
  469. package/__fixtures__/-2.complex.openai/videos__characters__retrieve/input.json +193 -0
  470. package/__fixtures__/-2.complex.openai/videos__characters__retrieve/output.py +22 -0
  471. package/__fixtures__/-2.complex.openai/videos__create/input.json +465 -0
  472. package/__fixtures__/-2.complex.openai/videos__create/output.py +16 -0
  473. package/__fixtures__/-2.complex.openai/videos__delete/input.json +190 -0
  474. package/__fixtures__/-2.complex.openai/videos__delete/output.py +16 -0
  475. package/__fixtures__/-2.complex.openai/videos__download_content/input.json +181 -0
  476. package/__fixtures__/-2.complex.openai/videos__download_content/output.py +18 -0
  477. package/__fixtures__/-2.complex.openai/videos__edits__create/input.json +422 -0
  478. package/__fixtures__/-2.complex.openai/videos__edits__create/output.py +20 -0
  479. package/__fixtures__/-2.complex.openai/videos__extensions__create/input.json +446 -0
  480. package/__fixtures__/-2.complex.openai/videos__extensions__create/output.py +20 -0
  481. package/__fixtures__/-2.complex.openai/videos__list/input.json +477 -0
  482. package/__fixtures__/-2.complex.openai/videos__list/output.py +17 -0
  483. package/__fixtures__/-2.complex.openai/videos__remix/input.json +405 -0
  484. package/__fixtures__/-2.complex.openai/videos__remix/output.py +16 -0
  485. package/__fixtures__/-2.complex.openai/videos__retrieve/input.json +380 -0
  486. package/__fixtures__/-2.complex.openai/videos__retrieve/output.py +16 -0
  487. package/__fixtures__/1.basic/input.json +249 -0
  488. package/__fixtures__/1.basic/output/petstore/__init__.py +6 -0
  489. package/__fixtures__/1.basic/output/petstore/_client.py +21 -0
  490. package/__fixtures__/1.basic/output/petstore/_pagination.py +42 -0
  491. package/__fixtures__/1.basic/output/petstore/_transport.py +391 -0
  492. package/__fixtures__/1.basic/output/petstore/models.py +33 -0
  493. package/__fixtures__/1.basic/output/petstore/resources.py +25 -0
  494. package/__fixtures__/1.basic/output/pyproject.toml +12 -0
  495. package/__fixtures__/1.basic/output/tests/conftest.py +16 -0
  496. package/__fixtures__/1.basic/output/tests/test_pets.py +36 -0
  497. package/__fixtures__/1.basic/output/tests/utils.py +28 -0
  498. package/__fixtures__/2.wire/input.json +351 -0
  499. package/__fixtures__/2.wire/output/pyproject.toml +12 -0
  500. package/__fixtures__/2.wire/output/tests/conftest.py +16 -0
  501. package/__fixtures__/2.wire/output/tests/test_items.py +18 -0
  502. package/__fixtures__/2.wire/output/tests/test_tokens.py +17 -0
  503. package/__fixtures__/2.wire/output/tests/test_uploads.py +27 -0
  504. package/__fixtures__/2.wire/output/tests/utils.py +28 -0
  505. package/__fixtures__/2.wire/output/wire_service/__init__.py +6 -0
  506. package/__fixtures__/2.wire/output/wire_service/_client.py +23 -0
  507. package/__fixtures__/2.wire/output/wire_service/_pagination.py +42 -0
  508. package/__fixtures__/2.wire/output/wire_service/_transport.py +391 -0
  509. package/__fixtures__/2.wire/output/wire_service/models.py +44 -0
  510. package/__fixtures__/2.wire/output/wire_service/resources.py +38 -0
  511. package/__tests__/docs.test.ts +115 -0
  512. package/__tests__/e2e/harness.ts +79 -0
  513. package/__tests__/e2e/openai.test.ts +14 -0
  514. package/__tests__/e2e/publish.test.ts +19 -0
  515. package/__tests__/opensdk-python.test.ts +134 -0
  516. package/__tests__/utils.ts +117 -0
  517. package/biome.json +25 -0
  518. package/dist/index.cjs +1274 -0
  519. package/dist/index.cjs.map +1 -0
  520. package/dist/index.d.cts +32 -0
  521. package/dist/index.d.ts +32 -0
  522. package/dist/index.js +1246 -0
  523. package/dist/index.js.map +1 -0
  524. package/index.ts +1 -0
  525. package/package.json +30 -0
  526. package/src/emitter.ts +95 -0
  527. package/src/example-py.ts +60 -0
  528. package/src/index.ts +4 -0
  529. package/src/method.ts +13 -0
  530. package/src/naming.ts +45 -0
  531. package/src/project.ts +446 -0
  532. package/src/publish.ts +22 -0
  533. package/src/pytype.ts +86 -0
  534. package/src/runtime.ts +551 -0
  535. package/src/tests-py.ts +197 -0
  536. package/src/types.ts +8 -0
  537. package/tsconfig.json +18 -0
  538. package/tsup.config.ts +19 -0
  539. package/vitest.config.ts +8 -0
package/src/project.ts ADDED
@@ -0,0 +1,446 @@
1
+ import {
2
+ type Field,
3
+ type Method,
4
+ type NamedType,
5
+ type OpensdkSpecJson,
6
+ type Param,
7
+ type ResolvedSdkBehavior,
8
+ type Resource,
9
+ type TypeRef,
10
+ sdkBehavior,
11
+ } from '@xyd-js/opensdk-core';
12
+ import { type OperationPlan, planOperation } from '@xyd-js/opensdk-framework';
13
+
14
+ import { pyPageName } from './method';
15
+ import { pascalCase, pyModuleName, screamingSnakeCase, snakeCase } from './naming';
16
+ import { PyUses, isPassthroughType, optionalize, pyType } from './pytype';
17
+ import type { OpensdkPythonOptions } from './types';
18
+
19
+ // Pure per-file renderers for the Python SDK — the second target (after Go),
20
+ // proving the IR is language-agnostic. Dependency-free (stdlib urllib
21
+ // transport in runtime.ts); mirrors the Go emitter's minimum bar: typed
22
+ // signatures, decoded model returns, page containers, structured errors and
23
+ // wire-correct query/form/multipart encoding. Driven by the emitter plugin in
24
+ // emitter.ts; `opensdkPython()` there wraps it for back-compat.
25
+
26
+ export interface ResolvedPythonOptions {
27
+ pkg: string;
28
+ baseURL: string;
29
+ envVar: string;
30
+ }
31
+
32
+ export function resolvePythonOptions(spec: OpensdkSpecJson, options: OpensdkPythonOptions): ResolvedPythonOptions {
33
+ const pkg = options.packageName ?? pyModuleName(spec.info.title);
34
+ return {
35
+ pkg,
36
+ baseURL: options.baseURL ?? spec.servers?.[0] ?? '',
37
+ envVar: spec.security?.find((s) => s.envVar)?.envVar ?? `${screamingSnakeCase(pkg)}_API_KEY`,
38
+ };
39
+ }
40
+
41
+ /**
42
+ * The generated `pyproject.toml`: a PEP 621 project table with a `[build-system]`
43
+ * so `python -m build` produces an installable/publishable wheel + sdist. Publish
44
+ * identity (description/authors/license/urls) comes from `spec.info` — the OpenAPI
45
+ * `info` or an sdk.json `publish` override. Dependency-free (stdlib transport).
46
+ */
47
+ export function pyproject(pkg: string, spec: OpensdkSpecJson): string {
48
+ const info = spec.info;
49
+ const lines = [
50
+ '[build-system]',
51
+ 'requires = ["setuptools>=61"]',
52
+ 'build-backend = "setuptools.build_meta"',
53
+ '',
54
+ '[project]',
55
+ `name = ${JSON.stringify(pkg.replace(/_/g, '-'))}`,
56
+ `version = ${JSON.stringify(info.version || '0.0.0')}`,
57
+ ];
58
+ if (info.description) lines.push(`description = ${JSON.stringify(info.description)}`);
59
+ lines.push('requires-python = ">=3.9"');
60
+ if (info.contact?.name) lines.push(`authors = [{ name = ${JSON.stringify(info.contact.name)} }]`);
61
+ if (info.license?.identifier) lines.push(`license = { text = ${JSON.stringify(info.license.identifier)} }`);
62
+ const urls: string[] = [];
63
+ if (info.homepage) urls.push(`Homepage = ${JSON.stringify(info.homepage)}`);
64
+ if (info.repository) urls.push(`Repository = ${JSON.stringify(info.repository)}`);
65
+ if (urls.length) lines.push('', '[project.urls]', ...urls);
66
+ lines.push('', '[tool.setuptools.packages.find]', `include = [${JSON.stringify(pkg)}]`);
67
+ return `${lines.join('\n')}\n`;
68
+ }
69
+
70
+ // ---- models.py -----------------------------------------------------------
71
+
72
+ interface ModelsCtx {
73
+ uses: PyUses;
74
+ needsField: boolean;
75
+ }
76
+
77
+ export function modelsPy(spec: OpensdkSpecJson): string {
78
+ const ctx: ModelsCtx = { uses: new PyUses(), needsField: false };
79
+ // Ordering matters: a struct's field annotations are lazy (`from __future__
80
+ // import annotations`), so structs/enums may appear in any order. But an
81
+ // alias/union assignment `X = list[Y]` is evaluated EAGERLY at import, so Y
82
+ // must already be defined. Emit all structs/enums first, then the alias group
83
+ // topologically sorted so an alias that references another alias comes after it.
84
+ const types = spec.types || [];
85
+ const aliasKinds = new Set(['alias', 'union']);
86
+ const structsEnums = types.filter((t) => !aliasKinds.has(t.kind));
87
+ const aliases = orderAliases(types.filter((t) => aliasKinds.has(t.kind)));
88
+ const decls = [...structsEnums, ...aliases].map((t) => namedType(t, ctx)).filter(Boolean);
89
+ const lines = [
90
+ 'from __future__ import annotations',
91
+ '',
92
+ `from dataclasses import dataclass${ctx.needsField ? ', field' : ''}`,
93
+ 'from enum import Enum',
94
+ ];
95
+ const typingLine = ctx.uses.typingImport();
96
+ if (typingLine) lines.push(typingLine);
97
+ return `${lines.join('\n')}\n\n\n${decls.join('\n\n\n')}\n`;
98
+ }
99
+
100
+ /** All named-type references inside a TypeRef tree (for alias dependency ordering). */
101
+ function typeRefNames(ref: TypeRef | undefined, out: Set<string>): void {
102
+ if (!ref) return;
103
+ if (ref.kind === 'ref' && ref.name) out.add(ref.name);
104
+ typeRefNames(ref.items as TypeRef | undefined, out);
105
+ typeRefNames(ref.values as TypeRef | undefined, out);
106
+ }
107
+
108
+ /**
109
+ * Topologically order the alias/union group so an alias whose RHS references
110
+ * another alias is emitted after it (the RHS is eagerly evaluated at import).
111
+ * References to structs/enums are ignored (already emitted above); cycles fall
112
+ * back to input order (unreachable for list/dict/Any alias forms).
113
+ */
114
+ function orderAliases(aliases: NamedType[]): NamedType[] {
115
+ const byName = new Map(aliases.map((a) => [a.name, a]));
116
+ const ordered: NamedType[] = [];
117
+ const done = new Set<string>();
118
+ const visiting = new Set<string>();
119
+ const visit = (a: NamedType) => {
120
+ if (done.has(a.name) || visiting.has(a.name)) return;
121
+ visiting.add(a.name);
122
+ const refs = new Set<string>();
123
+ if (a.kind === 'alias') typeRefNames(a.of as TypeRef | undefined, refs);
124
+ for (const r of refs) {
125
+ const dep = byName.get(r);
126
+ if (dep && dep !== a) visit(dep);
127
+ }
128
+ visiting.delete(a.name);
129
+ done.add(a.name);
130
+ ordered.push(a);
131
+ };
132
+ for (const a of aliases) visit(a);
133
+ return ordered;
134
+ }
135
+
136
+ function namedType(type: NamedType, ctx: ModelsCtx): string {
137
+ switch (type.kind) {
138
+ case 'enum':
139
+ return enumType(type);
140
+ case 'alias':
141
+ return `${pascalCase(type.name)} = ${pyType(type.of, ctx.uses)}`;
142
+ case 'union':
143
+ ctx.uses.use('Any');
144
+ return `${pascalCase(type.name)} = Any`;
145
+ default:
146
+ return structType(type, ctx);
147
+ }
148
+ }
149
+
150
+ function structType(type: NamedType, ctx: ModelsCtx): string {
151
+ const name = pascalCase(type.name);
152
+ const fields = type.fields || [];
153
+ if (fields.length === 0) return `@dataclass\nclass ${name}:\n pass`;
154
+ // Required fields first (no default), then optional (Optional[...] = None).
155
+ const required = fields.filter((f) => f.required);
156
+ const optional = fields.filter((f) => !f.required);
157
+ const lines = [...required, ...optional].map((f) => structFieldLine(f, ctx));
158
+ return `@dataclass\nclass ${name}:\n${lines.join('\n')}`;
159
+ }
160
+
161
+ /**
162
+ * One dataclass field. When the Python name differs from the wire name the
163
+ * raw name is kept in `field(metadata={"wire": ...})` so the runtime's
164
+ * encode/decode stay wire-correct.
165
+ */
166
+ function structFieldLine(f: Field, ctx: ModelsCtx): string {
167
+ const py = snakeCase(f.name);
168
+ const type = pyType(f.type, ctx.uses);
169
+ const wire = py === f.name ? null : `metadata={"wire": ${JSON.stringify(f.name)}}`;
170
+ if (f.required) {
171
+ if (!wire) return ` ${py}: ${type}`;
172
+ ctx.needsField = true;
173
+ return ` ${py}: ${type} = field(${wire})`;
174
+ }
175
+ const opt = optionalize(type, ctx.uses);
176
+ if (!wire) return ` ${py}: ${opt} = None`;
177
+ ctx.needsField = true;
178
+ return ` ${py}: ${opt} = field(default=None, ${wire})`;
179
+ }
180
+
181
+ function enumType(type: NamedType): string {
182
+ const name = pascalCase(type.name);
183
+ const base = type.base === 'integer' ? 'int' : 'str';
184
+ const values = type.values || [];
185
+ if (values.length === 0) return `class ${name}(${base}, Enum):\n pass`;
186
+ const members = values.map((v) => {
187
+ const member = screamingSnakeCase(String(v.name ?? v.value)) || 'VALUE';
188
+ const lit = base === 'int' ? String(v.value) : JSON.stringify(String(v.value));
189
+ return ` ${member} = ${lit}`;
190
+ });
191
+ return `class ${name}(${base}, Enum):\n${members.join('\n')}`;
192
+ }
193
+
194
+ // ---- resources.py --------------------------------------------------------
195
+
196
+ interface ResourcesCtx {
197
+ types: Map<string, NamedType>;
198
+ /** The resolved runtime-behavior policies (sdk block over canonical defaults). */
199
+ behavior: ResolvedSdkBehavior;
200
+ uses: PyUses;
201
+ /** Extra names imported from ._transport (decode, join_csv). */
202
+ transportImports: Set<string>;
203
+ /** Page containers imported from ._pagination. */
204
+ pages: Set<'CursorPage' | 'Page'>;
205
+ }
206
+
207
+ export function resourcesPy(spec: OpensdkSpecJson, types: Map<string, NamedType>): string {
208
+ const ctx: ResourcesCtx = {
209
+ types,
210
+ behavior: sdkBehavior(spec),
211
+ uses: new PyUses(),
212
+ transportImports: new Set(),
213
+ pages: new Set(),
214
+ };
215
+ const classes: string[] = [];
216
+ const emit = (resources: Resource[], parent: string[]) => {
217
+ for (const r of resources) {
218
+ const segments = [...parent, r.name];
219
+ classes.push(resourceClass(r, segments, ctx));
220
+ if (r.resources?.length) emit(r.resources, segments);
221
+ }
222
+ };
223
+ emit(spec.resources || [], []);
224
+
225
+ const lines = ['from __future__ import annotations', ''];
226
+ const typingLine = ctx.uses.typingImport();
227
+ if (typingLine) lines.push(typingLine, '');
228
+ if (ctx.pages.size > 0) {
229
+ const pageNames = (['CursorPage', 'Page'] as const).filter((n) => ctx.pages.has(n));
230
+ lines.push(`from ._pagination import ${pageNames.join(', ')}`);
231
+ }
232
+ const transportNames = ['Transport', ...['decode', 'join_csv'].filter((n) => ctx.transportImports.has(n))];
233
+ lines.push(`from ._transport import ${transportNames.join(', ')}`);
234
+ lines.push('from .models import * # noqa: F401,F403');
235
+ return `${lines.join('\n')}\n\n\n${classes.join('\n\n\n')}\n`;
236
+ }
237
+
238
+ /**
239
+ * The globally-unique resource class name, path-qualified by the FULL segment
240
+ * chain from root (mirrors the Go emitter's `serviceTypeName`). Two different
241
+ * `roles` resources under different parents (`projects.roles` vs
242
+ * `projects.groups.roles`) therefore get distinct class names
243
+ * (`ProjectsRolesResource` vs `ProjectsGroupsRolesResource`) instead of one
244
+ * shadowing the other in the single generated `resources.py` module. Attribute
245
+ * (field) names stay local (`self.roles`), like the Go emitter.
246
+ */
247
+ function resourceClassName(segments: string[]): string {
248
+ return `${segments.map((s) => pascalCase(s)).join('')}Resource`;
249
+ }
250
+
251
+ function resourceClass(resource: Resource, segments: string[], ctx: ResourcesCtx): string {
252
+ const cls = resourceClassName(segments);
253
+ const subs = resource.resources || [];
254
+ const ctorLines = [' self._transport = transport'];
255
+ for (const sub of subs)
256
+ ctorLines.push(` self.${snakeCase(sub.name)} = ${resourceClassName([...segments, sub.name])}(transport)`);
257
+ const ctor = ` def __init__(self, transport: Transport) -> None:\n${ctorLines.join('\n')}`;
258
+ const methods = (resource.methods || []).map((m) => methodDef(m, ctx));
259
+ return `class ${cls}:\n${[ctor, ...methods].join('\n\n')}`;
260
+ }
261
+
262
+ function methodDef(method: Method, ctx: ResourcesCtx): string {
263
+ const plan = planOperation(method, ctx.types);
264
+ const name = snakeCase(method.action);
265
+ const { path: pathParams, query: queryParams, header: headerParams } = plan.paramGroups;
266
+ const rawContentType = plan.binaryContentType;
267
+
268
+ // Signature: positional path args, then keyword-only query/header/body params.
269
+ const positional = pathParams.map((p) => `${snakeCase(p.name)}: ${pyType(p.type, ctx.uses)}`);
270
+ const kwArgs: string[] = [];
271
+ for (const p of [...queryParams, ...headerParams]) kwArgs.push(paramArg(p, ctx));
272
+ const bodyParams = bodyFieldList(method, ctx.types);
273
+ for (const b of bodyParams) {
274
+ const type = pyType(b.type, ctx.uses);
275
+ kwArgs.push(
276
+ b.required ? `${snakeCase(b.name)}: ${type}` : `${snakeCase(b.name)}: ${optionalize(type, ctx.uses)} = None`,
277
+ );
278
+ }
279
+ const params = ['self', ...positional, ...(kwArgs.length ? ['*', ...kwArgs] : [])].join(', ');
280
+
281
+ const httpMethod = method.httpMethod.toUpperCase();
282
+ const callArgs = [JSON.stringify(httpMethod), pathExpr(method.path, pathParams.length > 0)];
283
+ if (queryParams.length) {
284
+ callArgs.push(`query={${queryParams.map((q) => queryEntry(q, ctx)).join(', ')}}`);
285
+ }
286
+ if (bodyParams.length) {
287
+ const entries = bodyParams.map((b) => `${JSON.stringify(b.name)}: ${snakeCase(b.name)}`).join(', ');
288
+ callArgs.push(`body={${entries}}`);
289
+ }
290
+ // Header params go on the wire under their raw names; binary downloads also
291
+ // send an Accept header for the primary content type (user params win).
292
+ const headerEntries = headerParams.map((h) => `${JSON.stringify(h.wireName ?? h.name)}: ${snakeCase(h.name)}`);
293
+ if (rawContentType) headerEntries.unshift(`"Accept": ${JSON.stringify(rawContentType)}`);
294
+ if (headerEntries.length) callArgs.push(`headers={${headerEntries.join(', ')}}`);
295
+ // Body encoding: the IR encoding (json|multipart|form) normally decides, but a
296
+ // body that carries a binary field (bytes / file-like) must NOT be json.dumps'd
297
+ // even when the spec labels it application/json — some specs (e.g. OpenAI's
298
+ // `skills` upload) declare a json content type over a `format: binary` field.
299
+ // Route those through the multipart encoder, mirroring the Go apiform encoder.
300
+ let encoding = plan.encoding ?? 'json';
301
+ if (bodyParams.length && encoding === 'json' && bodyParams.some((b) => isBinaryTypeRef(b.type, ctx.types))) {
302
+ encoding = 'multipart';
303
+ }
304
+ if (bodyParams.length && encoding !== 'json') callArgs.push(`encoding=${JSON.stringify(encoding)}`);
305
+ if (rawContentType) callArgs.push('raw=True');
306
+ // sdk.idempotency: flagged methods get a transport-generated key (one per
307
+ // logical call, stable across retries) under the policy header name.
308
+ if (plan.injectIdempotencyKey && ctx.behavior.idempotency.autoGenerateForPost) {
309
+ callArgs.push('idempotency=True');
310
+ }
311
+
312
+ const call = `self._transport.request(${callArgs.join(', ')})`;
313
+ const { annotation, body } = returnPlan(plan, call, ctx);
314
+ const guards = pathParamGuards(pathParams);
315
+ const fullBody = guards ? `${guards}\n${body}` : body;
316
+ return ` def ${name}(${params}) -> ${annotation}:\n${fullBody}`;
317
+ }
318
+
319
+ /**
320
+ * Guard statements raised at the top of a method for each required string path
321
+ * param: reject the empty string BEFORE building the path (an empty segment
322
+ * would otherwise silently collapse `/pets/{id}` to the collection endpoint).
323
+ * Matches openai-python and the Go emitter's guard; the generated test suite's
324
+ * test_path_params_* variant asserts it fires.
325
+ */
326
+ function pathParamGuards(pathParams: Param[]): string {
327
+ const lines: string[] = [];
328
+ for (const p of pathParams) {
329
+ if (p.type?.kind !== 'scalar' || p.type.scalar !== 'string' || p.required === false) continue;
330
+ const n = snakeCase(p.name);
331
+ lines.push(` if not ${n}:`);
332
+ lines.push(` raise ValueError(f"Expected a non-empty value for \`${n}\` but received {${n}!r}")`);
333
+ }
334
+ return lines.join('\n');
335
+ }
336
+
337
+ function paramArg(p: Param, ctx: ResourcesCtx): string {
338
+ const type = pyType(p.type, ctx.uses);
339
+ if (p.required) return `${snakeCase(p.name)}: ${type}`;
340
+ return `${snakeCase(p.name)}: ${optionalize(type, ctx.uses)} = None`;
341
+ }
342
+
343
+ /**
344
+ * One `wire-name: value` query entry. Exploded arrays are sent as repeated
345
+ * keys by the transport (urlencode doseq); explode=false arrays comma-join.
346
+ */
347
+ function queryEntry(q: Param, ctx: ResourcesCtx): string {
348
+ const wire = JSON.stringify(q.wireName ?? q.name);
349
+ const value = snakeCase(q.name);
350
+ if (q.type?.kind === 'array' && q.explode === false) {
351
+ ctx.transportImports.add('join_csv');
352
+ return `${wire}: join_csv(${value})`;
353
+ }
354
+ return `${wire}: ${value}`;
355
+ }
356
+
357
+ /** The return annotation plus the method body (indented statement lines). */
358
+ function returnPlan(plan: OperationPlan, call: string, ctx: ResourcesCtx): { annotation: string; body: string } {
359
+ const { method } = plan;
360
+ if (plan.binaryContentType) return { annotation: 'bytes', body: ` return ${call}` };
361
+ const page = pyPageName(plan);
362
+ if (page) {
363
+ ctx.pages.add(page);
364
+ const item = pyType(method.pagination?.itemType as TypeRef | undefined, ctx.uses);
365
+ return { annotation: `${page}[${item}]`, body: ` return ${page}.from_response(${item}, ${call})` };
366
+ }
367
+ const primary = method.primaryResponse as TypeRef | undefined;
368
+ if (!primary) return { annotation: 'None', body: ` ${call}` };
369
+ const type = pyType(primary, ctx.uses);
370
+ if (isPassthroughType(type)) return { annotation: type, body: ` return ${call}` };
371
+ ctx.transportImports.add('decode');
372
+ return { annotation: type, body: ` return decode(${type}, ${call})` };
373
+ }
374
+
375
+ interface BodyField {
376
+ name: string;
377
+ type: TypeRef;
378
+ required: boolean;
379
+ }
380
+
381
+ /**
382
+ * Whether a TypeRef ultimately carries binary bytes (`format: binary`),
383
+ * following array items and named union/alias refs. Struct/enum refs are never
384
+ * binary. A `seen` set guards recursive/self-referential unions.
385
+ */
386
+ function isBinaryTypeRef(ref: TypeRef | undefined, types: Map<string, NamedType>, seen = new Set<string>()): boolean {
387
+ if (!ref) return false;
388
+ if (ref.kind === 'scalar') return ref.scalar === 'string' && ref.format === 'binary';
389
+ if (ref.kind === 'array') return isBinaryTypeRef(ref.items as TypeRef | undefined, types, seen);
390
+ if (ref.kind === 'ref' && ref.name) {
391
+ if (seen.has(ref.name)) return false;
392
+ seen.add(ref.name);
393
+ const named = types.get(ref.name);
394
+ if (!named) return false;
395
+ if (named.kind === 'union') {
396
+ return (named.variants || []).some((v) => isBinaryTypeRef(v as TypeRef, types, seen));
397
+ }
398
+ if (named.kind === 'alias') return isBinaryTypeRef(named.of as TypeRef | undefined, types, seen);
399
+ }
400
+ return false;
401
+ }
402
+
403
+ function bodyFieldList(method: Method, types: Map<string, NamedType>): BodyField[] {
404
+ const ref = method.requestBody?.type;
405
+ if (ref?.kind !== 'ref' || !ref.name) return [];
406
+ const named = types.get(ref.name);
407
+ return (named?.fields || []).map((f) => ({ name: f.name, type: f.type, required: f.required === true }));
408
+ }
409
+
410
+ function pathExpr(path: string, hasParams: boolean): string {
411
+ const p = path.startsWith('/') ? path : `/${path}`;
412
+ if (!hasParams) return JSON.stringify(p);
413
+ // Replace {wire} with {snake} and emit an f-string.
414
+ const fstr = p.replace(/\{([^}]+)\}/g, (_, name) => `{${snakeCase(name)}}`);
415
+ return `f${JSON.stringify(fstr)}`;
416
+ }
417
+
418
+ // ---- _client.py ----------------------------------------------------------
419
+
420
+ export function clientPy(spec: OpensdkSpecJson, envVar: string): string {
421
+ const resources = spec.resources || [];
422
+ const attrLines = resources.map(
423
+ (r) => ` self.${snakeCase(r.name)} = ${resourceClassName([r.name])}(self._transport)`,
424
+ );
425
+ const imports = resources.map((r) => resourceClassName([r.name])).join(', ');
426
+ return `from __future__ import annotations
427
+
428
+ import os
429
+ from typing import Optional
430
+
431
+ from ._transport import Transport
432
+ from .resources import ${imports}
433
+
434
+
435
+ class Client:
436
+ def __init__(
437
+ self,
438
+ api_key: Optional[str] = None,
439
+ base_url: Optional[str] = None,
440
+ timeout: Optional[float] = None,
441
+ ) -> None:
442
+ key = api_key if api_key is not None else os.environ.get(${JSON.stringify(envVar)})
443
+ self._transport = Transport(base_url=base_url, api_key=key, timeout=timeout)
444
+ ${attrLines.join('\n')}
445
+ `;
446
+ }
package/src/publish.ts ADDED
@@ -0,0 +1,22 @@
1
+ import { type EmitterPublishOptions, runCommand } from '@xyd-js/opensdk-framework';
2
+
3
+ /**
4
+ * Publish the generated Python SDK to a PyPI-compatible index: `python -m build`
5
+ * (needs the PyPA `build` package) then `twine upload`. Auth via TWINE_* env; the
6
+ * token becomes TWINE_PASSWORD with the `__token__` username convention.
7
+ */
8
+ export function publishPython(dir: string, opts: EmitterPublishOptions = {}): void {
9
+ runCommand('python3', ['-m', 'build'], { cwd: dir });
10
+ if (opts.dryRun) return;
11
+ const args = ['upload'];
12
+ if (opts.registry) args.push('--repository-url', opts.registry);
13
+ args.push('dist/*');
14
+ runCommand('twine', args, {
15
+ cwd: dir,
16
+ env: {
17
+ ...process.env,
18
+ TWINE_USERNAME: process.env.TWINE_USERNAME ?? '__token__',
19
+ TWINE_PASSWORD: opts.token ?? process.env.TWINE_PASSWORD ?? 'opensdk',
20
+ },
21
+ });
22
+ }
package/src/pytype.ts ADDED
@@ -0,0 +1,86 @@
1
+ import type { TypeRef } from '@xyd-js/opensdk-core';
2
+
3
+ import { pascalCase } from './naming';
4
+
5
+ /**
6
+ * Records which `typing` names a rendered file actually uses so the generated
7
+ * import line stays minimal (mirrors the Go emitter's Imports tracker).
8
+ */
9
+ export class PyUses {
10
+ private readonly typing = new Set<string>();
11
+
12
+ use(name: string): void {
13
+ this.typing.add(name);
14
+ }
15
+
16
+ /** The `from typing import ...` line, or null when nothing is used. */
17
+ typingImport(): string | null {
18
+ if (this.typing.size === 0) return null;
19
+ const order = ['Any', 'BinaryIO', 'Optional', 'Union'];
20
+ return `from typing import ${order.filter((n) => this.typing.has(n)).join(', ')}`;
21
+ }
22
+ }
23
+
24
+ /**
25
+ * Map an IR TypeRef to a Python type expression (PEP 585 builtin generics:
26
+ * list[T] / dict[str, T]). Every returned expression is ALSO a valid runtime
27
+ * value, so generated code can hand it to the transport's `decode()`.
28
+ */
29
+ export function pyType(ref: TypeRef | undefined, uses: PyUses): string {
30
+ if (!ref) return anyType(uses);
31
+ const base = pyBase(ref, uses);
32
+ return ref.nullable ? optionalize(base, uses) : base;
33
+ }
34
+
35
+ function pyBase(ref: TypeRef, uses: PyUses): string {
36
+ switch (ref.kind) {
37
+ case 'scalar':
38
+ return pyScalar(ref.scalar, ref.format, uses);
39
+ case 'ref':
40
+ return ref.name ? pascalCase(ref.name) : anyType(uses);
41
+ case 'array':
42
+ return `list[${pyType(ref.items as TypeRef | undefined, uses)}]`;
43
+ case 'map':
44
+ return `dict[str, ${pyType(ref.values as TypeRef | undefined, uses)}]`;
45
+ default:
46
+ return anyType(uses);
47
+ }
48
+ }
49
+
50
+ function pyScalar(scalar: string | undefined, format: string | undefined, uses: PyUses): string {
51
+ switch (scalar) {
52
+ case 'string':
53
+ if (format === 'binary') {
54
+ // Upload fields accept raw bytes or an open file-like object.
55
+ uses.use('Union');
56
+ uses.use('BinaryIO');
57
+ return 'Union[bytes, BinaryIO]';
58
+ }
59
+ return 'str';
60
+ case 'integer':
61
+ return 'int';
62
+ case 'number':
63
+ return 'float';
64
+ case 'boolean':
65
+ return 'bool';
66
+ default:
67
+ return anyType(uses);
68
+ }
69
+ }
70
+
71
+ function anyType(uses: PyUses): string {
72
+ uses.use('Any');
73
+ return 'Any';
74
+ }
75
+
76
+ /** Wrap a type in Optional[...] unless it already is. */
77
+ export function optionalize(type: string, uses: PyUses): string {
78
+ if (type.startsWith('Optional[')) return type;
79
+ uses.use('Optional');
80
+ return `Optional[${type}]`;
81
+ }
82
+
83
+ /** Type expressions `decode()` can't refine — methods return the raw JSON as-is. */
84
+ export function isPassthroughType(type: string): boolean {
85
+ return type === 'Any' || type === 'str' || type === 'int' || type === 'float' || type === 'bool';
86
+ }