MeUtils 2025.2.18.19.56.22__py3-none-any.whl → 2025.2.20.17.30.7__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.
@@ -7,9 +7,14 @@
7
7
  # @WeChat : meutils
8
8
  # @Software : PyCharm
9
9
  # @Description :
10
+ """
11
+ guidance 控制精细度 => sample_strength 0-1 数值越大生成的效果质量越好,耗时会更久
12
+
13
+ """
10
14
 
11
15
  from meutils.pipe import *
12
16
  from meutils.caches.redis_cache import cache
17
+ from meutils.decorators.retry import retrying
13
18
 
14
19
  from meutils.schemas.jimeng_types import BASE_URL, MODELS_MAP, FEISHU_URL
15
20
  from meutils.schemas.image_types import ImageRequest
@@ -137,7 +142,7 @@ async def create_draft_content(request: ImageRequest, token: str):
137
142
  "prompt": request.prompt,
138
143
  "negative_prompt": request.negative_prompt or "",
139
144
  "seed": request.seed or 426999300,
140
- "sample_strength": 0.5,
145
+ "sample_strength": request.guidance or 0.5, # 精细度
141
146
  "image_ratio": 1,
142
147
  "large_image_info": {
143
148
  "type": "",
@@ -170,6 +175,7 @@ async def create_draft_content(request: ImageRequest, token: str):
170
175
  return draft_content
171
176
 
172
177
 
178
+ @retrying(max_retries=3)
173
179
  async def create_task(request: ImageRequest, token: Optional[str] = None):
174
180
  token = token or await get_next_token_for_polling(FEISHU_URL, check_token)
175
181
 
@@ -221,6 +227,7 @@ async def create_task(request: ImageRequest, token: Optional[str] = None):
221
227
  )
222
228
 
223
229
 
230
+ @retrying()
224
231
  async def get_task(task_id, token):
225
232
  url = "/mweb/v1/get_history_by_ids"
226
233
  headers = get_headers(url, token)
@@ -270,11 +277,14 @@ async def get_task(task_id, token):
270
277
  # @cache: todo: cache 积分异常消耗
271
278
  # @cache(ttl=3600)
272
279
  async def generate(request: ImageRequest):
280
+ # logger.debug(request)
281
+
273
282
  task_response = await create_task(request)
274
283
 
275
- for i in range(1, 10):
276
- await asyncio.sleep(max(10 / i, 1))
284
+ for i in range(1, 15):
285
+ await asyncio.sleep(max(15 / i, 5))
277
286
  response = await get_task(task_response.task_id, task_response.system_fingerprint)
287
+ logger.debug(f"{task_response.task_id, task_response.system_fingerprint}")
278
288
  logger.debug(response)
279
289
  if response.status.lower().startswith("fail"):
