magic_hour 0.18.0__tar.gz → 0.19.0__tar.gz

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 (164) hide show
  1. {magic_hour-0.18.0 → magic_hour-0.19.0}/PKG-INFO +5 -1
  2. {magic_hour-0.18.0 → magic_hour-0.19.0}/README.md +4 -0
  3. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/__init__.py +2 -0
  4. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/query.py +23 -10
  5. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/request.py +27 -21
  6. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/environment.py +1 -1
  7. magic_hour-0.19.0/magic_hour/resources/v1/ai_gif_generator/README.md +31 -0
  8. magic_hour-0.19.0/magic_hour/resources/v1/ai_gif_generator/__init__.py +4 -0
  9. magic_hour-0.19.0/magic_hour/resources/v1/ai_gif_generator/client.py +117 -0
  10. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/client.py +6 -0
  11. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/__init__.py +2 -0
  12. magic_hour-0.19.0/magic_hour/types/models/v1_ai_gif_generator_create_response.py +25 -0
  13. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_image_projects_get_response.py +1 -1
  14. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/__init__.py +12 -0
  15. magic_hour-0.19.0/magic_hour/types/params/v1_ai_gif_generator_create_body.py +37 -0
  16. magic_hour-0.19.0/magic_hour/types/params/v1_ai_gif_generator_create_body_style.py +28 -0
  17. {magic_hour-0.18.0 → magic_hour-0.19.0}/pyproject.toml +1 -1
  18. {magic_hour-0.18.0 → magic_hour-0.19.0}/LICENSE +0 -0
  19. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/__init__.py +0 -0
  20. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/client.py +0 -0
  21. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/api_error.py +0 -0
  22. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/auth.py +0 -0
  23. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/base_client.py +0 -0
  24. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/binary_response.py +0 -0
  25. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/response.py +0 -0
  26. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/type_utils.py +0 -0
  27. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/core/utils.py +0 -0
  28. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/__init__.py +0 -0
  29. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_clothes_changer/README.md +0 -0
  30. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_clothes_changer/__init__.py +0 -0
  31. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_clothes_changer/client.py +0 -0
  32. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_face_editor/README.md +0 -0
  33. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_face_editor/__init__.py +0 -0
  34. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_face_editor/client.py +0 -0
  35. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_headshot_generator/README.md +0 -0
  36. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_headshot_generator/__init__.py +0 -0
  37. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_headshot_generator/client.py +0 -0
  38. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_image_generator/README.md +0 -0
  39. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_image_generator/__init__.py +0 -0
  40. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_image_generator/client.py +0 -0
  41. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_image_upscaler/README.md +0 -0
  42. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_image_upscaler/__init__.py +0 -0
  43. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_image_upscaler/client.py +0 -0
  44. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_meme_generator/README.md +0 -0
  45. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_meme_generator/__init__.py +0 -0
  46. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_meme_generator/client.py +0 -0
  47. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_photo_editor/README.md +0 -0
  48. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_photo_editor/__init__.py +0 -0
  49. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_photo_editor/client.py +0 -0
  50. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_qr_code_generator/README.md +0 -0
  51. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_qr_code_generator/__init__.py +0 -0
  52. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_qr_code_generator/client.py +0 -0
  53. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_talking_photo/README.md +0 -0
  54. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_talking_photo/__init__.py +0 -0
  55. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/ai_talking_photo/client.py +0 -0
  56. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/animation/README.md +0 -0
  57. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/animation/__init__.py +0 -0
  58. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/animation/client.py +0 -0
  59. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/face_swap/README.md +0 -0
  60. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/face_swap/__init__.py +0 -0
  61. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/face_swap/client.py +0 -0
  62. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/face_swap_photo/README.md +0 -0
  63. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/face_swap_photo/__init__.py +0 -0
  64. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/face_swap_photo/client.py +0 -0
  65. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/files/__init__.py +0 -0
  66. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/files/client.py +0 -0
  67. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/files/upload_urls/README.md +0 -0
  68. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/files/upload_urls/__init__.py +0 -0
  69. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/files/upload_urls/client.py +0 -0
  70. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/image_background_remover/README.md +0 -0
  71. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/image_background_remover/__init__.py +0 -0
  72. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/image_background_remover/client.py +0 -0
  73. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/image_projects/README.md +0 -0
  74. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/image_projects/__init__.py +0 -0
  75. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/image_projects/client.py +0 -0
  76. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/image_to_video/README.md +0 -0
  77. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/image_to_video/__init__.py +0 -0
  78. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/image_to_video/client.py +0 -0
  79. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/lip_sync/README.md +0 -0
  80. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/lip_sync/__init__.py +0 -0
  81. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/lip_sync/client.py +0 -0
  82. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/photo_colorizer/README.md +0 -0
  83. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/photo_colorizer/__init__.py +0 -0
  84. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/photo_colorizer/client.py +0 -0
  85. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/text_to_video/README.md +0 -0
  86. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/text_to_video/__init__.py +0 -0
  87. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/text_to_video/client.py +0 -0
  88. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/video_projects/README.md +0 -0
  89. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/video_projects/__init__.py +0 -0
  90. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/video_projects/client.py +0 -0
  91. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/video_to_video/README.md +0 -0
  92. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/video_to_video/__init__.py +0 -0
  93. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/resources/v1/video_to_video/client.py +0 -0
  94. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_ai_clothes_changer_create_response.py +0 -0
  95. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_ai_face_editor_create_response.py +0 -0
  96. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_ai_headshot_generator_create_response.py +0 -0
  97. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_ai_image_generator_create_response.py +0 -0
  98. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_ai_image_upscaler_create_response.py +0 -0
  99. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_ai_meme_generator_create_response.py +0 -0
  100. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_ai_photo_editor_create_response.py +0 -0
  101. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_ai_qr_code_generator_create_response.py +0 -0
  102. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_ai_talking_photo_create_response.py +0 -0
  103. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_animation_create_response.py +0 -0
  104. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_face_swap_create_response.py +0 -0
  105. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_face_swap_photo_create_response.py +0 -0
  106. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_files_upload_urls_create_response.py +0 -0
  107. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_files_upload_urls_create_response_items_item.py +0 -0
  108. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_image_background_remover_create_response.py +0 -0
  109. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_image_projects_get_response_downloads_item.py +0 -0
  110. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_image_projects_get_response_error.py +0 -0
  111. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_image_to_video_create_response.py +0 -0
  112. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_lip_sync_create_response.py +0 -0
  113. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_photo_colorizer_create_response.py +0 -0
  114. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_text_to_video_create_response.py +0 -0
  115. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_video_projects_get_response.py +0 -0
  116. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_video_projects_get_response_download.py +0 -0
  117. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_video_projects_get_response_downloads_item.py +0 -0
  118. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_video_projects_get_response_error.py +0 -0
  119. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/models/v1_video_to_video_create_response.py +0 -0
  120. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_clothes_changer_create_body.py +0 -0
  121. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_clothes_changer_create_body_assets.py +0 -0
  122. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_face_editor_create_body.py +0 -0
  123. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_face_editor_create_body_assets.py +0 -0
  124. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_face_editor_create_body_style.py +0 -0
  125. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_headshot_generator_create_body.py +0 -0
  126. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_headshot_generator_create_body_assets.py +0 -0
  127. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_headshot_generator_create_body_style.py +0 -0
  128. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_image_generator_create_body.py +0 -0
  129. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_image_generator_create_body_style.py +0 -0
  130. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_image_upscaler_create_body.py +0 -0
  131. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_image_upscaler_create_body_assets.py +0 -0
  132. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_image_upscaler_create_body_style.py +0 -0
  133. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_meme_generator_create_body.py +0 -0
  134. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_meme_generator_create_body_style.py +0 -0
  135. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_photo_editor_create_body.py +0 -0
  136. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_photo_editor_create_body_assets.py +0 -0
  137. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_photo_editor_create_body_style.py +0 -0
  138. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_qr_code_generator_create_body.py +0 -0
  139. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_qr_code_generator_create_body_style.py +0 -0
  140. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_talking_photo_create_body.py +0 -0
  141. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_ai_talking_photo_create_body_assets.py +0 -0
  142. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_animation_create_body.py +0 -0
  143. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_animation_create_body_assets.py +0 -0
  144. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_animation_create_body_style.py +0 -0
  145. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_face_swap_create_body.py +0 -0
  146. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_face_swap_create_body_assets.py +0 -0
  147. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_face_swap_photo_create_body.py +0 -0
  148. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_face_swap_photo_create_body_assets.py +0 -0
  149. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_files_upload_urls_create_body.py +0 -0
  150. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_files_upload_urls_create_body_items_item.py +0 -0
  151. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_image_background_remover_create_body.py +0 -0
  152. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_image_background_remover_create_body_assets.py +0 -0
  153. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_image_to_video_create_body.py +0 -0
  154. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_image_to_video_create_body_assets.py +0 -0
  155. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_image_to_video_create_body_style.py +0 -0
  156. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_lip_sync_create_body.py +0 -0
  157. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_lip_sync_create_body_assets.py +0 -0
  158. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_photo_colorizer_create_body.py +0 -0
  159. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_photo_colorizer_create_body_assets.py +0 -0
  160. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_text_to_video_create_body.py +0 -0
  161. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_text_to_video_create_body_style.py +0 -0
  162. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_video_to_video_create_body.py +0 -0
  163. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_video_to_video_create_body_assets.py +0 -0
  164. {magic_hour-0.18.0 → magic_hour-0.19.0}/magic_hour/types/params/v1_video_to_video_create_body_style.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: magic_hour
