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.
- {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/METADATA +29 -30
- {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/RECORD +34 -32
- examples/_openaisdk/4v.py +3 -4
- examples/_openaisdk/openai_baichuan.py +7 -3
- examples/_openaisdk/openai_chatfire.py +15 -4
- examples/_openaisdk/openai_deepinfra.py +2 -2
- examples/_openaisdk/openai_modelscope.py +2 -1
- examples/_openaisdk/openai_together.py +2 -1
- examples/_openaisdk/openai_zhipu.py +9 -5
- examples/json_jmespath.py +13 -13
- meutils/apis/hunyuan/image_tools.py +6 -2
- meutils/apis/images/edits.py +70 -2
- meutils/apis/jimeng/common.py +0 -144
- meutils/apis/jimeng/files.py +25 -12
- meutils/apis/jimeng/images.py +166 -4
- meutils/apis/jimeng/videos.py +176 -107
- meutils/apis/vidu/vidu_video.py +3 -3
- meutils/data/VERSION +1 -1
- meutils/data/oneapi/NOTICE.md +25 -8
- meutils/jwt_utils/common.py +46 -0
- meutils/llm/clients.py +4 -1
- meutils/llm/completions/agents/search.py +115 -0
- meutils/parsers/fileparser/mineru.py +48 -0
- meutils/schemas/image_types.py +12 -1
- meutils/schemas/oneapi/common.py +17 -5
- meutils/schemas/oneapi/models.py +1 -1
- meutils/schemas/openai_types.py +1 -1
- meutils/schemas/video_types.py +9 -1
- meutils/schemas/vidu_types.py +1 -1
- meutils/request_utils/jwt_utils/common.py +0 -42
- {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/LICENSE +0 -0
- {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/WHEEL +0 -0
- {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/entry_points.txt +0 -0
- {MeUtils-2025.1.23.10.16.28.dist-info → MeUtils-2025.1.29.10.0.47.dist-info}/top_level.txt +0 -0
- /meutils/{request_utils/jwt_utils → jwt_utils}/__init__.py +0 -0
meutils/apis/images/edits.py
CHANGED
@@ -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",
|
meutils/apis/jimeng/common.py
CHANGED
@@ -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):
|
meutils/apis/jimeng/files.py
CHANGED
@@ -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[
|
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
|
-
"
|
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": "
|
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))
|
meutils/apis/jimeng/images.py
CHANGED
@@ -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
|
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
|
-
|
58
|
-
|
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):
|