@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
@@ -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);