MeUtils 2025.9.7.0.22.5__py3-none-any.whl → 2025.9.9.15.11.11__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.
- examples/_openaisdk/openai_ffire.py +12 -5
- examples/_openaisdk/openai_moon.py +9 -9
- examples/_openaisdk/openai_router.py +8 -8
- meutils/apis/fal/images.py +1 -1
- meutils/apis/google/chat.py +1 -1
- meutils/apis/google/images.py +4 -5
- meutils/apis/meituan/__init__.py +0 -1
- meutils/apis/meituan/chat.py +59 -24
- meutils/apis/oneapi/channel.py +36 -9
- meutils/apis/volcengine_apis/images.py +11 -4
- meutils/apis/volcengine_apis/videos.py +27 -28
- meutils/data/VERSION +1 -1
- meutils/llm/check_utils.py +2 -2
- meutils/llm/utils.py +8 -6
- meutils/schemas/oneapi/_types.py +2 -2
- meutils/schemas/oneapi/common.py +1 -0
- {meutils-2025.9.7.0.22.5.dist-info → meutils-2025.9.9.15.11.11.dist-info}/METADATA +260 -260
- {meutils-2025.9.7.0.22.5.dist-info → meutils-2025.9.9.15.11.11.dist-info}/RECORD +22 -22
- {meutils-2025.9.7.0.22.5.dist-info → meutils-2025.9.9.15.11.11.dist-info}/WHEEL +0 -0
- {meutils-2025.9.7.0.22.5.dist-info → meutils-2025.9.9.15.11.11.dist-info}/entry_points.txt +0 -0
- {meutils-2025.9.7.0.22.5.dist-info → meutils-2025.9.9.15.11.11.dist-info}/licenses/LICENSE +0 -0
- {meutils-2025.9.7.0.22.5.dist-info → meutils-2025.9.9.15.11.11.dist-info}/top_level.txt +0 -0
@@ -14,8 +14,10 @@ from openai import OpenAI
|
|
14
14
|
from openai import OpenAI, APIStatusError
|
15
15
|
|
16
16
|
client = OpenAI(
|
17
|
-
|
18
|
-
# api_key=os.getenv("FFIRE_API_KEY")
|
17
|
+
base_url=os.getenv("FFIRE_BASE_URL"),
|
18
|
+
# api_key=os.getenv("FFIRE_API_KEY") +"-29487"
|
19
|
+
api_key=os.getenv("FFIRE_API_KEY") + "-29492",
|
20
|
+
|
19
21
|
# base_url=os.getenv("ONEAPIS_BASE_URL"),
|
20
22
|
# api_key=os.getenv("ONEAPIS_API_KEY") + "-3"
|
21
23
|
|
@@ -30,18 +32,23 @@ for i in range(1):
|
|
30
32
|
# model="qwen3-235b-a22b-instruct-2507",
|
31
33
|
# model="qwen-image",
|
32
34
|
# model="glm-4.5",
|
33
|
-
model="deepseek-v3-1-think",
|
35
|
+
# model="deepseek-v3-1-think",
|
36
|
+
# model="kimi-k2-0905-preview",
|
37
|
+
# model="kimi-k2-0711-preview",
|
38
|
+
|
39
|
+
model="glm-4.5-air",
|
40
|
+
|
34
41
|
#
|
35
42
|
messages=[
|
36
43
|
{"role": "user", "content": 'are you ok?'}
|
37
44
|
],
|
38
45
|
stream=True,
|
39
|
-
|
46
|
+
max_tokens=10,
|
40
47
|
# extra_body={"xx": "xxxxxxxx"}
|
41
48
|
extra_body={
|
42
49
|
"thinking": {"type": "enabled"},
|
43
50
|
|
44
|
-
"enable_thinking": True
|
51
|
+
"enable_thinking": True # parameter.enable_thinking only support stream
|
45
52
|
}
|
46
53
|
)
|
47
54
|
print(completion)
|
@@ -18,7 +18,7 @@ client = OpenAI(
|
|
18
18
|
# base_url="http://ppu.chatfire.cc/v1"
|
19
19
|
)
|
20
20
|
|
21
|
-
print(client.models.list())
|
21
|
+
# print(client.models.list())
|
22
22
|
|
23
23
|
# completion = client.chat.completions.create(
|
24
24
|
# model="moonshot-v1-8k",
|
@@ -49,11 +49,11 @@ if __name__ == '__main__':
|
|
49
49
|
|
50
50
|
from meutils.pipe import timer
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
52
|
+
with timer():
|
53
|
+
completion = client.chat.completions.create(
|
54
|
+
model="kimi-k2-0905-preview",
|
55
|
+
messages=[
|
56
|
+
{"role": "user", "content": "你好"*100000 + "\n\n上文一共有多少个字"},
|
57
|
+
],
|
58
|
+
# temperature=0.3, extra_body={"refs": ["cn0bmk198onv4v01aafg"]}
|
59
|
+
)
|
@@ -17,15 +17,15 @@ from meutils.str_utils import parse_base64
|
|
17
17
|
# gets API Key from environment variable OPENAI_API_KEY
|
18
18
|
client = OpenAI(
|
19
19
|
# base_url="https://openrouter.ai/api/v1",
|
20
|
-
|
21
|
-
|
20
|
+
base_url="https://all.chatfire.cn/openrouter/v1",
|
21
|
+
api_key=os.getenv("OPENROUTER_API_KEY"),
|
22
22
|
#
|
23
23
|
# base_url="http://38.46.219.252:9001/v1",
|
24
24
|
#
|
25
25
|
# api_key="sk-Azgp1thTIonR7IdIEqlJU51tpDYNIYYpxHvAZwFeJiOdVWiz"
|
26
26
|
|
27
|
-
base_url="https://api.huandutech.com/v1",
|
28
|
-
api_key = "sk-qOpbMHesasoVgX75ZoeEeBEf1R9dmsUZVAPcu5KkvLFhElrn"
|
27
|
+
# base_url="https://api.huandutech.com/v1",
|
28
|
+
# api_key = "sk-qOpbMHesasoVgX75ZoeEeBEf1R9dmsUZVAPcu5KkvLFhElrn"
|
29
29
|
# api_key="sk-MAZ6SELJVtGNX6jgIcZBKuttsRibaDlAskFAnR7WD6PBSN6M",
|
30
30
|
# base_url="https://new.yunai.link/v1"
|
31
31
|
)
|
@@ -40,17 +40,17 @@ completion = client.chat.completions.create(
|
|
40
40
|
# model="openai/o1",
|
41
41
|
# model="deepseek/deepseek-r1-0528-qwen3-8b:free",
|
42
42
|
# model="google/gemini-2.5-flash-image-preview:free",
|
43
|
-
model="
|
43
|
+
model="deepseek/deepseek-chat-v3.1:free",
|
44
44
|
# model="gemini-2.0-flash-exp-image-generation",
|
45
|
-
|
46
|
-
|
45
|
+
max_tokens=10,
|
46
|
+
extra_body={"reasoning_stream": True},
|
47
47
|
messages=[
|
48
48
|
{
|
49
49
|
"role": "user",
|
50
50
|
"content": [
|
51
51
|
{
|
52
52
|
"type": "text",
|
53
|
-
"text": "
|
53
|
+
"text": "hi"
|
54
54
|
},
|
55
55
|
# {
|
56
56
|
# "type": "image_url",
|
meutils/apis/fal/images.py
CHANGED
@@ -225,7 +225,7 @@ async def generate(request: ImageRequest, api_key: Optional[str] = None):
|
|
225
225
|
from fastapi import HTTPException, status
|
226
226
|
raise HTTPException(
|
227
227
|
status_code=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
|
228
|
-
detail=f"Prompt is sensitive.\n\n{exc}",
|
228
|
+
detail=f"Prompt is sensitive.\n\n{request.prompt}\n\n{exc}",
|
229
229
|
)
|
230
230
|
|
231
231
|
|
meutils/apis/google/chat.py
CHANGED
@@ -242,7 +242,7 @@ class Completions(object):
|
|
242
242
|
else:
|
243
243
|
from fastapi import HTTPException, status
|
244
244
|
raise HTTPException(status_code=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
|
245
|
-
detail=f"Prompt is sensitive.\n\n{response}")
|
245
|
+
detail=f"Prompt is sensitive.\n\n{request.prompt}\n\n{response}")
|
246
246
|
|
247
247
|
async def create_for_images(self, request: CompletionRequest):
|
248
248
|
|
meutils/apis/google/images.py
CHANGED
@@ -51,7 +51,7 @@ async def openai_generate(request: ImageRequest, api_key: Optional[str] = None,
|
|
51
51
|
for image_url in image_urls or []
|
52
52
|
]
|
53
53
|
|
54
|
-
|
54
|
+
_request = CompletionRequest(
|
55
55
|
model=request.model,
|
56
56
|
stream=False,
|
57
57
|
max_tokens=None,
|
@@ -69,7 +69,7 @@ async def openai_generate(request: ImageRequest, api_key: Optional[str] = None,
|
|
69
69
|
],
|
70
70
|
)
|
71
71
|
|
72
|
-
data =
|
72
|
+
data = _request.model_dump(exclude_none=True)
|
73
73
|
|
74
74
|
client = AsyncOpenAI(
|
75
75
|
base_url=base_url,
|
@@ -113,7 +113,7 @@ async def openai_generate(request: ImageRequest, api_key: Optional[str] = None,
|
|
113
113
|
from fastapi import HTTPException, status
|
114
114
|
|
115
115
|
raise HTTPException(status_code=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
|
116
|
-
|
116
|
+
detail=f"Prompt is sensitive.\n\n{request.prompt}\n\n{completion}")
|
117
117
|
|
118
118
|
|
119
119
|
if __name__ == '__main__':
|
@@ -123,8 +123,7 @@ if __name__ == '__main__':
|
|
123
123
|
api_key = "sk-MAZ6SELJVtGNX6jgIcZBKuttsRibaDlAskFAnR7WD6PBSN6M"
|
124
124
|
base_url = "https://new.yunai.link/v1"
|
125
125
|
|
126
|
-
|
127
|
-
base_url="https://api.huandutech.com/v1"
|
126
|
+
base_url = "https://api.huandutech.com/v1"
|
128
127
|
api_key = "sk-qOpbMHesasoVgX75ZoeEeBEf1R9dmsUZVAPcu5KkvLFhElrn"
|
129
128
|
|
130
129
|
request = ImageRequest(
|
meutils/apis/meituan/__init__.py
CHANGED
meutils/apis/meituan/chat.py
CHANGED
@@ -9,27 +9,30 @@
|
|
9
9
|
# @Description : todo
|
10
10
|
|
11
11
|
|
12
|
-
from openai import AsyncOpenAI
|
12
|
+
from openai import AsyncOpenAI, OpenAI
|
13
13
|
|
14
14
|
from meutils.pipe import *
|
15
15
|
from meutils.decorators.retry import retrying
|
16
16
|
from meutils.io.files_utils import to_bytes, guess_mime_type
|
17
17
|
from meutils.caches import rcache
|
18
18
|
|
19
|
-
from meutils.llm.
|
19
|
+
from meutils.llm.utils import oneturn2multiturn
|
20
20
|
|
21
21
|
from meutils.config_utils.lark_utils import get_next_token_for_polling
|
22
22
|
from meutils.schemas.openai_types import chat_completion, chat_completion_chunk, CompletionRequest, CompletionUsage, \
|
23
|
-
ChatCompletion
|
23
|
+
ChatCompletion, ChatCompletionChunk
|
24
|
+
from openai._streaming import AsyncStream, Stream
|
24
25
|
|
25
26
|
base_url = "https://longcat.chat/api/v1/chat-completion"
|
26
27
|
base_url = "https://longcat.chat/api/v1/chat-completion-oversea"
|
27
28
|
base_url = "https://longcat.chat/api/v1"
|
28
29
|
|
30
|
+
cookie = "_lxsdk_cuid=1990e1e8790c8-0b2a66e23040a48-16525636-1fa400-1990e1e8790c8; passport_token_key=AgEGIygg22VuoMYTPonur9FA_-EVg9UXLu3LYOzJ4kIHSjQZeSNhwpytTU_cZFP6V1Juhk0CHMrAgwAAAABYLAAA9vXtnciaZBu2V99EMRJYRHTDSraV_OPLemUuVpi2WLsaa6RqC0PAKAOm6W_hIpbV"
|
31
|
+
|
29
32
|
|
30
33
|
class Completions(object):
|
31
34
|
def __init__(self, api_key: Optional[str] = None):
|
32
|
-
self.api_key = api_key
|
35
|
+
self.api_key = api_key or cookie
|
33
36
|
|
34
37
|
async def create(self, request: CompletionRequest, **kwargs):
|
35
38
|
payload = self.requset2payload(request)
|
@@ -47,28 +50,38 @@ class Completions(object):
|
|
47
50
|
response.raise_for_status()
|
48
51
|
|
49
52
|
async for chunk in response.aiter_lines():
|
50
|
-
|
53
|
+
if chunk := chunk.removeprefix("data:"):
|
54
|
+
_chunk = json.loads(chunk)
|
55
|
+
|
56
|
+
chat_completion_chunk = ChatCompletionChunk.model_validate(_chunk)
|
57
|
+
# logger.debug(chunk)
|
58
|
+
|
59
|
+
yield chat_completion_chunk
|
60
|
+
|
61
|
+
if not request.stream:
|
62
|
+
# logger.debug(_chunk)
|
63
|
+
model = _chunk.get("model", "LongCat-Flash")
|
64
|
+
content = _chunk.get("content", "")
|
65
|
+
reason_content = _chunk.get("reasonContent", "")
|
66
|
+
token_info = _chunk.get("tokenInfo", {})
|
67
|
+
|
68
|
+
chat_completion_chunk.choices[0].content = content
|
69
|
+
chat_completion_chunk.choices[0].reason_content = reason_content
|
70
|
+
usage = CompletionUsage(
|
71
|
+
prompt_tokens=token_info.get("promptTokens"),
|
72
|
+
completion_tokens=token_info.get("completionTokens")
|
73
|
+
)
|
74
|
+
chat_completion.model = model
|
75
|
+
chat_completion.usage = usage
|
76
|
+
chat_completion.choices = chat_completion_chunk.choices
|
77
|
+
# logger.debug(chat_completion)
|
78
|
+
yield chat_completion
|
51
79
|
|
52
80
|
def requset2payload(self, request: CompletionRequest):
|
53
81
|
payload = {
|
54
|
-
"content": request
|
55
|
-
"messages":
|
56
|
-
|
57
|
-
# "role": "user",
|
58
|
-
# "content": "hi",
|
59
|
-
# "chatStatus": "FINISHED",
|
60
|
-
# "messageId": 11263291,
|
61
|
-
# "idType": "custom"
|
62
|
-
# },
|
63
|
-
# {
|
64
|
-
# "role": "assistant",
|
65
|
-
# "content": "",
|
66
|
-
# "chatStatus": "LOADING",
|
67
|
-
# "messageId": 92193819,
|
68
|
-
# "idType": "custom"
|
69
|
-
# }
|
70
|
-
],
|
71
|
-
"reasonEnabled": 0,
|
82
|
+
"content": oneturn2multiturn(request), # todo: 多轮
|
83
|
+
# "messages": request.messages,
|
84
|
+
"reasonEnabled": request.enable_thinking and 1 or 0,
|
72
85
|
"searchEnabled": 0,
|
73
86
|
"regenerate": 0
|
74
87
|
}
|
@@ -103,7 +116,29 @@ class Completions(object):
|
|
103
116
|
if __name__ == '__main__':
|
104
117
|
cookie = "_lxsdk_cuid=1990e1e8790c8-0b2a66e23040a48-16525636-1fa400-1990e1e8790c8; passport_token_key=AgEGIygg22VuoMYTPonur9FA_-EVg9UXLu3LYOzJ4kIHSjQZeSNhwpytTU_cZFP6V1Juhk0CHMrAgwAAAABYLAAA9vXtnciaZBu2V99EMRJYRHTDSraV_OPLemUuVpi2WLsaa6RqC0PAKAOm6W_hIpbV"
|
105
118
|
request = CompletionRequest(
|
106
|
-
messages=[
|
119
|
+
messages=[
|
120
|
+
{'role': 'user', 'content': '1+1'},
|
121
|
+
{'role': 'assistant', 'content': '2'},
|
122
|
+
{'role': 'user', 'content': '裸体傻女'},
|
123
|
+
]
|
107
124
|
)
|
108
125
|
arun(Completions(api_key=cookie).create(request))
|
109
126
|
# arun(Completions(api_key=cookie).create_chat())
|
127
|
+
|
128
|
+
# payload = {
|
129
|
+
# "content": "1+1",
|
130
|
+
# "messages": [
|
131
|
+
# {
|
132
|
+
# "role": "user",
|
133
|
+
# "content": "1+1",
|
134
|
+
# "chatStatus": "FINISHED",
|
135
|
+
# "messageId": 0,
|
136
|
+
# "idType": "system"
|
137
|
+
# }
|
138
|
+
# ],
|
139
|
+
# "reasonEnabled": 0,
|
140
|
+
# "searchEnabled": 0,
|
141
|
+
# "regenerate": 0
|
142
|
+
# }
|
143
|
+
#
|
144
|
+
# Completions(api_key=cookie).stream_create(payload)
|
meutils/apis/oneapi/channel.py
CHANGED
@@ -19,6 +19,23 @@ headers = {
|
|
19
19
|
'rix-api-user': '1',
|
20
20
|
}
|
21
21
|
|
22
|
+
"https://api.ffire.cc/api/channel/multi_key/manage"
|
23
|
+
|
24
|
+
|
25
|
+
async def manage_multi_key(id: int, base_url: str, action: str = "enable_all_keys") -> ChannelInfo:
|
26
|
+
# "disable_all_keys"
|
27
|
+
payload = {
|
28
|
+
"channel_id": id,
|
29
|
+
"action": action
|
30
|
+
}
|
31
|
+
async with httpx.AsyncClient(base_url=base_url, headers=headers, timeout=30) as client:
|
32
|
+
response = await client.post("/api/channel/multi_key/manage", json=payload)
|
33
|
+
response.raise_for_status()
|
34
|
+
|
35
|
+
data = response.json()
|
36
|
+
logger.debug(bjson(data))
|
37
|
+
return data
|
38
|
+
|
22
39
|
|
23
40
|
async def get_channel_info(id: int, base_url: str) -> ChannelInfo:
|
24
41
|
params = {"keyword": id} # keyword=21222&group=&model=&id_sort=true&tag_mode=false&p=1&page_size=100
|
@@ -28,7 +45,7 @@ async def get_channel_info(id: int, base_url: str) -> ChannelInfo:
|
|
28
45
|
response.raise_for_status()
|
29
46
|
|
30
47
|
data = response.json()
|
31
|
-
|
48
|
+
logger.debug(bjson(data))
|
32
49
|
if (items := data.get("data", {}).get("items", [])) and (item := items[0]):
|
33
50
|
return item['status'] # status==1 是正常
|
34
51
|
|
@@ -176,7 +193,12 @@ async def create_or_update_channel(
|
|
176
193
|
logger.debug(response.text)
|
177
194
|
|
178
195
|
response.raise_for_status()
|
179
|
-
|
196
|
+
|
197
|
+
data = response.json()
|
198
|
+
logger.debug(bjson(data))
|
199
|
+
if (data := data.get("data")) and data['channel_info']['is_multi_key']:
|
200
|
+
await manage_multi_key(data['id'], base_url=base_url)
|
201
|
+
|
180
202
|
return response.json()
|
181
203
|
|
182
204
|
|
@@ -268,15 +290,20 @@ if __name__ == '__main__':
|
|
268
290
|
# arun(create_or_update_channel(tokens, base_url))
|
269
291
|
# arun(create_or_update_channel(tokens))
|
270
292
|
# # arun(delete_channel(range(10000, 20000)))
|
271
|
-
key = "KEY"
|
272
|
-
request = ChannelInfo(name='', key=key)
|
273
|
-
request = ChannelInfo(id=21223, key=key, used_quota=0.001)
|
274
|
-
|
275
|
-
|
293
|
+
key = "KEY\nKEY2"
|
294
|
+
# request = ChannelInfo(id = 1, name='xx', key=key)
|
295
|
+
# request = ChannelInfo(id=21223, key=key, used_quota=0.001)
|
296
|
+
request = ChannelInfo(id=29483, key=key, used_quota=0.001,
|
297
|
+
# key_mode="append"
|
298
|
+
)
|
299
|
+
|
300
|
+
arun(create_or_update_channel(request, base_url=base_url))
|
276
301
|
#
|
277
302
|
# arun(exist_channel(request, base_url=base_url))
|
278
303
|
|
279
|
-
arun(get_channel_info(21222, base_url=base_url))
|
280
|
-
# arun(get_channel_info(
|
304
|
+
# arun(get_channel_info(21222, base_url=base_url))
|
305
|
+
# arun(get_channel_info(29483, base_url=base_url))
|
281
306
|
|
282
307
|
# arun(delete_channel(range(10015, 10032), base_url=base_url))
|
308
|
+
|
309
|
+
# arun(manage_multi_key(29483, base_url=base_url))
|
@@ -22,7 +22,6 @@ from meutils.schemas.image_types import ImageRequest, ImagesResponse
|
|
22
22
|
from volcengine.visual.VisualService import VisualService
|
23
23
|
|
24
24
|
|
25
|
-
@retrying()
|
26
25
|
async def generate(request: ImageRequest, token: Optional[str] = None):
|
27
26
|
"""
|
28
27
|
|
@@ -65,9 +64,16 @@ async def generate(request: ImageRequest, token: Optional[str] = None):
|
|
65
64
|
|
66
65
|
if request.response_format == "oss_url":
|
67
66
|
payload["return_url"] = False
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
try:
|
68
|
+
response = visual_service.cv_process(payload)
|
69
|
+
logger.debug(bjson(response))
|
70
|
+
except Exception as exc: #
|
71
|
+
logger.error(exc)
|
72
|
+
from fastapi import HTTPException, status
|
73
|
+
raise HTTPException(
|
74
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
75
|
+
detail=f"Prompt is sensitive.\n\n{request.prompt}\n\n{exc}",
|
76
|
+
)
|
71
77
|
|
72
78
|
if request.response_format == "b64_json":
|
73
79
|
data = [{"b64_json": b64_json} for b64_json in response['data'].get('binary_data_base64', [])]
|
@@ -97,6 +103,7 @@ if __name__ == '__main__':
|
|
97
103
|
|
98
104
|
让这个女人带上眼镜 衣服换个颜色
|
99
105
|
"""
|
106
|
+
prompt = "裸体女孩"
|
100
107
|
|
101
108
|
request = ImageRequest(
|
102
109
|
# model="high_aes_general_v30l_zt2i",
|
@@ -7,19 +7,17 @@
|
|
7
7
|
# @WeChat : meutils
|
8
8
|
# @Software : PyCharm
|
9
9
|
# @Description :
|
10
|
-
import time
|
11
10
|
|
12
11
|
from meutils.pipe import *
|
13
12
|
from meutils.io.files_utils import to_url
|
14
13
|
from meutils.decorators.retry import retrying
|
14
|
+
|
15
15
|
from meutils.llm.clients import AsyncClient
|
16
16
|
from meutils.schemas.openai_types import CompletionRequest
|
17
17
|
from meutils.schemas.video_types import VideoRequest
|
18
18
|
|
19
|
-
from meutils.notice.feishu import send_message_for_volc as send_message
|
20
|
-
|
21
19
|
from meutils.db.redis_db import redis_aclient
|
22
|
-
from meutils.llm.check_utils import check_token_for_volc
|
20
|
+
from meutils.llm.check_utils import check_token_for_volc
|
23
21
|
from meutils.config_utils.lark_utils import get_next_token_for_polling, get_series
|
24
22
|
|
25
23
|
from fastapi import APIRouter, File, UploadFile, Query, Form, Depends, Request, HTTPException, status, BackgroundTasks
|
@@ -28,31 +26,29 @@ from fastapi import APIRouter, File, UploadFile, Query, Form, Depends, Request,
|
|
28
26
|
FEISHU_URL = "https://xchatllm.feishu.cn/sheets/GYCHsvI4qhnDPNtI4VPcdw2knEd?sheet=8W6kk8" # 超刷
|
29
27
|
|
30
28
|
|
31
|
-
async def get_valid_token(tokens: Optional[list] = None,
|
29
|
+
async def get_valid_token(tokens: Optional[list] = None, batch_size: Optional[int] = None, seed: int = 0):
|
30
|
+
"""返回 tokens
|
31
|
+
1. 从redis获取token
|
32
|
+
2. 校验token
|
33
|
+
3. 校验失败则从飞书获取token
|
34
|
+
4. 校验token
|
35
|
+
5. 校验通过则返回token
|
36
|
+
"""
|
32
37
|
tokens = tokens or await get_series(FEISHU_URL, duplicated=True)
|
38
|
+
batch_size = batch_size or 1
|
33
39
|
|
34
|
-
if
|
35
|
-
|
36
|
-
|
37
|
-
if force_update: # 强制检测更新
|
38
|
-
if await check(token):
|
39
|
-
return token
|
40
|
-
else:
|
41
|
-
await redis_aclient.delete("volc-token") # 删除无效
|
42
|
-
else:
|
43
|
-
return token
|
44
|
-
for i, token in enumerate(tokens, 1):
|
45
|
-
if await check(token):
|
46
|
-
await redis_aclient.set("volc-token", token, ex=2 * 3600 - 10 * 60)
|
47
|
-
|
48
|
-
return token
|
49
|
-
if batch_size == i:
|
50
|
-
break
|
40
|
+
if seed == 0 and (volc_tokens := await redis_aclient.get(f"volc_tokens")):
|
41
|
+
return volc_tokens.decode()
|
51
42
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
43
|
+
valid_tokens = []
|
44
|
+
for token in tokens:
|
45
|
+
if token := await check_token_for_volc([token]):
|
46
|
+
valid_tokens += token
|
47
|
+
logger.debug(valid_tokens)
|
48
|
+
if len(valid_tokens) == batch_size:
|
49
|
+
_ = '\n'.join(valid_tokens)
|
50
|
+
await redis_aclient.set(f"volc_tokens", _, ex=2 * 3600)
|
51
|
+
return _
|
56
52
|
|
57
53
|
|
58
54
|
# check_image_and_video = partial(check, purpose='video and image')
|
@@ -61,7 +57,9 @@ async def get_valid_token(tokens: Optional[list] = None, force_update: bool = Tr
|
|
61
57
|
@retrying()
|
62
58
|
async def create_task(request: Union[CompletionRequest, VideoRequest], api_key: Optional[str] = None):
|
63
59
|
# api_key = api_key or await get_next_token_for_polling(feishu_url=FEISHU_URL, check_token=check)
|
64
|
-
api_key = api_key or await get_valid_token(
|
60
|
+
api_key = api_key or await get_valid_token()
|
61
|
+
|
62
|
+
api_key = np.random.choice(api_key.split('\n'))
|
65
63
|
|
66
64
|
# feishu_url = "https://xchatllm.feishu.cn/sheets/Z59Js10DbhT8wdt72LachSDlnlf?sheet=rcoDg7"
|
67
65
|
# api_key = api_key or await get_next_token_for_polling(
|
@@ -267,7 +265,8 @@ c4356b58-4aa3-4a52-b907-b40c4dd2e502
|
|
267
265
|
# arun(get_task_from_feishu(ids, tokens))
|
268
266
|
# arun(get_task_from_feishu(ids, ))
|
269
267
|
|
270
|
-
arun(get_valid_token())
|
268
|
+
# arun(get_valid_token(['a93ea9a5-3831-47b8-863a-57e10233f922']))
|
269
|
+
arun(get_valid_token(batch_size=2, seed=3))
|
271
270
|
|
272
271
|
"""
|
273
272
|
{'id': 'cgt-20250613160030-2dvd7',
|
meutils/data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2025.09.
|
1
|
+
2025.09.09.15.11.11
|
meutils/llm/check_utils.py
CHANGED
@@ -176,7 +176,7 @@ async def check_token_for_ppinfra(api_key, threshold: float = 1): # 1块钱 100
|
|
176
176
|
if not isinstance(api_key, str):
|
177
177
|
return await check_tokens(api_key, partial(check_token_for_ppinfra, threshold=threshold))
|
178
178
|
try:
|
179
|
-
client = AsyncOpenAI(base_url="https://api.ppinfra.com/v3/user", api_key=api_key)
|
179
|
+
client = AsyncOpenAI(base_url="https://api.ppinfra.com/v3/user", api_key=api_key.strip())
|
180
180
|
data = await client.get("", cast_to=object)
|
181
181
|
logger.debug(data) # credit_balance
|
182
182
|
return data["credit_balance"] >= threshold
|
@@ -214,7 +214,7 @@ async def check_token_for_sophnet(api_key, threshold: float = 1):
|
|
214
214
|
|
215
215
|
#
|
216
216
|
@retrying()
|
217
|
-
|
217
|
+
@rcache(ttl=7 * 24 * 3600, skip_cache_func=skip_cache_func)
|
218
218
|
async def check_token_for_volc(api_key, threshold: float = 1, purpose: Optional[str] = None):
|
219
219
|
if not isinstance(api_key, str):
|
220
220
|
return await check_tokens(api_key, check_token_for_volc)
|
meutils/llm/utils.py
CHANGED
@@ -8,16 +8,13 @@
|
|
8
8
|
# @Software : PyCharm
|
9
9
|
# @Description :
|
10
10
|
|
11
|
-
from contextlib import asynccontextmanager
|
12
11
|
|
13
12
|
from meutils.pipe import *
|
14
|
-
from meutils.
|
15
|
-
from meutils.schemas.oneapi import MODEL_PRICE
|
16
|
-
from meutils.notice.feishu import send_message
|
17
|
-
from meutils.apis.oneapi.utils import get_user_quota
|
13
|
+
from meutils.schemas.openai_types import CompletionRequest
|
18
14
|
|
19
15
|
|
20
|
-
|
16
|
+
|
17
|
+
def oneturn2multiturn(messages: Union[dict, CompletionRequest], template: Optional[str] = None, ignore_system: bool = True):
|
21
18
|
"""todo: https://github.com/hiyouga/LLaMA-Factory/blob/e898fabbe3efcd8b44d0e119e7afaed4542a9f39/src/llmtuner/data/template.py#L423-L427
|
22
19
|
|
23
20
|
_register_template(
|
@@ -45,6 +42,10 @@ def oneturn2multiturn(messages, template: Optional[str] = None, ignore_system: b
|
|
45
42
|
# role, content = message.get("role"), message.get("content")
|
46
43
|
# context += f"<|im_start|>{role}\n{content}<|im_end|>\n"
|
47
44
|
# context += "<|im_start|>assistant\n"
|
45
|
+
if isinstance(messages, CompletionRequest):
|
46
|
+
messages = messages.messages
|
47
|
+
|
48
|
+
|
48
49
|
if len(messages) == 1:
|
49
50
|
content = messages[0].get("content")
|
50
51
|
if isinstance(content, list):
|
@@ -53,6 +54,7 @@ def oneturn2multiturn(messages, template: Optional[str] = None, ignore_system: b
|
|
53
54
|
|
54
55
|
context = "\n"
|
55
56
|
for message in messages:
|
57
|
+
logger.info(message)
|
56
58
|
role = message.get("role")
|
57
59
|
content = message.get("content")
|
58
60
|
|
meutils/schemas/oneapi/_types.py
CHANGED
@@ -91,9 +91,9 @@ class ChannelInfo(BaseModel):
|
|
91
91
|
# new
|
92
92
|
max_input_tokens: int = 0
|
93
93
|
|
94
|
-
mode:Optional[Literal["multi_to_single"]] = None
|
94
|
+
mode: Optional[Literal["multi_to_single"]] = None
|
95
95
|
multi_key_mode: Literal['random', 'polling'] = "polling"
|
96
|
-
key_mode: Optional[Literal['append', 'replace']] = None
|
96
|
+
key_mode: Optional[Literal['append', 'replace']] = None # none是覆盖
|
97
97
|
|
98
98
|
def __init__(self, /, **data: Any):
|
99
99
|
super().__init__(**data)
|
meutils/schemas/oneapi/common.py
CHANGED
@@ -29,6 +29,7 @@ FAL_MODELS = {
|
|
29
29
|
"fal-ai/clarity-upscaler": 1, # Your request will cost $0.03 per upscaled megapixel.
|
30
30
|
|
31
31
|
'fal-kling-video-lipsync-audio-to-video': 0.5,
|
32
|
+
'fal-ai/kling-video/lipsync/text-to-video': 0.14 * FAL,
|
32
33
|
|
33
34
|
'fal-pixverse-v4.5-effects': 1,
|
34
35
|
'fal-pixverse-v4.5-text-to-video': 0.9,
|