MeUtils 2025.4.1.18.47.48__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.4.1.18.47.48.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/METADATA +263 -263
- {MeUtils-2025.4.1.18.47.48.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/RECORD +34 -26
- examples/_openaisdk/openai_ark_bots.py +4 -22
- examples/_openaisdk/openai_audio_gpt.py +67 -0
- examples/_openaisdk/openai_google.py +128 -77
- examples/_openaisdk/zhipu_/346/231/272/350/203/275/344/275/223.py +3 -3
- 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/{llm/completions → apis/google_apis}/google2openai.py +22 -8
- 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/jimeng/images.py +2 -1
- meutils/apis/search/ark_web_search.py +8 -4
- meutils/apis/search/zhipu_web_search.py +6 -3
- meutils/apis/textin_apis/common.py +1 -1
- meutils/apis/tripo3d/images.py +1 -1
- meutils/caches/common.py +2 -2
- meutils/data/VERSION +1 -1
- meutils/io/files_utils.py +27 -22
- meutils/llm/completions/assistants/ppt.py +17 -13
- meutils/llm/completions/qwenllm.py +8 -2
- 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.4.1.18.47.48.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/LICENSE +0 -0
- {MeUtils-2025.4.1.18.47.48.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/WHEEL +0 -0
- {MeUtils-2025.4.1.18.47.48.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/entry_points.txt +0 -0
- {MeUtils-2025.4.1.18.47.48.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Project : AI. @by PyCharm
|
4
|
+
# @File : audios
|
5
|
+
# @Time : 2025/4/2 11:00
|
6
|
+
# @Author : betterme
|
7
|
+
# @WeChat : meutils
|
8
|
+
# @Software : PyCharm
|
9
|
+
# @Description : https://platform.openai.com/docs/guides/audio?example=audio-in
|
10
|
+
|
11
|
+
from meutils.pipe import *
|
12
|
+
#!/usr/bin/env python
|
13
|
+
# -*- coding: utf-8 -*-
|
14
|
+
# @Project : AI. @by PyCharm
|
15
|
+
# @File : openai_siliconflow
|
16
|
+
# @Time : 2024/6/26 10:42
|
17
|
+
# @Author : betterme
|
18
|
+
# @WeChat : meutils
|
19
|
+
# @Software : PyCharm
|
20
|
+
# @Description :
|
21
|
+
import os
|
22
|
+
|
23
|
+
from meutils.pipe import *
|
24
|
+
from openai import OpenAI
|
25
|
+
from openai import OpenAI, APIStatusError
|
26
|
+
from meutils.schemas.openai_types import ChatCompletionRequest
|
27
|
+
from meutils.llm.openai_utils import to_openai_completion_params
|
28
|
+
from meutils.io.files_utils import to_base64
|
29
|
+
|
30
|
+
base64_audio = arun(to_base64("https://oss.ffire.cc/files/lipsync.mp3"))
|
31
|
+
|
32
|
+
|
33
|
+
client = OpenAI(
|
34
|
+
# api_key=os.getenv("GOOGLE_API_KEY"),
|
35
|
+
api_key="AIzaSyAQAt73dfL5-v3zaAHtXajZalZxfiumMOU",
|
36
|
+
base_url=os.getenv("GOOGLE_BASE_URL"),
|
37
|
+
)
|
38
|
+
|
39
|
+
print(client.models.list().model_dump_json(indent=4))
|
40
|
+
|
41
|
+
# {
|
42
|
+
# "gemini-2.0-pro-exp": "models/gemini-2.0-pro-exp",
|
43
|
+
# "gemini-2.0-pro-exp-02-05": "models/gemini-2.0-pro-exp-02-05",
|
44
|
+
# "gemini-2.5-pro-exp-03-25": "models/gemini-2.5-pro-exp-03-25",
|
45
|
+
# "gemini-2.0-flash-thinking-exp": "models/gemini-2.0-flash-thinking-exp",
|
46
|
+
# "gemini-2.0-flash": "models/gemini-2.0-flash"
|
47
|
+
#
|
48
|
+
# }
|
49
|
+
|
50
|
+
|
51
|
+
if __name__ == '__main__':
|
52
|
+
# messages = [
|
53
|
+
#
|
54
|
+
# {
|
55
|
+
# "role": "user", "content": [
|
56
|
+
# {
|
57
|
+
# "type": "text",
|
58
|
+
# "text": "一句话总结"
|
59
|
+
# },
|
60
|
+
# {
|
61
|
+
# "type": "image_url",
|
62
|
+
# "image_url": {
|
63
|
+
# "url": "https://oss.ffire.cc/files/kling_watermark.png"
|
64
|
+
# }
|
65
|
+
# }
|
66
|
+
# ]
|
67
|
+
# }
|
68
|
+
#
|
69
|
+
# ]
|
70
|
+
messages = [
|
71
|
+
{
|
72
|
+
"role": "user",
|
73
|
+
"content": [
|
74
|
+
{
|
75
|
+
"type": "text",
|
76
|
+
"text": "一句话总结",
|
77
|
+
},
|
78
|
+
{
|
79
|
+
"type": "input_audio",
|
80
|
+
"input_audio": {
|
81
|
+
"data": base64_audio,
|
82
|
+
"format": "wav"
|
83
|
+
}
|
84
|
+
}
|
85
|
+
],
|
86
|
+
}
|
87
|
+
]
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
try:
|
92
|
+
completion = client.chat.completions.create(
|
93
|
+
# model="models/gemini-2.5-pro-exp-03-25",
|
94
|
+
model="models/gemini-2.0-flash",
|
95
|
+
# model="models/gemini-2.0-flash-exp-image-generation",
|
96
|
+
messages=messages,
|
97
|
+
# top_p=0.7,
|
98
|
+
top_p=None,
|
99
|
+
temperature=None,
|
100
|
+
# stream=True,
|
101
|
+
stream=False,
|
102
|
+
|
103
|
+
max_tokens=None,
|
104
|
+
)
|
105
|
+
except APIStatusError as e:
|
106
|
+
print(e.status_code)
|
107
|
+
|
108
|
+
print(e.response)
|
109
|
+
print(e.message)
|
110
|
+
print(e.code)
|
111
|
+
print(completion)
|
112
|
+
for chunk in completion: # 剔除extra body
|
113
|
+
print(chunk)
|
114
|
+
if chunk.choices:
|
115
|
+
print(chunk.choices[0].delta.content)
|
@@ -0,0 +1,251 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Project : AI. @by PyCharm
|
4
|
+
# @File : common
|
5
|
+
# @Time : 2025/4/2 13:03
|
6
|
+
# @Author : betterme
|
7
|
+
# @WeChat : meutils
|
8
|
+
# @Software : PyCharm
|
9
|
+
# @Description : https://ai.google.dev/gemini-api/docs/openai?hl=zh-cn
|
10
|
+
import asyncio
|
11
|
+
import os
|
12
|
+
|
13
|
+
import shortuuid
|
14
|
+
|
15
|
+
from meutils.pipe import *
|
16
|
+
from meutils.llm.clients import AsyncOpenAI
|
17
|
+
from meutils.io.files_utils import to_url, to_bytes, guess_mime_type
|
18
|
+
from meutils.str_utils.regular_expression import parse_url
|
19
|
+
|
20
|
+
from meutils.schemas.openai_types import chat_completion, chat_completion_chunk, CompletionRequest, CompletionUsage
|
21
|
+
|
22
|
+
from meutils.config_utils.lark_utils import get_next_token_for_polling
|
23
|
+
from google import genai
|
24
|
+
from google.genai import types
|
25
|
+
from google.genai.types import HttpOptions, GenerateContentConfig, Content, HarmCategory, HarmBlockThreshold, Part
|
26
|
+
from google.genai.types import UserContent, ModelContent
|
27
|
+
|
28
|
+
FEISHU_URL = "https://xchatllm.feishu.cn/sheets/Bmjtst2f6hfMqFttbhLcdfRJnNf?sheet=MJw6hI"
|
29
|
+
|
30
|
+
"""
|
31
|
+
Gemini 1.5 Pro 和 1.5 Flash 最多支持 3,600 个文档页面。文档页面必须采用以下文本数据 MIME 类型之一:
|
32
|
+
|
33
|
+
PDF - application/pdf
|
34
|
+
JavaScript - application/x-javascript、text/javascript
|
35
|
+
Python - application/x-python、text/x-python
|
36
|
+
TXT - text/plain
|
37
|
+
HTML - text/html
|
38
|
+
CSS - text/css
|
39
|
+
Markdown - text/md
|
40
|
+
CSV - text/csv
|
41
|
+
XML - text/xml
|
42
|
+
RTF - text/rtf
|
43
|
+
|
44
|
+
- 小文件
|
45
|
+
- 大文件: 需要等待处理
|
46
|
+
"""
|
47
|
+
|
48
|
+
|
49
|
+
class GeminiClient(object):
|
50
|
+
def __init__(self, api_key: Optional[str] = None):
|
51
|
+
self.api_key = api_key # or await get_next_token_for_polling(feishu_url=FEISHU_URL, from_redis=True)
|
52
|
+
self.base_url = "https://all.chatfire.cc/genai"
|
53
|
+
|
54
|
+
async def create(self, request: CompletionRequest):
|
55
|
+
client = await self.get_client()
|
56
|
+
|
57
|
+
if any(i in request.model for i in ("image",)):
|
58
|
+
messages = await self.to_image_messages(request)
|
59
|
+
|
60
|
+
if len(messages) > 1:
|
61
|
+
history = messages[:-1]
|
62
|
+
message = messages[-1].parts
|
63
|
+
else:
|
64
|
+
history = []
|
65
|
+
message = messages[-1].parts
|
66
|
+
|
67
|
+
chat = client.aio.chats.create( # todo: system_instruction
|
68
|
+
model=request.model,
|
69
|
+
config=GenerateContentConfig(
|
70
|
+
response_modalities=['Text', 'Image'],
|
71
|
+
),
|
72
|
+
history=history
|
73
|
+
)
|
74
|
+
|
75
|
+
logger.debug(message)
|
76
|
+
|
77
|
+
# message = [
|
78
|
+
# Part.from_text(text="画条狗")
|
79
|
+
# ]
|
80
|
+
|
81
|
+
for i in range(5):
|
82
|
+
try:
|
83
|
+
chunks = await chat.send_message_stream(message)
|
84
|
+
async for chunk in chunks:
|
85
|
+
|
86
|
+
if chunk.candidates:
|
87
|
+
parts = chunk.candidates[0].content.parts or []
|
88
|
+
for part in parts:
|
89
|
+
logger.debug(part)
|
90
|
+
if part.text:
|
91
|
+
yield part.text
|
92
|
+
|
93
|
+
if part.inline_data:
|
94
|
+
image_url = await to_url(
|
95
|
+
part.inline_data.data,
|
96
|
+
mime_type=part.inline_data.mime_type
|
97
|
+
)
|
98
|
+
yield f""
|
99
|
+
break
|
100
|
+
|
101
|
+
except Exception as e:
|
102
|
+
logger.debug(f"重试{i}: {e}")
|
103
|
+
if "The model is overloaded." in str(e):
|
104
|
+
await asyncio.sleep(1)
|
105
|
+
continue
|
106
|
+
else:
|
107
|
+
yield e
|
108
|
+
raise e
|
109
|
+
|
110
|
+
async def to_image_messages(self, request: CompletionRequest):
|
111
|
+
# 两轮即可连续编辑图片
|
112
|
+
|
113
|
+
messages = []
|
114
|
+
for m in request.messages:
|
115
|
+
contents = m.get("content")
|
116
|
+
if m.get("role") == "assistant":
|
117
|
+
assistant_content = str(contents)
|
118
|
+
if urls := parse_url(assistant_content): # assistant
|
119
|
+
datas = await asyncio.gather(*map(to_bytes, urls))
|
120
|
+
|
121
|
+
parts = [
|
122
|
+
Part.from_bytes(
|
123
|
+
data=data,
|
124
|
+
mime_type="image/png"
|
125
|
+
)
|
126
|
+
for data in datas
|
127
|
+
]
|
128
|
+
parts += [
|
129
|
+
Part.from_text(
|
130
|
+
text=request.last_assistant_content
|
131
|
+
),
|
132
|
+
]
|
133
|
+
messages.append(ModelContent(parts=parts))
|
134
|
+
|
135
|
+
elif m.get("role") == "user":
|
136
|
+
if isinstance(contents, list):
|
137
|
+
parts = []
|
138
|
+
for content in contents:
|
139
|
+
if content.get("type") == "image_url":
|
140
|
+
image_url = content.get("image_url", {}).get("url")
|
141
|
+
data = await to_bytes(image_url)
|
142
|
+
|
143
|
+
parts += [
|
144
|
+
Part.from_bytes(data=data, mime_type="image/png")
|
145
|
+
]
|
146
|
+
|
147
|
+
elif content.get("type") == "text":
|
148
|
+
text = content.get("text")
|
149
|
+
if text.startswith('http'):
|
150
|
+
image_url, text = text.split(maxsplit=1)
|
151
|
+
data = await to_bytes(image_url)
|
152
|
+
|
153
|
+
parts += [
|
154
|
+
Part.from_bytes(data=data, mime_type="image/png"),
|
155
|
+
Part.from_text(text=text)
|
156
|
+
]
|
157
|
+
else:
|
158
|
+
parts += [
|
159
|
+
Part.from_text(text=text)
|
160
|
+
]
|
161
|
+
|
162
|
+
messages.append(UserContent(parts=parts))
|
163
|
+
|
164
|
+
else: # str
|
165
|
+
if str(contents).startswith('http'): # 修正提问格式, 兼容 url
|
166
|
+
image_url, text = str(contents).split(maxsplit=1)
|
167
|
+
data = await to_bytes(image_url)
|
168
|
+
parts = [
|
169
|
+
Part.from_bytes(
|
170
|
+
data=data,
|
171
|
+
mime_type="image/png"
|
172
|
+
),
|
173
|
+
Part.from_text(
|
174
|
+
text=str(contents)
|
175
|
+
),
|
176
|
+
]
|
177
|
+
else:
|
178
|
+
parts = [
|
179
|
+
Part.from_text(
|
180
|
+
text=str(contents)
|
181
|
+
),
|
182
|
+
]
|
183
|
+
messages.append(UserContent(parts=parts))
|
184
|
+
|
185
|
+
return messages
|
186
|
+
|
187
|
+
async def upload(self, files: Union[str, List[str]]): # => openai files
|
188
|
+
client = await self.get_client()
|
189
|
+
|
190
|
+
if isinstance(files, list):
|
191
|
+
return await asyncio.gather(*map(self.upload, files))
|
192
|
+
|
193
|
+
file_config = {"name": f"{shortuuid.random().lower()}", "mime_type": guess_mime_type(files)}
|
194
|
+
return await client.aio.files.upload(file=io.BytesIO(await to_bytes(files)), config=file_config)
|
195
|
+
|
196
|
+
@alru_cache()
|
197
|
+
async def get_client(self):
|
198
|
+
api_key = self.api_key or await get_next_token_for_polling(feishu_url=FEISHU_URL, from_redis=True)
|
199
|
+
|
200
|
+
logger.info(f"GeminiClient: {api_key}")
|
201
|
+
|
202
|
+
return genai.Client(
|
203
|
+
api_key=api_key,
|
204
|
+
http_options=HttpOptions(
|
205
|
+
base_url=self.base_url
|
206
|
+
)
|
207
|
+
)
|
208
|
+
|
209
|
+
|
210
|
+
if __name__ == '__main__':
|
211
|
+
file = "https://oss.ffire.cc/files/kling_watermark.png"
|
212
|
+
|
213
|
+
api_key = os.getenv("GOOGLE_API_KEY")
|
214
|
+
|
215
|
+
# arun(GeminiClient(api_key=api_key).upload(file))
|
216
|
+
# arun(GeminiClient(api_key=api_key).upload([file] * 2))
|
217
|
+
# arun(GeminiClient(api_key=api_key).create())
|
218
|
+
|
219
|
+
content = [
|
220
|
+
|
221
|
+
{"type": "text", "text": "https://oss.ffire.cc/files/nsfw.jpg 移除右下角的水印"},
|
222
|
+
|
223
|
+
# {"type": "text", "text": "总结下"},
|
224
|
+
# {"type": "image_url", "image_url": {"url": url}},
|
225
|
+
|
226
|
+
# {"type": "video_url", "video_url": {"url": url}}
|
227
|
+
|
228
|
+
]
|
229
|
+
|
230
|
+
# content = "https://oss.ffire.cc/files/nsfw.jpg 移除右下角的水印"
|
231
|
+
|
232
|
+
#
|
233
|
+
request = CompletionRequest(
|
234
|
+
# model="qwen-turbo-2024-11-01",
|
235
|
+
# model="gemini-all",
|
236
|
+
model="gemini-2.0-flash-exp-image-generation",
|
237
|
+
# model="qwen-plus-latest",
|
238
|
+
|
239
|
+
messages=[
|
240
|
+
{
|
241
|
+
'role': 'user',
|
242
|
+
|
243
|
+
'content': content
|
244
|
+
},
|
245
|
+
|
246
|
+
],
|
247
|
+
stream=True,
|
248
|
+
)
|
249
|
+
|
250
|
+
# arun(GeminiClient(api_key=api_key).to_image_messages(request))
|
251
|
+
arun(GeminiClient(api_key=api_key).create(request))
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Project : AI. @by PyCharm
|
4
|
+
# @File : files
|
5
|
+
# @Time : 2025/4/2 10:40
|
6
|
+
# @Author : betterme
|
7
|
+
# @WeChat : meutils
|
8
|
+
# @Software : PyCharm
|
9
|
+
# @Description :
|
10
|
+
|
11
|
+
from meutils.pipe import *
|
12
|
+
|
13
|
+
|
14
|
+
file = "/Users/betterme/PycharmProjects/AI/QR.png"
|
15
|
+
#
|
16
|
+
# file_object = client.files.upload(file=file)
|
17
|
+
# prompt = "一句话总结"
|
18
|
+
|
19
|
+
file_object = client.aio.files.upload(file=file)
|
@@ -0,0 +1,170 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Project : AI. @by PyCharm
|
4
|
+
# @File : st
|
5
|
+
# @Time : 2025/4/3 15:24
|
6
|
+
# @Author : betterme
|
7
|
+
# @WeChat : meutils
|
8
|
+
# @Software : PyCharm
|
9
|
+
# @Description :
|
10
|
+
|
11
|
+
from meutils.pipe import *
|
12
|
+
from meutils.async_utils import async_to_sync
|
13
|
+
|
14
|
+
from meutils.io.files_utils import to_url, to_bytes
|
15
|
+
from meutils.schemas.openai_types import CompletionRequest
|
16
|
+
|
17
|
+
from google import genai
|
18
|
+
from google.genai.types import HttpOptions, GenerateContentConfig, Content, HarmCategory, HarmBlockThreshold, Part, \
|
19
|
+
ThinkingConfig
|
20
|
+
from google.genai.chats import _is_part_type
|
21
|
+
|
22
|
+
config = GenerateContentConfig(
|
23
|
+
|
24
|
+
temperature=0.7,
|
25
|
+
top_p=0.8,
|
26
|
+
response_modalities=['Text', 'Image'],
|
27
|
+
)
|
28
|
+
|
29
|
+
# self._http_options.base_url = 'https://generativelanguage.googleapis.com/'
|
30
|
+
# self._http_options.api_version = 'v1beta'
|
31
|
+
client = genai.Client(
|
32
|
+
api_key="AIzaSyCa8PYURpxFKz7yOtQB_O_wRfrX0gYh9L4",
|
33
|
+
http_options=HttpOptions(
|
34
|
+
base_url="https://all.chatfire.cc/genai"
|
35
|
+
)
|
36
|
+
)
|
37
|
+
|
38
|
+
if __name__ == '__main__':
|
39
|
+
model = "gemini-2.0-flash-exp-image-generation"
|
40
|
+
|
41
|
+
request = CompletionRequest(
|
42
|
+
model=model,
|
43
|
+
messages=[
|
44
|
+
{
|
45
|
+
"role": "user", "content": [
|
46
|
+
{
|
47
|
+
"type": "text",
|
48
|
+
"text": "一句话总结"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"type": "image_url",
|
52
|
+
"image_url": {
|
53
|
+
|
54
|
+
"url": "https://oss.ffire.cc/files/kling_watermark.png"
|
55
|
+
|
56
|
+
}
|
57
|
+
}
|
58
|
+
]
|
59
|
+
}],
|
60
|
+
|
61
|
+
)
|
62
|
+
|
63
|
+
response = client.aio.chats.create(
|
64
|
+
model=model,
|
65
|
+
config=GenerateContentConfig(
|
66
|
+
system_instruction=None,
|
67
|
+
max_output_tokens=None,
|
68
|
+
response_modalities=['Text', 'Image'],
|
69
|
+
|
70
|
+
# thinking_config=ThinkingConfig(include_thoughts=True),
|
71
|
+
|
72
|
+
),
|
73
|
+
|
74
|
+
# history=[
|
75
|
+
#
|
76
|
+
# Content(
|
77
|
+
# role="user",
|
78
|
+
# parts=[
|
79
|
+
# Part.from_text(
|
80
|
+
# text="画条狗"
|
81
|
+
# )
|
82
|
+
# ]
|
83
|
+
# ),
|
84
|
+
# Content(
|
85
|
+
# role="model",
|
86
|
+
# parts=[
|
87
|
+
# Part.from_text(
|
88
|
+
# text="Ok"
|
89
|
+
# ),
|
90
|
+
#
|
91
|
+
# Part.from_bytes(
|
92
|
+
# data=async_to_sync(to_bytes)("https://oss.ffire.cc/files/kling_watermark.png"),
|
93
|
+
# mime_type="image/png"
|
94
|
+
# ),
|
95
|
+
# ]
|
96
|
+
# )
|
97
|
+
#
|
98
|
+
# ]
|
99
|
+
)
|
100
|
+
|
101
|
+
# "mime_type": "image/png"
|
102
|
+
|
103
|
+
p = Part.from_uri(file_uri="https://oss.ffire.cc/files/kling_watermark.png", mime_type="image/png")
|
104
|
+
pp = Part.from_bytes(
|
105
|
+
data=async_to_sync(to_bytes)("https://oss.ffire.cc/files/kling_watermark.png"),
|
106
|
+
mime_type="image/png"
|
107
|
+
)
|
108
|
+
|
109
|
+
|
110
|
+
# pt = Part.from_text(text="文本")
|
111
|
+
|
112
|
+
# {'video_metadata': None,
|
113
|
+
# 'thought': None,
|
114
|
+
# 'code_execution_result': None,
|
115
|
+
# 'executable_code': None,
|
116
|
+
# 'file_data': {'file_uri': 'https://oss.ffire.cc/files/kling_watermark.png',
|
117
|
+
# 'mime_type': 'image/png'},
|
118
|
+
# 'function_call': None,
|
119
|
+
# 'function_response': None,
|
120
|
+
# 'inline_data': None,
|
121
|
+
# 'text': None}
|
122
|
+
|
123
|
+
#
|
124
|
+
async def main():
|
125
|
+
message = [
|
126
|
+
Part.from_text(text="画条狗 带个眼镜"),
|
127
|
+
# pp
|
128
|
+
]
|
129
|
+
|
130
|
+
print(_is_part_type(message))
|
131
|
+
chunks = await response.send_message_stream(message)
|
132
|
+
|
133
|
+
async for chunk in chunks:
|
134
|
+
if chunk.candidates:
|
135
|
+
parts = chunk.candidates[0].content.parts
|
136
|
+
for part in parts or []:
|
137
|
+
if len(str(part)) < 500:
|
138
|
+
logger.debug(part)
|
139
|
+
if part.inline_data:
|
140
|
+
image_url = await to_url(part.inline_data.data, mime_type=part.inline_data.mime_type)
|
141
|
+
logger.info(image_url)
|
142
|
+
|
143
|
+
if part.text:
|
144
|
+
logger.info(part.text)
|
145
|
+
# print(i.model_dump_json(indent=4, exclude_none=True)) # inline_data
|
146
|
+
|
147
|
+
|
148
|
+
# response = client.models.generate_content(
|
149
|
+
# model="gemini-2.0-flash-exp-image-generation",
|
150
|
+
# contents=['画条狗'],
|
151
|
+
#
|
152
|
+
# # model="gemini-2.5-pro-exp-03-25",
|
153
|
+
# # model="gemini-2.0-flash",
|
154
|
+
#
|
155
|
+
# # contents=[
|
156
|
+
# # Part.from_uri(file_uri='https://generativelanguage.googleapis.com/v1beta/files/test', mime_type='image/png'),
|
157
|
+
# #
|
158
|
+
# # "一句话总结"],
|
159
|
+
# config=config
|
160
|
+
# )
|
161
|
+
#
|
162
|
+
# # client.aio.
|
163
|
+
# # client.aio.chats.create()
|
164
|
+
#
|
165
|
+
# if __name__ == '__main__':
|
166
|
+
# arun(file_object)
|
167
|
+
|
168
|
+
arun(main())
|
169
|
+
|
170
|
+
# ValueError: Message must be a valid part type: typing.Union[google.genai.types.File, google.genai.types.Part, PIL.Image.Image, str] or typing.Union[google.genai.types.File, google.genai.types.Part, PIL.Image.Image, str, google.genai.types.PartDict], got <class 'list'>
|
@@ -15,6 +15,7 @@
|
|
15
15
|
|
16
16
|
"""
|
17
17
|
from meutils.pipe import *
|
18
|
+
from meutils.schemas.openai_types import CompletionRequest
|
18
19
|
|
19
20
|
from google import genai
|
20
21
|
from google.genai.types import HttpOptions, GenerateContentConfig, Content, HarmCategory, HarmBlockThreshold, Part
|
@@ -26,7 +27,7 @@ config = GenerateContentConfig(
|
|
26
27
|
|
27
28
|
temperature=0.7,
|
28
29
|
top_p=0.8,
|
29
|
-
|
30
|
+
response_modalities=['Text', 'Image'],
|
30
31
|
|
31
32
|
# 公民诚信类别的默认屏蔽阈值为 Block none(对于别名为 gemini-2.0-flash、gemini-2.0-pro-exp-02-05 和 gemini-2.0-flash-lite 的 gemini-2.0-flash-001),适用于 Google AI Studio 和 Gemini API;仅适用于 Google AI Studio 中的所有其他模型的 Block most。
|
32
33
|
# safety_settings=[
|
@@ -37,10 +38,11 @@ config = GenerateContentConfig(
|
|
37
38
|
# ]
|
38
39
|
)
|
39
40
|
|
41
|
+
|
40
42
|
# self._http_options.base_url = 'https://generativelanguage.googleapis.com/'
|
41
43
|
# self._http_options.api_version = 'v1beta'
|
42
44
|
client = genai.Client(
|
43
|
-
api_key="
|
45
|
+
api_key="AIzaSyAlpq4kR9ZP0NwaqQzqHtDKqiV8PLdUqnA",
|
44
46
|
http_options=HttpOptions(
|
45
47
|
base_url="https://all.chatfire.cc/genai"
|
46
48
|
)
|
@@ -51,7 +53,7 @@ file = "/Users/betterme/PycharmProjects/AI/QR.png"
|
|
51
53
|
# file_object = client.files.upload(file=file)
|
52
54
|
# prompt = "一句话总结"
|
53
55
|
|
54
|
-
file_object = client.aio.files.upload(file=file)
|
56
|
+
# file_object = client.aio.files.upload(file=file)
|
55
57
|
# https://generativelanguage.googleapis.com/v1beta/files/ickgffcfb9zl
|
56
58
|
#
|
57
59
|
# contents = ('Hi, can you create a 3d rendered image of a pig '
|
@@ -60,16 +62,28 @@ file_object = client.aio.files.upload(file=file)
|
|
60
62
|
#
|
61
63
|
# prompt = "9.11 9.8哪个大呢"
|
62
64
|
#
|
65
|
+
|
66
|
+
# client.aio.chats.create(
|
67
|
+
# model="gemini-2.0-flash-exp-image-generation",
|
68
|
+
# )
|
69
|
+
|
63
70
|
response = client.models.generate_content(
|
64
|
-
|
71
|
+
model="gemini-2.0-flash-exp-image-generation",
|
72
|
+
contents=['画条狗'],
|
65
73
|
|
66
|
-
model
|
74
|
+
# model="gemini-2.5-pro-exp-03-25",
|
75
|
+
# model="gemini-2.0-flash",
|
67
76
|
|
68
|
-
contents=
|
69
|
-
#
|
77
|
+
# contents=[
|
78
|
+
# Part.from_uri(file_uri='https://generativelanguage.googleapis.com/v1beta/files/test', mime_type='image/png'),
|
79
|
+
#
|
80
|
+
# "一句话总结"],
|
81
|
+
config=config
|
70
82
|
)
|
83
|
+
|
71
84
|
# client.aio.
|
72
85
|
# client.aio.chats.create()
|
73
86
|
|
74
87
|
if __name__ == '__main__':
|
75
|
-
arun(file_object)
|
88
|
+
# arun(file_object)
|
89
|
+
pass
|
@@ -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",
|