MeUtils 2024.12.23.16.36.51__py3-none-any.whl → 2024.12.31.17.51.53__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 (44) hide show
  1. {MeUtils-2024.12.23.16.36.51.dist-info → MeUtils-2024.12.31.17.51.53.dist-info}/METADATA +26 -26
  2. {MeUtils-2024.12.23.16.36.51.dist-info → MeUtils-2024.12.31.17.51.53.dist-info}/RECORD +44 -38
  3. examples/_openaisdk/4v.py +5 -3
  4. examples/_openaisdk/openai_chatfire.py +9 -1
  5. examples/_openaisdk/openai_modelscope.py +6 -2
  6. examples/_openaisdk/openai_siliconflow.py +1 -1
  7. examples/_openaisdk/openai_tune.py +7 -4
  8. examples/_openaisdk/openai_zhipu.py +7 -5
  9. examples/_openaisdk/zhipu_/346/231/272/350/203/275/344/275/223.py +45 -0
  10. meutils/_utils.py +15 -1
  11. meutils/apis/chatglm/glm_video_api.py +34 -2
  12. meutils/apis/hailuoai/videos.py +1 -1
  13. meutils/apis/images/recraft.py +2 -3
  14. meutils/apis/jimeng/common.py +6 -3
  15. meutils/apis/jimeng/images.py +41 -6
  16. meutils/apis/kling/kolors_virtual_try_on.py +29 -5
  17. meutils/apis/oneapi/user.py +3 -3
  18. meutils/apis/oneapi/utils.py +32 -0
  19. meutils/async_utils/common.py +11 -1
  20. meutils/common.py +2 -0
  21. meutils/config_utils/lark_utils/common.py +2 -2
  22. meutils/data/VERSION +1 -1
  23. meutils/data/oneapi/NOTICE.md +15 -0
  24. meutils/db/orm.py +40 -5
  25. meutils/db/redis_db.py +8 -5
  26. meutils/decorators/polling.py +46 -0
  27. meutils/init/evn.py +1 -1
  28. meutils/llm/completions/modelscope.py +11 -0
  29. meutils/llm/completions/rag/fire.py +42 -12
  30. meutils/llm/openai_utils/common.py +1 -1
  31. meutils/request_utils/ark.py +47 -0
  32. meutils/{jwt_utils → request_utils/jwt_utils}/common.py +1 -0
  33. meutils/request_utils/volc.py +160 -0
  34. meutils/schemas/db/oneapi_types.py +30 -0
  35. meutils/schemas/image_types.py +2 -0
  36. meutils/schemas/oneapi/common.py +27 -10
  37. meutils/schemas/openai_types.py +17 -6
  38. meutils/schemas/video_types.py +34 -1
  39. meutils/serving/fastapi/dependencies/auth.py +34 -6
  40. {MeUtils-2024.12.23.16.36.51.dist-info → MeUtils-2024.12.31.17.51.53.dist-info}/LICENSE +0 -0
  41. {MeUtils-2024.12.23.16.36.51.dist-info → MeUtils-2024.12.31.17.51.53.dist-info}/WHEEL +0 -0
  42. {MeUtils-2024.12.23.16.36.51.dist-info → MeUtils-2024.12.31.17.51.53.dist-info}/entry_points.txt +0 -0
  43. {MeUtils-2024.12.23.16.36.51.dist-info → MeUtils-2024.12.31.17.51.53.dist-info}/top_level.txt +0 -0
  44. /meutils/{jwt_utils → request_utils/jwt_utils}/__init__.py +0 -0
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : volc
5
+ # @Time : 2024/12/31 13:20
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+
11
+
12
+ import hashlib
13
+ import hmac
14
+ import os
15
+ from urllib.parse import quote
16
+
17
+ from meutils.pipe import *
18
+
19
+ # 以下参数视服务不同而不同,一个服务内通常是一致的
20
+ Service = "iam"
21
+ Version = "2018-01-01"
22
+ Region = "cn-beijing"
23
+ Host = "iam.volcengineapi.com"
24
+ ContentType = "application/x-www-form-urlencoded"
25
+
26
+ # 请求的凭证,从IAM或者STS服务中获取
27
+ AK = os.getenv("ARK_ACCESS_KEY")
28
+ SK = os.getenv("ARK_SECRET_ACCESS_KEY")
29
+ # 当使用临时凭证时,需要使用到SessionToken传入Header,并计算进SignedHeader中,请自行在header参数中添加X-Security-Token头
30
+ # SessionToken = ""
31
+
32
+
33
+ def norm_query(params):
34
+ query = ""
35
+ for key in sorted(params.keys()):
36
+ if type(params[key]) == list:
37
+ for k in params[key]:
38
+ query = (
39
+ query + quote(key, safe="-_.~") + "=" + quote(k, safe="-_.~") + "&"
40
+ )
41
+ else:
42
+ query = (query + quote(key, safe="-_.~") + "=" + quote(params[key], safe="-_.~") + "&")
43
+ query = query[:-1]
44
+ return query.replace("+", "%20")
45
+
46
+
47
+ # 第一步:准备辅助函数。
48
+ # sha256 非对称加密
49
+ def hmac_sha256(key: bytes, content: str):
50
+ return hmac.new(key, content.encode("utf-8"), hashlib.sha256).digest()
51
+
52
+
53
+ # sha256 hash算法
54
+ def hash_sha256(content: str):
55
+ return hashlib.sha256(content.encode("utf-8")).hexdigest()
56
+
57
+
58
+ # 第二步:签名请求函数
59
+ def request(method, date, query, header, ak, sk, action, body):
60
+ # 第三步:创建身份证明。其中的 Service 和 Region 字段是固定的。ak 和 sk 分别代表
61
+ # AccessKeyID 和 SecretAccessKey。同时需要初始化签名结构体。一些签名计算时需要的属性也在这里处理。
62
+ # 初始化身份证明结构体
63
+ credential = {
64
+ "access_key_id": ak,
65
+ "secret_access_key": sk,
66
+ "service": Service,
67
+ "region": Region,
68
+ }
69
+ # 初始化签名结构体
70
+ request_param = {
71
+ "body": body,
72
+ "host": Host,
73
+ "path": "/",
74
+ "method": method,
75
+ "content_type": ContentType,
76
+ "date": date,
77
+ "query": {"Action": action, "Version": Version, **query},
78
+ }
79
+ if body is None:
80
+ request_param["body"] = ""
81
+ # 第四步:接下来开始计算签名。在计算签名前,先准备好用于接收签算结果的 signResult 变量,并设置一些参数。
82
+ # 初始化签名结果的结构体
83
+ x_date = request_param["date"].strftime("%Y%m%dT%H%M%SZ")
84
+ short_x_date = x_date[:8]
85
+ x_content_sha256 = hash_sha256(request_param["body"])
86
+ sign_result = {
87
+ "Host": request_param["host"],
88
+ "X-Content-Sha256": x_content_sha256,
89
+ "X-Date": x_date,
90
+ "Content-Type": request_param["content_type"],
91
+ }
92
+ # 第五步:计算 Signature 签名。
93
+ signed_headers_str = ";".join(
94
+ ["content-type", "host", "x-content-sha256", "x-date"]
95
+ )
96
+ # signed_headers_str = signed_headers_str + ";x-security-token"
97
+ canonical_request_str = "\n".join(
98
+ [request_param["method"].upper(),
99
+ request_param["path"],
100
+ norm_query(request_param["query"]),
101
+ "\n".join(
102
+ [
103
+ "content-type:" + request_param["content_type"],
104
+ "host:" + request_param["host"],
105
+ "x-content-sha256:" + x_content_sha256,
106
+ "x-date:" + x_date,
107
+ ]
108
+ ),
109
+ "",
110
+ signed_headers_str,
111
+ x_content_sha256,
112
+ ]
113
+ )
114
+
115
+ # 打印正规化的请求用于调试比对
116
+ print(canonical_request_str)
117
+ hashed_canonical_request = hash_sha256(canonical_request_str)
118
+
119
+ # 打印hash值用于调试比对
120
+ print(hashed_canonical_request)
121
+ credential_scope = "/".join([short_x_date, credential["region"], credential["service"], "request"])
122
+ string_to_sign = "\n".join(["HMAC-SHA256", x_date, credential_scope, hashed_canonical_request])
123
+
124
+ # 打印最终计算的签名字符串用于调试比对
125
+ print(string_to_sign)
126
+ k_date = hmac_sha256(credential["secret_access_key"].encode("utf-8"), short_x_date)
127
+ k_region = hmac_sha256(k_date, credential["region"])
128
+ k_service = hmac_sha256(k_region, credential["service"])
129
+ k_signing = hmac_sha256(k_service, "request")
130
+ signature = hmac_sha256(k_signing, string_to_sign).hex()
131
+
132
+ sign_result["Authorization"] = "HMAC-SHA256 Credential={}, SignedHeaders={}, Signature={}".format(
133
+ credential["access_key_id"] + "/" + credential_scope,
134
+ signed_headers_str,
135
+ signature,
136
+ )
137
+ header = {**header, **sign_result}
138
+ # header = {**header, **{"X-Security-Token": SessionToken}}
139
+ # 第六步:将 Signature 签名写入 HTTP Header 中,并发送 HTTP 请求。
140
+ r = requests.request(method=method,
141
+ url="https://{}{}".format(request_param["host"], request_param["path"]),
142
+ headers=header,
143
+ params=request_param["query"],
144
+ data=request_param["body"],
145
+ )
146
+ return r.json()
147
+
148
+
149
+ if __name__ == "__main__":
150
+ # response_body = request("Get", datetime.datetime.utcnow(), {}, {}, AK, SK, "ListUsers", None)
151
+ # print(response_body)
152
+
153
+ now = datetime.datetime.utcnow()
154
+
155
+ # Body的格式需要配合Content-Type,API使用的类型请阅读具体的官方文档,如:json格式需要json.dumps(obj)
156
+ # response_body = request("GET", now, {"Limit": "2"}, {}, AK, SK, "ListUsers", None)
157
+ # print(response_body)
158
+
159
+ response_body = request("POST", now, {"Limit": "10"}, {}, AK, SK, "ListUsers", "UnUseParam=ASDF")
160
+ print(response_body)
@@ -77,6 +77,36 @@ class OneapiTask(SQLModel, table=True):
77
77
  arbitrary_types_allowed = True
