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.
Files changed (47) hide show
  1. {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/METADATA +27 -28
  2. {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/RECORD +46 -43
  3. examples/_openaisdk/4v.py +3 -4
  4. examples/_openaisdk/openai_baichuan.py +7 -3
  5. examples/_openaisdk/openai_chatfire.py +17 -4
  6. examples/_openaisdk/openai_deepinfra.py +2 -2
  7. examples/_openaisdk/openai_deepseek.py +7 -6
  8. examples/_openaisdk/openai_doubao.py +16 -7
  9. examples/_openaisdk/openai_embeddings.py +1 -1
  10. examples/_openaisdk/openai_modelscope.py +2 -1
  11. examples/_openaisdk/openai_together.py +2 -1
  12. meutils/apis/jimeng/lip_sync.py → examples/_openaisdk/openai_x.py +3 -2
  13. examples/_openaisdk/openai_zhipu.py +9 -5
  14. examples/bserver.py +60 -518
  15. examples/json_jmespath.py +13 -13
  16. meutils/apis/fal/videos.py +13 -7
  17. meutils/apis/hailuoai/videos.py +16 -6
  18. meutils/apis/hunyuan/image_tools.py +6 -2
  19. meutils/apis/images/edits.py +74 -6
  20. meutils/apis/images/recraft.py +5 -5
  21. meutils/apis/jimeng/common.py +2 -147
  22. meutils/apis/jimeng/doubao.py +2 -2
  23. meutils/apis/jimeng/files.py +84 -29
  24. meutils/apis/jimeng/images.py +177 -11
  25. meutils/apis/jimeng/videos.py +305 -0
  26. meutils/apis/oneapi/user.py +3 -1
  27. meutils/data/VERSION +1 -1
  28. meutils/io/files_utils.py +9 -3
  29. meutils/jwt_utils/common.py +46 -0
  30. meutils/llm/clients.py +4 -1
  31. meutils/llm/completions/agents/file.py +7 -4
  32. meutils/llm/completions/agents/search.py +115 -0
  33. meutils/parsers/fileparser/mineru.py +48 -0
  34. meutils/schemas/hailuo_types.py +8 -2
  35. meutils/schemas/image_types.py +19 -5
  36. meutils/schemas/oneapi/common.py +152 -45
  37. meutils/schemas/oneapi/models.py +1 -1
  38. meutils/schemas/openai_types.py +1 -1
  39. meutils/schemas/task_types.py +2 -0
  40. meutils/schemas/video_types.py +19 -1
  41. meutils/str_utils/json_utils.py +29 -1
  42. meutils/request_utils/jwt_utils/common.py +0 -42
  43. {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/LICENSE +0 -0
  44. {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/WHEEL +0 -0
  45. {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/entry_points.txt +0 -0
  46. {MeUtils-2025.1.17.19.49.29.dist-info → MeUtils-2025.1.27.15.5.31.dist-info}/top_level.txt +0 -0
  47. /meutils/{request_utils/jwt_utils → jwt_utils}/__init__.py +0 -0
@@ -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[0:8]}/cn-north-1/{self.serviceName}/aws4_request, SignedHeaders=x-amz-date;x-amz-security-token, Signature={self.signature()}"
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
- logger.debug(response)
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
- @cache(ttl=15 * 60)
177
- def upload_for_vod(image: bytes, upload_token: dict): # oss 跨账号不知道是否可以使用
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
- "s": random_str(10),
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": "image/jpeg",
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
- logger.debug(response)
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("11.jpg", "rb") as f:
260
- file = image = f.read()
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
- # upload(image, upload_token)
263
- print(upload_for_vod(image, upload_token))
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))
@@ -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 create_draft_content, get_headers, check_token
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
- return TaskResponse(
239
+ response = TaskResponse(
91
240
  task_id=task_id,
92
241
  data=task_data,
93
- message=data.get("errmsg") if status_code!=30 else "触发内容审核451",
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(get_task(*t3))
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(generate(ImageRequest(prompt="做一个圣诞节的海报")))
306
+ # arun(get_task(task.task_id, task.system_fingerprint))