MeUtils 2025.6.9.11.23.49__py3-none-any.whl → 2025.6.12.17.34.4__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.6.9.11.23.49.dist-info → MeUtils-2025.6.12.17.34.4.dist-info}/METADATA +257 -257
- {MeUtils-2025.6.9.11.23.49.dist-info → MeUtils-2025.6.12.17.34.4.dist-info}/RECORD +23 -18
- examples/_openaisdk/openai_chatfire_usa.py +32 -0
- meutils/apis/fal/images.py +20 -16
- meutils/apis/google/chat.py +3 -3
- meutils/apis/images/generations.py +34 -0
- meutils/apis/jimeng/images.py +3 -2
- meutils/apis/volcengine_apis/videos.py +129 -0
- meutils/data/VERSION +1 -1
- meutils/llm/check_utils.py +2 -2
- meutils/llm/openai_utils/adapters.py +3 -0
- meutils/llm/openai_utils/common.py +1 -1
- meutils/math_utils/__init__.py +11 -0
- meutils/math_utils/common.py +50 -0
- meutils/notice/feishu.py +5 -1
- meutils/schemas/image_types.py +61 -43
- meutils/schemas/oneapi/common.py +35 -0
- meutils/str_utils/__init__.py +17 -4
- meutils/str_utils/regular_expression.py +16 -5
- {MeUtils-2025.6.9.11.23.49.dist-info → MeUtils-2025.6.12.17.34.4.dist-info}/LICENSE +0 -0
- {MeUtils-2025.6.9.11.23.49.dist-info → MeUtils-2025.6.12.17.34.4.dist-info}/WHEEL +0 -0
- {MeUtils-2025.6.9.11.23.49.dist-info → MeUtils-2025.6.12.17.34.4.dist-info}/entry_points.txt +0 -0
- {MeUtils-2025.6.9.11.23.49.dist-info → MeUtils-2025.6.12.17.34.4.dist-info}/top_level.txt +0 -0
meutils/schemas/image_types.py
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
# @Description : todo: 通用比例适配
|
10
10
|
|
11
11
|
from meutils.pipe import *
|
12
|
-
from meutils.str_utils
|
12
|
+
from meutils.str_utils import parse_url
|
13
|
+
from meutils.math_utils import size2aspect_ratio
|
13
14
|
|
14
15
|
from pydantic import constr
|
15
16
|
from openai.types import ImagesResponse as _ImagesResponse, Image
|
@@ -88,9 +89,9 @@ class ImageRequest(BaseModel): # openai
|
|
88
89
|
"""
|
89
90
|
图生图 两种方式: prompt + controls
|
90
91
|
"""
|
91
|
-
model: str
|
92
|
+
model: str = ''
|
92
93
|
|
93
|
-
prompt: constr(min_length=1, max_length=
|
94
|
+
prompt: constr(min_length=1, max_length=4096) = ""
|
94
95
|
|
95
96
|
n: Optional[int] = 1
|
96
97
|
|
@@ -124,11 +125,7 @@ class ImageRequest(BaseModel): # openai
|
|
124
125
|
self.size = ASPECT_RATIOS.get(self.aspect_ratio, '1024x1024')
|
125
126
|
|
126
127
|
elif self.size: # 适配尺寸
|
127
|
-
|
128
|
-
self.aspect_ratio = self.size
|
129
|
-
|
130
|
-
else:
|
131
|
-
self.aspect_ratio = ASPECT_RATIOS.get(self.size, '1:1')
|
128
|
+
self.aspect_ratio = size2aspect_ratio(self.size)
|
132
129
|
|
133
130
|
self.size = self.size if 'x' in self.size else '512x512'
|
134
131
|
|
@@ -138,7 +135,7 @@ class ImageRequest(BaseModel): # openai
|
|
138
135
|
if len(prompts) == 2:
|
139
136
|
return prompts
|
140
137
|
else:
|
141
|
-
return prompts + [' ']
|
138
|
+
return prompts + [' '] # 只有 单url
|
142
139
|
|
143
140
|
elif "http" in self.prompt and (images := parse_url(self.prompt)):
|
144
141
|
return images[0], self.prompt.replace(images[0], "")
|
@@ -146,6 +143,11 @@ class ImageRequest(BaseModel): # openai
|
|
146
143
|
else:
|
147
144
|
return None, self.prompt
|
148
145
|
|
146
|
+
def prompt2aspect_ratio(self, aspect_ratios): # 提示词优先级最高:从支持的比例中选择匹配
|
147
|
+
for aspect_ratio in aspect_ratios:
|
148
|
+
if aspect_ratio in self.prompt:
|
149
|
+
return aspect_ratio
|
150
|
+
|
149
151
|
class Config:
|
150
152
|
extra = "allow"
|
151
153
|
|
@@ -162,6 +164,40 @@ class ImageRequest(BaseModel): # openai
|
|
162
164
|
}
|
163
165
|
|
164
166
|
|
167
|
+
class ImageEditRequest(BaseModel):
|
168
|
+
model: Union[str, Literal["dall-e-2", "dall-e-3", "gpt-image-1"]]
|
169
|
+
|
170
|
+
prompt: str
|
171
|
+
image: Any # 图片
|
172
|
+
|
173
|
+
mask: Optional[Any] = None # 图片
|
174
|
+
background: Optional[Literal["transparent", "opaque", "auto"]] = None
|
175
|
+
|
176
|
+
n: Optional[int] = 1
|
177
|
+
quality: Optional[Literal["standard", "low", "medium", "high", "auto"]] = None
|
178
|
+
size: Optional[
|
179
|
+
Union[str, Literal["256x256", "512x512", "1024x1024", "1536x1024", "1024x1536", "auto"]]] = "1024x1024"
|
180
|
+
response_format: Optional[Literal["url", "b64_json"]] = None
|
181
|
+
|
182
|
+
aspect_ratio: Optional[str] = None
|
183
|
+
|
184
|
+
user: Optional[str] = None
|
185
|
+
|
186
|
+
def __init__(self, /, **data: Any):
|
187
|
+
super().__init__(**data)
|
188
|
+
if not isinstance(self.image, list):
|
189
|
+
self.image = [self.image]
|
190
|
+
|
191
|
+
if self.aspect_ratio: # 适配比例
|
192
|
+
self.size = ASPECT_RATIOS.get(self.aspect_ratio, '1024x1024')
|
193
|
+
|
194
|
+
elif self.size: # 适配尺寸
|
195
|
+
|
196
|
+
self.aspect_ratio = size2aspect_ratio(self.size)
|
197
|
+
|
198
|
+
self.size = self.size if 'x' in self.size else '512x512'
|
199
|
+
|
200
|
+
|
165
201
|
class FalImageRequest(ImageRequest):
|
166
202
|
prompt: str
|
167
203
|
seed: Optional[int] = None
|
@@ -525,40 +561,6 @@ class ImageProcess(BaseModel):
|
|
525
561
|
# extra = "allow"
|
526
562
|
|
527
563
|
|
528
|
-
class ImageEditRequest(BaseModel):
|
529
|
-
model: Union[str, Literal["dall-e-2", "dall-e-3", "gpt-image-1"]]
|
530
|
-
|
531
|
-
prompt: str
|
532
|
-
image: Any # 图片
|
533
|
-
|
534
|
-
mask: Optional[Any] = None # 图片
|
535
|
-
background: Optional[Literal["transparent", "opaque", "auto"]] = None
|
536
|
-
|
537
|
-
n: Optional[int] = 1
|
538
|
-
quality: Optional[Literal["standard", "low", "medium", "high", "auto"]] = None
|
539
|
-
size: Optional[
|
540
|
-
Union[str, Literal["256x256", "512x512", "1024x1024", "1536x1024", "1024x1536", "auto"]]] = "1024x1024"
|
541
|
-
response_format: Optional[Literal["url", "b64_json"]] = None
|
542
|
-
|
543
|
-
aspect_ratio: Optional[str] = None
|
544
|
-
|
545
|
-
user: Optional[str] = None
|
546
|
-
|
547
|
-
def __init__(self, /, **data: Any):
|
548
|
-
super().__init__(**data)
|
549
|
-
if not isinstance(self.image, list):
|
550
|
-
self.image = [self.image]
|
551
|
-
|
552
|
-
if self.aspect_ratio: # 适配比例
|
553
|
-
self.size = ASPECT_RATIOS.get(self.aspect_ratio, '1024x1024')
|
554
|
-
|
555
|
-
elif self.size: # 适配尺寸
|
556
|
-
if ':' in self.size:
|
557
|
-
self.aspect_ratio = self.size
|
558
|
-
|
559
|
-
self.size = self.size if 'x' in self.size else '512x512'
|
560
|
-
|
561
|
-
|
562
564
|
if __name__ == '__main__':
|
563
565
|
# print(ASPECT_RATIOS.items())
|
564
566
|
|
@@ -596,3 +598,19 @@ if __name__ == '__main__':
|
|
596
598
|
|
597
599
|
data = {"image[]": "xxx"}
|
598
600
|
r = ImageRequest(**data)
|
601
|
+
|
602
|
+
data = {
|
603
|
+
"model": "flux-kontext-pro",
|
604
|
+
"prompt": "a cat and a dog",
|
605
|
+
"size": "512x1024",
|
606
|
+
# "aspect_ratio": "16:9"
|
607
|
+
}
|
608
|
+
|
609
|
+
dd = {
|
610
|
+
"model": "flux-kontext-pro",
|
611
|
+
"prompt": "a cat and a dog",
|
612
|
+
"size": "5121x1024",
|
613
|
+
# "aspect_ratio": "16:9"
|
614
|
+
}
|
615
|
+
|
616
|
+
r = ImageRequest(**data)
|
meutils/schemas/oneapi/common.py
CHANGED
@@ -92,6 +92,19 @@ MODEL_PRICE = {
|
|
92
92
|
"sora-1:1-480p-5s": 1.2,
|
93
93
|
"dall-e-3": 0.03,
|
94
94
|
|
95
|
+
# rag
|
96
|
+
"qwen3-reranker-0.6b": 0.0011,
|
97
|
+
"qwen3-reranker-4b": 0.0011,
|
98
|
+
"qwen3-reranker-8b": 0.0011,
|
99
|
+
|
100
|
+
"qwen3-embedding-0.6b": 0.0011,
|
101
|
+
"qwen3-embedding-4b": 0.0011,
|
102
|
+
"qwen3-embedding-8b": 0.0011,
|
103
|
+
|
104
|
+
# 视频
|
105
|
+
"api-videos-3d": 0.01,
|
106
|
+
"api-videos-3d-1.5": 0.01,
|
107
|
+
|
95
108
|
# 智能体
|
96
109
|
"ppt": 0.1,
|
97
110
|
"ppt-islide": 0.1,
|
@@ -667,6 +680,10 @@ MODEL_RATIO = {
|
|
667
680
|
"meta-deepresearch": 2,
|
668
681
|
|
669
682
|
# 豆包
|
683
|
+
"doubao-seed-1-6-flash-250615": 0.075,
|
684
|
+
"doubao-seed-1-6-250615": 0.4,
|
685
|
+
"doubao-seed-1-6-thinking-250615": 0.4,
|
686
|
+
|
670
687
|
"doubao-1-5-ui-tars-250428": 1.75,
|
671
688
|
"ui-tars-72b": 1.75,
|
672
689
|
"doubao-1-5-pro-32k": 0.4,
|
@@ -725,6 +742,11 @@ MODEL_RATIO = {
|
|
725
742
|
"hunyuan-standard-256k": 60,
|
726
743
|
|
727
744
|
# 百度文心
|
745
|
+
"ernie-4.5-turbo-vl-32k": 0.45,
|
746
|
+
"ernie-4.5-turbo-128k": 0.12,
|
747
|
+
"ernie-x1-turbo-32k": 0.15,
|
748
|
+
"ernie-x1-32k-preview": 0.3,
|
749
|
+
|
728
750
|
"ERNIE-Speed-8K": 0.2858,
|
729
751
|
"ERNIE-Speed-128K": 0.2858,
|
730
752
|
|
@@ -912,6 +934,8 @@ MODEL_RATIO = {
|
|
912
934
|
"o3": 5,
|
913
935
|
"o3-2025-04-16": 5,
|
914
936
|
|
937
|
+
"o3-pro": 10,
|
938
|
+
|
915
939
|
# 硅基
|
916
940
|
"llama-3.1-8b-instruct": 0.01,
|
917
941
|
"meta-llama/Meta-Llama-3.1-8B-Instruct": 0.01,
|
@@ -1023,6 +1047,7 @@ COMPLETION_RATIO = {
|
|
1023
1047
|
|
1024
1048
|
"o3": 4,
|
1025
1049
|
"o3-2025-04-16": 4,
|
1050
|
+
"o3-pro": 4,
|
1026
1051
|
|
1027
1052
|
"gpt-4o-realtime-preview": 4,
|
1028
1053
|
"gpt-4o-realtime-preview-2024-10-01": 4,
|
@@ -1095,6 +1120,11 @@ COMPLETION_RATIO = {
|
|
1095
1120
|
"ERNIE-4.0-Turbo-8K": 3,
|
1096
1121
|
"ERNIE-4.0-8K": 3,
|
1097
1122
|
|
1123
|
+
"ernie-4.5-turbo-vl-32k": 4,
|
1124
|
+
"ernie-4.5-turbo-128k": 4,
|
1125
|
+
"ernie-x1-turbo-32k": 4,
|
1126
|
+
"ernie-x1-32k-preview": 4,
|
1127
|
+
|
1098
1128
|
"gemini-all": 5,
|
1099
1129
|
"gemini-1.5-pro-001": 4,
|
1100
1130
|
"gemini-1.5-pro-002": 4,
|
@@ -1193,6 +1223,11 @@ COMPLETION_RATIO = {
|
|
1193
1223
|
"deepseek-ai/deepseek-vl2": 4,
|
1194
1224
|
|
1195
1225
|
# 豆包
|
1226
|
+
"doubao-seed-1-6-flash-250615": 10,
|
1227
|
+
# doubao-seed-1-6-flash-250615,doubao-seed-1-6-250615,doubao-seed-1-6-thinking-250615
|
1228
|
+
"doubao-seed-1-6-250615": 10,
|
1229
|
+
"doubao-seed-1-6-thinking-250615": 10,
|
1230
|
+
|
1196
1231
|
"doubao-1-5-ui-tars-250428": 3.43,
|
1197
1232
|
"ui-tars-72b": 4,
|
1198
1233
|
|
meutils/str_utils/__init__.py
CHANGED
@@ -6,8 +6,10 @@
|
|
6
6
|
# @Author : yuanjie
|
7
7
|
# @WeChat : meutils
|
8
8
|
# @Software : PyCharm
|
9
|
-
# @Description :
|
9
|
+
# @Description :
|
10
|
+
import re
|
10
11
|
|
12
|
+
import httpx
|
11
13
|
|
12
14
|
from meutils.pipe import *
|
13
15
|
# from meutils.str_utils.translater import translater
|
@@ -231,13 +233,13 @@ def validate_url(url):
|
|
231
233
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
232
234
|
}
|
233
235
|
|
234
|
-
response = requests.head(url, timeout=5, allow_redirects=
|
236
|
+
# response = requests.head(url, timeout=5, allow_redirects=False, headers=headers)
|
237
|
+
response = requests.head(url, timeout=5, headers=headers)
|
235
238
|
if response.status_code >= 400:
|
236
239
|
logger.error(f"URL 返回错误状态码: {response.status_code}")
|
237
240
|
|
238
241
|
return False
|
239
242
|
|
240
|
-
logger.error("URL 有效")
|
241
243
|
return True
|
242
244
|
except requests.exceptions.RequestException as e:
|
243
245
|
logger.error(f"连接错误: {str(e)}")
|
@@ -277,4 +279,15 @@ if __name__ == '__main__':
|
|
277
279
|
|
278
280
|
url = 'https://fal.ai/models/fal-ai/flux-pro/kontext/requests/de5f28be-2ca8-4bd4-8c42-c7fc32969801?output=0'
|
279
281
|
url = "https://5b0988e595225.cdn.sohucs.com/images/20190814/5ebb727f502545718c4a06f199cd848b.jpeg"
|
280
|
-
|
282
|
+
# url = "https://filesystem.site/cdn/20250609/1XPdqIyhHiOJ8SC68W4ZQGBrf7XRZD.png"
|
283
|
+
|
284
|
+
# url = "https://filesystem.site/cdn/20250609/1QUKzDHRQedraO15CXnUc22aBjvqEN.png"
|
285
|
+
|
286
|
+
# url = "https://photog.art/api/oss/R2yh8N"
|
287
|
+
|
288
|
+
url = "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"
|
289
|
+
|
290
|
+
# print(validate_url([url] * 3))
|
291
|
+
print(validate_url(url))
|
292
|
+
|
293
|
+
print(re.findall("http", url*2))
|
@@ -8,6 +8,7 @@
|
|
8
8
|
# @Software : PyCharm
|
9
9
|
# @Description :
|
10
10
|
import json
|
11
|
+
import re
|
11
12
|
|
12
13
|
from meutils.pipe import *
|
13
14
|
from urllib.parse import unquote, unquote_plus
|
@@ -66,6 +67,9 @@ def get_parse_and_index(text, pattern):
|
|
66
67
|
|
67
68
|
@lru_cache()
|
68
69
|
def parse_url(text: str, for_image=False, fn: Optional[Callable] = None):
|
70
|
+
if text.strip().startswith("http") and len(re.findall("http", text)) == 1: # http开头且是单链接
|
71
|
+
return text.split(maxsplit=1)[:1]
|
72
|
+
|
69
73
|
fn = fn or (lambda x: x.removesuffix(")"))
|
70
74
|
|
71
75
|
# url_pattern = r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
|
@@ -97,9 +101,7 @@ def parse_url(text: str, for_image=False, fn: Optional[Callable] = None):
|
|
97
101
|
|
98
102
|
valid_urls = []
|
99
103
|
for url in urls:
|
100
|
-
url = url.strip(r"\n")
|
101
|
-
if fn:
|
102
|
-
url = fn(url) # lambda x: x.removesuffix(")")
|
104
|
+
url = fn(url.strip(r"\n"))
|
103
105
|
|
104
106
|
valid_urls.append(url)
|
105
107
|
|
@@ -171,7 +173,16 @@ if __name__ == '__main__':
|
|
171
173
|
|
172
174
|
# print(parse_url(text, True))
|
173
175
|
text = """
|
174
|
-
|
176
|
+
https://p26-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/f13171faeed2447b8b9c301ba912f25c.jpg~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1779880356&x-signature=AJop4%2FM8VjCUfjqiEzUugprc0CI%3D&x-wf-file_name=B0DCGKG71N.MAIN.jpg
|
177
|
+
|
178
|
+
还有这种url,两个.jpg的也能兼容么
|
175
179
|
"""
|
176
|
-
print(parse_url(text
|
180
|
+
print(parse_url(text))
|
181
|
+
|
177
182
|
|
183
|
+
# print(parse_url(text, for_image=False))
|
184
|
+
|
185
|
+
# text = """https://photog.art/api/oss/R2yh8N Convert this portrait into a straight-on,front-facing ID-style headshot."""
|
186
|
+
# print(parse_url(text))
|
187
|
+
#
|
188
|
+
# valid_urls = parse_url(text, for_image=True)
|
File without changes
|
File without changes
|
{MeUtils-2025.6.9.11.23.49.dist-info → MeUtils-2025.6.12.17.34.4.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|