MeUtils 2025.7.28.19.31.30__py3-none-any.whl → 2025.8.5.10.8.29__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 +7 -3
- examples/_openaisdk/openai_modelscope.py +8 -80
- examples/_openaisdk/openai_zhipu.py +3 -3
- examples/vllms/__init__.py +11 -0
- meutils/apis/fal/audio.py +20 -13
- meutils/apis/gitee/image_to_3d.py +63 -10
- meutils/apis/images/generations.py +4 -0
- meutils/apis/models.py +8 -5
- meutils/apis/ppio/__init__.py +0 -1
- meutils/apis/ppio/audio.py +109 -0
- meutils/apis/ppio/videos.py +2 -2
- meutils/apis/proxy/ips.py +3 -3
- meutils/apis/volcengine_apis/videos.py +2 -2
- meutils/data/VERSION +1 -1
- meutils/llm/check_utils.py +1 -1
- meutils/schemas/image_types.py +3 -3
- meutils/schemas/oneapi/common.py +49 -8
- meutils-2025.8.5.10.8.29.dist-info/METADATA +724 -0
- {MeUtils-2025.7.28.19.31.30.dist-info → meutils-2025.8.5.10.8.29.dist-info}/RECORD +23 -21
- {MeUtils-2025.7.28.19.31.30.dist-info → meutils-2025.8.5.10.8.29.dist-info}/WHEEL +1 -1
- MeUtils-2025.7.28.19.31.30.dist-info/METADATA +0 -708
- {MeUtils-2025.7.28.19.31.30.dist-info → meutils-2025.8.5.10.8.29.dist-info}/entry_points.txt +0 -0
- {MeUtils-2025.7.28.19.31.30.dist-info → meutils-2025.8.5.10.8.29.dist-info/licenses}/LICENSE +0 -0
- {MeUtils-2025.7.28.19.31.30.dist-info → meutils-2025.8.5.10.8.29.dist-info}/top_level.txt +0 -0
@@ -15,14 +15,16 @@ from openai import OpenAI, APIStatusError
|
|
15
15
|
|
16
16
|
client = OpenAI(
|
17
17
|
base_url=os.getenv("FFIRE_BASE_URL"),
|
18
|
-
api_key=os.getenv("FFIRE_API_KEY")
|
18
|
+
api_key=os.getenv("FFIRE_API_KEY")#+"-1101"
|
19
19
|
)
|
20
20
|
|
21
21
|
for i in range(10):
|
22
22
|
try:
|
23
23
|
completion = client.chat.completions.create(
|
24
|
-
model="kimi-k2-0711-preview",
|
24
|
+
# model="kimi-k2-0711-preview",
|
25
25
|
# model="deepseek-reasoner",
|
26
|
+
model="xx",
|
27
|
+
|
26
28
|
messages=[
|
27
29
|
{"role": "user", "content": 'hi'}
|
28
30
|
],
|
@@ -30,8 +32,10 @@ for i in range(10):
|
|
30
32
|
top_p=None,
|
31
33
|
temperature=None,
|
32
34
|
# stream=True,
|
33
|
-
max_tokens=1000
|
35
|
+
max_tokens=1000,
|
36
|
+
extra_body={"xx": "xxxxxxxx"}
|
34
37
|
)
|
38
|
+
print(completion)
|
35
39
|
except Exception as e:
|
36
40
|
print(e)
|
37
41
|
|
@@ -52,7 +52,9 @@ def main():
|
|
52
52
|
try:
|
53
53
|
completion = client.chat.completions.create(
|
54
54
|
# model="step-1-8k",
|
55
|
-
model="deepseek-ai/DeepSeek-R1-0528",
|
55
|
+
# model="deepseek-ai/DeepSeek-R1-0528",
|
56
|
+
# model="deepseek-ai/DeepSeek-R1-0528",
|
57
|
+
model="ZhipuAI/GLM-4.5",
|
56
58
|
|
57
59
|
# model="Qwen/QVQ-72B-Preview",
|
58
60
|
# model="qwen/qvq-72b-preview",
|
@@ -64,7 +66,7 @@ def main():
|
|
64
66
|
top_p=None,
|
65
67
|
temperature=None,
|
66
68
|
stream=True,
|
67
|
-
max_tokens=
|
69
|
+
max_tokens=100
|
68
70
|
)
|
69
71
|
except APIStatusError as e:
|
70
72
|
print(e.status_code)
|
@@ -80,81 +82,7 @@ def main():
|
|
80
82
|
print(chunk)
|
81
83
|
|
82
84
|
|
83
|
-
|
84
|
-
|
85
|
-
#
|
86
|
-
|
87
|
-
|
88
|
-
"""
|
89
|
-
|
90
|
-
UPSTREAM_BASE_URL=https://api.chatfire.cn
|
91
|
-
UPSTREAM_API_KEY=
|
92
|
-
|
93
|
-
API_KEY=https://xchatllm.feishu.cn/sheets/MekfsfVuohfUf1tsWV0cCvTmn3c?sheet=305f17[:20]
|
94
|
-
BASE_URL=https://api-inference.modelscope.cn
|
95
|
-
|
96
|
-
|
97
|
-
curl -X 'POST' http://openai-dev.chatfire.cn/oneapi/channel \
|
98
|
-
-H "Authorization: Bearer $API_KEY" \
|
99
|
-
-H "UPSTREAM-BASE-URL: $UPSTREAM_BASE_URL" \
|
100
|
-
-H "UPSTREAM-API-KEY: $UPSTREAM_API_KEY" \
|
101
|
-
-H 'accept: application/json' \
|
102
|
-
-H 'Content-Type: application/json' \
|
103
|
-
-d '{
|
104
|
-
"id": "1:20",
|
105
|
-
"name": "modelscope",
|
106
|
-
"tag": "modelscope",
|
107
|
-
"key": "$KEY",
|
108
|
-
"type": 0,
|
109
|
-
|
110
|
-
"base_url": "'$BASE_URL'",
|
111
|
-
"group": "default,china",
|
112
|
-
|
113
|
-
"models": "deepseek-r1-distill-qwen-14b,deepseek-r1-distill-llama-70b,deepseek-r1,deepseek-r1-0528,deepseek-r1-250528,deepseek-chat,deepseek-v3,deepseek-v3-0324,deepseek-v3-250324,PaddlePaddle/ERNIE-4.5-21B-A3B-PT,PaddlePaddle/ERNIE-4.5-0.3B-PT,PaddlePaddle/ERNIE-4.5-VL-28B-A3B-PT,PaddlePaddle/ERNIE-4.5-300B-A47B-PT,qwen2.5-coder-32b-instruct,qwen2.5-coder-14b-instruct,qwen2.5-coder-7b-instruct,qwen2.5-72b-instruct,qwen2.5-32b-instruct,qwen2.5-14b-instruct,qwen2.5-7b-instruct,qwq-32b-preview,qvq-72b-preview,qwen2-vl-7b-instruct,qwen2.5-14b-instruct-1m,qwen2.5-7b-instruct-1m,qwen2.5-vl-3b-instruct,qwen2.5-vl-7b-instruct,qwen2.5-vl-72b-instruct,qwq-32b,qwen2.5-vl-32b-instruct,qwen3-0.6b,qwen3-1.7b,qwen3-4b,qwen3-8b,qwen3-14b,qwen3-30b-a3b,qwen3-32b,qwen3-235b-a22b",
|
114
|
-
"model_mapping": {
|
115
|
-
"deepseek-reasoner": "deepseek-ai/DeepSeek-R1-0528",
|
116
|
-
"deepseek-r1": "deepseek-ai/DeepSeek-R1-0528",
|
117
|
-
"deepseek-r1-0528": "deepseek-ai/DeepSeek-R1-0528",
|
118
|
-
"deepseek-r1-250528": "deepseek-ai/DeepSeek-R1-0528",
|
119
|
-
|
120
|
-
"deepseek-chat": "deepseek-ai/DeepSeek-V3",
|
121
|
-
"deepseek-v3": "deepseek-ai/DeepSeek-V3",
|
122
|
-
"deepseek-v3-0324": "deepseek-ai/DeepSeek-V3-0324",
|
123
|
-
"deepseek-v3-250324": "deepseek-ai/DeepSeek-V3-0324",
|
124
|
-
|
125
|
-
"deepseek-r1-distill-qwen-14b": "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B",
|
126
|
-
"deepseek-r1-distill-llama-70b": "deepseek-ai/DeepSeek-R1-Distill-Llama-70B",
|
127
|
-
|
128
|
-
"majicflus_v1": "MAILAND/majicflus_v1",
|
129
|
-
|
130
|
-
"qwen2.5-coder-32b-instruct": "Qwen/Qwen2.5-Coder-32B-Instruct",
|
131
|
-
"qwen2.5-coder-14b-instruct": "Qwen/Qwen2.5-Coder-14B-Instruct",
|
132
|
-
"qwen2.5-coder-7b-instruct": "Qwen/Qwen2.5-Coder-7B-Instruct",
|
133
|
-
"qwen2.5-72b-instruct": "Qwen/Qwen2.5-72B-Instruct",
|
134
|
-
"qwen2.5-32b-instruct": "Qwen/Qwen2.5-32B-Instruct",
|
135
|
-
"qwen2.5-14b-instruct": "Qwen/Qwen2.5-14B-Instruct",
|
136
|
-
"qwen2.5-7b-instruct": "Qwen/Qwen2.5-7B-Instruct",
|
137
|
-
"qwq-32b-preview": "Qwen/QwQ-32B-Preview",
|
138
|
-
"qvq-72b-preview": "Qwen/QVQ-72B-Preview",
|
139
|
-
"qwen2-vl-7b-instruct": "Qwen/Qwen2-VL-7B-Instruct",
|
140
|
-
"qwen2.5-14b-instruct-1m": "Qwen/Qwen2.5-14B-Instruct-1M",
|
141
|
-
"qwen2.5-7b-instruct-1m": "Qwen/Qwen2.5-7B-Instruct-1M",
|
142
|
-
"qwen2.5-vl-3b-instruct": "Qwen/Qwen2.5-VL-3B-Instruct",
|
143
|
-
"qwen2.5-vl-7b-instruct": "Qwen/Qwen2.5-VL-7B-Instruct",
|
144
|
-
"qwen2.5-vl-72b-instruct": "Qwen/Qwen2.5-VL-72B-Instruct",
|
145
|
-
"qwq-32b": "Qwen/QwQ-32B",
|
146
|
-
"qwen2.5-vl-32b-instruct": "Qwen/Qwen2.5-VL-32B-Instruct",
|
147
|
-
"qwen3-0.6b": "Qwen/Qwen3-0.6B",
|
148
|
-
"qwen3-1.7b": "Qwen/Qwen3-1.7B",
|
149
|
-
"qwen3-4b": "Qwen/Qwen3-4B",
|
150
|
-
"qwen3-8b": "Qwen/Qwen3-8B",
|
151
|
-
"qwen3-14b": "Qwen/Qwen3-14B",
|
152
|
-
"qwen3-30b-a3b": "Qwen/Qwen3-30B-A3B",
|
153
|
-
"qwen3-32b": "Qwen/Qwen3-32B",
|
154
|
-
"qwen3-235b-a22b": "Qwen/Qwen3-235B-A22B"
|
155
|
-
|
156
|
-
}
|
157
|
-
|
158
|
-
}'
|
159
|
-
|
160
|
-
"""
|
85
|
+
if __name__ == '__main__':
|
86
|
+
for i in tqdm(range(1)):
|
87
|
+
# break
|
88
|
+
main()
|
@@ -16,8 +16,8 @@ from openai import OpenAI, APIStatusError
|
|
16
16
|
|
17
17
|
client = OpenAI(
|
18
18
|
# base_url="https://free.chatfire.cn/v1",
|
19
|
-
api_key="
|
20
|
-
base_url="https://open.bigmodel.cn/api/paas/v4
|
19
|
+
api_key="e21bd630f681c4d90b390cd609720483.WSFVgA3KkwNCX0mN",
|
20
|
+
base_url="https://open.bigmodel.cn/api/paas/v4"
|
21
21
|
|
22
22
|
# api_key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI3YmFmYWQzYTRmZDU0OTk3YjNmYmNmYjExMjY5NThmZiIsImV4cCI6MTczODAyNDg4MiwibmJmIjoxNzIyNDcyODgyLCJpYXQiOjE3MjI0NzI4ODIsImp0aSI6IjY5Y2ZiNzgzNjRjODQxYjA5Mjg1OTgxYmY4ODMzZDllIiwidWlkIjoiNjVmMDc1Y2E4NWM3NDFiOGU2ZmRjYjEyIiwidHlwZSI6InJlZnJlc2gifQ.u9pIfuQZ7Y00DB6x3rbWYomwQGEyYDSE-814k67SH74",
|
23
23
|
# base_url="https://any2chat.chatfire.cn/glm/v1"
|
@@ -29,7 +29,7 @@ A Chinese beauty plays Catwoman. She is seductive. She wears a fitted black leat
|
|
29
29
|
|
30
30
|
try:
|
31
31
|
completion = client.chat.completions.create(
|
32
|
-
model="glm-4
|
32
|
+
model="glm-4.5",
|
33
33
|
# model="xxxxxxxxxxxxx",
|
34
34
|
messages=[
|
35
35
|
{"role": "system", "content": '你是个内容审核助手'},
|
meutils/apis/fal/audio.py
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
from openai import AsyncOpenAI
|
13
13
|
|
14
14
|
from meutils.pipe import *
|
15
|
-
from meutils.io.files_utils import to_url
|
15
|
+
from meutils.io.files_utils import to_url, to_bytes
|
16
16
|
from meutils.llm.clients import AsyncOpenAI
|
17
17
|
from meutils.llm.openai_utils import to_openai_params
|
18
18
|
from meutils.llm.check_utils import get_valid_token_for_fal
|
@@ -47,21 +47,23 @@ from fal_client.client import AsyncClient, SyncClient, Status, FalClientError
|
|
47
47
|
|
48
48
|
# "fal-ai/minimax/speech-02-turbo"
|
49
49
|
async def text_to_speech(request: TTSRequest, api_key: Optional[str] = None):
|
50
|
+
if isinstance(api_key, str) and api_key.startswith("oneapi:"):
|
51
|
+
api_key = api_key.removeprefix("oneapi:")
|
52
|
+
|
50
53
|
api_key = api_key or await get_valid_token_for_fal()
|
51
54
|
|
55
|
+
payload = request.model_dump(exclude_none=True)
|
52
56
|
payload = {
|
53
|
-
|
54
57
|
"text": request.input,
|
55
|
-
"
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
# **request.model_dump(exclude_none=True)
|
58
|
+
"stream": False,
|
59
|
+
"output_format": request.response_format if request.response_format in {"url", "hex"} else "hex",
|
60
|
+
"voice_setting":
|
61
|
+
{
|
62
|
+
"speed": request.speed or 1,
|
63
|
+
"voice_id": request.voice or "wumei_yujie",
|
64
|
+
"emotion": "happy"
|
65
|
+
},
|
66
|
+
**payload
|
65
67
|
}
|
66
68
|
|
67
69
|
try:
|
@@ -70,8 +72,13 @@ async def text_to_speech(request: TTSRequest, api_key: Optional[str] = None):
|
|
70
72
|
application=request.model,
|
71
73
|
arguments=payload,
|
72
74
|
)
|
75
|
+
# {'audio': {'url': 'https://v3.fal.media/files/zebra/wTM2HIdYkQTl0q5qdTDl9_speech.mp3', 'content_type': 'audio/mpeg', 'file_name': 'speech.mp3', 'file_size': 64034}, 'duration_ms': 3888}
|
73
76
|
logger.debug(data)
|
74
77
|
|
78
|
+
if request.response_format not in {"url", "hex"}:
|
79
|
+
_ = await to_bytes(data["audio"]["url"])
|
80
|
+
return _
|
81
|
+
|
75
82
|
except Exception as exc: #
|
76
83
|
logger.error(exc)
|
77
84
|
from fastapi import HTTPException, status
|
@@ -88,7 +95,7 @@ if __name__ == '__main__':
|
|
88
95
|
"input": "根据 prompt audio url克隆音色",
|
89
96
|
# "response_format": "url"
|
90
97
|
|
91
|
-
"voice": "Wise_Woman"
|
98
|
+
# "voice": "Wise_Woman"
|
92
99
|
}
|
93
100
|
|
94
101
|
request = TTSRequest(**data)
|
@@ -10,8 +10,12 @@
|
|
10
10
|
|
11
11
|
from meutils.pipe import *
|
12
12
|
from meutils.db.redis_db import redis_aclient
|
13
|
+
from meutils.io.files_utils import to_bytes
|
14
|
+
|
13
15
|
from meutils.apis.utils import make_request_httpx
|
14
16
|
from meutils.schemas.gitee_types import FEISHU_URL, BASE_URL
|
17
|
+
from meutils.schemas.image_types import ImageRequest, ImagesResponse
|
18
|
+
|
15
19
|
from meutils.config_utils.lark_utils import get_next_token_for_polling
|
16
20
|
|
17
21
|
"""
|
@@ -23,6 +27,9 @@ curl https://ai.gitee.com/v1/async/image-to-3d \
|
|
23
27
|
-F "model=Hi3DGen" \
|
24
28
|
-F "seed=1234" \
|
25
29
|
-F "file_format=glb"
|
30
|
+
|
31
|
+
|
32
|
+
texture=true 带纹理
|
26
33
|
"""
|
27
34
|
|
28
35
|
|
@@ -58,12 +65,7 @@ async def create_task(image, data: Optional[dict] = None, api_key: Optional[str]
|
|
58
65
|
"Authorization": f"Bearer {api_key}",
|
59
66
|
}
|
60
67
|
|
61
|
-
|
62
|
-
"type": "glb",
|
63
|
-
"model": "Hi3DGen",
|
64
|
-
"seed": 1234,
|
65
|
-
"file_format": "glb",
|
66
|
-
}
|
68
|
+
# (filename, file_bytes, mime_type) = image
|
67
69
|
|
68
70
|
response = await make_request_httpx(
|
69
71
|
base_url=BASE_URL,
|
@@ -84,15 +86,66 @@ async def create_task(image, data: Optional[dict] = None, api_key: Optional[str]
|
|
84
86
|
{'task_id': 'GB84DX8LK6NUJ0WHZLUNRCXDBFKMVVFH'}
|
85
87
|
|
86
88
|
"""
|
89
|
+
logger.debug(response)
|
87
90
|
if task_id := response.get("task_id"):
|
88
91
|
await redis_aclient.set(task_id, api_key, ex=24 * 3600)
|
89
92
|
return {"task_id": response.get("task_id")}
|
90
93
|
|
91
94
|
|
92
|
-
async def generate(request):
|
93
|
-
|
95
|
+
async def generate(request: ImageRequest, api_key: Optional[str] = None):
|
96
|
+
payload = request.model_dump(exclude_none=True, exclude={"extra_fields", "controls"})
|
97
|
+
|
98
|
+
payload = {
|
99
|
+
"type": "glb",
|
100
|
+
"model": request.model,
|
101
|
+
"file_format": request.response_format if request.response_format in ["glb", "stl"] else "glb",
|
102
|
+
|
103
|
+
**payload,
|
104
|
+
**(request.extra_fields or {})
|
105
|
+
}
|
106
|
+
|
107
|
+
image = await to_bytes(payload.pop('image'))
|
108
|
+
|
109
|
+
logger.debug(payload)
|
110
|
+
response = await create_task(image=image, data=payload)
|
111
|
+
if response:
|
112
|
+
for i in range(100):
|
113
|
+
await asyncio.sleep(3)
|
114
|
+
_ = await get_task(response['task_id'])
|
115
|
+
logger.debug(bjson(_))
|
116
|
+
if file_url := (_.get("output") or {}).get("file_url"):
|
117
|
+
return ImagesResponse(data=[{"url": file_url}])
|
118
|
+
|
94
119
|
|
95
120
|
if __name__ == '__main__':
|
96
121
|
image = "/Users/betterme/PycharmProjects/AI/test.png"
|
97
|
-
# arun(
|
98
|
-
|
122
|
+
# arun(get_task('GB84DX8LK6NUJ0WHZLUNRCXDBFKMVVFH'))
|
123
|
+
# image = ('x.png', open(image, 'rb').read(), 'image/png')
|
124
|
+
image = open(image, 'rb').read()
|
125
|
+
image = "https://s3.ffire.cc/files/christmas-tree.png"
|
126
|
+
|
127
|
+
# image = None
|
128
|
+
arun(
|
129
|
+
create_task(
|
130
|
+
# image=open(image, 'rb'),
|
131
|
+
image=image,
|
132
|
+
|
133
|
+
data={
|
134
|
+
"type": "glb",
|
135
|
+
"model": "Hunyuan3D-2",
|
136
|
+
"file_format": "glb",
|
137
|
+
}
|
138
|
+
))
|
139
|
+
|
140
|
+
# arun(generate(
|
141
|
+
# ImageRequest(
|
142
|
+
# model="Hunyuan3D-2",
|
143
|
+
# response_format="glb",
|
144
|
+
# extra_fields={
|
145
|
+
# "image": image,
|
146
|
+
#
|
147
|
+
# "texture": True,
|
148
|
+
# }
|
149
|
+
# )
|
150
|
+
# )
|
151
|
+
# )
|
@@ -16,6 +16,7 @@ from meutils.schemas.image_types import ImageRequest
|
|
16
16
|
|
17
17
|
from meutils.apis.fal.images import generate as fal_generate
|
18
18
|
|
19
|
+
from meutils.apis.gitee.image_to_3d import generate as image_to_3d_generate
|
19
20
|
|
20
21
|
async def generate(
|
21
22
|
request: ImageRequest,
|
@@ -29,6 +30,9 @@ async def generate(
|
|
29
30
|
if request.model.startswith("fal-ai"):
|
30
31
|
return await fal_generate(request, api_key)
|
31
32
|
|
33
|
+
if request.model in {"Hunyuan3D-2", "Hi3DGen", "Step1X-3D"}:
|
34
|
+
return await image_to_3d_generate(request, api_key)
|
35
|
+
|
32
36
|
|
33
37
|
if __name__ == '__main__':
|
34
38
|
arun(generate(ImageRequest(model="flux", prompt="笑起来")))
|
meutils/apis/models.py
CHANGED
@@ -11,14 +11,17 @@
|
|
11
11
|
from meutils.pipe import *
|
12
12
|
|
13
13
|
|
14
|
-
def
|
15
|
-
|
14
|
+
def make_billing_model(model: str, request: dict):
|
15
|
+
_model = model.removeprefix("fal-")
|
16
|
+
if _model.startswith(("pika", "fal-pika")):
|
16
17
|
duration = request.get("duration")
|
17
18
|
resolution = request.get("resolution")
|
18
19
|
|
19
20
|
billing_model = f"{duration}s_{resolution}"
|
20
|
-
return billing_model
|
21
21
|
|
22
|
-
|
22
|
+
return f"{model}_{billing_model}"
|
23
|
+
|
24
|
+
elif _model.startswith(("ideogram", "fal-ideogram")):
|
23
25
|
billing_model = request.get("rendering_speed", "BALANCED").lower()
|
24
|
-
|
26
|
+
|
27
|
+
return f"{model}_{billing_model}"
|
meutils/apis/ppio/__init__.py
CHANGED
@@ -0,0 +1,109 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Project : AI. @by PyCharm
|
4
|
+
# @File : ppio_hailuo
|
5
|
+
# @Time : 2025/7/30 09:02
|
6
|
+
# @Author : betterme
|
7
|
+
# @WeChat : meutils
|
8
|
+
# @Software : PyCharm
|
9
|
+
# @Description :
|
10
|
+
|
11
|
+
from meutils.pipe import *
|
12
|
+
from meutils.decorators.retry import retrying
|
13
|
+
from meutils.apis.utils import make_request_httpx
|
14
|
+
from meutils.schemas.openai_types import TTSRequest
|
15
|
+
from meutils.config_utils.lark_utils import get_next_token_for_polling
|
16
|
+
|
17
|
+
from meutils.apis.ppio.videos import base_url, feishu_url
|
18
|
+
|
19
|
+
|
20
|
+
@retrying()
|
21
|
+
async def text_to_speech(request: TTSRequest, api_key: Optional[str] = None):
|
22
|
+
"""
|
23
|
+
调用ppio接口创建语音
|
24
|
+
:param request:
|
25
|
+
:return:
|
26
|
+
"""
|
27
|
+
if isinstance(api_key, str) and api_key.startswith("oneapi:"):
|
28
|
+
api_key = api_key.removeprefix("oneapi:")
|
29
|
+
|
30
|
+
api_key = api_key or await get_next_token_for_polling(feishu_url, from_redis=True, ttl=3600) # todo: 优化
|
31
|
+
|
32
|
+
headers = {
|
33
|
+
"Authorization": f"Bearer {api_key}",
|
34
|
+
"Content-Type": "application/json",
|
35
|
+
}
|
36
|
+
|
37
|
+
payload = request.model_dump(exclude_none=True)
|
38
|
+
payload = {
|
39
|
+
"text": request.input,
|
40
|
+
"stream": False,
|
41
|
+
"output_format": request.response_format if request.response_format in {"url", "hex"} else "hex",
|
42
|
+
"voice_setting":
|
43
|
+
{
|
44
|
+
"speed": request.speed or 1,
|
45
|
+
"voice_id": request.voice or "wumei_yujie",
|
46
|
+
"emotion": "happy"
|
47
|
+
},
|
48
|
+
**payload
|
49
|
+
}
|
50
|
+
|
51
|
+
# logger.debug(bjson(payload))
|
52
|
+
|
53
|
+
response = await make_request_httpx(
|
54
|
+
base_url=base_url,
|
55
|
+
path=request.model,
|
56
|
+
payload=payload,
|
57
|
+
|
58
|
+
headers=headers,
|
59
|
+
|
60
|
+
debug=True
|
61
|
+
)
|
62
|
+
|
63
|
+
if request.response_format not in {"url", "hex"}:
|
64
|
+
_ = bytes.fromhex(response["audio"])
|
65
|
+
|
66
|
+
# logger.debug(type(_))
|
67
|
+
|
68
|
+
return _
|
69
|
+
|
70
|
+
return response
|
71
|
+
|
72
|
+
|
73
|
+
if __name__ == '__main__':
|
74
|
+
data = {
|
75
|
+
"model": "minimax-speech-02-turbo",
|
76
|
+
"input": "你好",
|
77
|
+
"voice": "柔美女友",
|
78
|
+
"response_format": "url"
|
79
|
+
}
|
80
|
+
arun(
|
81
|
+
text_to_speech(
|
82
|
+
TTSRequest(
|
83
|
+
model="minimax-speech-02-turbo",
|
84
|
+
input="你好",
|
85
|
+
|
86
|
+
# response_format='hex',
|
87
|
+
|
88
|
+
# **data
|
89
|
+
)
|
90
|
+
))
|
91
|
+
|
92
|
+
"""
|
93
|
+
curl \
|
94
|
+
-X POST https://api.ppinfra.com/v3/minimax-speech-02-turbo \
|
95
|
+
-H "Authorization: Bearer sk_3W5amR6wiLNSzAyz9wkHBxSf848ZQckbTzZQrxNY1Og" \
|
96
|
+
-H "Content-Type: application/json" \
|
97
|
+
-d '{
|
98
|
+
"text": "近年来,人工智能在国内迎来高速发展期,技术创新与产业应用齐头并进。从基础的大模型研发到语音识别、图像处理、自然语言理解等关键技术突破,AI 正在深度赋能医疗、金融、制造、交通等多个领域。同时,政策支持和资本推动加速了技术落地,众多科技企业、创业团队和科研机构持续投入,形成了活跃的创新生态。AI 正逐步从实验室走向实际生产力,成为推动数字中国建设和经济高质量发展的重要引擎,未来发展潜力巨大。",
|
99
|
+
"stream": false,
|
100
|
+
"output_format": "url",
|
101
|
+
"voice_setting": {
|
102
|
+
"speed": 1.1,
|
103
|
+
"voice_id": "male-qn-jingying",
|
104
|
+
"emotion": "happy"
|
105
|
+
}
|
106
|
+
}'
|
107
|
+
|
108
|
+
"""
|
109
|
+
|
meutils/apis/ppio/videos.py
CHANGED
@@ -21,8 +21,8 @@ base_url = "https://api.ppinfra.com/v3"
|
|
21
21
|
feishu_url = "https://xchatllm.feishu.cn/sheets/Z59Js10DbhT8wdt72LachSDlnlf?sheet=b0e241"
|
22
22
|
|
23
23
|
|
24
|
-
async def get_valid_token():
|
25
|
-
_ = await get_next_token(feishu_url, check_token, min_points=
|
24
|
+
async def get_valid_token(min_points=18000):
|
25
|
+
_ = await get_next_token(feishu_url, check_token, min_points=min_points, ttl=600)
|
26
26
|
logger.debug(_)
|
27
27
|
return _
|
28
28
|
|
meutils/apis/proxy/ips.py
CHANGED
@@ -79,7 +79,7 @@ async def add_ips(ips: Optional[str] = None):
|
|
79
79
|
await asyncio.sleep(5)
|
80
80
|
|
81
81
|
|
82
|
-
@rcache(ttl=
|
82
|
+
@rcache(ttl=2.5 * 60)
|
83
83
|
@retrying()
|
84
84
|
async def get_proxies(request_type: str = "httpx", **kwargs):
|
85
85
|
params = {
|
@@ -146,11 +146,11 @@ if __name__ == '__main__':
|
|
146
146
|
ip = "http://154.9.252.28:38443"
|
147
147
|
ip = "http://110.42.51.223:38443"
|
148
148
|
ip = "http://154.40.54.76:38443"
|
149
|
-
proxy = "http://120.26.134.112:22443"
|
149
|
+
# proxy = "http://120.26.134.112:22443"
|
150
150
|
|
151
151
|
# arun(check_proxy(proxy))
|
152
152
|
|
153
|
-
arun(get_one_proxy())
|
153
|
+
# arun(get_one_proxy())
|
154
154
|
|
155
155
|
# arun(add_ips())
|
156
156
|
# arun(get_one_proxy(from_redis=True))
|
@@ -202,12 +202,12 @@ if __name__ == "__main__":
|
|
202
202
|
prompt="无人机以极快速度穿越复杂障碍或自然奇观,带来沉浸式飞行体验",
|
203
203
|
duration=10
|
204
204
|
)
|
205
|
-
|
205
|
+
r = arun(create_task(request))
|
206
206
|
# r = {'id': 'cgt-20250612172542-6nbt2'}
|
207
207
|
|
208
208
|
# arun(get_task(r.get('id')))
|
209
209
|
|
210
|
-
arun(get_task("cgt-20250707162431-smhwc"))
|
210
|
+
# arun(get_task("cgt-20250707162431-smhwc"))
|
211
211
|
|
212
212
|
# arun(get_task("cgt-20250707160713-j8kll"))
|
213
213
|
|
meutils/data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2025.
|
1
|
+
2025.08.05.10.08.29
|
meutils/llm/check_utils.py
CHANGED
@@ -400,7 +400,7 @@ if __name__ == '__main__':
|
|
400
400
|
|
401
401
|
# arun(check_token_for_ppinfra("sk_F0kgPyCMTzmOH_-VCEJucOK8HIrbnLGYm_IWxBToHZQ"))
|
402
402
|
|
403
|
-
arun(check_token_for_volc("
|
403
|
+
arun(check_token_for_volc("97237d3b-76b3-4a92-8150-5b64bba0b8b1"))
|
404
404
|
# arun(check_token_for_volc("279749bd-ba5e-4962-9c65-eb6604b65594"))
|
405
405
|
|
406
406
|
# arun(check_token_for_ppinfra("sk_mCb5sRGTi6GXkSRp5F679Rbs0V_Hfee3p85lccGXCOo"))
|
meutils/schemas/image_types.py
CHANGED
@@ -87,7 +87,7 @@ class ImageRequest(BaseModel): # openai
|
|
87
87
|
"""
|
88
88
|
model: str = ''
|
89
89
|
|
90
|
-
prompt: constr(min_length=1, max_length=10240) = ""
|
90
|
+
prompt: constr(min_length=1, max_length=10240) = " "
|
91
91
|
|
92
92
|
n: Optional[int] = 1
|
93
93
|
|
@@ -97,7 +97,7 @@ class ImageRequest(BaseModel): # openai
|
|
97
97
|
# 测试默认值 Optional[Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]]
|
98
98
|
size: Optional[str] = '1024x1024' # null auto
|
99
99
|
|
100
|
-
response_format: Optional[Literal["oss_url", "
|
100
|
+
response_format: Optional[Literal["url", "b64_json", "oss_url", "glb", "stl"]] = "url"
|
101
101
|
|
102
102
|
seed: Optional[int] = None
|
103
103
|
|
@@ -108,7 +108,7 @@ class ImageRequest(BaseModel): # openai
|
|
108
108
|
guidance: Optional[float] = None
|
109
109
|
steps: Optional[int] = None
|
110
110
|
|
111
|
-
controls: Optional[dict] =
|
111
|
+
controls: Optional[dict] = None # 额外参数
|
112
112
|
|
113
113
|
safety_tolerance: Optional[int] = None
|
114
114
|
|