280
290
  raise HTTPException(
@@ -320,11 +330,11 @@ if __name__ == '__main__':
320
330
  data = {
321
331
  "model": "seededit",
322
332
  "prompt": "https://oss.ffire.cc/files/kling_watermark.png 让这个女人带上墨镜,衣服换个颜色",
323
- "size": "1024x1024"
333
+ "size": "1024x1024",
324
334
  }
325
- # arun(generate(ImageRequest(**data)))
335
+ arun(generate(ImageRequest(**data)))
326
336
 
327
- arun(generate(ImageRequest(prompt="做一个圣诞节的海报")))
337
+ # arun(generate(ImageRequest(prompt="做一个圣诞节的海报")))
328
338
  # 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"
329
339
  # request = ImageRequest(prompt=prompt)
330
340
  # task = arun(create_task(request))
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : zhipu
5
+ # @Time : 2025/2/19 20:42
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+
11
+ from meutils.pipe import *
12
+ from meutils.str_utils.json_utils import json_path
13
+ from meutils.llm.clients import AsyncOpenAI, chatfire_client, zhipuai_client, moonshot_client
14
+ from meutils.llm.openai_utils import to_openai_params
15
+ from meutils.schemas.openai_types import chat_completion, chat_completion_chunk, ChatCompletionRequest, CompletionUsage
16
+
17
+
18
+ class Completions(object):
19
+
20
+ def __init__(self, api_key: Optional[str] = None):
21
+ self.api_key = api_key
22
+
23
+ async def create(self, request: ChatCompletionRequest, search_result2md: bool = False):
24
+ request.stream = False
25
+ request.model = "web-search-pro"
26
+ request.messages = [{
27
+ "role": "user",
28
+ "content": request.last_content,
29
+ }]
30
+ data = to_openai_params(request)
31
+
32
+ search_completion = await zhipuai_client.chat.completions.create(**data)
33
+ logger.debug(search_completion.model_dump_json(indent=4))
34
+
35
+ if results := json_path(search_completion, '$..[keywords,query,search_result]'):
36
+ data = dict(zip(["keywords", "query", "search_result"], results))
37
+ if search_result2md:
38
+ global df
39
+
40
+ df = pd.DataFrame(data["search_result"])
41
+
42
+ df['title'] = [f"[{k}]({v})" for k, v in zip(df['title'], df['link'])]
43
+ df['media'] = [f"![{k}]({v})" for k, v in zip(df['media'], df['icon'])]
44
+
45
+ df = df[['title', 'media']]
46
+ df.index += 1
47
+ # {df_.to_markdown(index=False).replace('|:-', '|-').replace('-:|', '-|')}
48
+ data["search_result"] = df.to_markdown()
49
+ return data
50
+
51
+ async def query(self, q: str):
52
+ pass
53
+
54
+ # {
55
+ # "role": "user",
56
+ # "content": search_completion.model_dump_json(indent=4),
57
+ # }
58
+
59
+
60
+ if __name__ == '__main__':
61
+ model = "web-search-pro"
62
+ # model = "tencent-search"
63
+
64
+ request = ChatCompletionRequest(
65
+ # model="baichuan4-turbo",
66
+ # model="xx",
67
+ # model="deepseek-r1",
68
+ # model="deepseek-r1:1.5b",
69
+ model=model,
70
+
71
+ # model="moonshot-v1-8k",
72
+ # model="doubao",
73
+
74
+ messages=[
75
+ {"role": "user", "content": "《哪吒之魔童闹海》现在的票房是多少"}
76
+ ],
77
+
78
+ stream=True
79
+ )
80
+ arun(Completions().create(request, search_result2md=True))
@@ -208,7 +208,8 @@ if __name__ == '__main__':
208
208
  d = {
209
209
  "model": 'vidu-2.0',
210
210
  "prompt": "这个女人笑起来",
211
- "url": "https://oss.ffire.cc/files/kling_watermark.png" # failed to save uploads
211
+ "url": "https://oss.ffire.cc/files/kling_watermark.png", # failed to save uploads
212
+ "tail_image_url": "https://oss.ffire.cc/files/kling_watermark.png",
212
213
  }
213
214
  token = None
214
215
  # print(bjson(ViduRequest(**d).payload))
meutils/caches/acache.py CHANGED
@@ -27,7 +27,7 @@ async def cached_fc(user_id, **kwargs):
27
27
  rcache = RedisCache(
28
28
  endpoint="127.0.0.1", port=6379, namespace="me" # 缓存键前缀
29
29
  )
30
- @cached(ttl=60, cache=rcache)
30
+ @cached(cache=rcache)
31
31
  async def redis_fc(user_id, **kwargs):
32
32
  logger.debug(user_id)
33
33
  return False
meutils/data/VERSION CHANGED
@@ -1 +1 @@
1
- 2025.02.18.19.56.22
1
+ 2025.02.20.17.30.07
@@ -11,6 +11,7 @@
11
11
  from meutils.pipe import *
12
12
 
13
13
  from contextlib import contextmanager, asynccontextmanager
14
+ from concurrent.futures import ThreadPoolExecutor, as_completed, TimeoutError
14
15
 
15
16
 
16
17
  @contextmanager
@@ -56,10 +57,52 @@ async def atry_catcher(task="Task", fallback: Callable = None, is_trace: bool =
56
57
  yield await fallback()
57
58
 
58
59
 
60
+ @contextmanager
61
+ def timeout_task_executor(timeout: float=3, max_workers: int = None):
62
+ """
63
+ 一个上下文管理器,用于执行任务并设置超时时间。
64
+ :param timeout: 超时时间(秒)。
65
+ :param max_workers: 线程池的最大工作线程数,默认为 None(由系统决定)。
66
+ """
67
+ executor = ThreadPoolExecutor(max_workers=max_workers)
68
+
69
+ def execute_task(task: Callable[[], Any]) -> Any:
70
+ """
71
+ 在上下文中执行任务,并设置超时时间。
72
+ :param task: 要执行的任务函数。
73
+ :return: 任务的结果。如果超时,抛出 TimeoutError。
74
+ """
75
+ future = executor.submit(task)
76
+ try:
77
+ return future.result(timeout=timeout)
78
+ except TimeoutError:
79
+ logger.error(f"Task was terminated due to timeout after {timeout} seconds.")
80
+ return None
81
+
82
+ try:
83
+ yield execute_task # 返回一个可调用对象,用于执行任务
84
+ finally:
85
+ executor.shutdown(wait=False) # 不等待未完成的任务,直接关闭
86
+
87
+
59
88
  if __name__ == '__main__':
60
- async def f():
61
- return 1/0
89
+ # async def f():
90
+ # return 1/0
91
+ #
92
+ #
93
+ # with try_catcher("test"):
94
+ # arun(f())
95
+
96
+ def example_task():
97
+ print("Starting task...")
98
+ time.sleep(4) # 模拟耗时任务
99
+ print("Task completed!")
100
+ return "Done"
62
101
 
63
102
 
64
- with try_catcher("test"):
65
- arun(f())
103
+ with timeout_task_executor(timeout=3) as execute:
104
+ try:
105
+ result = execute(example_task)
106
+ print(f"Task result: {result}")
107
+ except TimeoutError:
108
+ print("Task did not complete in time.")
@@ -97,7 +97,7 @@ if __name__ == '__main__':
97
97
  check_valid_token = partial(check_token_for_siliconflow, threshold=-1)
98
98
 
99
99
  pass
100
- arun(check_valid_token("sk-sjfqlwkuqkkrrgfguxckuagmuhzmvxuxocgvxjgygxwsqawr", threshold=0.1))
100
+ arun(check_valid_token("sk-geevdizajhngehlkrjlgwcugcunrircpezhqijrscmtiafxj", threshold=0.1))
101
101
 
102
102
  FEISHU_URL = "https://xchatllm.feishu.cn/sheets/Bmjtst2f6hfMqFttbhLcdfRJnNf?sheet=KVClcs"
103
103
 
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : search_prompt
5
+ # @Time : 2025/2/19 10:37
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description : 提示词模板
10
+
11
+ from meutils.pipe import *
12
+
13
+ current_date = datetime.datetime.now().strftime("%Y-%m-%d")
14
+
15
+ system_prompt = f"""你是一个具备网络访问能力的智能助手,在适当情况下,优先使用网络信息(参考信息)来回答,
16
+ 以确保用户得到最新、准确的帮助。当前日期是 {current_date}。"""
17
+
18
+ # deepseek_prompt
@@ -83,7 +83,7 @@ class ImageRequest(BaseModel): # openai
83
83
 
84
84
  # oneapi
85
85
  negative_prompt: Optional[str] = None
86
- guidance: Optional[int] = None
86
+ guidance: Optional[float] = None
87
87
  steps: Optional[int] = None
88
88
 
89
89
  controls: Optional[dict] = {} # 额外参数
@@ -479,6 +479,9 @@ class ImageProcess(BaseModel):
479
479
 
480
480
  response_format: Literal["url", "b64_json"] = "url"
481
481
 
482
+ # class Config:
483
+ # extra = "allow"
484
+
482
485
 
483
486
  if __name__ == '__main__':
484
487
  # print(ASPECT_RATIOS.items())
@@ -412,7 +412,7 @@ MODEL_RATIO = {
412
412
  "qwen2.5-coder-7b-instruct": 0.05,
413
413
  "qwen2.5-7b-instruct": 0.05,
414
414
  "qwen2.5-14b-instruct": 0.25,
415
- "qwen2.5-32b-instruct": 0.5,
415
+ "qwen2.5-32b-instruct": 1,
416
416
  "qwen2.5-72b-instruct": 2,
417
417
  "qwen2.5-math-72b-instruct": 2,
418
418
  "qwen2.5-coder-32b-instruct": 0.5,
@@ -568,7 +568,7 @@ MODEL_RATIO = {
568
568
  "ERNIE-3.5-128K": 4,
569
569
 
570
570
  "ERNIE-4.0-Turbo-8K": 15,
571
- "ERNIE-4.0-8K": 20,
571
+ "ERNIE-4.0-8K": 10,
572
572
 
573
573
  "text-ada-001": 0.2,
574
574
  "text-babbage-001": 0.25,
@@ -622,9 +622,9 @@ MODEL_RATIO = {
622
622
  "google/gemini-flash-1.5-exp": 0.1, # openrouter免费
623
623
  "google/gemini-flash-1.5-8b-exp": 0.1, # openrouter免费
624
624
 
625
- "gemini-2.0-flash": 0.075,
626
- "gemini-2.0-flash-001": 0.075,
627
- "gemini-2.0-flash-lite-preview-02-05": 0.075,
625
+ "gemini-2.0-flash": 0.0625,
626
+ "gemini-2.0-flash-001": 0.0625,
627
+ "gemini-2.0-flash-lite-preview-02-05": 0.0625,
628
628
 
629
629
  "gemini-2.0-pro": 1.25,
630
630
  "gemini-2.0-pro-exp-02-05": 1.25,
@@ -735,6 +735,8 @@ MODEL_RATIO = {
735
735
  "ep-20240515073409-dlpqp": 5,
736
736
  "microsoft/phi-4": 0.035 * 5,
737
737
 
738
+ "meta-llama/Llama-3.2-11B-Vision-Instruct": 0.1,
739
+
738
740
  }
739
741
 
740
742
  COMPLETION_RATIO = {
@@ -915,6 +917,8 @@ COMPLETION_RATIO = {
915
917
  "step-1.5v-mini": 5,
916
918
  "step-1o-vision-32k": 5,
917
919
 
920
+ "meta-llama/Llama-3.2-11B-Vision-Instruct": 4
921
+
918
922
  }
919
923
 
920
924
  REDIRECT_MODEL = {
@@ -92,10 +92,13 @@ class VideoRequest(BaseModel):
92
92
 
93
93
  class ViduRequest(BaseModel):
94
94
  """quality 倍率2"""
95
- model: Union[str, Literal['vidu-1.5', 'vidu-high-performance', 'vidu-high-quality']] = "vidu-high-performance"
95
+ model: Union[str, Literal['vidu-2.0', 'vidu-1.5', 'vidu-high-performance', 'vidu-high-quality']] = "vidu-high-performance"
96
96
 
97
97
  prompt: Optional[str] = None
98
+
98
99
  url: Optional[str] = None # ssupload:?id=
100
+ tail_image_url: Optional[str] = None
101
+
99
102
  style: str = "general" # anime
100
103
  aspect_ratio: str = "16:9"
101
104
  duration: int = 4
@@ -103,7 +106,7 @@ class ViduRequest(BaseModel):
103
106
  type: Optional[str] = None # text2video img2video character2video headtailimg2video
104
107
 
105
108
  """vidu-1.5"""
106
- resolution: Literal['512', '720p', 'vidu-high-quality'] = "512"
109
+ resolution: Union[str, Literal['512', '720p', '1080p']] = "512"
107
110
  movement_amplitude: Optional[str] = "auto" # small medium high
108
111
 
109
112
  sample_count: int = 1
@@ -143,6 +146,17 @@ class ViduRequest(BaseModel):
143
146
  }
144
147
  )
145
148
 
149
+ if self.tail_image_url:
150
+ type = "headtailimg2video"
151
+ input['prompts'].append(
152
+ {
153
+ "type": "image",
154
+ "content": self.tail_image_url,
155
+ "src_imgs": [self.tail_image_url, ]
156
+ }
157
+ )
158
+
159
+
146
160
  if self.model in ("vidu-1.5", "vidu-2.0"):
147
161
  self.payload = {
148
162
  "input": input,
@@ -52,6 +52,7 @@ def json_loads(s):
52
52
 
53
53
 
54
54
  def json_path(obj, expr): # todo: 缓存
55
+ """$..["keywords","query","search_result"]"""
55
56
  if isinstance(obj, dict):
56
57
  pass
57
58
  elif isinstance(obj, str):
@@ -145,9 +145,14 @@ if __name__ == '__main__':
145
145
  print(parse_url(text, for_image=False))
146
146
 
147
147
  d = {"url": "https://mj101-1317487292.cos.ap-shanghai.myqcloud.com/ai/test.pdf\n\n总结下"}
148
- print(parse_url(str(d)))
148
+ # print(parse_url(str(d)))
149
149
 
150
- print('https://mj101-1317487292.cos.ap-shanghai.myqcloud.com/ai/test.pdf\\n\\n'.strip(r"\n"))
150
+
151
+ text = "https://sc-maas.oss-cn-shanghai.aliyuncs.com/outputs/bb305b60-d258-4542-8b07-5ced549e9896_0.png?OSSAccessKeyId=LTAI5tQnPSzwAnR8NmMzoQq4&Expires=1739948468&Signature=NAswPSXj4AGghDuoNX5rVFIidcs%3D 笑起来"
152
+
153
+ print(parse_url(text))
154
+
155
+ # print('https://mj101-1317487292.cos.ap-shanghai.myqcloud.com/ai/test.pdf\\n\\n'.strip(r"\n"))
151
156
 
152
157
  # print(parse_url("http://154.3.0.117:39666/docs#/default/get_content_preview_spider_playwright_get"))
153
158