magic_hour 0.9.3__tar.gz → 0.9.4__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.

Potentially problematic release.


This version of magic_hour might be problematic. Click here for more details.

Files changed (132) hide show
  1. {magic_hour-0.9.3 → magic_hour-0.9.4}/PKG-INFO +1 -1
  2. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/core/__init__.py +2 -3
  3. magic_hour-0.9.4/magic_hour/core/query.py +106 -0
  4. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/core/request.py +3 -5
  5. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/core/utils.py +1 -1
  6. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/environment.py +1 -1
  7. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/get_v1_image_projects_id_response.py +1 -1
  8. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/get_v1_video_projects_id_response.py +1 -1
  9. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_ai_clothes_changer_response.py +1 -1
  10. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_ai_headshot_generator_response.py +1 -1
  11. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_ai_image_generator_response.py +1 -1
  12. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_ai_image_upscaler_response.py +1 -1
  13. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_ai_photo_editor_response.py +1 -1
  14. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_ai_qr_code_generator_response.py +1 -1
  15. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_animation_response.py +1 -1
  16. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_face_swap_photo_response.py +1 -1
  17. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_face_swap_response.py +1 -1
  18. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_image_background_remover_response.py +1 -1
  19. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_image_to_video_response.py +1 -1
  20. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_lip_sync_response.py +1 -1
  21. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_text_to_video_response.py +1 -1
  22. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_video_to_video_response.py +1 -1
  23. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_clothes_changer_body_assets.py +2 -2
  24. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_headshot_generator_body_assets.py +1 -1
  25. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_image_upscaler_body_assets.py +1 -1
  26. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_photo_editor_body_assets.py +1 -1
  27. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_animation_body_assets.py +2 -2
  28. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_face_swap_body_assets.py +2 -2
  29. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_face_swap_photo_body_assets.py +2 -2
  30. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_image_background_remover_body_assets.py +1 -1
  31. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_image_to_video_body_assets.py +1 -1
  32. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_lip_sync_body_assets.py +2 -2
  33. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_video_to_video_body_assets.py +1 -1
  34. {magic_hour-0.9.3 → magic_hour-0.9.4}/pyproject.toml +1 -1
  35. {magic_hour-0.9.3 → magic_hour-0.9.4}/LICENSE +0 -0
  36. {magic_hour-0.9.3 → magic_hour-0.9.4}/README.md +0 -0
  37. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/__init__.py +0 -0
  38. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/client.py +1 -1
  39. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/core/api_error.py +0 -0
  40. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/core/auth.py +0 -0
  41. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/core/base_client.py +0 -0
  42. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/core/binary_response.py +0 -0
  43. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/core/response.py +0 -0
  44. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/core/type_utils.py +0 -0
  45. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/__init__.py +0 -0
  46. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_clothes_changer/README.md +0 -0
  47. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_clothes_changer/__init__.py +0 -0
  48. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_clothes_changer/client.py +0 -0
  49. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_headshot_generator/README.md +0 -0
  50. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_headshot_generator/__init__.py +0 -0
  51. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_headshot_generator/client.py +0 -0
  52. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_image_generator/README.md +0 -0
  53. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_image_generator/__init__.py +0 -0
  54. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_image_generator/client.py +0 -0
  55. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_image_upscaler/README.md +0 -0
  56. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_image_upscaler/__init__.py +0 -0
  57. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_image_upscaler/client.py +0 -0
  58. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_photo_editor/README.md +0 -0
  59. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_photo_editor/__init__.py +0 -0
  60. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_photo_editor/client.py +0 -0
  61. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_qr_code_generator/README.md +0 -0
  62. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_qr_code_generator/__init__.py +0 -0
  63. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/ai_qr_code_generator/client.py +0 -0
  64. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/animation/README.md +0 -0
  65. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/animation/__init__.py +0 -0
  66. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/animation/client.py +0 -0
  67. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/client.py +0 -0
  68. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/face_swap/README.md +0 -0
  69. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/face_swap/__init__.py +0 -0
  70. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/face_swap/client.py +0 -0
  71. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/face_swap_photo/README.md +0 -0
  72. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/face_swap_photo/__init__.py +0 -0
  73. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/face_swap_photo/client.py +0 -0
  74. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/files/__init__.py +0 -0
  75. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/files/client.py +0 -0
  76. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/files/upload_urls/README.md +0 -0
  77. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/files/upload_urls/__init__.py +0 -0
  78. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/files/upload_urls/client.py +0 -0
  79. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/image_background_remover/README.md +0 -0
  80. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/image_background_remover/__init__.py +0 -0
  81. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/image_background_remover/client.py +0 -0
  82. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/image_projects/README.md +0 -0
  83. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/image_projects/__init__.py +0 -0
  84. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/image_projects/client.py +0 -0
  85. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/image_to_video/README.md +0 -0
  86. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/image_to_video/__init__.py +0 -0
  87. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/image_to_video/client.py +0 -0
  88. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/lip_sync/README.md +0 -0
  89. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/lip_sync/__init__.py +0 -0
  90. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/lip_sync/client.py +0 -0
  91. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/text_to_video/README.md +0 -0
  92. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/text_to_video/__init__.py +0 -0
  93. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/text_to_video/client.py +0 -0
  94. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/video_projects/README.md +0 -0
  95. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/video_projects/__init__.py +0 -0
  96. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/video_projects/client.py +0 -0
  97. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/video_to_video/README.md +0 -0
  98. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/video_to_video/__init__.py +0 -0
  99. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/resources/v1/video_to_video/client.py +0 -0
  100. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/__init__.py +0 -0
  101. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/get_v1_image_projects_id_response_downloads_item.py +0 -0
  102. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/get_v1_image_projects_id_response_error.py +0 -0
  103. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/get_v1_video_projects_id_response_download.py +0 -0
  104. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/get_v1_video_projects_id_response_downloads_item.py +0 -0
  105. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/get_v1_video_projects_id_response_error.py +0 -0
  106. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_files_upload_urls_response.py +0 -0
  107. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/models/post_v1_files_upload_urls_response_items_item.py +0 -0
  108. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/__init__.py +0 -0
  109. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_clothes_changer_body.py +0 -0
  110. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_headshot_generator_body.py +0 -0
  111. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_image_generator_body.py +0 -0
  112. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_image_generator_body_style.py +0 -0
  113. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_image_upscaler_body.py +0 -0
  114. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_image_upscaler_body_style.py +0 -0
  115. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_photo_editor_body.py +0 -0
  116. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_photo_editor_body_style.py +0 -0
  117. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_qr_code_generator_body.py +0 -0
  118. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_ai_qr_code_generator_body_style.py +0 -0
  119. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_animation_body.py +0 -0
  120. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_animation_body_style.py +0 -0
  121. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_face_swap_body.py +0 -0
  122. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_face_swap_photo_body.py +0 -0
  123. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_files_upload_urls_body.py +0 -0
  124. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_files_upload_urls_body_items_item.py +0 -0
  125. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_image_background_remover_body.py +0 -0
  126. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_image_to_video_body.py +0 -0
  127. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_image_to_video_body_style.py +0 -0
  128. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_lip_sync_body.py +0 -0
  129. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_text_to_video_body.py +0 -0
  130. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_text_to_video_body_style.py +0 -0
  131. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_video_to_video_body.py +0 -0
  132. {magic_hour-0.9.3 → magic_hour-0.9.4}/magic_hour/types/params/post_v1_video_to_video_body_style.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: magic_hour
