most-client 1.0.18__py3-none-any.whl → 1.0.20__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 +54 -7
- most/async_api.py +54 -7
- most/score_calculation.py +23 -0
- most/types.py +35 -0
- {most_client-1.0.18.dist-info → most_client-1.0.20.dist-info}/METADATA +1 -1
- most_client-1.0.20.dist-info/RECORD +10 -0
- most_client-1.0.18.dist-info/RECORD +0 -9
- {most_client-1.0.18.dist-info → most_client-1.0.20.dist-info}/WHEEL +0 -0
- {most_client-1.0.18.dist-info → most_client-1.0.20.dist-info}/top_level.txt +0 -0
- {most_client-1.0.18.dist-info → most_client-1.0.20.dist-info}/zip-safe +0 -0
most/api.py
CHANGED
@@ -9,6 +9,7 @@ import requests
|
|
9
9
|
from adaptix import Retort
|
10
10
|
from pydub import AudioSegment
|
11
11
|
|
12
|
+
from most.score_calculation import ScoreCalculation
|
12
13
|
from most.types import (
|
13
14
|
Audio,
|
14
15
|
DialogResult,
|
@@ -17,7 +18,7 @@ from most.types import (
|
|
17
18
|
Script,
|
18
19
|
StoredAudioData,
|
19
20
|
Text,
|
20
|
-
is_valid_id,
|
21
|
+
is_valid_id, SearchParams, ScriptScoreMapping,
|
21
22
|
)
|
22
23
|
|
23
24
|
|
@@ -48,6 +49,7 @@ class MostClient(object):
|
|
48
49
|
self.session = requests.Session()
|
49
50
|
self.access_token = None
|
50
51
|
self.model_id = model_id
|
52
|
+
self.score_modifier = None
|
51
53
|
|
52
54
|
self.refresh_access_token()
|
53
55
|
|
@@ -77,11 +79,13 @@ class MostClient(object):
|
|
77
79
|
model_id=self.model_id)
|
78
80
|
client.access_token = self.access_token
|
79
81
|
client.session = self.session
|
82
|
+
client.score_modifier = self.score_modifier
|
80
83
|
return client
|
81
84
|
|
82
85
|
def with_model(self, model_id):
|
83
86
|
client = self.clone()
|
84
87
|
client.model_id = model_id
|
88
|
+
client.score_modifier = None
|
85
89
|
return client
|
86
90
|
|
87
91
|
def refresh_access_token(self):
|
@@ -176,12 +180,23 @@ class MostClient(object):
|
|
176
180
|
resp = self.get(f"https://api.the-most.ai/api/external/{self.client_id}/model/{self.model_id}/script")
|
177
181
|
return self.retort.load(resp.json(), Script)
|
178
182
|
|
183
|
+
def get_score_modifier(self):
|
184
|
+
if self.score_modifier is None:
|
185
|
+
if not is_valid_id(self.model_id):
|
186
|
+
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
187
|
+
|
188
|
+
resp = self.get(f"https://api.the-most.ai/api/external/{self.client_id}/model/{self.model_id}/score_mapping")
|
189
|
+
score_mapping = self.retort.load(resp.json(), List[ScriptScoreMapping])
|
190
|
+
self.score_modifier = ScoreCalculation(score_mapping)
|
191
|
+
return self.score_modifier
|
192
|
+
|
179
193
|
def list_models(self):
|
180
194
|
resp = self.get("https://api.the-most.ai/api/external/list_models")
|
181
195
|
return [self.with_model(model['model'])
|
182
196
|
for model in resp.json()]
|
183
197
|
|
184
|
-
def apply(self, audio_id
|
198
|
+
def apply(self, audio_id,
|
199
|
+
modify_scores: bool = False) -> Result:
|
185
200
|
if not is_valid_id(self.model_id):
|
186
201
|
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
187
202
|
|
@@ -189,9 +204,13 @@ class MostClient(object):
|
|
189
204
|
raise RuntimeError("Please use valid audio_id. [try audio.id from list_audios()]")
|
190
205
|
|
191
206
|
resp = self.post(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/apply")
|
192
|
-
|
207
|
+
result = self.retort.load(resp.json(), Result)
|
208
|
+
if modify_scores:
|
209
|
+
result = self.score_modifier.modify(result)
|
210
|
+
return result
|
193
211
|
|
194
|
-
def apply_later(self, audio_id
|
212
|
+
def apply_later(self, audio_id,
|
213
|
+
modify_scores: bool = False) -> Result:
|
195
214
|
if not is_valid_id(self.model_id):
|
196
215
|
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
197
216
|
|
@@ -199,7 +218,10 @@ class MostClient(object):
|
|
199
218
|
raise RuntimeError("Please use valid audio_id. [try audio.id from list_audios()]")
|
200
219
|
|
201
220
|
resp = self.post(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/apply_async")
|
202
|
-
|
221
|
+
result = self.retort.load(resp.json(), Result)
|
222
|
+
if modify_scores:
|
223
|
+
result = self.score_modifier.modify(result)
|
224
|
+
return result
|
203
225
|
|
204
226
|
def get_job_status(self, audio_id) -> JobStatus:
|
205
227
|
if not is_valid_id(self.model_id):
|
@@ -211,7 +233,8 @@ class MostClient(object):
|
|
211
233
|
resp = self.post(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/apply_status")
|
212
234
|
return self.retort.load(resp.json(), JobStatus)
|
213
235
|
|
214
|
-
def fetch_results(self, audio_id
|
236
|
+
def fetch_results(self, audio_id,
|
237
|
+
modify_scores: bool = False) -> Result:
|
215
238
|
if not is_valid_id(self.model_id):
|
216
239
|
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
217
240
|
|
@@ -219,7 +242,10 @@ class MostClient(object):
|
|
219
242
|
raise RuntimeError("Please use valid audio_id. [try audio.id from list_audios()]")
|
220
243
|
|
221
244
|
resp = self.get(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/results")
|
222
|
-
|
245
|
+
result = self.retort.load(resp.json(), Result)
|
246
|
+
if modify_scores:
|
247
|
+
result = self.score_modifier.modify(result)
|
248
|
+
return result
|
223
249
|
|
224
250
|
def fetch_text(self, audio_id: str) -> Result:
|
225
251
|
if not is_valid_id(self.model_id):
|
@@ -296,3 +322,24 @@ class MostClient(object):
|
|
296
322
|
audio = AudioSegment.from_file(io.BytesIO(resp.content),
|
297
323
|
format=format)
|
298
324
|
return audio
|
325
|
+
|
326
|
+
def index_audio(self, audio_id: str) -> None:
|
327
|
+
resp = self.post(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/indexing")
|
328
|
+
if resp.status_code >= 400:
|
329
|
+
raise RuntimeError("Audio can't be indexed")
|
330
|
+
return None
|
331
|
+
|
332
|
+
def search(self,
|
333
|
+
query: str,
|
334
|
+
filter: SearchParams,
|
335
|
+
limit: int = 10) -> List[Audio]:
|
336
|
+
resp = self.post(f"https://api.the-most.ai/api/external/{self.client_id}/model/{self.model_id}/search",
|
337
|
+
json={
|
338
|
+
"query": query,
|
339
|
+
"filter": filter.to_dict(),
|
340
|
+
"limit": limit,
|
341
|
+
})
|
342
|
+
if resp.status_code >= 400:
|
343
|
+
raise RuntimeError("Audio can't be indexed")
|
344
|
+
audio_list = resp.json()
|
345
|
+
return self.retort.load(audio_list, List[Audio])
|
most/async_api.py
CHANGED
@@ -9,6 +9,7 @@ import json5
|
|
9
9
|
from adaptix import Retort
|
10
10
|
from pydub import AudioSegment
|
11
11
|
|
12
|
+
from most.score_calculation import ScoreCalculation
|
12
13
|
from most.types import (
|
13
14
|
Audio,
|
14
15
|
DialogResult,
|
@@ -17,7 +18,7 @@ from most.types import (
|
|
17
18
|
Script,
|
18
19
|
StoredAudioData,
|
19
20
|
Text,
|
20
|
-
is_valid_id,
|
21
|
+
is_valid_id, SearchParams, ScriptScoreMapping,
|
21
22
|
)
|
22
23
|
|
23
24
|
|
@@ -48,6 +49,7 @@ class AsyncMostClient(object):
|
|
48
49
|
self.session = httpx.AsyncClient()
|
49
50
|
self.access_token = None
|
50
51
|
self.model_id = model_id
|
52
|
+
self.score_modifier: Optional[ScoreCalculation] = None
|
51
53
|
|
52
54
|
async def __aenter__(self):
|
53
55
|
await self.session.__aenter__()
|
@@ -83,6 +85,7 @@ class AsyncMostClient(object):
|
|
83
85
|
model_id=self.model_id)
|
84
86
|
client.access_token = self.access_token
|
85
87
|
client.session = self.session
|
88
|
+
client.score_modifier = self.score_modifier
|
86
89
|
return client
|
87
90
|
|
88
91
|
def with_model(self, model_id):
|
@@ -90,6 +93,7 @@ class AsyncMostClient(object):
|
|
90
93
|
if not is_valid_id(self.model_id):
|
91
94
|
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
92
95
|
client.model_id = model_id
|
96
|
+
client.score_modifier = None
|
93
97
|
return client
|
94
98
|
|
95
99
|
async def refresh_access_token(self):
|
@@ -185,12 +189,23 @@ class AsyncMostClient(object):
|
|
185
189
|
resp = await self.get(f"https://api.the-most.ai/api/external/{self.client_id}/model/{self.model_id}/script")
|
186
190
|
return self.retort.load(resp.json(), Script)
|
187
191
|
|
192
|
+
async def get_score_modifier(self):
|
193
|
+
if self.score_modifier is None:
|
194
|
+
if not is_valid_id(self.model_id):
|
195
|
+
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
196
|
+
|
197
|
+
resp = await self.get(f"https://api.the-most.ai/api/external/{self.client_id}/model/{self.model_id}/score_mapping")
|
198
|
+
score_mapping = self.retort.load(resp.json(), List[ScriptScoreMapping])
|
199
|
+
self.score_modifier = ScoreCalculation(score_mapping)
|
200
|
+
return self.score_modifier
|
201
|
+
|
188
202
|
async def list_models(self):
|
189
203
|
resp = await self.get("https://api.the-most.ai/api/external/list_models")
|
190
204
|
return [self.with_model(model['model'])
|
191
205
|
for model in resp.json()]
|
192
206
|
|
193
|
-
async def apply(self, audio_id
|
207
|
+
async def apply(self, audio_id,
|
208
|
+
modify_scores: bool = False) -> Result:
|
194
209
|
if not is_valid_id(self.model_id):
|
195
210
|
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
196
211
|
|
@@ -198,9 +213,13 @@ class AsyncMostClient(object):
|
|
198
213
|
raise RuntimeError("Please use valid audio_id. [try audio.id from list_audios()]")
|
199
214
|
|
200
215
|
resp = await self.post(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/apply")
|
201
|
-
|
216
|
+
result = self.retort.load(resp.json(), Result)
|
217
|
+
if modify_scores:
|
218
|
+
result = self.score_modifier.modify(result)
|
219
|
+
return result
|
202
220
|
|
203
|
-
async def apply_later(self, audio_id
|
221
|
+
async def apply_later(self, audio_id,
|
222
|
+
modify_scores: bool = False) -> Result:
|
204
223
|
if not is_valid_id(self.model_id):
|
205
224
|
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
206
225
|
|
@@ -208,7 +227,10 @@ class AsyncMostClient(object):
|
|
208
227
|
raise RuntimeError("Please use valid audio_id. [try audio.id from list_audios()]")
|
209
228
|
|
210
229
|
resp = await self.post(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/apply_async")
|
211
|
-
|
230
|
+
result = self.retort.load(resp.json(), Result)
|
231
|
+
if modify_scores:
|
232
|
+
result = self.score_modifier.modify(result)
|
233
|
+
return result
|
212
234
|
|
213
235
|
async def get_job_status(self, audio_id) -> JobStatus:
|
214
236
|
if not is_valid_id(self.model_id):
|
@@ -220,7 +242,8 @@ class AsyncMostClient(object):
|
|
220
242
|
resp = await self.post(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/apply_status")
|
221
243
|
return self.retort.load(resp.json(), JobStatus)
|
222
244
|
|
223
|
-
async def fetch_results(self, audio_id
|
245
|
+
async def fetch_results(self, audio_id,
|
246
|
+
modify_scores: bool = False) -> Result:
|
224
247
|
if not is_valid_id(self.model_id):
|
225
248
|
raise RuntimeError("Please choose valid model to apply. [try list_models()]")
|
226
249
|
|
@@ -228,7 +251,10 @@ class AsyncMostClient(object):
|
|
228
251
|
raise RuntimeError("Please use valid audio_id. [try audio.id from list_audios()]")
|
229
252
|
|
230
253
|
resp = await self.get(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/results")
|
231
|
-
|
254
|
+
result = self.retort.load(resp.json(), Result)
|
255
|
+
if modify_scores:
|
256
|
+
result = self.score_modifier.modify(result)
|
257
|
+
return result
|
232
258
|
|
233
259
|
async def fetch_text(self, audio_id) -> Result:
|
234
260
|
if not is_valid_id(self.model_id):
|
@@ -301,3 +327,24 @@ class AsyncMostClient(object):
|
|
301
327
|
audio = AudioSegment.from_file(io.BytesIO(resp.content),
|
302
328
|
format=format)
|
303
329
|
return audio
|
330
|
+
|
331
|
+
async def index_audio(self, audio_id: str) -> None:
|
332
|
+
resp = await self.post(f"https://api.the-most.ai/api/external/{self.client_id}/audio/{audio_id}/model/{self.model_id}/indexing")
|
333
|
+
if resp.status_code >= 400:
|
334
|
+
raise RuntimeError("Audio can't be indexed")
|
335
|
+
return None
|
336
|
+
|
337
|
+
async def search(self,
|
338
|
+
query: str,
|
339
|
+
filter: SearchParams,
|
340
|
+
limit: int = 10) -> List[Audio]:
|
341
|
+
resp = await self.post(f"https://api.the-most.ai/api/external/{self.client_id}/model/{self.model_id}/search",
|
342
|
+
json={
|
343
|
+
"query": query,
|
344
|
+
"filter": filter.to_dict(),
|
345
|
+
"limit": limit,
|
346
|
+
})
|
347
|
+
if resp.status_code >= 400:
|
348
|
+
raise RuntimeError("Audio can't be indexed")
|
349
|
+
audio_list = resp.json()
|
350
|
+
return self.retort.load(audio_list, List[Audio])
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import dataclasses
|
2
|
+
from typing import Dict, Tuple, List, Optional
|
3
|
+
|
4
|
+
from .types import Result, ScriptScoreMapping
|
5
|
+
|
6
|
+
|
7
|
+
class ScoreCalculation:
|
8
|
+
def __init__(self, score_mapping: List[ScriptScoreMapping]):
|
9
|
+
super(ScoreCalculation, self).__init__()
|
10
|
+
self.score_mapping = {
|
11
|
+
(sm.column, sm.subcolumn, sm.from_score): sm.to_score
|
12
|
+
for sm in score_mapping
|
13
|
+
}
|
14
|
+
|
15
|
+
def modify(self, result: Optional[Result]):
|
16
|
+
if result is None:
|
17
|
+
return None
|
18
|
+
result = dataclasses.replace(result)
|
19
|
+
for column_result in result.results:
|
20
|
+
for subcolumn_result in column_result.subcolumns:
|
21
|
+
subcolumn_result.score = self.score_mapping[(column_result.name, subcolumn_result.name, subcolumn_result.score)]
|
22
|
+
|
23
|
+
return result
|
most/types.py
CHANGED
@@ -53,6 +53,15 @@ class Script(DataClassJsonMixin):
|
|
53
53
|
columns: List[Column]
|
54
54
|
|
55
55
|
|
56
|
+
@dataclass_json
|
57
|
+
@dataclass
|
58
|
+
class ScriptScoreMapping(DataClassJsonMixin):
|
59
|
+
column: str
|
60
|
+
subcolumn: str
|
61
|
+
from_score: int
|
62
|
+
to_score: int
|
63
|
+
|
64
|
+
|
56
65
|
@dataclass_json
|
57
66
|
@dataclass
|
58
67
|
class JobStatus(DataClassJsonMixin):
|
@@ -113,6 +122,32 @@ class DialogResult(DataClassJsonMixin):
|
|
113
122
|
results: Optional[List[ColumnResult]]
|
114
123
|
|
115
124
|
|
125
|
+
@dataclass_json
|
126
|
+
@dataclass
|
127
|
+
class StoredInfoCondition(DataClassJsonMixin):
|
128
|
+
key: str
|
129
|
+
match: Optional[str] = None
|
130
|
+
starts_with: Optional[str] = None
|
131
|
+
ends_with: Optional[str] = None
|
132
|
+
|
133
|
+
|
134
|
+
@dataclass_json
|
135
|
+
@dataclass
|
136
|
+
class ResultsCondition(DataClassJsonMixin):
|
137
|
+
column: str
|
138
|
+
subcolumn: str
|
139
|
+
score_greater_than: Optional[int] = None
|
140
|
+
score_less_than: Optional[int] = None
|
141
|
+
|
142
|
+
|
143
|
+
@dataclass_json
|
144
|
+
@dataclass
|
145
|
+
class SearchParams(DataClassJsonMixin):
|
146
|
+
must: List[StoredInfoCondition | ResultsCondition]
|
147
|
+
should: List[StoredInfoCondition | ResultsCondition]
|
148
|
+
must_not: List[StoredInfoCondition | ResultsCondition]
|
149
|
+
|
150
|
+
|
116
151
|
def is_valid_objectid(oid: str) -> bool:
|
117
152
|
"""
|
118
153
|
Check if a given string is a valid MongoDB ObjectId (24-character hex).
|
@@ -0,0 +1,10 @@
|
|
1
|
+
most/__init__.py,sha256=62uFFeM_1VVR83K3bTYWK3PEoqnmFCy9aWYerQ6U4Ds,67
|
2
|
+
most/api.py,sha256=8OzUI_Af0Ct1hx0fopTf3bDGPU8gxWuuMP1VvxpAFiU,14227
|
3
|
+
most/async_api.py,sha256=40orcOYLvFJTTlfYGIyyUXvvsfKYchDblRXzHNNGNPs,15124
|
4
|
+
most/score_calculation.py,sha256=oGBEIzefKiqCS77BOX7-jHTvpLRkH0Vhnqu1IVDmsdM,800
|
5
|
+
most/types.py,sha256=Qgyv261J8b1cfbmeITz1C9QgkoCMGQQd_L4t4M3dd6M,3603
|
6
|
+
most_client-1.0.20.dist-info/METADATA,sha256=XTRaD7okJvsBLOJWUKlRTPaRhM423CFOkQ6wuT2_1XI,1027
|
7
|
+
most_client-1.0.20.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
8
|
+
most_client-1.0.20.dist-info/top_level.txt,sha256=2g5fk02LKkM1hV3pVVti_LQ60TToLBcR2zQ3JEKGVk8,5
|
9
|
+
most_client-1.0.20.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
10
|
+
most_client-1.0.20.dist-info/RECORD,,
|
@@ -1,9 +0,0 @@
|
|
1
|
-
most/__init__.py,sha256=62uFFeM_1VVR83K3bTYWK3PEoqnmFCy9aWYerQ6U4Ds,67
|
2
|
-
most/api.py,sha256=IvgklvaP9fvcr_fy-gGvnEDWcyxPRTxNN0MO492YgT0,12101
|
3
|
-
most/async_api.py,sha256=tFFLTWhGVexVz5v9hYuNp4BqFEWTNSp_6DLSAQBjF9c,12858
|
4
|
-
most/types.py,sha256=apUz6FHFAHWJNVvRh57wVQk5DFw2XKnLLhkAyWgtvfw,2825
|
5
|
-
most_client-1.0.18.dist-info/METADATA,sha256=bJfi-Nsqkp3oHirr417vvUtJgo79AzaCOqsBUSUJq58,1027
|
6
|
-
most_client-1.0.18.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
7
|
-
most_client-1.0.18.dist-info/top_level.txt,sha256=2g5fk02LKkM1hV3pVVti_LQ60TToLBcR2zQ3JEKGVk8,5
|
8
|
-
most_client-1.0.18.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
9
|
-
most_client-1.0.18.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|