MeUtils 2025.3.31.19.40.39__py3-none-any.whl → 2025.4.8.18.11.44__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.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/METADATA +264 -264
- {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/RECORD +41 -27
- examples/_openaisdk/openai_ark_bots.py +64 -0
- examples/_openaisdk/openai_audio_gpt.py +67 -0
- examples/_openaisdk/openai_google.py +129 -77
- examples/_openaisdk/openai_kindo.py +1 -1
- examples/_openaisdk/zhipu_/346/231/272/350/203/275/344/275/223.py +5 -2
- meutils/ai_audio/tts/minimax.py +34 -0
- meutils/apis/google_apis/__init__.py +11 -0
- meutils/apis/google_apis/audios.py +115 -0
- meutils/apis/google_apis/common.py +251 -0
- meutils/apis/google_apis/files.py +19 -0
- meutils/apis/google_apis/gemini_sdk.py +170 -0
- meutils/apis/google_apis/google2openai.py +89 -0
- meutils/apis/google_apis/images.py +11 -0
- meutils/apis/google_apis/search.py +46 -0
- meutils/apis/hailuoai/videos.py +1 -1
- meutils/apis/images/google/__init__.py +11 -0
- meutils/apis/images/google/images.py +32 -0
- meutils/apis/jimeng/images.py +2 -1
- meutils/apis/search/ark_web_search.py +69 -0
- meutils/apis/search/{web_search.py → zhipu_web_search.py} +21 -30
- meutils/apis/textin_apis/common.py +1 -1
- meutils/apis/tripo3d/images.py +1 -1
- meutils/caches/common.py +4 -2
- meutils/data/VERSION +1 -1
- meutils/io/files_utils.py +27 -22
- meutils/llm/clients.py +6 -5
- meutils/llm/completions/assistants/ppt.py +17 -13
- meutils/llm/completions/chat_gemini.py +1 -1
- meutils/llm/completions/qwenllm.py +8 -2
- meutils/llm/openai_utils/common.py +5 -0
- meutils/oss/minio_oss.py +38 -8
- meutils/oss/minio_utils.py +2 -2
- meutils/schemas/oneapi/common.py +23 -6
- meutils/schemas/openai_types.py +70 -40
- meutils/str_utils/regular_expression.py +6 -3
- {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/LICENSE +0 -0
- {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/WHEEL +0 -0
- {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/entry_points.txt +0 -0
- {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Project : AI. @by PyCharm
|
4
|
+
# @File : search
|
5
|
+
# @Time : 2025/4/2 11:19
|
6
|
+
# @Author : betterme
|
7
|
+
# @WeChat : meutils
|
8
|
+
# @Software : PyCharm
|
9
|
+
# @Description :
|
10
|
+
|
11
|
+
from meutils.pipe import *
|
12
|
+
from google import genai
|
13
|
+
from google.genai.types import Tool, GenerateContentConfig, GoogleSearch,HttpOptions
|
14
|
+
|
15
|
+
client = genai.Client(
|
16
|
+
api_key="AIzaSyD19pv1qsYjx4ZKbfH6qvNdYzHMV2TxmPU",
|
17
|
+
http_options=HttpOptions(
|
18
|
+
base_url="https://all.chatfire.cc/genai"
|
19
|
+
)
|
20
|
+
)
|
21
|
+
|
22
|
+
|
23
|
+
google_search_tool = Tool(
|
24
|
+
google_search=GoogleSearch()
|
25
|
+
)
|
26
|
+
|
27
|
+
|
28
|
+
model_id = "gemini-2.0-flash"
|
29
|
+
|
30
|
+
response = client.models.generate_content(
|
31
|
+
model=model_id,
|
32
|
+
contents="写一首关于牡丹的诗歌",
|
33
|
+
config=GenerateContentConfig(
|
34
|
+
tools=[google_search_tool],
|
35
|
+
# response_modalities=["TEXT"],
|
36
|
+
)
|
37
|
+
)
|
38
|
+
|
39
|
+
for each in response.candidates[0].content.parts:
|
40
|
+
print(each.text)
|
41
|
+
# Example response:
|
42
|
+
# The next total solar eclipse visible in the contiguous United States will be on ...
|
43
|
+
|
44
|
+
# To get grounding metadata as web content.
|
45
|
+
print(response.candidates[0].grounding_metadata.search_entry_point.rendered_content)
|
46
|
+
print(response.candidates[0].grounding_metadata.grounding_chunks)
|
meutils/apis/hailuoai/videos.py
CHANGED
@@ -420,7 +420,7 @@ if __name__ == '__main__': # 304752356930580482
|
|
420
420
|
# arun(get_task(task_id="307177115102699528", token=token))
|
421
421
|
|
422
422
|
token = None
|
423
|
-
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDQ3MDMwNzIsInVzZXIiOnsiaWQiOiIzMDI4MzM4Njc3NzE5NDkwNTgiLCJuYW1lIjoibWUgYmV0dGVyIiwiYXZhdGFyIjoiIiwiZGV2aWNlSUQiOiIzMDI4MzM3NTk1MTI3NjQ0MTciLCJpc0Fub255bW91cyI6ZmFsc2V9fQ.Mjb64ZjkKyV9pj-_bXyLczU6kU729VLaKbYj9NmrK-4"
|
423
|
+
# token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDQ3MDMwNzIsInVzZXIiOnsiaWQiOiIzMDI4MzM4Njc3NzE5NDkwNTgiLCJuYW1lIjoibWUgYmV0dGVyIiwiYXZhdGFyIjoiIiwiZGV2aWNlSUQiOiIzMDI4MzM3NTk1MTI3NjQ0MTciLCJpc0Fub255bW91cyI6ZmFsc2V9fQ.Mjb64ZjkKyV9pj-_bXyLczU6kU729VLaKbYj9NmrK-4"
|
424
424
|
# token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzUxMTcwNzcsInVzZXIiOnsiaWQiOiIzMTEyOTUzMTkzMjc1NzYwNjQiLCJuYW1lIjoiVUdIUiBKVkJYIiwiYXZhdGFyIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUNnOG9jS3RuR2NjdGZsWV9fR2tiQ1MzdnhzSXdWSEFUX0ZmMFdyb3RvMnN4bFdWZW1KMm53PXM5Ni1jIiwiZGV2aWNlSUQiOiIzMTMzMTU5NTMxMDA0MTA4ODciLCJpc0Fub255bW91cyI6ZmFsc2V9fQ.KsRcfnAoPAR08ygzq-GIiujkFbZ2CgLeww7EP9qcb9Q"
|
425
425
|
request = VideoRequest(
|
426
426
|
model="I2V-01-live",
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Project : AI. @by PyCharm
|
4
|
+
# @File : images
|
5
|
+
# @Time : 2025/4/1 14:11
|
6
|
+
# @Author : betterme
|
7
|
+
# @WeChat : meutils
|
8
|
+
# @Software : PyCharm
|
9
|
+
# @Description :
|
10
|
+
import os
|
11
|
+
|
12
|
+
from meutils.pipe import *
|
13
|
+
import base64
|
14
|
+
from openai import OpenAI
|
15
|
+
from PIL import Image
|
16
|
+
from io import BytesIO
|
17
|
+
|
18
|
+
client = OpenAI(
|
19
|
+
api_key=os.getenv("GOOGLE_API_KEY"),
|
20
|
+
base_url=os.getenv("GOOGLE_BASE_URL"),
|
21
|
+
)
|
22
|
+
|
23
|
+
response = client.images.generate(
|
24
|
+
model="imagen-3.0-generate-002",
|
25
|
+
prompt="a portrait of a sheepadoodle wearing a cape",
|
26
|
+
response_format='b64_json',
|
27
|
+
n=1,
|
28
|
+
)
|
29
|
+
#
|
30
|
+
# for image_data in response.data:
|
31
|
+
# image = Image.open(BytesIO(base64.b64decode(image_data.b64_json)))
|
32
|
+
# image.show()
|
meutils/apis/jimeng/images.py
CHANGED
@@ -50,7 +50,8 @@ async def create_draft_content(request: ImageRequest, token: str):
|
|
50
50
|
|
51
51
|
main_component_id = str(uuid.uuid4())
|
52
52
|
if (urls := parse_url(request.prompt)) or image_uri: # 图生 # todo: image base64
|
53
|
-
request.model = "high_aes_general_v20_L:general_v2.0_L"
|
53
|
+
# request.model = "high_aes_general_v20_L:general_v2.0_L"
|
54
|
+
request.model = "high_aes_general_v30l:general_v3.0_18b" # 2.1不支持图片编辑 某些不支持
|
54
55
|
|
55
56
|
if image_uri:
|
56
57
|
pass
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Project : AI. @by PyCharm
|
4
|
+
# @File : ark
|
5
|
+
# @Time : 2025/4/1 16:56
|
6
|
+
# @Author : betterme
|
7
|
+
# @WeChat : meutils
|
8
|
+
# @Software : PyCharm
|
9
|
+
# @Description :
|
10
|
+
|
11
|
+
from meutils.pipe import *
|
12
|
+
from meutils.caches import rcache
|
13
|
+
|
14
|
+
from meutils.llm.clients import AsyncClient
|
15
|
+
from meutils.llm.openai_utils import to_openai_params
|
16
|
+
|
17
|
+
from meutils.schemas.openai_types import chat_completion, chat_completion_chunk, CompletionRequest, ChatCompletionChunk
|
18
|
+
|
19
|
+
|
20
|
+
class Completions(object):
|
21
|
+
|
22
|
+
def __init__(self, api_key: Optional[str] = None):
|
23
|
+
self.client = AsyncClient(
|
24
|
+
api_key=api_key or os.getenv('ARK_BOTS_API_KEY'),
|
25
|
+
base_url="https://ark.cn-beijing.volces.com/api/v3/bots",
|
26
|
+
)
|
27
|
+
|
28
|
+
async def create(self, request: CompletionRequest):
|
29
|
+
data = to_openai_params(request)
|
30
|
+
return await self.client.chat.completions.create(**data)
|
31
|
+
|
32
|
+
@rcache(noself=True, ttl=15 * 60)
|
33
|
+
async def query(self, q: str):
|
34
|
+
request = CompletionRequest(
|
35
|
+
model="bot-20250401164325-s7945", # todo
|
36
|
+
|
37
|
+
messages=[
|
38
|
+
{"role": "user", "content": q},
|
39
|
+
],
|
40
|
+
temperature=0,
|
41
|
+
max_tokens=10,
|
42
|
+
stream=False,
|
43
|
+
)
|
44
|
+
completion = await self.create(request)
|
45
|
+
logger.debug(completion)
|
46
|
+
# print(completion.choices[0].message.content)
|
47
|
+
|
48
|
+
data = {"data": []}
|
49
|
+
if hasattr(completion, "references"):
|
50
|
+
data['data'] = completion.references
|
51
|
+
|
52
|
+
return data
|
53
|
+
|
54
|
+
|
55
|
+
if __name__ == '__main__':
|
56
|
+
c = Completions(api_key=os.getenv('ARK_BOTS_API_KEY'))
|
57
|
+
# s = c.create(CompletionRequest(
|
58
|
+
# model="bot-20250401164325-s7945",
|
59
|
+
# messages=[
|
60
|
+
# {"role": "user", "content": "今天南京天气如何?"},
|
61
|
+
# ],
|
62
|
+
# stream=True,
|
63
|
+
# ))
|
64
|
+
q = "今天有什么热点新闻?"
|
65
|
+
q = "今日热点"
|
66
|
+
|
67
|
+
# arun(c.query("今天南京天气如何?"))
|
68
|
+
|
69
|
+
arun(c.query(q=q))
|
@@ -6,10 +6,11 @@
|
|
6
6
|
# @Author : betterme
|
7
7
|
# @WeChat : meutils
|
8
8
|
# @Software : PyCharm
|
9
|
-
# @Description :
|
9
|
+
# @Description :
|
10
10
|
|
11
|
-
from aiostream import stream
|
12
11
|
from meutils.pipe import *
|
12
|
+
from meutils.caches import rcache
|
13
|
+
|
13
14
|
from meutils.async_utils import sync_to_async
|
14
15
|
|
15
16
|
from meutils.llm.clients import zhipuai_sdk_client
|
@@ -39,17 +40,17 @@ class Completions(object):
|
|
39
40
|
def __init__(self, api_key: Optional[str] = None):
|
40
41
|
self.api_key = api_key
|
41
42
|
|
42
|
-
@
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
# @rcache(noself=True, ttl=15 * 60)
|
44
|
+
@sync_to_async
|
45
|
+
def query(self, q: str):
|
46
|
+
data = list(self.create(q))
|
47
|
+
return {"data": data}
|
48
|
+
|
49
|
+
def create(self, request: Union[CompletionRequest, str]):
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
+
q = request.last_user_content if isinstance(request, CompletionRequest) else request
|
52
|
+
q = f"{q} 【最新动态、相关信息或新闻】"
|
51
53
|
|
52
|
-
def _create(self, request: Union[CompletionRequest, str]):
|
53
54
|
chunks = zhipuai_sdk_client.assistant.conversation(
|
54
55
|
|
55
56
|
assistant_id="659e54b1b8006379b4b2abd6", # 搜索智能体
|
@@ -62,7 +63,7 @@ class Completions(object):
|
|
62
63
|
"type": "text",
|
63
64
|
# "text": "北京未来七天气温,做个折线图",
|
64
65
|
# "text": "画条狗"
|
65
|
-
"text":
|
66
|
+
"text": q,
|
66
67
|
|
67
68
|
}]
|
68
69
|
}
|
@@ -73,14 +74,17 @@ class Completions(object):
|
|
73
74
|
)
|
74
75
|
|
75
76
|
references = []
|
76
|
-
buffer = []
|
77
77
|
for chunk in chunks:
|
78
|
+
# logger.debug(chunk)
|
79
|
+
|
78
80
|
delta = chunk.choices[0].delta
|
79
81
|
if hasattr(delta, "tool_calls") and delta.tool_calls:
|
80
82
|
tool_call = delta.tool_calls[0].model_dump()
|
81
83
|
# logger.debug(tool_call)
|
82
84
|
tool_type = tool_call.get("type", "") # web_browser
|
83
85
|
references += tool_call.get(tool_type, {}).get("outputs") or [] # title link content
|
86
|
+
|
87
|
+
# logger.debug(f"references: {references}")
|
84
88
|
continue
|
85
89
|
|
86
90
|
if isinstance(request, CompletionRequest):
|
@@ -89,16 +93,6 @@ class Completions(object):
|
|
89
93
|
yield from urls
|
90
94
|
references = []
|
91
95
|
|
92
|
-
# logger.debug(delta)
|
93
|
-
# if delta.content.startswith('【') or buffer: # hasattr(delta, "content")
|
94
|
-
# buffer.append(delta.content)
|
95
|
-
# if len(buffer) < 20:
|
96
|
-
# continue
|
97
|
-
#
|
98
|
-
# if delta.content.endswith('】'):
|
99
|
-
# delta.content = convert_citations(''.join(buffer))
|
100
|
-
# if len(buffer) > 25: buffer = []
|
101
|
-
|
102
96
|
delta = chat_completion_chunk.choices[0].delta.model_construct(**delta.model_dump())
|
103
97
|
chat_completion_chunk.choices[0].delta = delta
|
104
98
|
yield chat_completion_chunk
|
@@ -109,24 +103,21 @@ class Completions(object):
|
|
109
103
|
|
110
104
|
|
111
105
|
if __name__ == '__main__':
|
112
|
-
model = "web-search-pro"
|
113
|
-
# model = "tencent-search"
|
114
|
-
|
115
106
|
request = CompletionRequest(
|
116
107
|
# model="baichuan4-turbo",
|
117
108
|
# model="xx",
|
118
109
|
# model="deepseek-r1",
|
119
110
|
# model="deepseek-r1:1.5b",
|
120
|
-
model=model,
|
111
|
+
model="model",
|
121
112
|
|
122
113
|
# model="moonshot-v1-8k",
|
123
114
|
# model="doubao",
|
124
115
|
|
125
116
|
messages=[
|
126
|
-
{"role": "user", "content": "
|
117
|
+
{"role": "user", "content": "周杰伦"}
|
127
118
|
],
|
128
119
|
|
129
120
|
stream=True
|
130
121
|
)
|
131
|
-
# arun(Completions().
|
132
|
-
arun(Completions().
|
122
|
+
# arun(Completions().create(request))
|
123
|
+
# arun(Completions().query(request.last_user_content))
|
@@ -57,7 +57,7 @@ if __name__ == '__main__':
|
|
57
57
|
# image = "doc_watermark.jpg"
|
58
58
|
|
59
59
|
# image = "https://oss.ffire.cc/files/nsfw.jpg"
|
60
|
-
image = "https://oss.ffire.cc/files/kling_watermark.png"
|
60
|
+
image = "https://oss.ffire.cc/files/kling_watermark.png" # 无水印
|
61
61
|
|
62
62
|
request = WatermarkRemove(
|
63
63
|
image=image,
|
meutils/apis/tripo3d/images.py
CHANGED
meutils/caches/common.py
CHANGED
@@ -18,6 +18,8 @@ cache = memory_cache = cached
|
|
18
18
|
|
19
19
|
def rcache(**kwargs):
|
20
20
|
"""serializer="pickle"
|
21
|
+
|
22
|
+
noself: bool = False,
|
21
23
|
:param endpoint: str with the endpoint to connect to. Default is "127.0.0.1".
|
22
24
|
:param port: int with the port to connect to. Default is 6379.
|
23
25
|
:param db: int indicating database to use. Default is 0.
|
@@ -56,8 +58,8 @@ if __name__ == '__main__':
|
|
56
58
|
return a
|
57
59
|
|
58
60
|
|
59
|
-
@cache(ttl=3)
|
60
|
-
@rcache(ttl=
|
61
|
+
# @cache(ttl=3)
|
62
|
+
@rcache(ttl=10)
|
61
63
|
async def mfn(a):
|
62
64
|
logger.debug(a)
|
63
65
|
return a
|
meutils/data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2025.
|
1
|
+
2025.04.08.18.11.44
|
meutils/io/files_utils.py
CHANGED
@@ -14,7 +14,8 @@ import shortuuid
|
|
14
14
|
|
15
15
|
from meutils.pipe import *
|
16
16
|
from meutils.decorators.retry import retrying
|
17
|
-
from meutils.caches
|
17
|
+
from meutils.caches import rcache, cache
|
18
|
+
from meutils.oss.minio_oss import Minio
|
18
19
|
|
19
20
|
# from fastapi import UploadFile 有点区别
|
20
21
|
from starlette.datastructures import UploadFile
|
@@ -49,6 +50,7 @@ def base64_to_bytes(base64_image_string):
|
|
49
50
|
|
50
51
|
|
51
52
|
@retrying()
|
53
|
+
@rcache(ttl=300, serializer='pickle') # todo: UploadFile不一定兼容
|
52
54
|
async def to_bytes(
|
53
55
|
file: Union[UploadFile, str, bytes],
|
54
56
|
headers: Optional[dict] = None
|
@@ -73,7 +75,7 @@ async def to_bytes(
|
|
73
75
|
elif isinstance(file, str) and file.startswith('http'): # url
|
74
76
|
logger.debug(f"FileType: HTTP")
|
75
77
|
|
76
|
-
async with AsyncClient(headers=headers or {}, timeout=
|
78
|
+
async with AsyncClient(headers=headers or {}, timeout=100) as cilent:
|
77
79
|
resp = await cilent.get(file)
|
78
80
|
file_bytes = resp.content
|
79
81
|
|
@@ -139,33 +141,34 @@ async def to_url_fal(
|
|
139
141
|
|
140
142
|
|
141
143
|
async def to_url(
|
142
|
-
file: Union[
|
144
|
+
file: Union[str, bytes, List],
|
143
145
|
filename: Optional[str] = None,
|
144
146
|
headers: Optional[dict] = None,
|
145
|
-
|
147
|
+
|
148
|
+
content_type: Optional[str] = None,
|
149
|
+
mime_type: Optional[str] = None
|
146
150
|
):
|
147
|
-
|
148
|
-
|
151
|
+
if isinstance(file, list):
|
152
|
+
tasks = [to_url(_, f"{shortuuid.random()}_{filename}", headers) for _ in file]
|
153
|
+
urls = await asyncio.gather(*tasks)
|
154
|
+
return urls
|
149
155
|
|
150
|
-
|
151
|
-
from meutils.oss.minio_oss import Minio
|
152
|
-
uploads = [partial(Minio().put_object_for_openai, filename=filename, content_type=content_type)]
|
156
|
+
if not file: return
|
153
157
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
if isinstance(url, FileObject):
|
159
|
-
url = url.filename
|
160
|
-
return url
|
161
|
-
except Exception as e:
|
162
|
-
logger.error(e)
|
158
|
+
content_type = content_type or mime_type
|
159
|
+
file = await to_bytes(file, headers=headers)
|
160
|
+
file_url = await Minio().upload(file, filename, content_type=content_type)
|
161
|
+
return file_url
|
163
162
|
|
164
163
|
|
165
|
-
async def to_base64(file: Union[UploadFile, str, bytes, list]):
|
164
|
+
async def to_base64(file: Union[UploadFile, str, bytes, list], content_type: Optional[str] = None):
|
166
165
|
if not file: return
|
167
166
|
|
168
167
|
_ = base64.b64encode(await to_bytes(file)).decode('utf-8')
|
168
|
+
|
169
|
+
if content_type: # "image/png"
|
170
|
+
_ = f"data:{content_type};base64,{_}"
|
171
|
+
|
169
172
|
return _
|
170
173
|
|
171
174
|
|
@@ -256,10 +259,12 @@ if __name__ == '__main__':
|
|
256
259
|
# content_type=None))
|
257
260
|
|
258
261
|
# arun(to_url_fal(url))
|
259
|
-
print(guess_mime_type("base64xxxxxxxxxxxxxxxxxx.mp4"))
|
262
|
+
# print(guess_mime_type(b"base64xxxxxxxxxxxxxxxxxx.mp4"))
|
260
263
|
|
261
|
-
# arun(to_url(Path('img_1.png').read_bytes()))
|
264
|
+
# arun(to_url([Path('img_1.png').read_bytes()], filename='x.png'))
|
265
|
+
file = "/Users/betterme/PycharmProjects/AI/ppt.txt"
|
266
|
+
# arun(to_url(Path(file).read_bytes(), filename='ppt.txt'))
|
262
267
|
|
263
268
|
# arun(markdown_base64_to_url(""))
|
264
269
|
|
265
|
-
|
270
|
+
arun(to_bytes("https://oss.ffire.cc/files/kling_watermark.png"))
|
meutils/llm/clients.py
CHANGED
@@ -33,16 +33,17 @@ zhipuai_sdk_client = ZhipuAI(
|
|
33
33
|
base_url=os.getenv("ZHIPUAI_BASE_URL")
|
34
34
|
)
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
36
|
# zhipuai_client = OpenAI(
|
42
37
|
# api_key=os.getenv("ZHIPUAI_API_KEY"),
|
43
38
|
# base_url=os.getenv("ZHIPUAI_BASE_URL")
|
44
39
|
# )
|
45
40
|
|
41
|
+
# ark_bots_client = AsyncOpenAI(
|
42
|
+
# api_key=os.getenv("ZHIPUAI_API_KEY"),
|
43
|
+
# base_url="https://ark.cn-beijing.volces.com/api/v3/bots"
|
44
|
+
# )
|
45
|
+
|
46
|
+
|
46
47
|
if __name__ == '__main__':
|
47
48
|
from meutils.pipe import *
|
48
49
|
|
@@ -49,6 +49,8 @@ class Completions(object):
|
|
49
49
|
}
|
50
50
|
]
|
51
51
|
|
52
|
+
logger.debug(request)
|
53
|
+
|
52
54
|
data = to_openai_params(request)
|
53
55
|
return await self.client.chat.completions.create(**data)
|
54
56
|
|
@@ -59,19 +61,21 @@ if __name__ == '__main__':
|
|
59
61
|
"messages": [
|
60
62
|
{
|
61
63
|
"role": "user",
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
64
|
+
|
65
|
+
"content": "https://s3.ffire.cc/cdn/20250403/6MxhHmxeX7Z7WYMb8QWqfp_ppt 基于文件做个ppt"
|
66
|
+
# "content": [
|
67
|
+
# {
|
68
|
+
# "type": "file",
|
69
|
+
# "file_url": {
|
70
|
+
# "url": "https://mj101-1317487292.cos.ap-shanghai.myqcloud.com/ai/test.pdf"
|
71
|
+
# }
|
72
|
+
# },
|
73
|
+
# {
|
74
|
+
# "type": "text",
|
75
|
+
# # "text": "基于内容写个ppt给我"
|
76
|
+
# "text": "生成PPT"
|
77
|
+
# }
|
78
|
+
# ]
|
75
79
|
}
|
76
80
|
],
|
77
81
|
# "stream": false
|
@@ -60,7 +60,9 @@ async def create(request: CompletionRequest, token: Optional[str] = None): # Ch
|
|
60
60
|
if request.temperature > 1:
|
61
61
|
request.temperature = 1
|
62
62
|
|
63
|
-
token = token or await get_next_token_for_polling(feishu_url=FEISHU_URL)
|
63
|
+
token = token or await get_next_token_for_polling(feishu_url=FEISHU_URL, from_redis=True)
|
64
|
+
|
65
|
+
logger.debug(token)
|
64
66
|
|
65
67
|
client = AsyncOpenAI(
|
66
68
|
base_url=base_url,
|
@@ -81,6 +83,9 @@ async def create(request: CompletionRequest, token: Optional[str] = None): # Ch
|
|
81
83
|
request.model = "qwen-max-latest"
|
82
84
|
request.messages[-1]['feature_config'] = {"thinking_enabled": True}
|
83
85
|
|
86
|
+
if "omni" in model:
|
87
|
+
request.max_tokens = 2048
|
88
|
+
|
84
89
|
# 多模态: todo
|
85
90
|
# if any(i in request.model.lower() for i in ("-vl", "qvq")):
|
86
91
|
# # await to_file
|
@@ -180,7 +185,8 @@ if __name__ == '__main__':
|
|
180
185
|
# model="qwen-turbo-2024-11-01",
|
181
186
|
# model="qwen-max-latest",
|
182
187
|
# model="qvq-max-2025-03-25",
|
183
|
-
model="qvq-72b-preview-0310",
|
188
|
+
# model="qvq-72b-preview-0310",
|
189
|
+
model="qwen2.5-omni-7b",
|
184
190
|
|
185
191
|
# model="qwen-max-latest-search",
|
186
192
|
# model="qwq-max",
|
@@ -62,6 +62,11 @@ def to_openai_params(
|
|
62
62
|
data['extra_body'] = extra_body # 拓展字段
|
63
63
|
data['model'] = redirect_model or data['model']
|
64
64
|
|
65
|
+
if request.model.startswith(("gemini",)):
|
66
|
+
data.pop("extra_body", None)
|
67
|
+
data.pop("presence_penalty", None)
|
68
|
+
data.pop("frequency_penalty", None)
|
69
|
+
|
65
70
|
return data
|
66
71
|
|
67
72
|
|
meutils/oss/minio_oss.py
CHANGED
@@ -11,6 +11,7 @@ import datetime
|
|
11
11
|
import mimetypes
|
12
12
|
|
13
13
|
from meutils.pipe import *
|
14
|
+
|
14
15
|
from minio import Minio as _Minio
|
15
16
|
from openai.types.file_object import FileObject
|
16
17
|
from fastapi import APIRouter, File, UploadFile, Query, Form, BackgroundTasks, Depends, HTTPException, Request, status
|
@@ -23,7 +24,7 @@ class Minio(_Minio):
|
|
23
24
|
access_key: Optional[str] = None,
|
24
25
|
secret_key: Optional[str] = None,
|
25
26
|
**kwargs):
|
26
|
-
self.endpoint = endpoint or os.getenv('MINIO_ENDPOINT', '
|
27
|
+
self.endpoint = endpoint or os.getenv('MINIO_ENDPOINT', 's3.ffire.cc')
|
27
28
|
access_key = access_key or os.getenv('MINIO_ACCESS_KEY', 'minio')
|
28
29
|
secret_key = secret_key or os.getenv('MINIO_SECRET_KEY')
|
29
30
|
|
@@ -35,6 +36,35 @@ class Minio(_Minio):
|
|
35
36
|
# super().list_buckets()
|
36
37
|
# super().list_objects('中职职教高考政策解读.pdf')
|
37
38
|
# return super().list_buckets()
|
39
|
+
async def upload(
|
40
|
+
self,
|
41
|
+
file: bytes,
|
42
|
+
filename: Optional[str] = None,
|
43
|
+
|
44
|
+
content_type: Optional[str] = None,
|
45
|
+
|
46
|
+
bucket_name: str = "cdn",
|
47
|
+
|
48
|
+
):
|
49
|
+
file_name = filename or shortuuid.random()
|
50
|
+
|
51
|
+
content_type = (
|
52
|
+
content_type
|
53
|
+
or mimetypes.guess_type(file_name)[0]
|
54
|
+
or "application/octet-stream"
|
55
|
+
)
|
56
|
+
|
57
|
+
object_name = f"""{datetime.datetime.now().strftime("%Y%m%d")}/{file_name}"""
|
58
|
+
_ = await self.aput_object(
|
59
|
+
bucket_name,
|
60
|
+
object_name=object_name,
|
61
|
+
content_type=content_type,
|
62
|
+
|
63
|
+
data=io.BytesIO(file),
|
64
|
+
length=len(file),
|
65
|
+
)
|
66
|
+
|
67
|
+
return f"https://{self.endpoint}/{bucket_name}/{object_name}"
|
38
68
|
|
39
69
|
async def put_object_for_openai(
|
40
70
|
self,
|
@@ -89,7 +119,7 @@ class Minio(_Minio):
|
|
89
119
|
)
|
90
120
|
|
91
121
|
logger.debug(f"content_type: {content_type}")
|
92
|
-
object_name = f"""{datetime.datetime.now().strftime("%Y
|
122
|
+
object_name = f"""{datetime.datetime.now().strftime("%Y%m%d")}/{file_name}"""
|
93
123
|
_ = await self.aput_object(
|
94
124
|
bucket_name,
|
95
125
|
object_name=object_name,
|
@@ -177,10 +207,10 @@ if __name__ == '__main__':
|
|
177
207
|
# )
|
178
208
|
# print(arun(_, debug=True))
|
179
209
|
|
180
|
-
_ = client.put_object_for_openai(
|
181
|
-
|
182
|
-
|
183
|
-
)
|
184
|
-
arun(_)
|
185
|
-
|
210
|
+
# _ = client.put_object_for_openai(
|
211
|
+
# url,
|
212
|
+
# filename='cff.png'
|
213
|
+
# )
|
214
|
+
# arun(_)
|
186
215
|
|
216
|
+
f = client.upload(Path("/Users/betterme/PycharmProjects/AI/qun.png").read_bytes(), filename='x.png')
|
meutils/oss/minio_utils.py
CHANGED
@@ -14,7 +14,7 @@ minioClient = Minio(
|
|
14
14
|
endpoint=os.getenv('MINIO_ENDPOINT'),
|
15
15
|
access_key=os.getenv('MINIO_ACCESS_KEY'),
|
16
16
|
secret_key=os.getenv('MINIO_SECRET_KEY'),
|
17
|
-
# secure=False
|
17
|
+
# secure=False,
|
18
18
|
)
|
19
19
|
|
20
20
|
# Make a bucket with the make_bucket API call.
|
@@ -31,7 +31,7 @@ print(minioClient.list_buckets())
|
|
31
31
|
# minioClient.fput_object(bucket_name, 'file.py', 'file.py')
|
32
32
|
|
33
33
|
|
34
|
-
minioClient.fput_object(bucket_name, 'x/img','img.png', content_type='image/png')
|
34
|
+
# minioClient.fput_object(bucket_name, 'x/img','img.png', content_type='image/png')
|
35
35
|
|
36
36
|
|
37
37
|
# url = minioClient.get_presigned_url(
|