3
- Version: 0.9.3
3
+ Version: 0.9.4
4
4
  Summary: Python SDK for Magic Hour API
5
5
  Requires-Python: >=3.8,<4.0
6
6
  Classifier: Programming Language :: Python :: 3
@@ -13,14 +13,13 @@ from .auth import (
13
13
  )
14
14
  from .base_client import AsyncBaseClient, BaseClient, SyncBaseClient
15
15
  from .binary_response import BinaryResponse
16
+ from .query import encode_query_param, QueryParams
16
17
  from .request import (
17
- encode_param,
18
18
  filter_not_given,
19
19
  to_content,
20
20
  to_encodable,
21
21
  RequestOptions,
22
22
  default_request_options,
23
- QueryParams,
24
23
  )
25
24
  from .response import from_encodable, AsyncStreamResponse, StreamResponse
26
25
 
@@ -45,7 +44,7 @@ __all__ = [
45
44
  "to_encodable",
46
45
  "filter_not_given",
47
46
  "to_content",
48
- "encode_param",
47
+ "encode_query_param",
49
48
  "from_encodable",
50
49
  "AsyncStreamResponse",
51
50
  "StreamResponse",
@@ -0,0 +1,106 @@
1
+ from typing import Any, Dict, Union
2
+ from typing_extensions import Literal, Sequence
3
+ from urllib.parse import quote_plus, quote
4
+
5
+ import httpx
6
+
7
+
8
+ # Type alias for query parameters that can handle both primitive data and sequences
9
+ QueryParams = Dict[
10
+ str, Union[httpx._types.PrimitiveData, Sequence[httpx._types.PrimitiveData]]
11
+ ]
12
+
13
+
14
+ def encode_query_param(
15
+ params: QueryParams,
16
+ name: str,
17
+ value: Any,
18
+ style: Literal["form", "spaceDelimited", "pipeDelimited", "deepObject"] = "form",
19
+ explode: bool = True,
20
+ ):
21
+ if style == "form":
22
+ _encode_form(params, name, value, explode)
23
+ elif style == "spaceDelimited":
24
+ _encode_spaced_delimited(params, name, value, explode)
25
+ elif style == "pipeDelimited":
26
+ _encode_pipe_delimited(params, name, value, explode)
27
+ elif style == "deepObject":
28
+ _encode_deep_object(params, name, value, explode)
29
+ else:
30
+ raise NotImplementedError(f"query param style '{style}' not implemented")
31
+
32
+
33
+ def _encode_form(params: QueryParams, name: str, value: Any, explode: bool):
34
+ """
35
+ Encodes query params in the `form` style as defined by OpenAPI with both explode and non-explode
36
+ variants.
37
+ """
38
+ if isinstance(value, list) and not explode:
39
+ # non-explode form lists should be encoded like /users?id=3,4,5
40
+ params[name] = quote_plus(",".join(map(str, value)))
41
+ elif isinstance(value, dict):
42
+ if explode:
43
+ # explode form objects should be encoded like /users?key0=val0&key1=val1
44
+ # the input param name will be omitted
45
+ for k, v in value.items():
46
+ params[k] = quote_plus(str(v))
47
+ else:
48
+ # non-explode form objects should be encoded like /users?id=key0,val0,key1,val1
49
+ encoded_chunks = []
50
+ for k, v in value.items():
51
+ encoded_chunks.extend([str(k), str(v)])
52
+ params[name] = quote_plus(",".join(encoded_chunks))
53
+ else:
54
+ params[name] = value
55
+
56
+
57
+ def _encode_spaced_delimited(params: QueryParams, name: str, value: Any, explode: bool):
58
+ """
59
+ Encodes query params in the `spaceDelimited` style as defined by OpenAPI with both explode and non-explode
60
+ variants.
61
+ """
62
+ if isinstance(value, list) and not explode:
63
+ # non-explode spaceDelimited lists should be encoded like /users?id=3%204%205
64
+ params[name] = quote(" ".join(map(str, value)))
65
+ else:
66
+ # according to the docs, spaceDelimited + explode=false only effects lists,
67
+ # all other encodings are marked as n/a or are the same as `form` style
68
+ # fall back on form style as it is the default for query params
69
+ _encode_form(params, name, value, explode)
70
+
71
+
72
+ def _encode_pipe_delimited(params: QueryParams, name: str, value: Any, explode: bool):
73
+ """
74
+ Encodes query params in the `pipeDelimited` style as defined by OpenAPI with both explode and non-explode
75
+ variants.
76
+ """
77
+ if isinstance(value, list) and not explode:
78
+ # non-explode pipeDelimited lists should be encoded like /users?id=3|4|5
79
+ params[name] = quote("|".join(map(str, value)))
80
+ else:
81
+ # according to the docs, pipeDelimited + explode=false only effects lists,
82
+ # all other encodings are marked as n/a or are the same as `form` style
83
+ # fall back on form style as it is the default for query params
84
+ _encode_form(params, name, value, explode)
85
+
86
+
87
+ def _encode_deep_object(params: QueryParams, name: str, value: Any, explode: bool):
88
+ """ """
89
+ if isinstance(value, dict):
90
+ _encode_deep_object_key(params, name, value)
91
+ else:
92
+ # according to the docs, deepObject style only applies to
93
+ # object encodes, encodings for primitives & arrays are listed as n/a,
94
+ # fall back on form style as it is the default for query params
95
+ _encode_form(params, name, value, explode)
96
+
97
+
98
+ def _encode_deep_object_key(params: QueryParams, key: str, value: Any):
99
+ if isinstance(value, dict):
100
+ for k, v in value.items():
101
+ _encode_deep_object_key(params, f"{key}[{k}]", v)
102
+ elif isinstance(value, list):
103
+ for i, v in enumerate(value):
104
+ _encode_deep_object_key(params, f"{key}[{i}]", v)
105
+ else:
106
+ params[key] = value
@@ -1,9 +1,12 @@
1
1
  from typing import Any, Dict, Type, Union, Sequence, List
2
2
  from urllib.parse import quote_plus
3
+
3
4
  import httpx
4
5
  from typing_extensions import TypedDict, Required, NotRequired
5
6
  from pydantic import TypeAdapter, BaseModel
7
+
6
8
  from .type_utils import NotGiven
9
+ from .query import QueryParams
7
10
 
8
11
  """
9
12
  Request configuration and utility functions for handling HTTP requests.
@@ -11,11 +14,6 @@ This module provides type definitions and helper functions for building
11
14
  and processing HTTP requests in a type-safe manner.
12
15
  """
13
16
 
14
- # Type alias for query parameters that can handle both primitive data and sequences
15
- QueryParams = Dict[
16
- str, Union[httpx._types.PrimitiveData, Sequence[httpx._types.PrimitiveData]]
17
- ]
18
-
19
17
 
20
18
  class RequestConfig(TypedDict):
21
19
  """
@@ -21,7 +21,7 @@ def get_response_type(headers: httpx.Headers) -> Literal["json", "text", "binary
21
21
  """Check response type based on content type"""
22
22
  content_type = headers.get("content-type")
23
23
 
24
- if re.search("^application/(.+\+)?json", content_type):
24
+ if re.search("^application/(.+[+])?json", content_type):
25
25
  return "json"
26
26
  elif re.search("^text/(.+)", content_type):
27
27
  return "text"
@@ -3,4 +3,4 @@ import enum
3
3
 
4
4
  class Environment(enum.Enum):
5
5
  ENVIRONMENT = "https://api.magichour.ai"
6
- MOCK_SERVER = "https://api.sideko.dev/v1/mock/magichour/magic-hour/0.9.3"
6
+ MOCK_SERVER = "https://api.sideko.dev/v1/mock/magichour/magic-hour/0.9.4"
@@ -40,7 +40,7 @@ class GetV1ImageProjectsIdResponse(pydantic.BaseModel):
40
40
  alias="id",
41
41
  )
42
42
  """
43
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
43
+ 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
44
44
  """
45
45
  image_count: int = pydantic.Field(
46
46
  alias="image_count",
@@ -67,7 +67,7 @@ class GetV1VideoProjectsIdResponse(pydantic.BaseModel):
67
67
  alias="id",
68
68
  )
69
69
  """
70
- Unique ID of the video. This value can be used in the [get video project API](/api/tag/video-projects/get/v1/video-projects/{id}) to fetch additional details such as status
70
+ Unique ID of the video. This value can be used in the [get video project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch additional details such as status
71
71
  """
72
72
  name: typing.Optional[str] = pydantic.Field(
73
73
  alias="name",
@@ -21,5 +21,5 @@ class PostV1AiClothesChangerResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
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
25
  """
@@ -21,5 +21,5 @@ class PostV1AiHeadshotGeneratorResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
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
25
  """
@@ -21,5 +21,5 @@ class PostV1AiImageGeneratorResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
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
25
  """
@@ -21,5 +21,5 @@ class PostV1AiImageUpscalerResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
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
25
  """
@@ -21,5 +21,5 @@ class PostV1AiPhotoEditorResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
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
25
  """
@@ -21,5 +21,5 @@ class PostV1AiQrCodeGeneratorResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
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
25
  """
@@ -21,5 +21,5 @@ class PostV1AnimationResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the video. This value can be used in the [get video project API](/api/tag/video-projects/get/v1/video-projects/{id}) to fetch additional details such as status
24
+ Unique ID of the video. This value can be used in the [get video project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch additional details such as status
25
25
  """
@@ -21,5 +21,5 @@ class PostV1FaceSwapPhotoResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
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
25
  """
@@ -21,5 +21,5 @@ class PostV1FaceSwapResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
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
25
  """
@@ -21,5 +21,5 @@ class PostV1ImageBackgroundRemoverResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
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
25
  """
@@ -21,5 +21,5 @@ class PostV1ImageToVideoResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the video. This value can be used in the [get video project API](/api/tag/video-projects/get/v1/video-projects/{id}) to fetch additional details such as status
24
+ Unique ID of the video. This value can be used in the [get video project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch additional details such as status
25
25
  """
@@ -21,5 +21,5 @@ class PostV1LipSyncResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the video. This value can be used in the [get video project API](/api/tag/video-projects/get/v1/video-projects/{id}) to fetch additional details such as status
24
+ Unique ID of the video. This value can be used in the [get video project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch additional details such as status
25
25
  """
@@ -21,5 +21,5 @@ class PostV1TextToVideoResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the video. This value can be used in the [get video project API](/api/tag/video-projects/get/v1/video-projects/{id}) to fetch additional details such as status
24
+ Unique ID of the video. This value can be used in the [get video project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch additional details such as status
25
25
  """
@@ -21,5 +21,5 @@ class PostV1VideoToVideoResponse(pydantic.BaseModel):
21
21
  alias="id",
22
22
  )
23
23
  """
24
- Unique ID of the video. This value can be used in the [get video project API](/api/tag/video-projects/get/v1/video-projects/{id}) to fetch additional details such as status
24
+ Unique ID of the video. This value can be used in the [get video project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch additional details such as status
25
25
  """
@@ -9,7 +9,7 @@ class PostV1AiClothesChangerBodyAssets(typing_extensions.TypedDict):
9
9
 
10
10
  garment_file_path: typing_extensions.Required[str]
11
11
  """
12
- The image of the outfit. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file..
12
+ The image of the outfit. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file..
13
13
  """
14
14
 
15
15
  garment_type: typing_extensions.Required[
@@ -18,7 +18,7 @@ class PostV1AiClothesChangerBodyAssets(typing_extensions.TypedDict):
18
18
 
19
19
  person_file_path: typing_extensions.Required[str]
20
20
  """
21
- The image with the person. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file..
21
+ The image with the person. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file..
22
22
  """
23
23
 
24
24
 
@@ -9,7 +9,7 @@ class PostV1AiHeadshotGeneratorBodyAssets(typing_extensions.TypedDict):
9
9
 
10
10
  image_file_path: typing_extensions.Required[str]
11
11
  """
12
- The image used to generate the headshot. This image must contain one detectable face. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
12
+ The image used to generate the headshot. This image must contain one detectable face. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
13
13
  """
14
14
 
15
15
 
@@ -9,7 +9,7 @@ class PostV1AiImageUpscalerBodyAssets(typing_extensions.TypedDict):
9
9
 
10
10
  image_file_path: typing_extensions.Required[str]
11
11
  """
12
- The image to upscale. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
12
+ The image to upscale. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
13
13
  """
14
14
 
15
15
 
@@ -9,7 +9,7 @@ class PostV1AiPhotoEditorBodyAssets(typing_extensions.TypedDict):
9
9
 
10
10
  image_file_path: typing_extensions.Required[str]
11
11
  """
12
- The image used to generate the output. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
12
+ The image used to generate the output. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
13
13
  """
14
14
 
15
15
 
@@ -10,7 +10,7 @@ class PostV1AnimationBodyAssets(typing_extensions.TypedDict):
10
10
 
11
11
  audio_file_path: typing_extensions.NotRequired[str]
12
12
  """
13
- The path of the input audio. This field is required if `audio_source` is `file`. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
13
+ The path of the input audio. This field is required if `audio_source` is `file`. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
14
14
  """
15
15
 
16
16
  audio_source: typing_extensions.Required[
@@ -22,7 +22,7 @@ class PostV1AnimationBodyAssets(typing_extensions.TypedDict):
22
22
 
23
23
  image_file_path: typing_extensions.NotRequired[str]
24
24
  """
25
- An initial image to use a the first frame of the video. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
25
+ An initial image to use a the first frame of the video. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
26
26
  """
27
27
 
28
28
  youtube_url: typing_extensions.NotRequired[str]
@@ -10,12 +10,12 @@ class PostV1FaceSwapBodyAssets(typing_extensions.TypedDict):
10
10
 
11
11
  image_file_path: typing_extensions.Required[str]
12
12
  """
13
- The path of the input image. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
13
+ The path of the input image. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
14
14
  """
15
15
 
16
16
  video_file_path: typing_extensions.NotRequired[str]
17
17
  """
18
- The path of the input video. This field is required if `video_source` is `file`. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
18
+ The path of the input video. This field is required if `video_source` is `file`. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
19
19
  """
20
20
 
21
21
  video_source: typing_extensions.Required[
@@ -9,12 +9,12 @@ class PostV1FaceSwapPhotoBodyAssets(typing_extensions.TypedDict):
9
9
 
10
10
  source_file_path: typing_extensions.Required[str]
11
11
  """
12
- This is the image from which the face is extracted. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
12
+ This is the image from which the face is extracted. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
13
13
  """
14
14
 
15
15
  target_file_path: typing_extensions.Required[str]
16
16
  """
17
- This is the image where the face from the source image will be placed. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
17
+ This is the image where the face from the source image will be placed. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
18
18
  """
19
19
 
20
20
 
@@ -9,7 +9,7 @@ class PostV1ImageBackgroundRemoverBodyAssets(typing_extensions.TypedDict):
9
9
 
10
10
  image_file_path: typing_extensions.Required[str]
11
11
  """
12
- The image used to generate the image. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
12
+ The image used to generate the image. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
13
13
  """
14
14
 
15
15
 
@@ -9,7 +9,7 @@ class PostV1ImageToVideoBodyAssets(typing_extensions.TypedDict):
9
9
 
10
10
  image_file_path: typing_extensions.Required[str]
11
11
  """
12
- The path of the image file. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
12
+ The path of the image file. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
13
13
  """
14
14
 
15
15
 
@@ -10,12 +10,12 @@ class PostV1LipSyncBodyAssets(typing_extensions.TypedDict):
10
10
 
11
11
  audio_file_path: typing_extensions.Required[str]
12
12
  """
13
- The path of the audio file. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
13
+ The path of the audio file. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
14
14
  """
15
15
 
16
16
  video_file_path: typing_extensions.NotRequired[str]
17
17
  """
18
- The path of the input video. This field is required if `video_source` is `file`. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
18
+ The path of the input video. This field is required if `video_source` is `file`. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
19
19
  """
20
20
 
21
21
  video_source: typing_extensions.Required[
@@ -10,7 +10,7 @@ class PostV1VideoToVideoBodyAssets(typing_extensions.TypedDict):
10
10
 
11
11
  video_file_path: typing_extensions.NotRequired[str]
12
12
  """
13
- The path of the input video. This field is required if `video_source` is `file`. This value can be either the `file_path` field from the response of the [upload urls API](/docs/api/tag/files/post/v1/files/upload-urls), or the url of the file.
13
+ The path of the input video. This field is required if `video_source` is `file`. This value can be either the `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls), or the url of the file.
14
14
  """
15
15
 
16
16
  video_source: typing_extensions.Required[
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "magic_hour"
3
- version = "0.9.3"
3
+ version = "0.9.4"
4
4
  description = "Python SDK for Magic Hour API"
5
5
  readme = "README.md"
6
6
  authors = []
File without changes
File without changes
@@ -1,9 +1,9 @@
1
1
  import httpx
2
2
  import typing
3
3
 
4
- from magic_hour.resources.v1 import AsyncV1Client, V1Client
5
4
  from magic_hour.environment import Environment
6
5
  from magic_hour.core import AsyncBaseClient, AuthBearer, SyncBaseClient
6
+ from magic_hour.resources.v1 import AsyncV1Client, V1Client
7
7
 
8
8
 
9
9
  class Client: