MeUtils 2025.1.23.10.16.28__py3-none-any.whl → 2025.1.29.10.0.47__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 (35) hide show
  1. {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/METADATA +29 -30
  2. {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/RECORD +34 -32
  3. examples/_openaisdk/4v.py +3 -4
  4. examples/_openaisdk/openai_baichuan.py +7 -3
  5. examples/_openaisdk/openai_chatfire.py +15 -4
  6. examples/_openaisdk/openai_deepinfra.py +2 -2
  7. examples/_openaisdk/openai_modelscope.py +2 -1
  8. examples/_openaisdk/openai_together.py +2 -1
  9. examples/_openaisdk/openai_zhipu.py +9 -5
  10. examples/json_jmespath.py +13 -13
  11. meutils/apis/hunyuan/image_tools.py +6 -2
  12. meutils/apis/images/edits.py +70 -2
  13. meutils/apis/jimeng/common.py +0 -144
  14. meutils/apis/jimeng/files.py +25 -12
  15. meutils/apis/jimeng/images.py +166 -4
  16. meutils/apis/jimeng/videos.py +176 -107
  17. meutils/apis/vidu/vidu_video.py +3 -3
  18. meutils/data/VERSION +1 -1
  19. meutils/data/oneapi/NOTICE.md +25 -8
  20. meutils/jwt_utils/common.py +46 -0
  21. meutils/llm/clients.py +4 -1
  22. meutils/llm/completions/agents/search.py +115 -0
  23. meutils/parsers/fileparser/mineru.py +48 -0
  24. meutils/schemas/image_types.py +12 -1
  25. meutils/schemas/oneapi/common.py +17 -5
  26. meutils/schemas/oneapi/models.py +1 -1
  27. meutils/schemas/openai_types.py +1 -1
  28. meutils/schemas/video_types.py +9 -1
  29. meutils/schemas/vidu_types.py +1 -1
  30. meutils/request_utils/jwt_utils/common.py +0 -42
  31. {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/LICENSE +0 -0
  32. {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/WHEEL +0 -0
  33. {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/entry_points.txt +0 -0
  34. {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/top_level.txt +0 -0
  35. /meutils/{request_utils/jwt_utils → jwt_utils}/__init__.py +0 -0
@@ -9,9 +9,12 @@
9
9
  # @Description :
10
10
 
11
11
  from meutils.pipe import *
12
+ from meutils.decorators.retry import retrying, IgnoredRetryException
13
+
12
14
  from meutils.config_utils.lark_utils import get_next_token_for_polling
13
- from meutils.schemas.image_types import ImageRequest, ImagesResponse
15
+ from meutils.schemas.image_types import ImageRequest, ImagesResponse, HunyuanImageProcessRequest
14
16
  from meutils.schemas.image_types import ImageProcess
17
+ from meutils.schemas.yuanbao_types import YUANBAO_BASE_URL, FEISHU_URL as YUANBAO_FEISHU_URL
15
18
 
16
19
  from meutils.io.files_utils import to_bytes, to_base64, to_url_fal
17
20
 
@@ -28,6 +31,50 @@ send_message = partial(
28
31
  )
29
32
 
30
33
 
34
+ @retrying(min=3, ignored_exception_types=(IgnoredRetryException,))
35
+ async def make_request_for_hunyuan(payload, token: Optional[str] = None, response_format: str = "url"):
36
+ s = time.time()
37
+
38
+ token = token or await get_next_token_for_polling(YUANBAO_FEISHU_URL)
39
+
40
+ model = payload.pop("model", "removewatermark")
41
+
42
+ logger.debug(payload)
43
+
44
+ headers = {
45
+ 'cookie': token
46
+ }
47
+ async with httpx.AsyncClient(base_url=YUANBAO_BASE_URL, headers=headers, timeout=100) as client:
48
+ response = await client.post(f"/api/image/{model}", json=payload)
49
+ response.raise_for_status()
50
+ logger.debug(response.text)
51
+
52
+ skip_strings = ['DONE', 'TRACEID']
53
+ data = response.text.replace(r'\u0026', '&').splitlines() | xsse_parser(skip_strings=skip_strings)
54
+ data = data and data[-1]
55
+ logger.debug(data)
56
+
57
+ # todo: 错误处理
58
+ if isinstance(data, dict) and any(data["code"] == code for code in {"429"}):
59
+ Exception(f"重试: {response.text}")
60
+
61
+ elif isinstance(data, list) or any(i in response.text for i in {"当前图片没有检测到水印"}): # 跳过重试并返回原始错误
62
+ raise IgnoredRetryException(f"忽略重试: \n{response.text}")
63
+
64
+ data = [
65
+ {
66
+ "url": data["imageUrl"],
67
+ "imageUrl": data["imageUrl"],
68
+ "thumbnailUrl": data["thumbnailUrl"],
69
+ }
70
+ ]
71
+ if response_format == "url":
72
+ return ImagesResponse(data=data, timings={"inference": time.time() - s})
73
+ else:
74
+ data[0]["b64_json"] = await to_base64(data[0]['url'])
75
+ return ImagesResponse(data=data, timings={"inference": time.time() - s})
76
+
77
+
31
78
  async def make_request_for_gitee(payload, token: Optional[str] = None, response_format: str = "url"):
32
79
  s = time.time()
33
80
  feishu_url = "https://xchatllm.feishu.cn/sheets/MekfsfVuohfUf1tsWV0cCvTmn3c?sheet=PDnO6X"
@@ -83,6 +130,8 @@ async def make_request_for_baidu(payload, token: Optional[str] = None, response_
83
130
  except Exception as e:
84
131
  logger.error(e)
85
132
  if i > 3: break
133
+ if not image_base64:
134
+ raise Exception(f"未检测到: {data}")
86
135
 
87
136
  if response_format == "url":
88
137
  url = await to_url_fal(image_base64, content_type="image/png")
@@ -123,15 +172,34 @@ async def edit_image(request: ImageProcess):
123
172
  }
124
173
  return await make_request_for_gitee(payload, response_format=request.response_format)
125
174
 
175
+ elif request.model.startswith("hunyuan-"):
176
+ payload = {
177
+ "imageUrl": request.image if request.image.startswith("http") else await to_url_fal(request.image),
178
+ }
179
+ # "remove-watermark" "clarity"
180
+ if "remove-watermark" in request.model:
181
+ payload["model"] = "removewatermark"
182
+ elif "clarity" in request.model:
183
+ payload["model"] = "clarity"
184
+
185
+ return await make_request_for_hunyuan(payload, response_format=request.response_format)
186
+
126
187
 
127
188
  if __name__ == '__main__':
128
189
  token = "BAIDUID=FF8BB4BF861992E2BF4A585A37366236:FG=1; BAIDUID_BFESS=FF8BB4BF861992E2BF4A585A37366236:FG=1; BIDUPSID=FF8BB4BF861992E2BF4A585A37366236; BDRCVFR[dG2JNJb_ajR]=mk3SLVN4HKm; userFrom=null; ab_sr=1.0.1_NjY5OWZiZDg5YTJmYTQzNWUyNzU1YjBmN2FlMDFiNjMyOTVhMDE3ZWVlYWY5N2Y2MTg4NGI1MzRmMmVjMjQyZjlhZTU2MmM1NDRlMmU4YzgwMzRiMjUyYTc4ZjY1OTcxZTE4OTA4YTlmMWIwZWUzNTdiMzlhZTRiM2IzYTQ0MjgyMzc2MjQwMGRlYzZlZDhjOTg5Yzg4NWVjMTNiZmVmZQ==; BDRCVFR[-pGxjrCMryR]=mk3SLVN4HKm; H_WISE_SIDS=60273_60360_60623_60664_60678_60684_60700"
190
+ # hunyuan
191
+ token = "web_uid=ac283ec7-4bf6-40c9-a0ce-5a2e0cd7db06; hy_source=web; hy_user=I09MgMfFcUUyVSIg; hy_token=hevVCi/QuVjQcre5NDRMO7FuiWCZoDMIq3Zp8IwNxrPUofl4zWYazHEdeZ2S5o7q; _qimei_q36=; _qimei_h38=f2d27f50f0f23e085296d28303000006a17a09; _qimei_fingerprint=efbb885a22f7d4e5589008c28bc8e7ba; _qimei_uuid42=18c0310102d1002a082420cd40bb9717523c3c7e12; _gcl_au=1.1.915258067.1733278380; _ga_RPMZTEBERQ=GS1.1.1733722091.3.1.1733722108.0.0.0; _ga=GA1.2.981511920.1725261466; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22100000458739%22%2C%22first_id%22%3A%22191b198c7b2d52-0fcca8d731cb9b8-18525637-2073600-191b198c7b31fd9%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%A4%BE%E4%BA%A4%E7%BD%91%E7%AB%99%E6%B5%81%E9%87%8F%22%2C%22%24latest_utm_medium%22%3A%22cpc%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTkxYjE5OGM3YjJkNTItMGZjY2E4ZDczMWNiOWI4LTE4NTI1NjM3LTIwNzM2MDAtMTkxYjE5OGM3YjMxZmQ5IiwiJGlkZW50aXR5X2xvZ2luX2lkIjoiMTAwMDAwNDU4NzM5In0%3D%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%24identity_login_id%22%2C%22value%22%3A%22100000458739%22%7D%2C%22%24device_id%22%3A%22191b198c7b2d52-0fcca8d731cb9b8-18525637-2073600-191b198c7b31fd9%22%7D"
129
192
 
130
193
  url = "https://oss.ffire.cc/files/kling_watermark.png"
194
+ url = "https://oss.ffire.cc/files/shuiyin.jpg"
195
+ url = "https://oss.ffire.cc/files/shuiyin3.jpg"
196
+
131
197
  # url = "https://s22-def.ap4r.com/bs2/upload-ylab-stunt-sgp/se/ai_portal_sgp_queue_mmu_txt2img_aiweb/9c520b80-efc2-4321-8f0e-f1d34d483ddd/1.png"
132
198
 
133
199
  request = ImageProcess(
134
- model="remove-watermark",
200
+ model="hunyuan-remove-watermark",
201
+
202
+ # model="remove-watermark",
135
203
  # model="clarity",
136
204
  # model="expand",
137
205
  # model="rmbg-2.0",
@@ -11,12 +11,9 @@ from openai import AsyncClient
11
11
 
12
12
  from meutils.pipe import *
13
13
  from meutils.hash_utils import md5
14
- from meutils.schemas.image_types import ImageRequest
15
14
  from meutils.schemas.openai_types import TTSRequest
16
15
 
17
16
  from meutils.schemas.jimeng_types import BASE_URL, MODELS_MAP
18
- from meutils.str_utils.regular_expression import parse_url
19
- from meutils.apis.jimeng.files import upload_for_image
20
17
  from meutils.caches.redis_cache import cache
21
18
 
22
19
  from fake_useragent import UserAgent
@@ -97,148 +94,7 @@ async def check_token(token, threshold: int = 1):
97
94
  return False
98
95
 
99
96
 
100
- async def create_draft_content(request: ImageRequest, token: str):
101
- """
102
- 创建草稿内容
103
- """
104
- request.model = MODELS_MAP.get(request.model, MODELS_MAP["default"])
105
97
 
106
- height = width = 1360
107
- if 'x' in request.size:
108
- height, width = map(int, request.size.split('x'))
109
-
110
- main_component_id = str(uuid.uuid4())
111
-
112
- if urls := parse_url(request.prompt):
113
- url = urls[-1]
114
- image_uri = upload_for_image(url, token)
115
-
116
- request.prompt = request.prompt.replace(url, '')
117
- request.model = "high_aes_general_v20_L:general_v2.0_L" # 2.1不支持图片编辑
118
-
119
- component = {
120
- "type": "image_base_component",
121
- "id": main_component_id,
122
- "min_version": "3.0.2",
123
- "generate_type": "blend",
124
- "aigc_mode": "workbench",
125
- "abilities": {
126
- "type": "",
127
- "id": str(uuid.uuid4()),
128
- "blend": {
129
- "type": "",
130
- "id": str(uuid.uuid4()),
131
- "core_param": {
132
- "type": "",
133
- "id": str(uuid.uuid4()),
134
- "model": request.model,
135
- "prompt": f"##{request.prompt}",
136
- "sample_strength": 0.5,
137
- "image_ratio": 1,
138
- "large_image_info": {
139
- "type": "",
140
- "id": str(uuid.uuid4()),
141
- "height": height,
142
- "width": width
143
- },
144
- },
145
- "ability_list": [
146
- {
147
- "type": "",
148
- "id": str(uuid.uuid4()),
149
- "name": "byte_edit",
150
- "image_uri_list": [
151
- image_uri
152
- ],
153
- "image_list": [
154
- {
155
- "type": "image",
156
- "id": str(uuid.uuid4()),
157
- "source_from": "upload",
158
- "platform_type": 1,
159
- "name": "",
160
- "image_uri": image_uri,
161
- "width": 0,
162
- "height": 0,
163
- "format": "",
164
- "uri": image_uri
165
- }
166
- ],
167
- "strength": 0.5
168
- }
169
- ],
170
- "history_option": {
171
- "type": "",
172
- "id": str(uuid.uuid4()),
173
- },
174
- "prompt_placeholder_info_list": [
175
- {
176
- "type": "",
177
- "id": str(uuid.uuid4()),
178
- "ability_index": 0
179
- }
180
- ],
181
- "postedit_param": {
182
- "type": "",
183
- "id": str(uuid.uuid4()),
184
- "generate_type": 0
185
- }
186
- }
187
- }
188
- }
189
-
190
- else:
191
-
192
- component = {
193
- "type": "image_base_component",
194
- "id": main_component_id,
195
- "min_version": "3.0.2",
196
- "generate_type": "generate",
197
- "aigc_mode": "workbench",
198
- "abilities": {
199
- "type": "",
200
- "id": str(uuid.uuid4()),
201
- "generate": {
202
- "type": "",
203
- "id": str(uuid.uuid4()),
204
- "core_param": {
205
- "type": "",
206
- "id": str(uuid.uuid4()),
207
- "model": request.model,
208
- "prompt": request.prompt,
209
- "negative_prompt": request.negative_prompt or "",
210
- "seed": request.seed or 426999300,
211
- "sample_strength": 0.5,
212
- "image_ratio": 1,
213
- "large_image_info": {
214
- "type": "",
215
- "id": str(uuid.uuid4()),
216
- "height": height,
217
- "width": width
218
- }
219
- },
220
- "history_option": {
221
- "type": "",
222
- "id": str(uuid.uuid4()),
223
- }
224
- }
225
- }
226
- }
227
-
228
- draft_content = {
229
- "type": "draft",
230
- "id": str(uuid.uuid4()),
231
- "min_version": "3.0.2",
232
- "min_features": [],
233
- "is_from_tsn": True,
234
- "version": "3.0.8",
235
- "main_component_id": main_component_id,
236
- "component_list": [component]
237
- }
238
-
239
- logger.debug(bjson(draft_content))
240
-
241
- return draft_content
242
98
 
243
99
 
244
100
  def create_photo_lip_sync(request: TTSRequest):
@@ -15,7 +15,7 @@ import hashlib
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
-
18
+ from meutils.apis.jimeng.common import get_upload_token
19
19
 
20
20
  def random_str(n):
21
21
  return ''.join(random.sample('zyxwvutsrqponmlkjihgfedcba0123456789', n))
@@ -54,8 +54,7 @@ class JJRequest:
54
54
  self.serviceName = serviceName
55
55
 
56
56
  def getAuthorization(self):
57
- 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()}"
58
-
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()}"
59
58
  def signature(self):
60
59
  r = self.getSigningKey()
61
60
  return hmac_hash256(r, self.stringToSign()).hexdigest()
@@ -180,6 +179,14 @@ async def upload(image: bytes, upload_token: dict): # oss 跨账号不知道是
180
179
 
181
180
 
182
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
+ """
183
190
  # e = auth = upload_token['data']['auth'] # 豆包
184
191
  data = upload_token['data']
185
192
  service_id = data.get('service_id', '3jr8j4ixpe') # 即梦 3jr8j4ixpe 豆包 a9rns2rl98
@@ -195,13 +202,16 @@ async def upload_for_vod(image: bytes, upload_token: dict): # oss 跨账号不
195
202
  "Action": "ApplyUploadInner",
196
203
  "Version": "2020-11-19",
197
204
  # "ServiceId": service_id,
198
- "SpaceName": "artist_op",
205
+ # "SpaceName": "artist_op",
206
+ "SpaceName": "dreamina",
199
207
 
200
- "s": random_str(10),
208
+ "IsInner": "1",
201
209
 
202
210
  "FileType": "video",
203
211
  "FileSize": len(image),
204
212
 
213
+ "s": random_str(10),
214
+
205
215
  }
206
216
 
207
217
  r = JJRequest(data, t, "https://vod.bytedanceapi.com/", method="GET", params=params, serviceName="vod")
@@ -239,7 +249,7 @@ async def upload_for_vod(image: bytes, upload_token: dict): # oss 跨账号不
239
249
  headers = {
240
250
  "authorization": oss_token,
241
251
  "content-length": str(len(image)),
242
- "content-Type": "image/jpeg",
252
+ "content-Type": "application/octet-stream",
243
253
  "content-crc32": fileCRC32(image),
244
254
  }
245
255
 
@@ -257,11 +267,12 @@ async def upload_for_vod(image: bytes, upload_token: dict): # oss 跨账号不
257
267
  data = response.json()
258
268
  logger.debug(bjson(data))
259
269
 
260
- return oss_uri
270
+ return vid, oss_uri
261
271
 
262
272
 
263
273
  async def upload_for_image(image, token): # todo: 跨账号token
264
274
  """image url base64 bytes"""
275
+ if not image: return
265
276
 
266
277
  upload_token = await get_upload_token(token)
267
278
  image_uri = await upload(await to_bytes(image), upload_token)
@@ -269,15 +280,16 @@ async def upload_for_image(image, token): # todo: 跨账号token
269
280
 
270
281
 
271
282
  async def upload_for_video(video, token): # 跨账号token
272
- """video url base64 bytes"""
283
+ """video url base64 bytes
284
+ """
285
+ if not video: return
273
286
 
274
287
  upload_token = await get_upload_token(token)
275
- uri = await upload_for_vod(await to_bytes(video), upload_token)
276
- return uri
288
+ vid, uri = await upload_for_vod(await to_bytes(video), upload_token)
289
+ return vid, uri
277
290
 
278
291
 
279
292
  if __name__ == "__main__":
280
- from meutils.apis.jimeng.common import get_upload_token
281
293
 
282
294
  # 豆包
283
295
  token = "de2215a7bb8e442774cf388f03fac84c"
@@ -302,4 +314,5 @@ if __name__ == "__main__":
302
314
 
303
315
  with timer():
304
316
  url = "https://oss.ffire.cc/files/lipsync.mp3"
305
- arun(upload_for_video("https://oss.ffire.cc/files/lipsync.mp3", token))
317
+ # arun(upload_for_video("https://oss.ffire.cc/files/lipsync.mp3", token))
318
+ arun(upload_for_video(url, token))
@@ -14,14 +14,162 @@ from meutils.caches.redis_cache import cache
14
14
  from meutils.schemas.jimeng_types import BASE_URL, MODELS_MAP, FEISHU_URL
15
15
  from meutils.schemas.image_types import ImageRequest
16
16
  from meutils.schemas.task_types import TaskResponse
17
- 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
+
18
21
  from meutils.config_utils.lark_utils import get_next_token_for_polling
22
+ from fastapi import status, HTTPException
19
23
 
20
24
  from fake_useragent import UserAgent
21
25
 
22
26
  ua = UserAgent()
23
27
 
24
28
 
29
+ async def create_draft_content(request: ImageRequest, token: str):
30
+ """
31
+ 创建草稿内容
32
+ """
33
+ request.model = MODELS_MAP.get(request.model, MODELS_MAP["default"])
34
+
35
+ height = width = 1360
36
+ if 'x' in request.size:
37
+ height, width = map(int, request.size.split('x'))
38
+
39
+ main_component_id = str(uuid.uuid4())
40
+
41
+ if urls := parse_url(request.prompt):
42
+ url = urls[-1]
43
+ image_uri = upload_for_image(url, token)
44
+
45
+ request.prompt = request.prompt.replace(url, '')
46
+ request.model = "high_aes_general_v20_L:general_v2.0_L" # 2.1不支持图片编辑
47
+
48
+ component = {
49
+ "type": "image_base_component",
50
+ "id": main_component_id,
51
+ "min_version": "3.0.2",
52
+ "generate_type": "blend",
53
+ "aigc_mode": "workbench",
54
+ "abilities": {
55
+ "type": "",
56
+ "id": str(uuid.uuid4()),
57
+ "blend": {
58
+ "type": "",
59
+ "id": str(uuid.uuid4()),
60
+ "core_param": {
61
+ "type": "",
62
+ "id": str(uuid.uuid4()),
63
+ "model": request.model,
64
+ "prompt": f"##{request.prompt}",
65
+ "sample_strength": 0.5,
66
+ "image_ratio": 1,
67
+ "large_image_info": {
68
+ "type": "",
69
+ "id": str(uuid.uuid4()),
70
+ "height": height,
71
+ "width": width
72
+ },
73
+ },
74
+ "ability_list": [
75
+ {
76
+ "type": "",
77
+ "id": str(uuid.uuid4()),
78
+ "name": "byte_edit",
79
+ "image_uri_list": [
80
+ image_uri
81
+ ],
82
+ "image_list": [
83
+ {
84
+ "type": "image",
85
+ "id": str(uuid.uuid4()),
86
+ "source_from": "upload",
87
+ "platform_type": 1,
88
+ "name": "",
89
+ "image_uri": image_uri,
90
+ "width": 0,
91
+ "height": 0,
92
+ "format": "",
93
+ "uri": image_uri
94
+ }
95
+ ],
96
+ "strength": 0.5
97
+ }
98
+ ],
99
+ "history_option": {
100
+ "type": "",
101
+ "id": str(uuid.uuid4()),
102
+ },
103
+ "prompt_placeholder_info_list": [
104
+ {
105
+ "type": "",
106
+ "id": str(uuid.uuid4()),
107
+ "ability_index": 0
108
+ }
109
+ ],
110
+ "postedit_param": {
111
+ "type": "",
112
+ "id": str(uuid.uuid4()),
113
+ "generate_type": 0
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ else:
120
+
121
+ component = {
122
+ "type": "image_base_component",
123
+ "id": main_component_id,
124
+ "min_version": "3.0.2",
125
+ "generate_type": "generate",
126
+ "aigc_mode": "workbench",
127
+ "abilities": {
128
+ "type": "",
129
+ "id": str(uuid.uuid4()),
130
+ "generate": {
131
+ "type": "",
132
+ "id": str(uuid.uuid4()),
133
+ "core_param": {
134
+ "type": "",
135
+ "id": str(uuid.uuid4()),
136
+ "model": request.model,
137
+ "prompt": request.prompt,
138
+ "negative_prompt": request.negative_prompt or "",
139
+ "seed": request.seed or 426999300,
140
+ "sample_strength": 0.5,
141
+ "image_ratio": 1,
142
+ "large_image_info": {
143
+ "type": "",
144
+ "id": str(uuid.uuid4()),
145
+ "height": height,
146
+ "width": width
147
+ }
148
+ },
149
+ "history_option": {
150
+ "type": "",
151
+ "id": str(uuid.uuid4()),
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ draft_content = {
158
+ "type": "draft",
159
+ "id": str(uuid.uuid4()),
160
+ "min_version": "3.0.2",
161
+ "min_features": [],
162
+ "is_from_tsn": True,
163
+ "version": "3.0.8",
164
+ "main_component_id": main_component_id,
165
+ "component_list": [component]
166
+ }
167
+
168
+ logger.debug(bjson(draft_content))
169
+
170
+ return draft_content
171
+
172
+
25
173
  async def create_task(request: ImageRequest, token: Optional[str] = None):
26
174
  token = token or await get_next_token_for_polling(FEISHU_URL, check_token)
27
175
 
@@ -51,11 +199,25 @@ async def create_task(request: ImageRequest, token: Optional[str] = None):
51
199
  async with httpx.AsyncClient(base_url=BASE_URL, headers=headers, timeout=60) as client:
52
200
  response = await client.post(url, json=payload)
53
201
  response.raise_for_status()
202
+
54
203
  data = response.json()
55
204
  logger.debug(bjson(data))
56
-
57
- task_id = data.get("data", {}).get("aigc_data", {}).get("history_record_id")
58
- return TaskResponse(task_id=task_id, system_fingerprint=token)
205
+ if task_id := data.get("data", {}).get("aigc_data", {}).get("history_record_id"):
206
+ return TaskResponse(task_id=task_id, system_fingerprint=token)
207
+ else:
208
+
209
+ # {
210
+ # "ret": "1018",
211
+ # "errmsg": "account punish limit ai generate",
212
+ # "systime": "1737962056",
213
+ # "logid": "202501271514162E3DA8ECD70A3EE1400F",
214
+ # "data": null
215
+ # }
216
+
217
+ raise HTTPException(
218
+ status_code=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
219
+ detail="可能触发内容审核,请联系管理员"
220
+ )
59
221
 
60
222
 
61
223
  async def get_task(task_id, token):