magic_hour 0.18.0__py3-none-any.whl → 0.19.0__py3-none-any.whl
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.
- magic_hour/core/__init__.py +2 -0
- magic_hour/core/query.py +23 -10
- magic_hour/core/request.py +27 -21
- magic_hour/environment.py +1 -1
- magic_hour/resources/v1/ai_gif_generator/README.md +31 -0
- magic_hour/resources/v1/ai_gif_generator/__init__.py +4 -0
- magic_hour/resources/v1/ai_gif_generator/client.py +117 -0
- magic_hour/resources/v1/client.py +6 -0
- magic_hour/types/models/__init__.py +2 -0
- magic_hour/types/models/v1_ai_gif_generator_create_response.py +25 -0
- magic_hour/types/models/v1_image_projects_get_response.py +1 -1
- magic_hour/types/params/__init__.py +12 -0
- magic_hour/types/params/v1_ai_gif_generator_create_body.py +37 -0
- magic_hour/types/params/v1_ai_gif_generator_create_body_style.py +28 -0
- {magic_hour-0.18.0.dist-info → magic_hour-0.19.0.dist-info}/METADATA +5 -1
- {magic_hour-0.18.0.dist-info → magic_hour-0.19.0.dist-info}/RECORD +18 -12
- {magic_hour-0.18.0.dist-info → magic_hour-0.19.0.dist-info}/LICENSE +0 -0
- {magic_hour-0.18.0.dist-info → magic_hour-0.19.0.dist-info}/WHEEL +0 -0
magic_hour/core/__init__.py
CHANGED
|
@@ -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",
|
magic_hour/core/query.py
CHANGED
|
@@ -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:
|
|
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(
|
|
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(
|
|
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),
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
|
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)
|
magic_hour/core/request.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
from typing import Any, Dict, Type, Union,
|
|
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):
|
magic_hour/environment.py
CHANGED
|
@@ -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,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
|
Metadata-Version: 2.1
|
|
2
2
|
Name: magic_hour
|
|
3
|
-
Version: 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
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
magic_hour/__init__.py,sha256=KIpC-OAJjT6m-WLHmdIdUlsYyicCiX4WHVIwfPG-e0c,203
|
|
2
2
|
magic_hour/client.py,sha256=DMxeed7El-0q_URdGYXXNStGXJ11l7u6q1bQD8LWQ8g,2038
|
|
3
|
-
magic_hour/core/__init__.py,sha256=
|
|
3
|
+
magic_hour/core/__init__.py,sha256=YiyAhiYwhYzCN0Kk4jhca5HbxE-ot0fwXzHUL27HZu8,1217
|
|
4
4
|
magic_hour/core/api_error.py,sha256=K1d47qRbhLBNEaUVbs0NPgxee24X3qGZ37gBhleUzEE,1760
|
|
5
5
|
magic_hour/core/auth.py,sha256=NSjPcmTyHelRag9FqH1ufbchBWQgGDpH2P0akfppIPo,9130
|
|
6
6
|
magic_hour/core/base_client.py,sha256=H9FJtNvN3ZfjjnPq4t9HXgh0c1324x1RFtAHXWEnqWk,18846
|
|
7
7
|
magic_hour/core/binary_response.py,sha256=T-DATvb21P2ZRnYa4LlXmF77VfM8Tut2951QHEQct_U,681
|
|
8
|
-
magic_hour/core/query.py,sha256=
|
|
9
|
-
magic_hour/core/request.py,sha256=
|
|
8
|
+
magic_hour/core/query.py,sha256=FdGdyHggFc8weFDSiUuVIEfZ7B2UAU0QOS38bp2ud9o,4627
|
|
9
|
+
magic_hour/core/request.py,sha256=_ikn8iZ2fU9Ubqnt7M9hdEnXGV6AAFHJYmDKBtxEY4I,5263
|
|
10
10
|
magic_hour/core/response.py,sha256=Sl7nPL2axmz7em_6d9TkFSnQQKUpalWaVWbPPWoXJgM,10180
|
|
11
11
|
magic_hour/core/type_utils.py,sha256=4bU9WXnMXJ6YTtuqOMiB8t6Xw0RlfVWJ-IDBONlqEtQ,461
|
|
12
12
|
magic_hour/core/utils.py,sha256=34SiC1vw2A0TkYHONgMA_d09soIIYiiBWRXCZGdwGIk,1669
|
|
13
|
-
magic_hour/environment.py,sha256=
|
|
13
|
+
magic_hour/environment.py,sha256=ftSIikX25smGGgd-4zhB_YaihTypOrpHoZnLahAO5_s,213
|
|
14
14
|
magic_hour/resources/v1/__init__.py,sha256=Aj0sjVcoijjQyieNBxv2_uewPYC2vO2UG-ehoBgCz5E,86
|
|
15
15
|
magic_hour/resources/v1/ai_clothes_changer/README.md,sha256=KQTvbttct5GcdOJW3NG5gCsWF6G2qlwIoBjBd92TjUs,977
|
|
16
16
|
magic_hour/resources/v1/ai_clothes_changer/__init__.py,sha256=6W_Y2HxG2sDOBiJyzngK3Q2S3xfQgpK-j8xFRmBAhbQ,142
|
|
@@ -18,6 +18,9 @@ magic_hour/resources/v1/ai_clothes_changer/client.py,sha256=gnhqocjO0GjoGM6dFOKk
|
|
|
18
18
|
magic_hour/resources/v1/ai_face_editor/README.md,sha256=nhTRDxHPVqkd22FNZcZbtpEBqcV-t8-MavSqfuPh00w,1811
|
|
19
19
|
magic_hour/resources/v1/ai_face_editor/__init__.py,sha256=RY8GBMQcqsDFbFcUuK-4LPvablq-U9XmSSlQk4HLKmM,126
|
|
20
20
|
magic_hour/resources/v1/ai_face_editor/client.py,sha256=N5toTWe-Ag2iAhwk-CbWQxGnK6fZ2uHAFEKx15SPl-I,5315
|
|
21
|
+
magic_hour/resources/v1/ai_gif_generator/README.md,sha256=C_Kmd_gPva1vOU_XMqZ2zy0FKP2kKYiTX9fHCNB8tfI,650
|
|
22
|
+
magic_hour/resources/v1/ai_gif_generator/__init__.py,sha256=SG_WmxUnpQWlfNQoHfdXPEGQEPC0WZPgom8ATaR9jiY,134
|
|
23
|
+
magic_hour/resources/v1/ai_gif_generator/client.py,sha256=kQ3iCwCRtVIWu19Bn4Qwm3NHHdeKPPWfE4QAe2D7JVA,3487
|
|
21
24
|
magic_hour/resources/v1/ai_headshot_generator/README.md,sha256=CWihzwUuDVoLBItSDJKGBW1EQthz2REmkLkaaA68yao,705
|
|
22
25
|
magic_hour/resources/v1/ai_headshot_generator/__init__.py,sha256=4WZ3jfrL2yPhQaPalMJrUEykwUoF3KBtop2VJEij-0s,154
|
|
23
26
|
magic_hour/resources/v1/ai_headshot_generator/client.py,sha256=PoRzXFJCIyGA4PDOZyK6rQ1PHE6EUXSE7ilu_N9RTEc,4159
|
|
@@ -42,7 +45,7 @@ magic_hour/resources/v1/ai_talking_photo/client.py,sha256=TQNwMP3DhDj5jb51diMxcO
|
|
|
42
45
|
magic_hour/resources/v1/animation/README.md,sha256=uIVfUwD7iAOe2eJDgrxj4UyYmq9R30fdI3Z0JuEChc4,1477
|
|
43
46
|
magic_hour/resources/v1/animation/__init__.py,sha256=M6KUe6TEZl_DAdyn1HFQ2kHYanZo6xy3mvUdCN264hQ,114
|
|
44
47
|
magic_hour/resources/v1/animation/client.py,sha256=YYjggl_hszTW-Sn9SFs3m7bz7PvtRTruhHSSnrkkD9c,6401
|
|
45
|
-
magic_hour/resources/v1/client.py,sha256=
|
|
48
|
+
magic_hour/resources/v1/client.py,sha256=kxrv1LfFHebey-tVjxlBN6c-9hSYMBqno9rVl54pUUg,6626
|
|
46
49
|
magic_hour/resources/v1/face_swap/README.md,sha256=g5e_eZu3OsrIuc6ISpXbliIX1uVeYX7MwOfdw74dIoI,1306
|
|
47
50
|
magic_hour/resources/v1/face_swap/__init__.py,sha256=lyg5uAHyYHEUVAiAZtP3zwjGCEGqq8IWbQKexVdhr00,110
|
|
48
51
|
magic_hour/resources/v1/face_swap/client.py,sha256=-BpJae7J4PZPUG45BMA3HBB2XhrbHpgWqwwyaDFH88A,8519
|
|
@@ -78,9 +81,10 @@ magic_hour/resources/v1/video_projects/client.py,sha256=JvhYhf3phYkdVj8VpWxvxF8q
|
|
|
78
81
|
magic_hour/resources/v1/video_to_video/README.md,sha256=yOIRj1EPTVl8rl15SPWhpc2PZi1ddKGMix8WbaxlXzQ,1630
|
|
79
82
|
magic_hour/resources/v1/video_to_video/__init__.py,sha256=1SHaRLlsrlBkdxxKBYgdbHrGATlRvqlXc22RpjjHaOA,126
|
|
80
83
|
magic_hour/resources/v1/video_to_video/client.py,sha256=dYb2zi8MMhm1YUBFxGhFno4ikbMEjcLrs3JofapyP-s,8368
|
|
81
|
-
magic_hour/types/models/__init__.py,sha256=
|
|
84
|
+
magic_hour/types/models/__init__.py,sha256=Zv5G1HTpnPT94bSWyVhAxrijRGsInkXbBaifvaJxsr8,3423
|
|
82
85
|
magic_hour/types/models/v1_ai_clothes_changer_create_response.py,sha256=gpPZLGvSukhBSK2LzTckn4HFcNDseP_XtfwasxzE2uc,625
|
|
83
86
|
magic_hour/types/models/v1_ai_face_editor_create_response.py,sha256=mjeIlBOfcvHy9WrtOh0ZKFwrYZbA3gUY46fQ-fIGHuI,621
|
|
87
|
+
magic_hour/types/models/v1_ai_gif_generator_create_response.py,sha256=vcEFAN1F9ef4aMzrZhoAMOOu5I-DJCAKqVtzjb84xW4,623
|
|
84
88
|
magic_hour/types/models/v1_ai_headshot_generator_create_response.py,sha256=s4OheUpwh5jW1XAP4x_M7j-Xafq_gq9Lbz3NbUsFhs8,628
|
|
85
89
|
magic_hour/types/models/v1_ai_image_generator_create_response.py,sha256=gqRQUTb1dznt9trj5i4vIc2GcPac910ti7EXzz49btc,625
|
|
86
90
|
magic_hour/types/models/v1_ai_image_upscaler_create_response.py,sha256=u5z8WHJA7iT3u3EsTcDuAzwJ9JL9wMi0K93JhahjpGk,624
|
|
@@ -94,7 +98,7 @@ magic_hour/types/models/v1_face_swap_photo_create_response.py,sha256=d68oxwceXya
|
|
|
94
98
|
magic_hour/types/models/v1_files_upload_urls_create_response.py,sha256=ecdnxoo-ZBTa2kAusHq4nyz6RdugzyN7w4oazJt5ri0,460
|
|
95
99
|
magic_hour/types/models/v1_files_upload_urls_create_response_items_item.py,sha256=AjW1Myj-dB10IdM3zTMEsXouY3tnx8vdN5CW3HLQX_M,799
|
|
96
100
|
magic_hour/types/models/v1_image_background_remover_create_response.py,sha256=jK_RVF3V0VSZn70FzsEjCrA_SEbpvcDdxy1RSlvsygw,631
|
|
97
|
-
magic_hour/types/models/v1_image_projects_get_response.py,sha256=
|
|
101
|
+
magic_hour/types/models/v1_image_projects_get_response.py,sha256=BC0YSrI07xumBXmv-kbUxhi9aabEjWFU4Oo7RDtGWfw,2149
|
|
98
102
|
magic_hour/types/models/v1_image_projects_get_response_downloads_item.py,sha256=kC0UhiMug52kxN6Ib1H_u_JQGUbeRc91gjuVaXYaM-c,410
|
|
99
103
|
magic_hour/types/models/v1_image_projects_get_response_error.py,sha256=R1qg-aIt63h6Q7bQ4AvgeC0lbUg5u35rwFXFvU_gvZs,568
|
|
100
104
|
magic_hour/types/models/v1_image_to_video_create_response.py,sha256=9I3MptKUR2gdQW6SbGSZr5Usdte9PRSniq-pjwJySk4,736
|
|
@@ -106,12 +110,14 @@ magic_hour/types/models/v1_video_projects_get_response_download.py,sha256=nudDCN
|
|
|
106
110
|
magic_hour/types/models/v1_video_projects_get_response_downloads_item.py,sha256=DlUuLBSGa7jWoozxferkaOsGc4jASItcjjWbBXGu620,410
|
|
107
111
|
magic_hour/types/models/v1_video_projects_get_response_error.py,sha256=49QxnXAmYHcvSWuuhbQZeGlUfqVcO4YwZ414GczQnvA,568
|
|
108
112
|
magic_hour/types/models/v1_video_to_video_create_response.py,sha256=dRQql5qEQvcF0wbGO8M0yabgMef26w5T3JGtgnqLZ-Y,736
|
|
109
|
-
magic_hour/types/params/__init__.py,sha256=
|
|
113
|
+
magic_hour/types/params/__init__.py,sha256=I8TdaEeRIiRwIkM8i8q4RlYWcYD8dGitWEGEDP9ryYs,10237
|
|
110
114
|
magic_hour/types/params/v1_ai_clothes_changer_create_body.py,sha256=X5koqrTxYLiKcRMqPF7r-VwQzy4r_7k81o1289zHJvo,1006
|
|
111
115
|
magic_hour/types/params/v1_ai_clothes_changer_create_body_assets.py,sha256=GGnXOExxXtnHT9wQpDCEkLHQlQB5MbAbYuU47iHGf70,1509
|
|
112
116
|
magic_hour/types/params/v1_ai_face_editor_create_body.py,sha256=sF7mJbqratllYwQ3slqUTctOndAYnH9BDMJu-49Db-4,1313
|
|
113
117
|
magic_hour/types/params/v1_ai_face_editor_create_body_assets.py,sha256=lhfVPTuAEFWATi5Su0weYlM_Npd5qEu75LexlJP5UZA,843
|
|
114
118
|
magic_hour/types/params/v1_ai_face_editor_create_body_style.py,sha256=yNCL--4tDHR6eOltXh842YO0rcjBilJZxOXMcA6xaT4,3502
|
|
119
|
+
magic_hour/types/params/v1_ai_gif_generator_create_body.py,sha256=7kl9B9cjDgnBTp7necRx7E6wbzhrVsZFuYWrr3sLYnU,919
|
|
120
|
+
magic_hour/types/params/v1_ai_gif_generator_create_body_style.py,sha256=xefwoS15Iu9sbhc8oszcH8otTamk-ZTvSMuV1qvcYuQ,611
|
|
115
121
|
magic_hour/types/params/v1_ai_headshot_generator_create_body.py,sha256=Ydzqxzfo6mMEIUc8R_PTWJujfnTDdzt7Ze4ZYiWxWJM,1405
|
|
116
122
|
magic_hour/types/params/v1_ai_headshot_generator_create_body_assets.py,sha256=Zzb_CjU9PjGIugafxPIY59JiS1wABQRod29hPRm7xLc,908
|
|
117
123
|
magic_hour/types/params/v1_ai_headshot_generator_create_body_style.py,sha256=DrX20IwvAhoO0ETO3aNn4YLpfQM5nbUNyz0pm8AO_38,670
|
|
@@ -152,7 +158,7 @@ magic_hour/types/params/v1_text_to_video_create_body_style.py,sha256=9NTboy7J4ef
|
|
|
152
158
|
magic_hour/types/params/v1_video_to_video_create_body.py,sha256=iOb3qGXySlI4unyWPAXDmiLMUSHH6ymuDHeiwpmhKeE,2942
|
|
153
159
|
magic_hour/types/params/v1_video_to_video_create_body_assets.py,sha256=_-6iA5d8ndka6iJWyWvlJwzRkQcmurJE6hkg-fDwBmQ,1531
|
|
154
160
|
magic_hour/types/params/v1_video_to_video_create_body_style.py,sha256=2jgpJ3A8LNXksTPQ5pp1tWXtd753zBuhBjA22qqCsTE,5697
|
|
155
|
-
magic_hour-0.
|
|
156
|
-
magic_hour-0.
|
|
157
|
-
magic_hour-0.
|
|
158
|
-
magic_hour-0.
|
|
161
|
+
magic_hour-0.19.0.dist-info/LICENSE,sha256=F3fxj7JXPgB2K0uj8YXRsVss4u-Dgt_-U3V4VXsivNI,1070
|
|
162
|
+
magic_hour-0.19.0.dist-info/METADATA,sha256=3odRlp7YmOHingY8iZV0Qr4TM_w8xmrN6lyFHftpb1M,5483
|
|
163
|
+
magic_hour-0.19.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
164
|
+
magic_hour-0.19.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|