78
78
 
79
79
 
80
+ class OneapiUser(SQLModel, table=True):
81
+ __tablename__ = "users" # 自定义表名
82
+
83
+ id: Optional[int] = Field(default=None, primary_key=True)
84
+ username: Optional[str] = Field(default=None)
85
+ email: Optional[str] = Field(default=None)
86
+
87
+ quota: Optional[int] = Field(default=None)
88
+ used_quota: Optional[int] = Field(default=None)
89
+
90
+ request_count: Optional[int] = Field(default=None)
91
+
92
+ access_token: Optional[str] = Field(default=None)
93
+
94
+ class Config:
95
+ arbitrary_types_allowed = True
96
+
97
+
98
+ class OneapiToken(SQLModel, table=True):
99
+ __tablename__ = "tokens" # 自定义表名
100
+
101
+ id: Optional[int] = Field(default=None, primary_key=True)
102
+ user_id: Optional[int] = Field(default=None)
103
+ key: Optional[str] = Field(default=None)
104
+ used_quota: Optional[int] = Field(default=None)
105
+
106
+ class Config:
107
+ arbitrary_types_allowed = True
108
+
109
+
80
110
  if __name__ == '__main__':
81
111
  print(Hero())
82
112
  # print(Tasks())
@@ -82,6 +82,8 @@ class ImageRequest(BaseModel): # openai
82
82
  self.size = self.size if 'x' in self.size else '512x512'