3
- Version: 0.18.0
3
+ Version: 0.19.0
4
4
  Summary: Python SDK for Magic Hour API
5
5
  Requires-Python: >=3.8,<4.0
6
6
  Classifier: Programming Language :: Python :: 3
@@ -67,6 +67,10 @@ client = AsyncClient(token="my api key")
67
67
 
68
68
  * [create](magic_hour/resources/v1/ai_face_editor/README.md#create) - AI Face Editor
69
69
 
70
+ ### [v1.ai_gif_generator](magic_hour/resources/v1/ai_gif_generator/README.md)
71
+
72
+ * [create](magic_hour/resources/v1/ai_gif_generator/README.md#create) - AI GIFs
73
+
70
74
  ### [v1.ai_headshot_generator](magic_hour/resources/v1/ai_headshot_generator/README.md)
71
75
 
72
76
  * [create](magic_hour/resources/v1/ai_headshot_generator/README.md#create) - AI Headshots
@@ -49,6 +49,10 @@ client = AsyncClient(token="my api key")
49
49
 
50
50
  * [create](magic_hour/resources/v1/ai_face_editor/README.md#create) - AI Face Editor
51
51
 
52
+ ### [v1.ai_gif_generator](magic_hour/resources/v1/ai_gif_generator/README.md)
53
+
54
+ * [create](magic_hour/resources/v1/ai_gif_generator/README.md#create) - AI GIFs
55
+
52
56
  ### [v1.ai_headshot_generator](magic_hour/resources/v1/ai_headshot_generator/README.md)
53
57
 
54
58
  * [create](magic_hour/resources/v1/ai_headshot_generator/README.md#create) - AI Headshots
@@ -18,6 +18,7 @@ from .request import (
18
18
  filter_not_given,
19
19
  to_content,
20
20
  to_encodable,
21
+ to_form_urlencoded,
21
22
  RequestOptions,
22
23
  default_request_options,
23
24
  )
@@ -42,6 +43,7 @@ __all__ = [
42
43
  "OAuth2ClientCredentialsForm",
43
44
  "OAuth2PasswordForm",
44
45
  "to_encodable",
46
+ "to_form_urlencoded",
45
47
  "filter_not_given",
46
48
  "to_content",
47
49
  "encode_query_param",
@@ -1,3 +1,5 @@
1
+ import json
2
+
1
3
  from typing import Any, Dict, Union
2
4
  from typing_extensions import Literal, Sequence
3
5
  from urllib.parse import quote_plus, quote
@@ -9,13 +11,14 @@ import httpx
9
11
  QueryParams = Dict[
10
12
  str, Union[httpx._types.PrimitiveData, Sequence[httpx._types.PrimitiveData]]
11
13
  ]
14
+ QueryParamStyle = Literal["form", "spaceDelimited", "pipeDelimited", "deepObject"]
12
15
 
13
16
 
14
17
  def encode_query_param(
15
18
  params: QueryParams,
16
19
  name: str,
17
20
  value: Any,
18
- style: Literal["form", "spaceDelimited", "pipeDelimited", "deepObject"] = "form",
21
+ style: QueryParamStyle = "form",
19
22
  explode: bool = True,
20
23
  ):
21
24
  if style == "form":
@@ -30,6 +33,13 @@ def encode_query_param(
30
33
  raise NotImplementedError(f"query param style '{style}' not implemented")
31
34
 
32
35
 
36
+ def _query_str(val: Any) -> str:
37
+ """jsonify value without wrapping quotes for strings"""
38
+ if isinstance(val, str):
39
+ return val
40
+ return json.dumps(val)
41
+
42
+
33
43
  def _encode_form(params: QueryParams, name: str, value: Any, explode: bool):
34
44
  """
35
45
  Encodes query params in the `form` style as defined by OpenAPI with both explode and non-explode
@@ -37,18 +47,18 @@ def _encode_form(params: QueryParams, name: str, value: Any, explode: bool):
37
47
  """
38
48
  if isinstance(value, list) and not explode:
39
49
  # non-explode form lists should be encoded like /users?id=3,4,5
40
- params[name] = quote_plus(",".join(map(str, value)))
50
+ params[name] = quote_plus(",".join(map(_query_str, value)))
41
51
  elif isinstance(value, dict):
42
52
  if explode:
43
53
  # explode form objects should be encoded like /users?key0=val0&key1=val1
44
54
  # the input param name will be omitted
45
55
  for k, v in value.items():
46
- params[k] = quote_plus(str(v))
56
+ params[k] = quote_plus(_query_str(v))
47
57
  else:
48
58
  # non-explode form objects should be encoded like /users?id=key0,val0,key1,val1
49
59
  encoded_chunks = []
50
60
  for k, v in value.items():
51
- encoded_chunks.extend([str(k), str(v)])
61
+ encoded_chunks.extend([str(k), _query_str(v)])
52
62
  params[name] = quote_plus(",".join(encoded_chunks))
53
63
  else:
54
64
  params[name] = value
@@ -61,7 +71,7 @@ def _encode_spaced_delimited(params: QueryParams, name: str, value: Any, explode
61
71
  """
62
72
  if isinstance(value, list) and not explode:
63
73
  # non-explode spaceDelimited lists should be encoded like /users?id=3%204%205
64
- params[name] = quote(" ".join(map(str, value)))
74
+ params[name] = quote(" ".join(map(_query_str, value)))
65
75
  else:
66
76
  # according to the docs, spaceDelimited + explode=false only effects lists,
67
77
  # all other encodings are marked as n/a or are the same as `form` style
@@ -76,7 +86,7 @@ def _encode_pipe_delimited(params: QueryParams, name: str, value: Any, explode:
76
86
  """
77
87
  if isinstance(value, list) and not explode:
78
88
  # non-explode pipeDelimited lists should be encoded like /users?id=3|4|5
79
- params[name] = quote("|".join(map(str, value)))
89
+ params[name] = quote("|".join(map(_query_str, value)))
80
90
  else:
81
91
  # according to the docs, pipeDelimited + explode=false only effects lists,
82
92
  # all other encodings are marked as n/a or are the same as `form` style
@@ -85,12 +95,15 @@ def _encode_pipe_delimited(params: QueryParams, name: str, value: Any, explode:
85
95
 
86
96
 
87
97
  def _encode_deep_object(params: QueryParams, name: str, value: Any, explode: bool):
88
- """ """
89
- if isinstance(value, dict):
98
+ """
99
+ Encodes query params in the `deepObject` style as defined by with both explode and non-explode
100
+ variants.
101
+ """
102
+ if isinstance(value, (dict, list)):
90
103
  _encode_deep_object_key(params, name, value)
91
104
  else:
92
105
  # according to the docs, deepObject style only applies to
93
- # object encodes, encodings for primitives & arrays are listed as n/a,
106
+ # object encodes, encodings for primitives are listed as n/a,
94
107
  # fall back on form style as it is the default for query params
95
108
  _encode_form(params, name, value, explode)
96
109
 
@@ -103,4 +116,4 @@ def _encode_deep_object_key(params: QueryParams, key: str, value: Any):
103
116
  for i, v in enumerate(value):
104
117
  _encode_deep_object_key(params, f"{key}[{i}]", v)
105
118
  else:
106
- params[key] = value
119
+ params[key] = _query_str(value)
@@ -1,12 +1,11 @@
1
- from typing import Any, Dict, Type, Union, Sequence, List
2
- from urllib.parse import quote_plus
1
+ from typing import Any, Dict, Type, Union, List, Mapping
3
2
 
4
3
  import httpx
5
4
  from typing_extensions import TypedDict, Required, NotRequired
6
5
  from pydantic import TypeAdapter, BaseModel
7
6
 
8
7
  from .type_utils import NotGiven
9
- from .query import QueryParams
8
+ from .query import QueryParams, QueryParamStyle, encode_query_param
10
9
 
11
10
  """
12
11
  Request configuration and utility functions for handling HTTP requests.
@@ -96,6 +95,31 @@ def to_encodable(
96
95
  return model_dump(validated_item)
97
96
 
98
97
 
98
+ def to_form_urlencoded(
99
+ *,
100
+ item: Any,
101
+ dump_with: Union[Type, Union[Type, Any]],
102
+ style: Mapping[str, QueryParamStyle],
103
+ explode: Mapping[str, bool],
104
+ ) -> Mapping[str, Any]:
105
+ """
106
+ Encodes object as x-www-form-urlencoded according to style and explode options
107
+ """
108
+ encoded = to_encodable(item=item, dump_with=dump_with)
109
+
110
+ if not isinstance(encoded, dict):
111
+ raise TypeError("x-www-form-urlencoded data must be an object at the top level")
112
+
113
+ form_data: QueryParams = {}
114
+
115
+ for key, val in encoded.items():
116
+ key_style = style.get(key, "form")
117
+ key_explode = explode.get(key, key_style == "form")
118
+ encode_query_param(form_data, key, val, style=key_style, explode=key_explode)
119
+
120
+ return form_data
121
+
122
+
99
123
  def to_content(*, file: httpx._types.FileTypes) -> httpx._types.RequestContent:
100
124
  """
101
125
  Converts the various ways files can be provided to something that is accepted by
@@ -112,24 +136,6 @@ def to_content(*, file: httpx._types.FileTypes) -> httpx._types.RequestContent:
112
136
  return file_content
113
137
 
114
138
 
115
- def encode_param(
116
- value: Any, explode: bool
117
- ) -> Union[httpx._types.PrimitiveData, Sequence[httpx._types.PrimitiveData]]:
118
- """
119
- Encodes parameter values for use in URLs.
120
-
121
- Handles both simple values and collections, with special handling for
122
- unexploded collections (combining them with commas) versus exploded ones.
123
-
124
- Args:
125
- explode: Whether to explode collections into separate parameters
126
- """
127
- if isinstance(value, (list, dict)) and not explode:
128
- return quote_plus(",".join(map(str, value)))
129
- else:
130
- return value
131
-
132
-
133
139
  def filter_not_given(value: Any) -> Any:
134
140
  """Helper function to recursively filter out NotGiven values"""
135
141
  if isinstance(value, NotGiven):
@@ -5,4 +5,4 @@ class Environment(enum.Enum):
5
5
  """Pre-defined base URLs for the API"""
6
6
 
7
7
  ENVIRONMENT = "https://api.magichour.ai"
8
- MOCK_SERVER = "https://api.sideko.dev/v1/mock/magichour/magic-hour/0.18.0"
8
+ MOCK_SERVER = "https://api.sideko.dev/v1/mock/magichour/magic-hour/0.19.0"
@@ -0,0 +1,31 @@
1
+
2
+ ### create <a name="create"></a>
3
+ AI GIFs
4
+
5
+ Create an AI GIF. Each GIF costs 5 frames.
6
+
7
+ **API Endpoint**: `POST /v1/ai-gif-generator`
8
+
9
+ #### Synchronous Client
10
+
11
+ ```python
12
+ from magic_hour import Client
13
+ from os import getenv
14
+
15
+ client = Client(token=getenv("API_TOKEN"))
16
+ res = client.v1.ai_gif_generator.create(
17
+ style={"prompt": "Cute dancing cat, pixel art"}, name="Ai Gif gif"
18
+ )
19
+ ```
20
+
21
+ #### Asynchronous Client
22
+
23
+ ```python
24
+ from magic_hour import AsyncClient
25
+ from os import getenv
26
+
27
+ client = AsyncClient(token=getenv("API_TOKEN"))
28
+ res = await client.v1.ai_gif_generator.create(
29
+ style={"prompt": "Cute dancing cat, pixel art"}, name="Ai Gif gif"
30
+ )
31
+ ```
@@ -0,0 +1,4 @@
1
+ from .client import AiGifGeneratorClient, AsyncAiGifGeneratorClient
2
+
3
+
4
+ __all__ = ["AiGifGeneratorClient", "AsyncAiGifGeneratorClient"]
@@ -0,0 +1,117 @@
1
+ import typing
2
+
3
+ from magic_hour.core import (
4
+ AsyncBaseClient,
5
+ RequestOptions,
6
+ SyncBaseClient,
7
+ default_request_options,
8
+ to_encodable,
9
+ type_utils,
10
+ )
11
+ from magic_hour.types import models, params
12
+
13
+
14
+ class AiGifGeneratorClient:
15
+ def __init__(self, *, base_client: SyncBaseClient):
16
+ self._base_client = base_client
17
+
18
+ def create(
19
+ self,
20
+ *,
21
+ style: params.V1AiGifGeneratorCreateBodyStyle,
22
+ name: typing.Union[
23
+ typing.Optional[str], type_utils.NotGiven
24
+ ] = type_utils.NOT_GIVEN,
25
+ request_options: typing.Optional[RequestOptions] = None,
26
+ ) -> models.V1AiGifGeneratorCreateResponse:
27
+ """
28
+ AI GIFs
29
+
30
+ Create an AI GIF. Each GIF costs 5 frames.
31
+
32
+ POST /v1/ai-gif-generator
33
+
34
+ Args:
35
+ name: The name of gif
36
+ style: V1AiGifGeneratorCreateBodyStyle
37
+ request_options: Additional options to customize the HTTP request
38
+
39
+ Returns:
40
+ Success
41
+
42
+ Raises:
43
+ ApiError: A custom exception class that provides additional context
44
+ for API errors, including the HTTP status code and response body.
45
+
46
+ Examples:
47
+ ```py
48
+ client.v1.ai_gif_generator.create(
49
+ style={"prompt": "Cute dancing cat, pixel art"}, name="Ai Gif gif"
50
+ )
51
+ ```
52
+ """
53
+ _json = to_encodable(
54
+ item={"name": name, "style": style},
55
+ dump_with=params._SerializerV1AiGifGeneratorCreateBody,
56
+ )
57
+ return self._base_client.request(
58
+ method="POST",
59
+ path="/v1/ai-gif-generator",
60
+ auth_names=["bearerAuth"],
61
+ json=_json,
62
+ cast_to=models.V1AiGifGeneratorCreateResponse,
63
+ request_options=request_options or default_request_options(),
64
+ )
65
+
66
+
67
+ class AsyncAiGifGeneratorClient:
68
+ def __init__(self, *, base_client: AsyncBaseClient):
69
+ self._base_client = base_client
70
+
71
+ async def create(
72
+ self,
73
+ *,
74
+ style: params.V1AiGifGeneratorCreateBodyStyle,
75
+ name: typing.Union[
76
+ typing.Optional[str], type_utils.NotGiven
77
+ ] = type_utils.NOT_GIVEN,
78
+ request_options: typing.Optional[RequestOptions] = None,
79
+ ) -> models.V1AiGifGeneratorCreateResponse:
80
+ """
81
+ AI GIFs
82
+
83
+ Create an AI GIF. Each GIF costs 5 frames.
84
+
85
+ POST /v1/ai-gif-generator
86
+
87
+ Args:
88
+ name: The name of gif
89
+ style: V1AiGifGeneratorCreateBodyStyle
90
+ request_options: Additional options to customize the HTTP request
91
+
92
+ Returns:
93
+ Success
94
+
95
+ Raises:
96
+ ApiError: A custom exception class that provides additional context
97
+ for API errors, including the HTTP status code and response body.
98
+
99
+ Examples:
100
+ ```py
101
+ await client.v1.ai_gif_generator.create(
102
+ style={"prompt": "Cute dancing cat, pixel art"}, name="Ai Gif gif"
103
+ )
104
+ ```
105
+ """
106
+ _json = to_encodable(
107
+ item={"name": name, "style": style},
108
+ dump_with=params._SerializerV1AiGifGeneratorCreateBody,
109
+ )
110
+ return await self._base_client.request(
111
+ method="POST",
112
+ path="/v1/ai-gif-generator",
113
+ auth_names=["bearerAuth"],
114
+ json=_json,
115
+ cast_to=models.V1AiGifGeneratorCreateResponse,
116
+ request_options=request_options or default_request_options(),
117
+ )
@@ -7,6 +7,10 @@ from magic_hour.resources.v1.ai_face_editor import (
7
7
  AiFaceEditorClient,
8
8
  AsyncAiFaceEditorClient,
9
9
  )
10
+ from magic_hour.resources.v1.ai_gif_generator import (
11
+ AiGifGeneratorClient,
12
+ AsyncAiGifGeneratorClient,
13
+ )
10
14
  from magic_hour.resources.v1.ai_headshot_generator import (
11
15
  AiHeadshotGeneratorClient,
12
16
  AsyncAiHeadshotGeneratorClient,
@@ -80,6 +84,7 @@ class V1Client:
80
84
  self.video_projects = VideoProjectsClient(base_client=self._base_client)
81
85
  self.ai_clothes_changer = AiClothesChangerClient(base_client=self._base_client)
82
86
  self.ai_face_editor = AiFaceEditorClient(base_client=self._base_client)
87
+ self.ai_gif_generator = AiGifGeneratorClient(base_client=self._base_client)
83
88
  self.ai_headshot_generator = AiHeadshotGeneratorClient(
84
89
  base_client=self._base_client
85
90
  )
@@ -114,6 +119,7 @@ class AsyncV1Client:
114
119
  base_client=self._base_client
115
120
  )
116
121
  self.ai_face_editor = AsyncAiFaceEditorClient(base_client=self._base_client)
122
+ self.ai_gif_generator = AsyncAiGifGeneratorClient(base_client=self._base_client)
117
123
  self.ai_headshot_generator = AsyncAiHeadshotGeneratorClient(
118
124
  base_client=self._base_client
119
125
  )
@@ -1,5 +1,6 @@
1
1
  from .v1_ai_clothes_changer_create_response import V1AiClothesChangerCreateResponse
2
2
  from .v1_ai_face_editor_create_response import V1AiFaceEditorCreateResponse
3
+ from .v1_ai_gif_generator_create_response import V1AiGifGeneratorCreateResponse
3
4
  from .v1_ai_headshot_generator_create_response import (
4
5
  V1AiHeadshotGeneratorCreateResponse,
5
6
  )
@@ -40,6 +41,7 @@ from .v1_video_to_video_create_response import V1VideoToVideoCreateResponse
40
41
  __all__ = [
41
42
  "V1AiClothesChangerCreateResponse",
42
43
  "V1AiFaceEditorCreateResponse",
44
+ "V1AiGifGeneratorCreateResponse",
43
45
  "V1AiHeadshotGeneratorCreateResponse",
44
46
  "V1AiImageGeneratorCreateResponse",
45
47
  "V1AiImageUpscalerCreateResponse",
@@ -0,0 +1,25 @@
1
+ import pydantic
2
+
3
+
4
+ class V1AiGifGeneratorCreateResponse(pydantic.BaseModel):
5
+ """
6
+ Success
7
+ """
8
+
9
+ model_config = pydantic.ConfigDict(
10
+ arbitrary_types_allowed=True,
11
+ populate_by_name=True,
12
+ )
13
+
14
+ frame_cost: int = pydantic.Field(
15
+ alias="frame_cost",
16
+ )
17
+ """
18
+ The frame cost of the image generation
19
+ """
20
+ id: str = pydantic.Field(
21
+ alias="id",
22
+ )
23
+ """
24
+ Unique ID of the image. This value can be used in the [get image project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch additional details such as status
25
+ """
@@ -72,5 +72,5 @@ class V1ImageProjectsGetResponse(pydantic.BaseModel):
72
72
  alias="type",
73
73
  )
74
74
  """
75
- The type of the image project. Possible values are AI_HEADSHOT, AI_IMAGE, IMAGE_UPSCALER, FACE_SWAP, PHOTO_EDITOR, QR_CODE, BACKGROUND_REMOVER, CLOTHES_CHANGER, AI_MEME, FACE_EDITOR, PHOTO_COLORIZER
75
+ The type of the image project. Possible values are AI_HEADSHOT, AI_IMAGE, IMAGE_UPSCALER, FACE_SWAP, PHOTO_EDITOR, QR_CODE, BACKGROUND_REMOVER, CLOTHES_CHANGER, AI_MEME, FACE_EDITOR, PHOTO_COLORIZER, AI_GIF
76
76
  """
@@ -18,6 +18,14 @@ from .v1_ai_face_editor_create_body_style import (
18
18
  V1AiFaceEditorCreateBodyStyle,
19
19
  _SerializerV1AiFaceEditorCreateBodyStyle,
20
20
  )
21
+ from .v1_ai_gif_generator_create_body import (
22
+ V1AiGifGeneratorCreateBody,
23
+ _SerializerV1AiGifGeneratorCreateBody,
24
+ )
25
+ from .v1_ai_gif_generator_create_body_style import (
26
+ V1AiGifGeneratorCreateBodyStyle,
27
+ _SerializerV1AiGifGeneratorCreateBodyStyle,
28
+ )
21
29
  from .v1_ai_headshot_generator_create_body import (
22
30
  V1AiHeadshotGeneratorCreateBody,
23
31
  _SerializerV1AiHeadshotGeneratorCreateBody,
@@ -183,6 +191,8 @@ __all__ = [
183
191
  "V1AiFaceEditorCreateBody",
184
192
  "V1AiFaceEditorCreateBodyAssets",
185
193
  "V1AiFaceEditorCreateBodyStyle",
194
+ "V1AiGifGeneratorCreateBody",
195
+ "V1AiGifGeneratorCreateBodyStyle",
186
196
  "V1AiHeadshotGeneratorCreateBody",
187
197
  "V1AiHeadshotGeneratorCreateBodyAssets",
188
198
  "V1AiHeadshotGeneratorCreateBodyStyle",
@@ -228,6 +238,8 @@ __all__ = [
228
238
  "_SerializerV1AiFaceEditorCreateBody",
229
239
  "_SerializerV1AiFaceEditorCreateBodyAssets",
230
240
  "_SerializerV1AiFaceEditorCreateBodyStyle",
241
+ "_SerializerV1AiGifGeneratorCreateBody",
242
+ "_SerializerV1AiGifGeneratorCreateBodyStyle",
231
243
  "_SerializerV1AiHeadshotGeneratorCreateBody",
232
244
  "_SerializerV1AiHeadshotGeneratorCreateBodyAssets",
233
245
  "_SerializerV1AiHeadshotGeneratorCreateBodyStyle",
@@ -0,0 +1,37 @@
1
+ import pydantic
2
+ import typing
3
+ import typing_extensions
4
+
5
+ from .v1_ai_gif_generator_create_body_style import (
6
+ V1AiGifGeneratorCreateBodyStyle,
7
+ _SerializerV1AiGifGeneratorCreateBodyStyle,
8
+ )
9
+
10
+
11
+ class V1AiGifGeneratorCreateBody(typing_extensions.TypedDict):
12
+ """
13
+ V1AiGifGeneratorCreateBody
14
+ """
15
+
16
+ name: typing_extensions.NotRequired[str]
17
+ """
18
+ The name of gif
19
+ """
20
+
21
+ style: typing_extensions.Required[V1AiGifGeneratorCreateBodyStyle]
22
+
23
+
24
+ class _SerializerV1AiGifGeneratorCreateBody(pydantic.BaseModel):
25
+ """
26
+ Serializer for V1AiGifGeneratorCreateBody handling case conversions
27
+ and file omissions as dictated by the API
28
+ """
29
+
30
+ model_config = pydantic.ConfigDict(
31
+ populate_by_name=True,
32
+ )
33
+
34
+ name: typing.Optional[str] = pydantic.Field(alias="name", default=None)
35
+ style: _SerializerV1AiGifGeneratorCreateBodyStyle = pydantic.Field(
36
+ alias="style",
37
+ )
@@ -0,0 +1,28 @@
1
+ import pydantic
2
+ import typing_extensions
3
+
4
+
5
+ class V1AiGifGeneratorCreateBodyStyle(typing_extensions.TypedDict):
6
+ """
7
+ V1AiGifGeneratorCreateBodyStyle
8
+ """
9
+
10
+ prompt: typing_extensions.Required[str]
11
+ """
12
+ The prompt used for the GIF.
13
+ """
14
+
15
+
16
+ class _SerializerV1AiGifGeneratorCreateBodyStyle(pydantic.BaseModel):
17
+ """
18
+ Serializer for V1AiGifGeneratorCreateBodyStyle handling case conversions
19
+ and file omissions as dictated by the API
20
+ """
21
+
22
+ model_config = pydantic.ConfigDict(
23
+ populate_by_name=True,
24
+ )
25
+
26
+ prompt: str = pydantic.Field(
27
+ alias="prompt",
28
+ )
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "magic_hour"
3
- version = "0.18.0"
3
+ version = "0.19.0"
4
4
  description = "Python SDK for Magic Hour API"
5
5
  readme = "README.md"
6
6
  authors = []
File without changes