most-client 1.0.14__py3-none-any.whl → 1.0.16__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.
- most/api.py +50 -3
- most/async_api.py +53 -6
- most/types.py +39 -2
- {most_client-1.0.14.dist-info → most_client-1.0.16.dist-info}/METADATA +2 -1
- most_client-1.0.16.dist-info/RECORD +9 -0
- {most_client-1.0.14.dist-info → most_client-1.0.16.dist-info}/WHEEL +1 -1
- most_client-1.0.14.dist-info/RECORD +0 -9
- {most_client-1.0.14.dist-info → most_client-1.0.16.dist-info}/top_level.txt +0 -0
- {most_client-1.0.14.dist-info → most_client-1.0.16.dist-info}/zip-safe +0 -0
most/api.py
CHANGED
@@ -1,9 +1,23 @@
|
|
1
|
-
|
1
|
+
import io
|
2
|
+
import os
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import Dict, List
|
5
|
+
|
2
6
|
import json5
|
3
7
|
import requests
|
4
8
|
from adaptix import Retort
|
5
|
-
from
|
6
|
-
|
9
|
+
from pydub import AudioSegment
|
10
|
+
|
11
|
+
from most.types import (
|
12
|
+
Audio,
|
13
|
+
DialogResult,
|
14
|
+
JobStatus,
|
15
|
+
Result,
|
16
|
+
Script,
|
17
|
+
StoredAudioData,
|
18
|
+
Text,
|
19
|
+
is_valid_id,
|
20
|
+
)
|
7
21
|
|
8
22
|
|
9
23
|
class MostClient(object):
|
@@ -131,6 +145,14 @@ class MostClient(object):
|
|
131
145
|
files={"audio_file": f})
|
132
146
|
return self.retort.load(resp.json(), Audio)
|
133
147
|
|
148
|
+
def upload_audio_segment(self, audio: AudioSegment) -> Audio:
|
149
|
+
f = io.BytesIO()
|
150
|
+
audio.export(f, format="mp3")
|
151
|
+
f.seek(0)
|
152
|
+
resp = self.post(f"https://api.the-most.ai/api/external/{self.client_id}/upload",
|
153
|
+
files={"audio_file": f})
|
154
|
+
return self.retort.load(resp.json(), Audio)
|
155
|
+
|
134
156
|
def upload_audio_url(self, audio_url) -> Audio:
|
135
157
|
resp = self.post(f"https://api.the-most.ai/api/external/{self.client_id}/upload_url",
|
136
158
|
json={"audio_url": audio_url})
|
@@ -205,6 +227,16 @@ class MostClient(object):
|
|
205
227
|
resp = self.get(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/text")
|
206
228
|
return self.retort.load(resp.json(), Result)
|
207
229
|
|
230
|
+
def fetch_dialog(self, audio_id) -> DialogResult:
|
231
|
+
if not is_valid_id(self.model_id):
|
232
|
+
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
233
|
+
|
234
|
+
if not is_valid_id(audio_id):
|
235
|
+
raise RuntimeError("Please use valid audio_id. [try audio.id from list_audios()]")
|
236
|
+
|
237
|
+
resp = self.get(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/dialog")
|
238
|
+
return self.retort.load(resp.json(), DialogResult)
|
239
|
+
|
208
240
|
def export(self, audio_ids: List[str]) -> str:
|
209
241
|
if not is_valid_id(self.model_id):
|
210
242
|
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
@@ -238,3 +270,18 @@ class MostClient(object):
|
|
238
270
|
|
239
271
|
def __repr__(self):
|
240
272
|
return "<MostClient(model_id='%s')>" % (self.model_id, )
|
273
|
+
|
274
|
+
def get_audio_segment_by_url(self, audio_url,
|
275
|
+
format=None):
|
276
|
+
if format is None:
|
277
|
+
format = os.path.splitext(audio_url)[1]
|
278
|
+
format = format.strip().lower()
|
279
|
+
|
280
|
+
resp = self.session.get(audio_url,
|
281
|
+
timeout=None)
|
282
|
+
if resp.status_code >= 400:
|
283
|
+
raise RuntimeError("Audio url is not accessable")
|
284
|
+
|
285
|
+
audio = AudioSegment.from_file(io.BytesIO(resp.content),
|
286
|
+
format=format)
|
287
|
+
return audio
|
most/async_api.py
CHANGED
@@ -1,9 +1,23 @@
|
|
1
|
-
|
2
|
-
import
|
3
|
-
from adaptix import Retort
|
4
|
-
from most.types import Audio, Result, Script, JobStatus, Text, StoredAudioData, is_valid_id
|
1
|
+
import io
|
2
|
+
import os
|
5
3
|
from pathlib import Path
|
4
|
+
from typing import Dict, List
|
5
|
+
|
6
6
|
import httpx
|
7
|
+
import json5
|
8
|
+
from adaptix import Retort
|
9
|
+
from pydub import AudioSegment
|
10
|
+
|
11
|
+
from most.types import (
|
12
|
+
Audio,
|
13
|
+
DialogResult,
|
14
|
+
JobStatus,
|
15
|
+
Result,
|
16
|
+
Script,
|
17
|
+
StoredAudioData,
|
18
|
+
Text,
|
19
|
+
is_valid_id,
|
20
|
+
)
|
7
21
|
|
8
22
|
|
9
23
|
class AsyncMostClient(object):
|
@@ -135,6 +149,14 @@ class AsyncMostClient(object):
|
|
135
149
|
files={"audio_file": f})
|
136
150
|
return self.retort.load(resp.json(), Audio)
|
137
151
|
|
152
|
+
async def upload_audio_segment(self, audio: AudioSegment) -> Audio:
|
153
|
+
f = io.BytesIO()
|
154
|
+
audio.export(f, format="mp3")
|
155
|
+
f.seek(0)
|
156
|
+
resp = await self.post(f"https://api.the-most.ai/api/external/{self.client_id}/upload",
|
157
|
+
files={"audio_file": f})
|
158
|
+
return self.retort.load(resp.json(), Audio)
|
159
|
+
|
138
160
|
async def upload_text(self, text: str) -> Text:
|
139
161
|
resp = await self.post(f"https://api.the-most.ai/api/external/{self.client_id}/upload_text",
|
140
162
|
json={"text": text})
|
@@ -146,8 +168,8 @@ class AsyncMostClient(object):
|
|
146
168
|
return self.retort.load(resp.json(), Audio)
|
147
169
|
|
148
170
|
async def list_audios(self,
|
149
|
-
|
150
|
-
|
171
|
+
offset: int = 0,
|
172
|
+
limit: int = 10) -> List[Audio]:
|
151
173
|
resp = await self.get(f"https://api.the-most.ai/api/external/{self.client_id}/list?offset={offset}&limit={limit}")
|
152
174
|
audio_list = resp.json()
|
153
175
|
return self.retort.load(audio_list, List[Audio])
|
@@ -214,6 +236,16 @@ class AsyncMostClient(object):
|
|
214
236
|
resp = await self.get(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/text")
|
215
237
|
return self.retort.load(resp.json(), Result)
|
216
238
|
|
239
|
+
async def fetch_dialog(self, audio_id) -> DialogResult:
|
240
|
+
if not is_valid_id(self.model_id):
|
241
|
+
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
242
|
+
|
243
|
+
if not is_valid_id(audio_id):
|
244
|
+
raise RuntimeError("Please use valid audio_id. [try audio.id from list_audios()]")
|
245
|
+
|
246
|
+
resp = await self.get(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/dialog")
|
247
|
+
return self.retort.load(resp.json(), DialogResult)
|
248
|
+
|
217
249
|
async def export(self, audio_ids: List[str]) -> str:
|
218
250
|
if not is_valid_id(self.model_id):
|
219
251
|
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
@@ -243,3 +275,18 @@ class AsyncMostClient(object):
|
|
243
275
|
|
244
276
|
def __repr__(self):
|
245
277
|
return "<AsyncMostClient(model_id='%s')>" % (self.model_id, )
|
278
|
+
|
279
|
+
async def get_audio_segment_by_url(self, audio_url,
|
280
|
+
format=None):
|
281
|
+
if format is None:
|
282
|
+
format = os.path.splitext(audio_url)[1]
|
283
|
+
format = format.strip().lower()
|
284
|
+
|
285
|
+
resp = await self.session.get(audio_url,
|
286
|
+
timeout=None)
|
287
|
+
if resp.status_code >= 400:
|
288
|
+
raise RuntimeError("Audio url is not accessable")
|
289
|
+
|
290
|
+
audio = AudioSegment.from_file(io.BytesIO(resp.content),
|
291
|
+
format=format)
|
292
|
+
return audio
|
most/types.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
import re
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from
|
4
|
-
|
3
|
+
from typing import Dict, List, Literal, Optional
|
4
|
+
|
5
|
+
from dataclasses_json import DataClassJsonMixin, dataclass_json
|
5
6
|
|
6
7
|
|
7
8
|
@dataclass_json
|
@@ -76,6 +77,42 @@ class Result(DataClassJsonMixin):
|
|
76
77
|
for column_result in self.results])
|
77
78
|
|
78
79
|
|
80
|
+
@dataclass_json
|
81
|
+
@dataclass
|
82
|
+
class DialogSegment(DataClassJsonMixin):
|
83
|
+
start_time_ms: int
|
84
|
+
end_time_ms: int
|
85
|
+
text: str
|
86
|
+
speaker: str
|
87
|
+
emotion: Optional[str] = None
|
88
|
+
intensity: Optional[float] = None
|
89
|
+
|
90
|
+
def to_text(self):
|
91
|
+
if self.emotion is None:
|
92
|
+
return f'{self.speaker}: {self.text}\n'
|
93
|
+
else:
|
94
|
+
return f'{self.speaker}: <emotion name="{self.emotion}" intensity="{self.intensity}">{self.text}</emotion>\n'
|
95
|
+
|
96
|
+
|
97
|
+
@dataclass_json
|
98
|
+
@dataclass
|
99
|
+
class Dialog(DataClassJsonMixin):
|
100
|
+
segments: List[DialogSegment]
|
101
|
+
|
102
|
+
def to_text(self):
|
103
|
+
return ''.join([segment.to_text()
|
104
|
+
for segment in self.segments])
|
105
|
+
|
106
|
+
|
107
|
+
@dataclass_json
|
108
|
+
@dataclass
|
109
|
+
class DialogResult(DataClassJsonMixin):
|
110
|
+
id: str
|
111
|
+
dialog: Optional[Dialog]
|
112
|
+
url: Optional[str]
|
113
|
+
results: Optional[List[ColumnResult]]
|
114
|
+
|
115
|
+
|
79
116
|
def is_valid_objectid(oid: str) -> bool:
|
80
117
|
"""
|
81
118
|
Check if a given string is a valid MongoDB ObjectId (24-character hex).
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: most-client
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.16
|
4
4
|
Summary: Most AI API for https://the-most.ai
|
5
5
|
Home-page: https://github.com/the-most-ai/most-client
|
6
6
|
Author: George Kasparyants
|
@@ -26,6 +26,7 @@ Requires-Dist: pytest
|
|
26
26
|
Requires-Dist: tox
|
27
27
|
Requires-Dist: twine
|
28
28
|
Requires-Dist: httpx
|
29
|
+
Requires-Dist: pydub
|
29
30
|
Dynamic: author
|
30
31
|
Dynamic: author-email
|
31
32
|
Dynamic: classifier
|
@@ -0,0 +1,9 @@
|
|
1
|
+
most/__init__.py,sha256=62uFFeM_1VVR83K3bTYWK3PEoqnmFCy9aWYerQ6U4Ds,67
|
2
|
+
most/api.py,sha256=WCqoiEWJHT3CjJMtMYpLLiPdFfuWm6dZlAUTcHHIF2s,11578
|
3
|
+
most/async_api.py,sha256=frSdPUCBqgmfSyCdW36jBtZvNn1EtM67kR1a4ww0BNo,12305
|
4
|
+
most/types.py,sha256=apUz6FHFAHWJNVvRh57wVQk5DFw2XKnLLhkAyWgtvfw,2825
|
5
|
+
most_client-1.0.16.dist-info/METADATA,sha256=ZYksiJjL2z3czgL9B9YWYMqDOP4YG3_cTDki1TAhGP4,1027
|
6
|
+
most_client-1.0.16.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
7
|
+
most_client-1.0.16.dist-info/top_level.txt,sha256=2g5fk02LKkM1hV3pVVti_LQ60TToLBcR2zQ3JEKGVk8,5
|
8
|
+
most_client-1.0.16.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
9
|
+
most_client-1.0.16.dist-info/RECORD,,
|
@@ -1,9 +0,0 @@
|
|
1
|
-
most/__init__.py,sha256=62uFFeM_1VVR83K3bTYWK3PEoqnmFCy9aWYerQ6U4Ds,67
|
2
|
-
most/api.py,sha256=sGChrPUuwBjSdkkJK3BDOh3YYaxe9xAuGS82GcEdQk4,10074
|
3
|
-
most/async_api.py,sha256=ZiUXdqRBG8yTEBHfuglN1eaBMr29S9ibWWfFM5EP61w,10735
|
4
|
-
most/types.py,sha256=xk88nlu1AxMEF2pxvlwsNOYb_pY_CyNtk7RSzDyCwrY,1969
|
5
|
-
most_client-1.0.14.dist-info/METADATA,sha256=CSRTOFyulwnKul181jhb3OOryWdNVtFbzelAPq_YJqI,1006
|
6
|
-
most_client-1.0.14.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
|
7
|
-
most_client-1.0.14.dist-info/top_level.txt,sha256=2g5fk02LKkM1hV3pVVti_LQ60TToLBcR2zQ3JEKGVk8,5
|
8
|
-
most_client-1.0.14.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
9
|
-
most_client-1.0.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|