MeUtils 2025.1.17.19.49.29__py3-none-any.whl → 2025.1.27.15.5.31__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.
- {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/METADATA +27 -28
- {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/RECORD +46 -43
- examples/_openaisdk/4v.py +3 -4
- examples/_openaisdk/openai_baichuan.py +7 -3
- examples/_openaisdk/openai_chatfire.py +17 -4
- examples/_openaisdk/openai_deepinfra.py +2 -2
- examples/_openaisdk/openai_deepseek.py +7 -6
- examples/_openaisdk/openai_doubao.py +16 -7
- examples/_openaisdk/openai_embeddings.py +1 -1
- examples/_openaisdk/openai_modelscope.py +2 -1
- examples/_openaisdk/openai_together.py +2 -1
- meutils/apis/jimeng/lip_sync.py → examples/_openaisdk/openai_x.py +3 -2
- examples/_openaisdk/openai_zhipu.py +9 -5
- examples/bserver.py +60 -518
- examples/json_jmespath.py +13 -13
- meutils/apis/fal/videos.py +13 -7
- meutils/apis/hailuoai/videos.py +16 -6
- meutils/apis/hunyuan/image_tools.py +6 -2
- meutils/apis/images/edits.py +74 -6
- meutils/apis/images/recraft.py +5 -5
- meutils/apis/jimeng/common.py +2 -147
- meutils/apis/jimeng/doubao.py +2 -2
- meutils/apis/jimeng/files.py +84 -29
- meutils/apis/jimeng/images.py +177 -11
- meutils/apis/jimeng/videos.py +305 -0
- meutils/apis/oneapi/user.py +3 -1
- meutils/data/VERSION +1 -1
- meutils/io/files_utils.py +9 -3
- meutils/jwt_utils/common.py +46 -0
- meutils/llm/clients.py +4 -1
- meutils/llm/completions/agents/file.py +7 -4
- meutils/llm/completions/agents/search.py +115 -0
- meutils/parsers/fileparser/mineru.py +48 -0
- meutils/schemas/hailuo_types.py +8 -2
- meutils/schemas/image_types.py +19 -5
- meutils/schemas/oneapi/common.py +152 -45
- meutils/schemas/oneapi/models.py +1 -1
- meutils/schemas/openai_types.py +1 -1
- meutils/schemas/task_types.py +2 -0
- meutils/schemas/video_types.py +19 -1
- meutils/str_utils/json_utils.py +29 -1
- meutils/request_utils/jwt_utils/common.py +0 -42
- {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/LICENSE +0 -0
- {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/WHEEL +0 -0
- {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/entry_points.txt +0 -0
- {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/top_level.txt +0 -0
- /meutils/{request_utils/jwt_utils → jwt_utils}/__init__.py +0 -0
meutils/apis/jimeng/files.py
CHANGED
@@ -14,7 +14,8 @@ import hashlib
|
|
14
14
|
|
15
15
|
from meutils.pipe import *
|
16
16
|
from meutils.caches.redis_cache import cache
|
17
|
-
|
17
|
+
from meutils.io.files_utils import to_bytes
|
18
|
+
from meutils.apis.jimeng.common import get_upload_token
|
18
19
|
|
19
20
|
def random_str(n):
|
20
21
|
return ''.join(random.sample('zyxwvutsrqponmlkjihgfedcba0123456789', n))
|
@@ -53,8 +54,7 @@ class JJRequest:
|
|
53
54
|
self.serviceName = serviceName
|
54
55
|
|
55
56
|
def getAuthorization(self):
|
56
|
-
return f"AWS4-HMAC-SHA256 Credential={self.e['access_key_id']}/{self.t[
|
57
|
-
|
57
|
+
return f"AWS4-HMAC-SHA256 Credential={self.e['access_key_id']}/{self.t[:8]}/cn-north-1/{self.serviceName}/aws4_request, SignedHeaders=x-amz-date;x-amz-security-token, Signature={self.signature()}"
|
58
58
|
def signature(self):
|
59
59
|
r = self.getSigningKey()
|
60
60
|
return hmac_hash256(r, self.stringToSign()).hexdigest()
|
@@ -99,7 +99,7 @@ class JJRequest:
|
|
99
99
|
|
100
100
|
|
101
101
|
@cache(ttl=15 * 60)
|
102
|
-
def upload(image: bytes, upload_token: dict): # oss 跨账号不知道是否可以使用
|
102
|
+
async def upload(image: bytes, upload_token: dict): # oss 跨账号不知道是否可以使用
|
103
103
|
# e = auth = upload_token['data']['auth'] # 豆包
|
104
104
|
data = upload_token['data']
|
105
105
|
service_id = data.get('service_id', '3jr8j4ixpe') # 即梦 3jr8j4ixpe 豆包 a9rns2rl98
|
@@ -164,17 +164,29 @@ def upload(image: bytes, upload_token: dict): # oss 跨账号不知道是否可
|
|
164
164
|
# upload_url = f"https://tos-hl-x.snssdk.com/upload/v1/{oss_uri}"
|
165
165
|
upload_url = f"https://{response['Result']['UploadAddress']['UploadHosts'][0]}/upload/v1/{oss_uri}"
|
166
166
|
|
167
|
-
response = requests.post(upload_url, headers=headers, data=image)
|
168
|
-
response.raise_for_status()
|
169
|
-
response = response.json()
|
167
|
+
# response = requests.post(upload_url, headers=headers, data=image)
|
168
|
+
# response.raise_for_status()
|
169
|
+
# response = response.json()
|
170
|
+
# logger.debug(response)
|
170
171
|
|
171
|
-
|
172
|
+
async with httpx.AsyncClient(headers=headers, timeout=60) as client:
|
173
|
+
response = await client.post(upload_url, content=image)
|
174
|
+
response.raise_for_status()
|
175
|
+
data = response.json()
|
176
|
+
logger.debug(bjson(data))
|
172
177
|
|
173
178
|
return oss_uri
|
174
179
|
|
175
180
|
|
176
|
-
|
177
|
-
|
181
|
+
async def upload_for_vod(image: bytes, upload_token: dict): # oss 跨账号不知道是否可以使用
|
182
|
+
"""
|
183
|
+
"UploadHost": "tos-lf-x.snssdk.com",
|
184
|
+
"UploadHost": "tos-hl-x.snssdk.com",
|
185
|
+
|
186
|
+
:param image:
|
187
|
+
:param upload_token:
|
188
|
+
:return:
|
189
|
+
"""
|
178
190
|
# e = auth = upload_token['data']['auth'] # 豆包
|
179
191
|
data = upload_token['data']
|
180
192
|
service_id = data.get('service_id', '3jr8j4ixpe') # 即梦 3jr8j4ixpe 豆包 a9rns2rl98
|
@@ -190,13 +202,16 @@ def upload_for_vod(image: bytes, upload_token: dict): # oss 跨账号不知道
|
|
190
202
|
"Action": "ApplyUploadInner",
|
191
203
|
"Version": "2020-11-19",
|
192
204
|
# "ServiceId": service_id,
|
193
|
-
"SpaceName": "artist_op",
|
205
|
+
# "SpaceName": "artist_op",
|
206
|
+
"SpaceName": "dreamina",
|
194
207
|
|
195
|
-
"
|
208
|
+
"IsInner": "1",
|
196
209
|
|
197
210
|
"FileType": "video",
|
198
211
|
"FileSize": len(image),
|
199
212
|
|
213
|
+
"s": random_str(10),
|
214
|
+
|
200
215
|
}
|
201
216
|
|
202
217
|
r = JJRequest(data, t, "https://vod.bytedanceapi.com/", method="GET", params=params, serviceName="vod")
|
@@ -206,12 +221,18 @@ def upload_for_vod(image: bytes, upload_token: dict): # oss 跨账号不知道
|
|
206
221
|
'x-amz-security-token': session_token,
|
207
222
|
}
|
208
223
|
# logger.debug(headers)
|
209
|
-
response = requests.get(r.api, params=params, headers=headers)
|
210
|
-
response.raise_for_status()
|
211
|
-
logger.debug(response.status_code)
|
212
|
-
response = response.json()
|
224
|
+
# response = requests.get(r.api, params=params, headers=headers)
|
225
|
+
# response.raise_for_status()
|
226
|
+
# logger.debug(response.status_code)
|
227
|
+
# response = response.json()
|
228
|
+
# logger.debug(bjson(response))
|
229
|
+
|
230
|
+
async with httpx.AsyncClient(headers=headers, params=params, timeout=120) as client:
|
231
|
+
response = await client.get(r.api)
|
232
|
+
response.raise_for_status()
|
233
|
+
response = response.json()
|
234
|
+
logger.debug(bjson(response))
|
213
235
|
|
214
|
-
logger.debug(bjson(response))
|
215
236
|
if "Result" not in response:
|
216
237
|
return
|
217
238
|
|
@@ -228,24 +249,47 @@ def upload_for_vod(image: bytes, upload_token: dict): # oss 跨账号不知道
|
|
228
249
|
headers = {
|
229
250
|
"authorization": oss_token,
|
230
251
|
"content-length": str(len(image)),
|
231
|
-
"content-Type": "
|
252
|
+
"content-Type": "application/octet-stream",
|
232
253
|
"content-crc32": fileCRC32(image),
|
233
254
|
}
|
234
255
|
|
235
256
|
# upload_url = f"https://tos-hl-x.snssdk.com/upload/v1/{oss_uri}"
|
236
257
|
upload_url = f"https://{upload_host}/upload/v1/{oss_uri}"
|
237
258
|
|
238
|
-
response = requests.post(upload_url, headers=headers, data=image)
|
239
|
-
response.raise_for_status()
|
240
|
-
response = response.json()
|
259
|
+
# response = requests.post(upload_url, headers=headers, data=image)
|
260
|
+
# response.raise_for_status()
|
261
|
+
# response = response.json()
|
262
|
+
# logger.debug(response)
|
241
263
|
|
242
|
-
|
264
|
+
async with httpx.AsyncClient(headers=headers, timeout=120) as client:
|
265
|
+
response = await client.post(upload_url, content=image)
|
266
|
+
response.raise_for_status()
|
267
|
+
data = response.json()
|
268
|
+
logger.debug(bjson(data))
|
243
269
|
|
244
|
-
return oss_uri
|
270
|
+
return vid, oss_uri
|
271
|
+
|
272
|
+
|
273
|
+
async def upload_for_image(image, token): # todo: 跨账号token
|
274
|
+
"""image url base64 bytes"""
|
275
|
+
if not image: return
|
276
|
+
|
277
|
+
upload_token = await get_upload_token(token)
|
278
|
+
image_uri = await upload(await to_bytes(image), upload_token)
|
279
|
+
return image_uri
|
280
|
+
|
281
|
+
|
282
|
+
async def upload_for_video(video, token): # 跨账号token
|
283
|
+
"""video url base64 bytes
|
284
|
+
"""
|
285
|
+
if not video: return
|
286
|
+
|
287
|
+
upload_token = await get_upload_token(token)
|
288
|
+
vid, uri = await upload_for_vod(await to_bytes(video), upload_token)
|
289
|
+
return vid, uri
|
245
290
|
|
246
291
|
|
247
292
|
if __name__ == "__main__":
|
248
|
-
from meutils.apis.jimeng.common import get_upload_token
|
249
293
|
|
250
294
|
# 豆包
|
251
295
|
token = "de2215a7bb8e442774cf388f03fac84c"
|
@@ -253,11 +297,22 @@ if __name__ == "__main__":
|
|
253
297
|
# jimeng
|
254
298
|
token = "eb4d120829cfd3ee957943f63d6152ed"
|
255
299
|
#
|
256
|
-
upload_token = arun(get_upload_token(token))
|
300
|
+
# upload_token = arun(get_upload_token(token))
|
257
301
|
|
258
302
|
#
|
259
|
-
with open("
|
260
|
-
|
303
|
+
# with open("test.jpg", "rb") as f:
|
304
|
+
# file = image = f.read()
|
305
|
+
#
|
306
|
+
# print(upload(image, upload_token))
|
307
|
+
# print(upload_for_vod(image, upload_token))
|
308
|
+
#
|
309
|
+
# with timer():
|
310
|
+
# arun(upload_for_video("https://fal.media/files/koala/8teUPbRRMtAUTORDvqy0l.mp4", token))
|
311
|
+
|
312
|
+
# with timer():
|
313
|
+
# arun(upload_for_image("https://oss.ffire.cc/files/kling_watermark.png", token))
|
261
314
|
|
262
|
-
|
263
|
-
|
315
|
+
with timer():
|
316
|
+
url = "https://oss.ffire.cc/files/lipsync.mp3"
|
317
|
+
# arun(upload_for_video("https://oss.ffire.cc/files/lipsync.mp3", token))
|
318
|
+
arun(upload_for_video(url, token))
|
meutils/apis/jimeng/images.py
CHANGED
@@ -9,11 +9,15 @@
|
|
9
9
|
# @Description :
|
10
10
|
|
11
11
|
from meutils.pipe import *
|
12
|
+
from meutils.caches.redis_cache import cache
|
12
13
|
|
13
14
|
from meutils.schemas.jimeng_types import BASE_URL, MODELS_MAP, FEISHU_URL
|
14
15
|
from meutils.schemas.image_types import ImageRequest
|
15
16
|
from meutils.schemas.task_types import TaskResponse
|
16
|
-
from meutils.apis.jimeng.common import
|
17
|
+
from meutils.apis.jimeng.common import get_headers, check_token
|
18
|
+
from meutils.str_utils.regular_expression import parse_url
|
19
|
+
from meutils.apis.jimeng.files import upload_for_image
|
20
|
+
|
17
21
|
from meutils.config_utils.lark_utils import get_next_token_for_polling
|
18
22
|
|
19
23
|
from fake_useragent import UserAgent
|
@@ -21,6 +25,150 @@ from fake_useragent import UserAgent
|
|
21
25
|
ua = UserAgent()
|
22
26
|
|
23
27
|
|
28
|
+
async def create_draft_content(request: ImageRequest, token: str):
|
29
|
+
"""
|
30
|
+
创建草稿内容
|
31
|
+
"""
|
32
|
+
request.model = MODELS_MAP.get(request.model, MODELS_MAP["default"])
|
33
|
+
|
34
|
+
height = width = 1360
|
35
|
+
if 'x' in request.size:
|
36
|
+
height, width = map(int, request.size.split('x'))
|
37
|
+
|
38
|
+
main_component_id = str(uuid.uuid4())
|
39
|
+
|
40
|
+
if urls := parse_url(request.prompt):
|
41
|
+
url = urls[-1]
|
42
|
+
image_uri = upload_for_image(url, token)
|
43
|
+
|
44
|
+
request.prompt = request.prompt.replace(url, '')
|
45
|
+
request.model = "high_aes_general_v20_L:general_v2.0_L" # 2.1不支持图片编辑
|
46
|
+
|
47
|
+
component = {
|
48
|
+
"type": "image_base_component",
|
49
|
+
"id": main_component_id,
|
50
|
+
"min_version": "3.0.2",
|
51
|
+
"generate_type": "blend",
|
52
|
+
"aigc_mode": "workbench",
|
53
|
+
"abilities": {
|
54
|
+
"type": "",
|
55
|
+
"id": str(uuid.uuid4()),
|
56
|
+
"blend": {
|
57
|
+
"type": "",
|
58
|
+
"id": str(uuid.uuid4()),
|
59
|
+
"core_param": {
|
60
|
+
"type": "",
|
61
|
+
"id": str(uuid.uuid4()),
|
62
|
+
"model": request.model,
|
63
|
+
"prompt": f"##{request.prompt}",
|
64
|
+
"sample_strength": 0.5,
|
65
|
+
"image_ratio": 1,
|
66
|
+
"large_image_info": {
|
67
|
+
"type": "",
|
68
|
+
"id": str(uuid.uuid4()),
|
69
|
+
"height": height,
|
70
|
+
"width": width
|
71
|
+
},
|
72
|
+
},
|
73
|
+
"ability_list": [
|
74
|
+
{
|
75
|
+
"type": "",
|
76
|
+
"id": str(uuid.uuid4()),
|
77
|
+
"name": "byte_edit",
|
78
|
+
"image_uri_list": [
|
79
|
+
image_uri
|
80
|
+
],
|
81
|
+
"image_list": [
|
82
|
+
{
|
83
|
+
"type": "image",
|
84
|
+
"id": str(uuid.uuid4()),
|
85
|
+
"source_from": "upload",
|
86
|
+
"platform_type": 1,
|
87
|
+
"name": "",
|
88
|
+
"image_uri": image_uri,
|
89
|
+
"width": 0,
|
90
|
+
"height": 0,
|
91
|
+
"format": "",
|
92
|
+
"uri": image_uri
|
93
|
+
}
|
94
|
+
],
|
95
|
+
"strength": 0.5
|
96
|
+
}
|
97
|
+
],
|
98
|
+
"history_option": {
|
99
|
+
"type": "",
|
100
|
+
"id": str(uuid.uuid4()),
|
101
|
+
},
|
102
|
+
"prompt_placeholder_info_list": [
|
103
|
+
{
|
104
|
+
"type": "",
|
105
|
+
"id": str(uuid.uuid4()),
|
106
|
+
"ability_index": 0
|
107
|
+
}
|
108
|
+
],
|
109
|
+
"postedit_param": {
|
110
|
+
"type": "",
|
111
|
+
"id": str(uuid.uuid4()),
|
112
|
+
"generate_type": 0
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
else:
|
119
|
+
|
120
|
+
component = {
|
121
|
+
"type": "image_base_component",
|
122
|
+
"id": main_component_id,
|
123
|
+
"min_version": "3.0.2",
|
124
|
+
"generate_type": "generate",
|
125
|
+
"aigc_mode": "workbench",
|
126
|
+
"abilities": {
|
127
|
+
"type": "",
|
128
|
+
"id": str(uuid.uuid4()),
|
129
|
+
"generate": {
|
130
|
+
"type": "",
|
131
|
+
"id": str(uuid.uuid4()),
|
132
|
+
"core_param": {
|
133
|
+
"type": "",
|
134
|
+
"id": str(uuid.uuid4()),
|
135
|
+
"model": request.model,
|
136
|
+
"prompt": request.prompt,
|
137
|
+
"negative_prompt": request.negative_prompt or "",
|
138
|
+
"seed": request.seed or 426999300,
|
139
|
+
"sample_strength": 0.5,
|
140
|
+
"image_ratio": 1,
|
141
|
+
"large_image_info": {
|
142
|
+
"type": "",
|
143
|
+
"id": str(uuid.uuid4()),
|
144
|
+
"height": height,
|
145
|
+
"width": width
|
146
|
+
}
|
147
|
+
},
|
148
|
+
"history_option": {
|
149
|
+
"type": "",
|
150
|
+
"id": str(uuid.uuid4()),
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
draft_content = {
|
157
|
+
"type": "draft",
|
158
|
+
"id": str(uuid.uuid4()),
|
159
|
+
"min_version": "3.0.2",
|
160
|
+
"min_features": [],
|
161
|
+
"is_from_tsn": True,
|
162
|
+
"version": "3.0.8",
|
163
|
+
"main_component_id": main_component_id,
|
164
|
+
"component_list": [component]
|
165
|
+
}
|
166
|
+
|
167
|
+
logger.debug(bjson(draft_content))
|
168
|
+
|
169
|
+
return draft_content
|
170
|
+
|
171
|
+
|
24
172
|
async def create_task(request: ImageRequest, token: Optional[str] = None):
|
25
173
|
token = token or await get_next_token_for_polling(FEISHU_URL, check_token)
|
26
174
|
|
@@ -76,6 +224,7 @@ async def get_task(task_id, token):
|
|
76
224
|
item_list = task_info.get("item_list") # "status": 30,
|
77
225
|
|
78
226
|
status_code = task_info.get("status")
|
227
|
+
fail_msg = f"""{task_info.get("fail_msg")}"""
|
79
228
|
logger.debug(f"status: {status_code}")
|
80
229
|
|
81
230
|
"""
|
@@ -87,21 +236,33 @@ async def get_task(task_id, token):
|
|
87
236
|
|
88
237
|
task_data = sum(image_data, []) | xmap_(lambda x: {"url": x.get("image_url")})
|
89
238
|
|
90
|
-
|
239
|
+
response = TaskResponse(
|
91
240
|
task_id=task_id,
|
92
241
|
data=task_data,
|
93
|
-
message=data.get("errmsg")
|
242
|
+
message=data.get("errmsg"),
|
94
243
|
status="success" if item_list else 'processing',
|
95
244
|
code=status_code,
|
96
245
|
)
|
97
246
|
|
247
|
+
if status_code == 30:
|
248
|
+
response.status = "fail"
|
249
|
+
response.message = fail_msg
|
98
250
|
|
251
|
+
return response
|
252
|
+
|
253
|
+
|
254
|
+
# @cache: todo: cache 积分异常消耗
|
255
|
+
# @cache(ttl=3600)
|
99
256
|
async def generate(request: ImageRequest):
|
100
257
|
task_response = await create_task(request)
|
258
|
+
|
101
259
|
for i in range(1, 10):
|
102
260
|
await asyncio.sleep(max(10 / i, 1))
|
103
261
|
response = await get_task(task_response.task_id, task_response.system_fingerprint)
|
104
262
|
logger.debug(response)
|
263
|
+
if response.status.lower().startswith("fail"):
|
264
|
+
raise Exception(response.message)
|
265
|
+
|
105
266
|
if data := response.data:
|
106
267
|
return {"data": data}
|
107
268
|
|
@@ -128,13 +289,18 @@ if __name__ == '__main__':
|
|
128
289
|
|
129
290
|
# arun(get_task(task.task_id, task.system_fingerprint))
|
130
291
|
|
131
|
-
task_id = "10184295086338"
|
132
|
-
system_fingerprint = "eb4d120829cfd3ee957943f63d6152ed"
|
133
|
-
|
134
|
-
t1 = ("10184295086338", "eb4d120829cfd3ee957943f63d6152ed")
|
135
|
-
t2 = ("10184877310722", "dcf7bbc31faed9740b0bf748cd4d2c74")
|
136
|
-
t3 = ("10186352959490", "eb4d120829cfd3ee957943f63d6152ed")
|
292
|
+
# task_id = "10184295086338"
|
293
|
+
# system_fingerprint = "eb4d120829cfd3ee957943f63d6152ed"
|
294
|
+
#
|
295
|
+
# t1 = ("10184295086338", "eb4d120829cfd3ee957943f63d6152ed")
|
296
|
+
# t2 = ("10184877310722", "dcf7bbc31faed9740b0bf748cd4d2c74")
|
297
|
+
# t3 = ("10186352959490", "eb4d120829cfd3ee957943f63d6152ed")
|
298
|
+
#
|
299
|
+
# arun(get_task(*t3))
|
137
300
|
|
138
|
-
arun(
|
301
|
+
arun(generate(ImageRequest(prompt="做一个圣诞节的海报")))
|
302
|
+
# prompt = "A plump Chinese beauty wearing a wedding dress revealing her skirt and underwear is swinging on the swing,Happy smile,cleavage,Exposed thighs,Spread your legs open,Extend your leg,panties,upskirt,Barefoot,sole"
|
303
|
+
# request = ImageRequest(prompt=prompt)
|
304
|
+
# task = arun(create_task(request))
|
139
305
|
|
140
|
-
# arun(
|
306
|
+
# arun(get_task(task.task_id, task.system_fingerprint))
|