MeUtils 2025.5.30.20.48.16__py3-none-any.whl → 2025.6.4.17.6.12__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.5.30.20.48.16.dist-info → MeUtils-2025.6.4.17.6.12.dist-info}/METADATA +261 -261
- {MeUtils-2025.5.30.20.48.16.dist-info → MeUtils-2025.6.4.17.6.12.dist-info}/RECORD +26 -23
- examples/_openaisdk/openai_sophnet.py +26 -7
- meutils/apis/fal/chat.py +74 -0
- meutils/apis/fal/images.py +20 -12
- meutils/apis/fal/tasks.py +98 -0
- meutils/apis/images/openai_edits.py +1 -1
- meutils/apis/jimeng/videos.py +30 -10
- meutils/data/VERSION +1 -1
- meutils/llm/check_utils.py +4 -1
- meutils/llm/completions/sophnet.py +61 -0
- meutils/llm/completions/yuanbao.py +2 -2
- meutils/llm/openai_polling/chat.py +0 -3
- meutils/llm/openai_utils/adapters.py +12 -3
- meutils/llm/openai_utils/common.py +21 -2
- meutils/llm/utils.py +52 -21
- meutils/notice/feishu.py +2 -2
- meutils/schemas/image_types.py +4 -1
- meutils/schemas/oneapi/common.py +28 -13
- meutils/schemas/openai_types.py +7 -7
- meutils/serving/fastapi/dependencies/auth.py +3 -0
- meutils/str_utils/regular_expression.py +6 -2
- {MeUtils-2025.5.30.20.48.16.dist-info → MeUtils-2025.6.4.17.6.12.dist-info}/LICENSE +0 -0
- {MeUtils-2025.5.30.20.48.16.dist-info → MeUtils-2025.6.4.17.6.12.dist-info}/WHEEL +0 -0
- {MeUtils-2025.5.30.20.48.16.dist-info → MeUtils-2025.6.4.17.6.12.dist-info}/entry_points.txt +0 -0
- {MeUtils-2025.5.30.20.48.16.dist-info → MeUtils-2025.6.4.17.6.12.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Project : AI. @by PyCharm
|
4
|
+
# @File : sophnet
|
5
|
+
# @Time : 2025/6/4 16:16
|
6
|
+
# @Author : betterme
|
7
|
+
# @WeChat : meutils
|
8
|
+
# @Software : PyCharm
|
9
|
+
# @Description :
|
10
|
+
|
11
|
+
from meutils.pipe import *
|
12
|
+
from meutils.llm.clients import AsyncOpenAI
|
13
|
+
|
14
|
+
from meutils.llm.check_utils import check_token_for_sophnet as check_token
|
15
|
+
|
16
|
+
from meutils.config_utils.lark_utils import get_next_token_for_polling
|
17
|
+
from meutils.schemas.openai_types import chat_completion, chat_completion_chunk, CompletionRequest, CompletionUsage, \
|
18
|
+
ChatCompletion
|
19
|
+
|
20
|
+
FEISHU_URL = "https://xchatllm.feishu.cn/sheets/Bmjtst2f6hfMqFttbhLcdfRJnNf?sheet=lxJ27j"
|
21
|
+
|
22
|
+
base_url = "https://www.sophnet.com/api/open-apis/v1"
|
23
|
+
|
24
|
+
|
25
|
+
async def create(request: CompletionRequest, token: Optional[str] = None):
|
26
|
+
"""最终是非流"""
|
27
|
+
token = token or await get_next_token_for_polling(feishu_url=FEISHU_URL, from_redis=True, check_token=check_token)
|
28
|
+
|
29
|
+
client = AsyncOpenAI(base_url=base_url, api_key=token)
|
30
|
+
|
31
|
+
if not request.stream:
|
32
|
+
logger.debug("伪非流")
|
33
|
+
|
34
|
+
data = request.model_dump(exclude_none=True)
|
35
|
+
data['stream'] = True
|
36
|
+
|
37
|
+
chunks = await client.chat.completions.create(**data)
|
38
|
+
|
39
|
+
chunk = None
|
40
|
+
async for chunk in chunks:
|
41
|
+
if chunk.choices:
|
42
|
+
_ = chunk.choices[0].delta.content or ""
|
43
|
+
chat_completion.choices[0].message.content += _
|
44
|
+
# logger.debug(_)
|
45
|
+
if hasattr(chunk, "usage"):
|
46
|
+
chat_completion.usage = chunk.usage
|
47
|
+
|
48
|
+
logger.debug(chat_completion)
|
49
|
+
return chat_completion
|
50
|
+
else:
|
51
|
+
return client.chat.completions.create(**request.model_dump(exclude_none=True))
|
52
|
+
|
53
|
+
|
54
|
+
if __name__ == '__main__':
|
55
|
+
request = CompletionRequest(
|
56
|
+
model="DeepSeek-v3",
|
57
|
+
messages=[{"role": "user", "content": "hi"}],
|
58
|
+
stream=True,
|
59
|
+
)
|
60
|
+
|
61
|
+
arun(create(request))
|
@@ -200,8 +200,8 @@ if __name__ == '__main__':
|
|
200
200
|
# model = 'deep_seek-search'
|
201
201
|
model = 'deep_seek'
|
202
202
|
# model = 'hunyuan_t1'
|
203
|
-
model = 'hunyuan_t1-search'
|
204
|
-
|
203
|
+
# model = 'hunyuan_t1-search'
|
204
|
+
model = 'deep_seek-search'
|
205
205
|
|
206
206
|
arun(Completions().create(
|
207
207
|
CompletionRequest(
|
@@ -82,9 +82,6 @@ class Completions(object):
|
|
82
82
|
data.pop("frequency_penalty", None)
|
83
83
|
data.pop("extra_body", None)
|
84
84
|
|
85
|
-
if '2.5' in request.model and not request.reasoning_effort: # 默认关闭思考
|
86
|
-
data['reasoning_effort'] = "none"
|
87
|
-
|
88
85
|
if "thinking" in request.model:
|
89
86
|
data['model'] = data['model'].removesuffix("-thinking") # 开启思考
|
90
87
|
data['reasoning_effort'] = 'low'
|
@@ -9,10 +9,15 @@
|
|
9
9
|
# @Description :
|
10
10
|
|
11
11
|
from meutils.pipe import *
|
12
|
+
from meutils.io.files_utils import to_url, to_url_fal
|
12
13
|
from meutils.schemas.openai_types import CompletionRequest
|
13
14
|
from meutils.schemas.image_types import ImageRequest
|
14
15
|
from meutils.llm.openai_utils import chat_completion, chat_completion_chunk, create_chat_completion_chunk
|
15
16
|
|
17
|
+
async def stream_to_nostream(
|
18
|
+
request: CompletionRequest,
|
19
|
+
):
|
20
|
+
pass
|
16
21
|
|
17
22
|
async def chat_for_image(
|
18
23
|
generate: Callable,
|
@@ -24,14 +29,18 @@ async def chat_for_image(
|
|
24
29
|
"使用四到五个字直接返回这句话的简要主题",
|
25
30
|
"简要总结一下对话内容,用作后续的上下文提示 prompt,控制在 200 字以内"
|
26
31
|
)):
|
27
|
-
return
|
32
|
+
return chat_completion
|
33
|
+
|
34
|
+
prompt = request.last_user_content
|
35
|
+
if request.last_urls: # image_url
|
36
|
+
urls = await to_url_fal(request.last_urls["image_url"], content_type="image/png")
|
37
|
+
prompt = "\n".join(urls + [prompt])
|
28
38
|
|
29
39
|
request = ImageRequest(
|
30
40
|
model=request.model,
|
31
|
-
prompt=
|
41
|
+
prompt=prompt,
|
32
42
|
)
|
33
43
|
|
34
|
-
|
35
44
|
future_task = asyncio.create_task(generate(request)) # 异步执行
|
36
45
|
|
37
46
|
async def gen():
|
@@ -121,8 +121,11 @@ async def appu(
|
|
121
121
|
model='ppu',
|
122
122
|
api_key: Optional[str] = None,
|
123
123
|
base_url: Optional[str] = None,
|
124
|
+
|
125
|
+
dynamic: bool = False, # 动态路由模型
|
126
|
+
|
124
127
|
):
|
125
|
-
if model not in MODEL_PRICE:
|
128
|
+
if not dynamic and model not in MODEL_PRICE:
|
126
129
|
_ = f"模型未找到「{model}」,默认ppu-1"
|
127
130
|
|
128
131
|
logger.warning(_)
|
@@ -142,6 +145,9 @@ async def ppu_flow(
|
|
142
145
|
post: str = "ppu-1", # 后计费
|
143
146
|
|
144
147
|
pre: str = "ppu-0001", # 前置判断,废弃
|
148
|
+
|
149
|
+
dynamic: bool = False,
|
150
|
+
|
145
151
|
**kwargs
|
146
152
|
):
|
147
153
|
"""
|
@@ -164,7 +170,7 @@ async def ppu_flow(
|
|
164
170
|
|
165
171
|
# 计费逻辑
|
166
172
|
n = int(np.round(n)) or 1 # np.ceil(n)
|
167
|
-
await asyncio.gather(*[appu(post, api_key=api_key, base_url=base_url) for _ in range(n)])
|
173
|
+
await asyncio.gather(*[appu(post, api_key=api_key, base_url=base_url, dynamic=dynamic) for _ in range(n)])
|
168
174
|
|
169
175
|
if money is None: # 先扣费
|
170
176
|
yield
|
@@ -239,6 +245,19 @@ async def create_chat_completion_chunk(
|
|
239
245
|
yield "[DONE]" # 兼容标准格式
|
240
246
|
|
241
247
|
|
248
|
+
def get_payment_times(request: Union[BaseModel, dict], duration: float = 5):
|
249
|
+
if isinstance(request, BaseModel):
|
250
|
+
request = request.model_dump()
|
251
|
+
|
252
|
+
# 数量
|
253
|
+
N = request.get("n") or request.get("num_images") or 1
|
254
|
+
|
255
|
+
# 时长
|
256
|
+
N += request.get("duration", 0) // duration
|
257
|
+
|
258
|
+
return N
|
259
|
+
|
260
|
+
|
242
261
|
if __name__ == '__main__':
|
243
262
|
# print(ppu())
|
244
263
|
# print(appu())
|
meutils/llm/utils.py
CHANGED
@@ -70,7 +70,7 @@ async def ppu_flow(
|
|
70
70
|
yield
|
71
71
|
|
72
72
|
|
73
|
-
def oneturn2multiturn(messages, template: Optional[str] = None):
|
73
|
+
def oneturn2multiturn(messages, template: Optional[str] = None, ignore_system: bool = True):
|
74
74
|
"""todo: https://github.com/hiyouga/LLaMA-Factory/blob/e898fabbe3efcd8b44d0e119e7afaed4542a9f39/src/llmtuner/data/template.py#L423-L427
|
75
75
|
|
76
76
|
_register_template(
|
@@ -99,36 +99,67 @@ def oneturn2multiturn(messages, template: Optional[str] = None):
|
|
99
99
|
# context += f"<|im_start|>{role}\n{content}<|im_end|>\n"
|
100
100
|
# context += "<|im_start|>assistant\n"
|
101
101
|
if len(messages) == 1:
|
102
|
-
|
102
|
+
content = messages[0].get("content")
|
103
|
+
if isinstance(content, list):
|
104
|
+
content = content[-1].get('text', '')
|
105
|
+
return content
|
103
106
|
|
104
107
|
context = "\n"
|
105
108
|
for message in messages:
|
106
109
|
role = message.get("role")
|
107
110
|
content = message.get("content")
|
111
|
+
|
108
112
|
if isinstance(content, list): # content: {'type': 'text', 'text': ''}
|
109
113
|
content = content[-1].get('text', '')
|
110
114
|
|
115
|
+
if role == "system" and ignore_system:
|
116
|
+
continue
|
117
|
+
|
111
118
|
context += f"{role}:\n{content}\n\n"
|
112
|
-
context += "assistant:\n"
|
113
|
-
return context
|
114
119
|
|
120
|
+
return context
|
115
121
|
|
116
122
|
|
117
123
|
if __name__ == '__main__':
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
124
|
+
messages = [
|
125
|
+
{
|
126
|
+
"role": "system",
|
127
|
+
"content": [
|
128
|
+
{
|
129
|
+
"type": "text",
|
130
|
+
"text": "你是数学家"
|
131
|
+
}
|
132
|
+
]
|
133
|
+
},
|
134
|
+
{
|
135
|
+
"role": "user",
|
136
|
+
"content": [
|
137
|
+
{
|
138
|
+
"type": "text",
|
139
|
+
"text": "1+1"
|
140
|
+
}
|
141
|
+
]
|
142
|
+
},
|
143
|
+
{
|
144
|
+
"role": "assistant",
|
145
|
+
"content": [
|
146
|
+
{
|
147
|
+
"type": "text",
|
148
|
+
"text": "2"
|
149
|
+
}
|
150
|
+
]
|
151
|
+
},
|
152
|
+
|
153
|
+
{
|
154
|
+
"role": "user",
|
155
|
+
"content": [
|
156
|
+
{
|
157
|
+
"type": "text",
|
158
|
+
"text": "1+2"
|
159
|
+
}
|
160
|
+
]
|
161
|
+
},
|
162
|
+
|
163
|
+
]
|
164
|
+
|
165
|
+
print(oneturn2multiturn(messages,ignore_system=False))
|
meutils/notice/feishu.py
CHANGED
meutils/schemas/image_types.py
CHANGED
@@ -93,7 +93,7 @@ class ImageRequest(BaseModel): # openai
|
|
93
93
|
|
94
94
|
aspect_ratio: Optional[str] = None
|
95
95
|
|
96
|
-
user: Optional[str] = None
|
96
|
+
user: Optional[str] = None # to_url_fal
|
97
97
|
|
98
98
|
def __init__(self, /, **data: Any):
|
99
99
|
super().__init__(**data)
|
@@ -549,3 +549,6 @@ if __name__ == '__main__':
|
|
549
549
|
|
550
550
|
request = ImageRequest(prompt=prompt)
|
551
551
|
print(request.image_and_prompt)
|
552
|
+
|
553
|
+
data = {"image[]": "xxx"}
|
554
|
+
r = ImageRequest(**data)
|
meutils/schemas/oneapi/common.py
CHANGED
@@ -149,9 +149,9 @@ MODEL_PRICE = {
|
|
149
149
|
"ideogram-ai/ideogram-v2": 0.2,
|
150
150
|
"ideogram-ai/ideogram-v2-turbo": 0.1,
|
151
151
|
|
152
|
-
"imagen4": 0.05 *
|
153
|
-
"flux-kontext-pro": 0.04 *
|
154
|
-
"flux-kontext-max": 0.08 *
|
152
|
+
"imagen4": 0.05 * 3,
|
153
|
+
"flux-kontext-pro": 0.04 * 3,
|
154
|
+
"flux-kontext-max": 0.08 * 3,
|
155
155
|
|
156
156
|
"api-asr": 0.01,
|
157
157
|
"api-stt": 0.01,
|
@@ -626,6 +626,7 @@ MODEL_RATIO = {
|
|
626
626
|
"deepseek-r1-0528": 2,
|
627
627
|
"deepseek-r1-250528": 2,
|
628
628
|
"deepseek-r1-250528-qwen3-8b": 0.3,
|
629
|
+
"deepseek-r1-250528-think": 2,
|
629
630
|
|
630
631
|
"deepseek-search": 1,
|
631
632
|
'deepseek-r1-search': 2,
|
@@ -657,10 +658,14 @@ MODEL_RATIO = {
|
|
657
658
|
"hunyuan-t1": 1,
|
658
659
|
"hunyuan-t1-search": 1,
|
659
660
|
|
661
|
+
"hunyuan-r1-search": 2,
|
662
|
+
|
660
663
|
"deepseek-r1-metasearch": 2,
|
661
664
|
"meta-deepresearch": 2,
|
662
665
|
|
663
666
|
# 豆包
|
667
|
+
"doubao-1-5-ui-tars-250428": 1.75,
|
668
|
+
"ui-tars-72b": 1.75,
|
664
669
|
"doubao-1-5-pro-32k": 0.4,
|
665
670
|
"doubao-1-5-pro-32k-250115": 0.4,
|
666
671
|
"doubao-1-5-pro-256k": 2.5,
|
@@ -678,9 +683,9 @@ MODEL_RATIO = {
|
|
678
683
|
"doubao-pro-32k": 0.4,
|
679
684
|
"doubao-pro-32k-character": 0.4,
|
680
685
|
"doubao-pro-128k": 2.5,
|
681
|
-
"doubao-pro-256k": 5,
|
682
|
-
"doubao-1.5-pro-32k": 0.
|
683
|
-
"doubao-1.5-pro-256k": 5
|
686
|
+
"doubao-pro-256k": 2.5,
|
687
|
+
"doubao-1.5-pro-32k": 0.4,
|
688
|
+
"doubao-1.5-pro-256k": 2.5,
|
684
689
|
|
685
690
|
"doubao-1.5-vision-pro-32k": 1.5,
|
686
691
|
"doubao-1.5-vision-pro-250328": 1.5,
|
@@ -900,6 +905,9 @@ MODEL_RATIO = {
|
|
900
905
|
"o4-mini": 0.55,
|
901
906
|
"gpt-image-1": 2.5,
|
902
907
|
|
908
|
+
"o3": 5,
|
909
|
+
"o3-2025-04-16": 5,
|
910
|
+
|
903
911
|
# 硅基
|
904
912
|
"llama-3.1-8b-instruct": 0.01,
|
905
913
|
"meta-llama/Meta-Llama-3.1-8B-Instruct": 0.01,
|
@@ -1009,6 +1017,9 @@ COMPLETION_RATIO = {
|
|
1009
1017
|
"o3-mini": 4,
|
1010
1018
|
"o4-mini": 4,
|
1011
1019
|
|
1020
|
+
"o3": 4,
|
1021
|
+
"o3-2025-04-16": 4,
|
1022
|
+
|
1012
1023
|
"gpt-4o-realtime-preview": 4,
|
1013
1024
|
"gpt-4o-realtime-preview-2024-10-01": 4,
|
1014
1025
|
"gpt-4o-2024-11-20": 4,
|
@@ -1177,20 +1188,22 @@ COMPLETION_RATIO = {
|
|
1177
1188
|
"deepseek-ai/deepseek-vl2": 4,
|
1178
1189
|
|
1179
1190
|
# 豆包
|
1191
|
+
"doubao-1-5-ui-tars-250428": 3.43,
|
1192
|
+
"ui-tars-72b": 4,
|
1193
|
+
|
1180
1194
|
"doubao-lite-128k": 3,
|
1181
|
-
"doubao-lite-32k":
|
1195
|
+
"doubao-lite-32k": 2,
|
1182
1196
|
"doubao-lite-32k-character": 3,
|
1183
1197
|
"doubao-lite-4k": 3,
|
1184
1198
|
"doubao-1.5-lite-32k": 2,
|
1185
1199
|
|
1186
1200
|
"doubao-pro-4k": 3,
|
1187
|
-
"doubao-pro-32k":
|
1188
|
-
"doubao-pro-32k-241215": 3,
|
1201
|
+
"doubao-pro-32k": 2.5,
|
1189
1202
|
"doubao-pro-32k-character": 3,
|
1190
1203
|
"doubao-pro-128k": 3,
|
1191
|
-
"doubao-pro-256k":
|
1192
|
-
"doubao-1.5-pro-32k":
|
1193
|
-
"doubao-1.5-pro-256k":
|
1204
|
+
"doubao-pro-256k": 1.8,
|
1205
|
+
"doubao-1.5-pro-32k": 2.5,
|
1206
|
+
"doubao-1.5-pro-256k": 1.8,
|
1194
1207
|
|
1195
1208
|
"doubao-1.5-vision-pro-32k": 3,
|
1196
1209
|
"doubao-1.5-vision-pro-250328": 3,
|
@@ -1202,7 +1215,7 @@ COMPLETION_RATIO = {
|
|
1202
1215
|
"doubao-vision-pro-32k": 3,
|
1203
1216
|
|
1204
1217
|
"doubao-1-5-pro-32k": 1.25,
|
1205
|
-
"doubao-1-5-pro-32k-250115":
|
1218
|
+
"doubao-1-5-pro-32k-250115": 2.5,
|
1206
1219
|
"doubao-1-5-pro-256k": 1.8,
|
1207
1220
|
"doubao-1-5-pro-256k-250115": 1.8,
|
1208
1221
|
|
@@ -1233,6 +1246,7 @@ COMPLETION_RATIO = {
|
|
1233
1246
|
|
1234
1247
|
"hunyuan-t1": 4,
|
1235
1248
|
"hunyuan-t1-search": 4,
|
1249
|
+
"hunyuan-r1-search": 4,
|
1236
1250
|
|
1237
1251
|
"deepseek-r1-metasearch": 4,
|
1238
1252
|
"meta-deepresearch": 4,
|
@@ -1249,6 +1263,7 @@ COMPLETION_RATIO = {
|
|
1249
1263
|
"deepseek-r1-250120": 4,
|
1250
1264
|
"deepseek-r1-0528": 4,
|
1251
1265
|
"deepseek-r1-250528": 4,
|
1266
|
+
"deepseek-r1-250528-think": 4,
|
1252
1267
|
|
1253
1268
|
"deepseek-r1-250528-qwen3-8b": 4,
|
1254
1269
|
|
meutils/schemas/openai_types.py
CHANGED
@@ -620,10 +620,10 @@ if __name__ == '__main__':
|
|
620
620
|
# print(chat_completion_chunk)
|
621
621
|
# print(chat_completion)
|
622
622
|
|
623
|
-
chat_completion_chunk.usage = dict(
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
)
|
628
|
-
|
629
|
-
print(chat_completion_chunk)
|
623
|
+
# chat_completion_chunk.usage = dict(
|
624
|
+
# completion_tokens=10,
|
625
|
+
# prompt_tokens=10,
|
626
|
+
# total_tokens=20,
|
627
|
+
# )
|
628
|
+
#
|
629
|
+
# print(chat_completion_chunk)
|
@@ -26,7 +26,6 @@ def has_chinese(text):
|
|
26
26
|
return bool(pattern.search(text))
|
27
27
|
|
28
28
|
|
29
|
-
|
30
29
|
@lru_cache()
|
31
30
|
def remove_date_suffix(filename):
|
32
31
|
"""
|
@@ -147,6 +146,7 @@ if __name__ == '__main__':
|
|
147
146
|
https://oss.ffire.cc/files/%E6%8B%9B%E6%A0%87%E6%96%87%E4%BB%B6%E5%A4%87%E6%A1%88%E8%A1%A8%EF%BC%88%E7%AC%AC%E4%BA%8C%E6%AC%A1%EF%BC%89.pdf 这个文件讲了什么?
|
148
147
|
|
149
148
|
"""
|
149
|
+
|
150
150
|
# https://oss.ffire.cc/files/%E6%8B%9B%E6%A0%87%E6%96%87%E4%BB%B6%E5%A4%87%E6%A1%88%E8%A1%A8%EF%BC%88%E7%AC%AC%E4%BA%8C%E6%AC%A1%EF%BC%89.pdf 正则匹配会卡死
|
151
151
|
# from urllib3.util import parse_url
|
152
152
|
# text = "@firebot /换衣 https://oss.ffire.cc/files/try-on.png"
|
@@ -163,10 +163,14 @@ if __name__ == '__main__':
|
|
163
163
|
|
164
164
|
print(parse_url(text))
|
165
165
|
|
166
|
-
print(parse_url("[](https://oss.ffire.cc/cdn/2025-03-20/YbHhMbrXV82XGn4msunAJw)"))
|
166
|
+
# print(parse_url("[](https://oss.ffire.cc/cdn/2025-03-20/YbHhMbrXV82XGn4msunAJw)"))
|
167
167
|
|
168
168
|
# print('https://mj101-1317487292.cos.ap-shanghai.myqcloud.com/ai/test.pdf\\n\\n'.strip(r"\n"))
|
169
169
|
|
170
170
|
# print(parse_url("http://154.3.0.117:39666/docs#/default/get_content_preview_spider_playwright_get"))
|
171
171
|
|
172
172
|
# print(parse_url(text, True))
|
173
|
+
text = """
|
174
|
+
https://p3-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/1fe07cca46224208bfbed8c0f3c50ed8.png~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1780112531&x-signature=e7q1NOMjqCHvMz%2FC3dVAEVisAh4%3D&x-wf-file_name=9748f6214970f744fe7fd7a3699cfa2.png \nA young woman holding a lipstick tube with a black body and gold decorative rings, featuring a nude or light brown lipstick bullet. The lipstick product faces the camera, positioned slightly below her face. In the background, a close-up of lips coated with the same nude or light brown shade, creating a natural and soft effect.
|
175
|
+
"""
|
176
|
+
print(parse_url(text, for_image=True))
|
File without changes
|
File without changes
|
{MeUtils-2025.5.30.20.48.16.dist-info → MeUtils-2025.6.4.17.6.12.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|