83
83
 
84
84
  class Config:
85
+ extra = "allow"
86
+
85
87
  # frozen = True
86
88
  # populate_by_name = True
87
89
 
@@ -294,7 +294,7 @@ MODEL_RATIO = {
294
294
  "glm-4-0520": 2.5,
295
295
  "glm-4-airx": 10,
296
296
  "glm-4v": 2.5,
297
- "glm-4v-plus": 2.5, # 2.5
297
+ "glm-4v-plus": 5,
298
298
  "glm-4v-flash": 0.1,
299
299
  "glm-4-plus": 25,
300
300
 
@@ -321,6 +321,7 @@ MODEL_RATIO = {
321
321
  "qwen/qwq-32b-preview": 1,
322
322
  "Qwen/QwQ-32B-Preview": 1,
323
323
  "qwq-32b-preview": 1,
324
+ "qvq-72b-preview": 2,
324
325
 
325
326
  "qwen1.5-7b-chat": 0.05, # 特价
326
327
  "qwen1.5-14b-chat": 0.7,
@@ -372,16 +373,20 @@ MODEL_RATIO = {
372
373
 
373
374
  # deepseek
374
375
  "deepseek-chat": 0.5,
375
- "deepseek-coder": 0.5,
376
- 'deepseek-coder-v2-instruct': 0.5,
377
- 'deepseek-v2-chat': 0.5,
378
- 'deepseek-llm-67b-chat': 0.5,
379
376
  "deepseek-ai/deepseek-vl2": 0.5,
380
377
 
378
+ "deepseek-v3": 0.5,
379
+ 'deepseek-r1': 0.5,
380
+ 'deepseek-think': 0.5,
381
+ "deepseek-search": 0.5,
382
+
381
383
  # 豆包
382
384
  "doubao-lite-128k": 0.4,
383
385
  "doubao-lite-32k": 0.15,
384
386
  "doubao-lite-4k": 0.15,
387
+
388
+ "doubao-pro-256k": 5,
389
+
385
390
  "doubao-pro-128k": 2.5,
386
391
  "doubao-pro-32k": 0.4,
387
392
  "doubao-pro-4k": 0.4,
@@ -463,6 +468,8 @@ MODEL_RATIO = {
463
468
  "gemini-1.5-flash-exp-0827": 0.1,
464
469
  "google/gemini-flash-1.5-exp": 0.1, # openrouter免费
465
470
  "google/gemini-flash-1.5-8b-exp": 0.1, # openrouter免费
471
+ "gemini-2.0-flash": 0.5,
472
+ "gemini-2.0-flash-exp": 0.5,
466
473
 
467
474
  "gemini-1.5-pro-001": 1,
468
475
  "gemini-1.5-pro-002": 1,
@@ -625,13 +632,18 @@ COMPLETION_RATIO = {
625
632
  "gemini-1.5-pro-002": 4,
626
633
  "gemini-1.5-flash-002": 4,
627
634
 
635
+ "gemini-2.0-flash": 5,
636
+ "gemini-2.0-flash-exp": 5,
637
+
628
638
  "hunyuan-a52b-instruct": 5,
629
- "qwen2.5-coder-32b-instruct": 2,
639
+ "qwen2.5-coder-32b-instruct": 3,
630
640
 
631
641
  "qwen-turbo-2024-11-01": 3,
632
- "qwen/qwq-32b-preview": 2,
633
- "Qwen/QwQ-32B-Preview": 2,
634
- "qwq-32b-preview": 2,
642
+ "qwen/qwq-32b-preview": 3,
643
+ "Qwen/QwQ-32B-Preview": 3,
644
+ "qwq-32b-preview": 3,
645
+ "qvq-72b-preview": 3,
646
+
635
647
  "qwen-long": 5,
636
648
  "qwen-max": 5,
637
649
  "glm-4v-flash": 5,
@@ -640,6 +652,11 @@ COMPLETION_RATIO = {
640
652
  "doubao-vision-lite-32k": 3,
641
653
  "doubao-vision-pro-32k": 3,
642
654
 
655
+ "deepseek-v3": 1,
656
+ 'deepseek-r1': 1,
657
+ 'deepseek-think': 1,
658
+ "deepseek-search": 1,
659
+
643
660
  }
644
661
 
645
662
  REDIRECT_MODEL = {
@@ -705,7 +722,7 @@ REDIRECT_MODEL = {
705
722
  "qwen2.5-coder-7b-instruct": "Qwen/Qwen2.5-Coder-7B-Instruct",
706
723
  "qwen2.5-coder-32b-instruct": "Qwen/Qwen2.5-Coder-32B-Instruct",
707
724
 
708
- "qwen-turbo": "Qwen/Qwen2.5-7B-Instruct",
725
+ "qwen-turbo": "Qwen/Qwen2.5-7B-Instruct", # 兜底
709
726
  'qwen2-1.5b-instruct': 'Qwen/Qwen2-1.5B-Instruct',
710
727
  'qwen2-7b-instruct': 'Qwen/Qwen2-7B-Instruct',
711
728
  'qwen2-72b-instruct': 'Qwen/Qwen2-72B-Instruct',
@@ -312,7 +312,6 @@ class STTRequest(BaseModel): # ASR
312
312
  if __name__ == '__main__':
313
313
  pass
314
314
 
315
-
316
315
  # print(ChatCompletion(choices=[Choice(message=ChatCompletionMessage(content="ChatCompletion"))]))
317
316
  # print(ChatCompletionChunk(choices=[ChunkChoice(delta=ChoiceDelta(content="ChatCompletionChunk"))]))
318
317
  #
@@ -348,8 +347,20 @@ if __name__ == '__main__':
348
347
  # print(req1.model_dump()) # 输出: {'guidance_scale': 5.0}
349
348
  # print(req1.model_dump(by_alias=True)) # 输出: {'guidance': 5.0}
350
349
 
351
- class A(BaseModel):
352
- n: int = Field(1, ge=1, le=0)
353
-
354
-
355
- print(A(n=11))
350
+ # class A(BaseModel):
351
+ # n: int = Field(1, ge=1, le=0)
352
+ #
353
+ #
354
+ # print(A(n=11))
355
+ messages = [
356
+ {
357
+ "role": "user",
358
+ "content": [{'role': 'user', 'content': [{"type": "image_url", "image_url": "这是个图片链接"}]}]
359
+ },
360
+
361
+ # {'role': 'user', 'content': [{"type": "image_url", "image_url": {"url": "这是个图片链接"}}]},
362
+ ]
363
+
364
+ r = ChatCompletionRequest(model="gpt-3.5-turbo", messages=messages)
365
+ r.messages[-1]['content'] = [{"type": "image_url", "image_url": {"url": r.urls[-1]}}]
366
+ print(r)
@@ -12,9 +12,42 @@ from meutils.pipe import *
12
12
 
13
13
 
14
14
  class VideoRequest(BaseModel):
15
- model: str = "cogvideox"
15
+ model: Literal["cogvideox-flash", "cogvideox"] = "cogvideox-flash"
16
+
16
17
  prompt: str = "比得兔开小汽车,游走在马路上,脸上的表情充满开心喜悦。"
18
+
19
+ """
20
+ 提供基于其生成内容的图像。如果传入此参数,系统将以该图像为基础进行操作。支持通过URL或Base64编码传入图片。
21
+ 图片要求如下:图片支持.png、jpeg、.jpg 格式、图片大小:不超过5M。image_url和prompt二选一或者同时传入。
22
+ """
17
23
  image_url: Optional[str] = None
18
24
 
25
+ """
26
+ 输出模式,默认为 "quality"。 "quality":质量优先,生成质量高。 "speed":速度优先,生成时间更快,质量相对降低。
27
+ cogvideox-flash模型不支持选择输出模式。
28
+ """
29
+ quality: Literal["quality", "speed"] = "speed"
30
+
31
+ """是否生成 AI 音效。默认值: False(不生成音效)。"""
32
+ with_audio: bool = True
33
+
34
+ """
35
+ 默认值: 若不指定,默认生成视频的短边为 1080,长边根据原图片比例缩放。最高支持 4K 分辨率。
36
+ 分辨率选项:720x480、1024x1024、1280x960、960x1280、1920x1080、1080x1920、2048x1080、3840x2160
37
+ """
38
+ size: Literal[
39
+ '720x480',
40
+ '1024x1024',
41
+ '1280x960',
42
+ '960x1280',
43
+ '1920x1080',
44
+ '1080x1920',
45
+ '2048x1080',
46
+ '3840x2160'] = "1024x1024"
47
+
48
+ duration: Literal[5, 10] = 5
49
+
50
+ fps: Literal[30, 60] = 30
51
+
19
52
  class Config:
20
53
  frozen = True
@@ -8,6 +8,7 @@
8
8
  # @Software : PyCharm
9
9
  # @Description :
10
10
 
11
+ import numpy as np
11
12
  from typing import Optional, Union
12
13
 
13
14
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
@@ -16,10 +17,8 @@ from fastapi import Depends, HTTPException, status
16
17
  http_bearer = HTTPBearer()
17
18
 
18
19
 
19
- # get_bearer_token = http_bearer
20
-
21
-
22
20
  # 定义获取token的函数
21
+
23
22
  async def get_bearer_token(
24
23
  auth: Optional[HTTPAuthorizationCredentials] = Depends(http_bearer)
25
24
  ) -> Optional[str]:
@@ -31,10 +30,39 @@ async def get_bearer_token(
31
30
  if auth is None:
32
31
  return None
33
32
 
34
- return auth.credentials
33
+ token = auth.credentials
34
+ if token.startswith('redis:'): # 初始化吧,太长?
35
+ pass
36
+ if ',' in token: # 初始化redis
37
+ pass
38
+ elif ',' in token: # 分隔符
39
+ token = np.random.choice(token.split(','))
40
+
41
+ return token
42
+
43
+
44
+ # async def get_next_token(redis_key):
45
+ # """轮询"""
46
+ # if api_key := await redis_aclient.lpop(redis_key):
47
+ # await redis_aclient.rpush(redis_key, api_key)
48
+ # return api_key
49
+
50
+
51
+ async def get_bearer_token_for_oneapi(
52
+ auth: Optional[HTTPAuthorizationCredentials] = Depends(http_bearer)
53
+ ) -> Optional[str]:
54
+ """
55
+ # todo: oneapi userinfo apikey info
56
+ """
57
+ if auth is None:
58
+ return None
59
+
60
+ token = auth.credentials
35
61
 
62
+ return token
36
63
 
37
- # todo: oneapi userinfo apikey info
38
64
 
39
65
  if __name__ == '__main__':
40
- pass
66
+ from meutils.pipe import *
67
+
68
+ arun(get_bearer_token(HTTPAuthorizationCredentials(scheme="Bearer", credentials="123")))