sarvamai 0.1.22a3__py3-none-any.whl → 0.1.23a1__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.
- sarvamai/__init__.py +405 -206
- sarvamai/chat/raw_client.py +20 -20
- sarvamai/client.py +186 -34
- sarvamai/core/__init__.py +76 -21
- sarvamai/core/client_wrapper.py +19 -3
- sarvamai/core/force_multipart.py +4 -2
- sarvamai/core/http_client.py +217 -97
- sarvamai/core/http_response.py +1 -1
- sarvamai/core/http_sse/__init__.py +42 -0
- sarvamai/core/http_sse/_api.py +112 -0
- sarvamai/core/http_sse/_decoders.py +61 -0
- sarvamai/core/http_sse/_exceptions.py +7 -0
- sarvamai/core/http_sse/_models.py +17 -0
- sarvamai/core/jsonable_encoder.py +8 -0
- sarvamai/core/pydantic_utilities.py +110 -4
- sarvamai/errors/__init__.py +40 -6
- sarvamai/errors/bad_request_error.py +1 -1
- sarvamai/errors/forbidden_error.py +1 -1
- sarvamai/errors/internal_server_error.py +1 -1
- sarvamai/errors/service_unavailable_error.py +1 -1
- sarvamai/errors/too_many_requests_error.py +1 -1
- sarvamai/errors/unprocessable_entity_error.py +1 -1
- sarvamai/requests/__init__.py +150 -62
- sarvamai/requests/audio_data.py +0 -6
- sarvamai/requests/error_response_data.py +1 -1
- sarvamai/requests/file_signed_url_details.py +1 -1
- sarvamai/requests/speech_to_text_transcription_data.py +2 -8
- sarvamai/requests/speech_to_text_translate_transcription_data.py +0 -6
- sarvamai/speech_to_text/raw_client.py +54 -52
- sarvamai/speech_to_text_job/job.py +100 -2
- sarvamai/speech_to_text_job/raw_client.py +134 -130
- sarvamai/speech_to_text_streaming/__init__.py +38 -10
- sarvamai/speech_to_text_streaming/client.py +0 -44
- sarvamai/speech_to_text_streaming/raw_client.py +0 -44
- sarvamai/speech_to_text_streaming/types/__init__.py +36 -8
- sarvamai/speech_to_text_translate_job/job.py +100 -2
- sarvamai/speech_to_text_translate_job/raw_client.py +134 -130
- sarvamai/speech_to_text_translate_streaming/__init__.py +36 -9
- sarvamai/speech_to_text_translate_streaming/client.py +0 -44
- sarvamai/speech_to_text_translate_streaming/raw_client.py +0 -44
- sarvamai/speech_to_text_translate_streaming/types/__init__.py +36 -9
- sarvamai/text/client.py +0 -12
- sarvamai/text/raw_client.py +60 -72
- sarvamai/text_to_speech/client.py +18 -0
- sarvamai/text_to_speech/raw_client.py +38 -20
- sarvamai/text_to_speech_streaming/__init__.py +28 -1
- sarvamai/text_to_speech_streaming/types/__init__.py +30 -1
- sarvamai/types/__init__.py +222 -102
- sarvamai/types/audio_data.py +0 -6
- sarvamai/types/chat_completion_request_message.py +6 -2
- sarvamai/types/completion_event_flag.py +3 -1
- sarvamai/types/error_response_data.py +1 -1
- sarvamai/types/file_signed_url_details.py +1 -1
- sarvamai/types/speech_to_text_transcription_data.py +2 -8
- sarvamai/types/speech_to_text_translate_transcription_data.py +0 -6
- {sarvamai-0.1.22a3.dist-info → sarvamai-0.1.23a1.dist-info}/METADATA +2 -1
- {sarvamai-0.1.22a3.dist-info → sarvamai-0.1.23a1.dist-info}/RECORD +58 -59
- sarvamai/speech_to_text_streaming/types/speech_to_text_streaming_input_audio_codec.py +0 -33
- sarvamai/speech_to_text_streaming/types/speech_to_text_streaming_stream_ongoing_speech_results.py +0 -5
- sarvamai/speech_to_text_translate_streaming/types/speech_to_text_translate_streaming_input_audio_codec.py +0 -33
- sarvamai/speech_to_text_translate_streaming/types/speech_to_text_translate_streaming_stream_ongoing_speech_results.py +0 -5
- sarvamai/types/audio_data_input_audio_codec.py +0 -33
- sarvamai/types/response_speech_state.py +0 -7
- {sarvamai-0.1.22a3.dist-info → sarvamai-0.1.23a1.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
|
|
5
|
+
from ._models import ServerSentEvent
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SSEDecoder:
|
|
9
|
+
def __init__(self) -> None:
|
|
10
|
+
self._event = ""
|
|
11
|
+
self._data: List[str] = []
|
|
12
|
+
self._last_event_id = ""
|
|
13
|
+
self._retry: Optional[int] = None
|
|
14
|
+
|
|
15
|
+
def decode(self, line: str) -> Optional[ServerSentEvent]:
|
|
16
|
+
# See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501
|
|
17
|
+
|
|
18
|
+
if not line:
|
|
19
|
+
if not self._event and not self._data and not self._last_event_id and self._retry is None:
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
sse = ServerSentEvent(
|
|
23
|
+
event=self._event,
|
|
24
|
+
data="\n".join(self._data),
|
|
25
|
+
id=self._last_event_id,
|
|
26
|
+
retry=self._retry,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# NOTE: as per the SSE spec, do not reset last_event_id.
|
|
30
|
+
self._event = ""
|
|
31
|
+
self._data = []
|
|
32
|
+
self._retry = None
|
|
33
|
+
|
|
34
|
+
return sse
|
|
35
|
+
|
|
36
|
+
if line.startswith(":"):
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
fieldname, _, value = line.partition(":")
|
|
40
|
+
|
|
41
|
+
if value.startswith(" "):
|
|
42
|
+
value = value[1:]
|
|
43
|
+
|
|
44
|
+
if fieldname == "event":
|
|
45
|
+
self._event = value
|
|
46
|
+
elif fieldname == "data":
|
|
47
|
+
self._data.append(value)
|
|
48
|
+
elif fieldname == "id":
|
|
49
|
+
if "\0" in value:
|
|
50
|
+
pass
|
|
51
|
+
else:
|
|
52
|
+
self._last_event_id = value
|
|
53
|
+
elif fieldname == "retry":
|
|
54
|
+
try:
|
|
55
|
+
self._retry = int(value)
|
|
56
|
+
except (TypeError, ValueError):
|
|
57
|
+
pass
|
|
58
|
+
else:
|
|
59
|
+
pass # Field is ignored.
|
|
60
|
+
|
|
61
|
+
return None
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True)
|
|
9
|
+
class ServerSentEvent:
|
|
10
|
+
event: str = "message"
|
|
11
|
+
data: str = ""
|
|
12
|
+
id: str = ""
|
|
13
|
+
retry: Optional[int] = None
|
|
14
|
+
|
|
15
|
+
def json(self) -> Any:
|
|
16
|
+
"""Parse the data field as JSON."""
|
|
17
|
+
return json.loads(self.data)
|
|
@@ -30,6 +30,10 @@ DictIntStrAny = Dict[Union[int, str], Any]
|
|
|
30
30
|
|
|
31
31
|
def jsonable_encoder(obj: Any, custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None) -> Any:
|
|
32
32
|
custom_encoder = custom_encoder or {}
|
|
33
|
+
# Generated SDKs use Ellipsis (`...`) as the sentinel value for "OMIT".
|
|
34
|
+
# OMIT values should be excluded from serialized payloads.
|
|
35
|
+
if obj is Ellipsis:
|
|
36
|
+
return None
|
|
33
37
|
if custom_encoder:
|
|
34
38
|
if type(obj) in custom_encoder:
|
|
35
39
|
return custom_encoder[type(obj)](obj)
|
|
@@ -70,6 +74,8 @@ def jsonable_encoder(obj: Any, custom_encoder: Optional[Dict[Any, Callable[[Any]
|
|
|
70
74
|
allowed_keys = set(obj.keys())
|
|
71
75
|
for key, value in obj.items():
|
|
72
76
|
if key in allowed_keys:
|
|
77
|
+
if value is Ellipsis:
|
|
78
|
+
continue
|
|
73
79
|
encoded_key = jsonable_encoder(key, custom_encoder=custom_encoder)
|
|
74
80
|
encoded_value = jsonable_encoder(value, custom_encoder=custom_encoder)
|
|
75
81
|
encoded_dict[encoded_key] = encoded_value
|
|
@@ -77,6 +83,8 @@ def jsonable_encoder(obj: Any, custom_encoder: Optional[Dict[Any, Callable[[Any]
|
|
|
77
83
|
if isinstance(obj, (list, set, frozenset, GeneratorType, tuple)):
|
|
78
84
|
encoded_list = []
|
|
79
85
|
for item in obj:
|
|
86
|
+
if item is Ellipsis:
|
|
87
|
+
continue
|
|
80
88
|
encoded_list.append(jsonable_encoder(item, custom_encoder=custom_encoder))
|
|
81
89
|
return encoded_list
|
|
82
90
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# nopycln: file
|
|
4
4
|
import datetime as dt
|
|
5
|
+
import inspect
|
|
5
6
|
from collections import defaultdict
|
|
6
7
|
from typing import Any, Callable, ClassVar, Dict, List, Mapping, Optional, Set, Tuple, Type, TypeVar, Union, cast
|
|
7
8
|
|
|
@@ -37,7 +38,36 @@ Model = TypeVar("Model", bound=pydantic.BaseModel)
|
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
def parse_obj_as(type_: Type[T], object_: Any) -> T:
|
|
40
|
-
|
|
41
|
+
# convert_and_respect_annotation_metadata is required for TypedDict aliasing.
|
|
42
|
+
#
|
|
43
|
+
# For Pydantic models, whether we should pre-dealias depends on how the model encodes aliasing:
|
|
44
|
+
# - If the model uses real Pydantic aliases (pydantic.Field(alias=...)), then we must pass wire keys through
|
|
45
|
+
# unchanged so Pydantic can validate them.
|
|
46
|
+
# - If the model encodes aliasing only via FieldMetadata annotations, then we MUST pre-dealias because Pydantic
|
|
47
|
+
# will not recognize those aliases during validation.
|
|
48
|
+
if inspect.isclass(type_) and issubclass(type_, pydantic.BaseModel):
|
|
49
|
+
has_pydantic_aliases = False
|
|
50
|
+
if IS_PYDANTIC_V2:
|
|
51
|
+
for field_name, field_info in getattr(type_, "model_fields", {}).items(): # type: ignore[attr-defined]
|
|
52
|
+
alias = getattr(field_info, "alias", None)
|
|
53
|
+
if alias is not None and alias != field_name:
|
|
54
|
+
has_pydantic_aliases = True
|
|
55
|
+
break
|
|
56
|
+
else:
|
|
57
|
+
for field in getattr(type_, "__fields__", {}).values():
|
|
58
|
+
alias = getattr(field, "alias", None)
|
|
59
|
+
name = getattr(field, "name", None)
|
|
60
|
+
if alias is not None and name is not None and alias != name:
|
|
61
|
+
has_pydantic_aliases = True
|
|
62
|
+
break
|
|
63
|
+
|
|
64
|
+
dealiased_object = (
|
|
65
|
+
object_
|
|
66
|
+
if has_pydantic_aliases
|
|
67
|
+
else convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read")
|
|
68
|
+
)
|
|
69
|
+
else:
|
|
70
|
+
dealiased_object = convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read")
|
|
41
71
|
if IS_PYDANTIC_V2:
|
|
42
72
|
adapter = pydantic.TypeAdapter(type_) # type: ignore[attr-defined]
|
|
43
73
|
return adapter.validate_python(dealiased_object)
|
|
@@ -59,9 +89,46 @@ class UniversalBaseModel(pydantic.BaseModel):
|
|
|
59
89
|
protected_namespaces=(),
|
|
60
90
|
)
|
|
61
91
|
|
|
92
|
+
@pydantic.model_validator(mode="before") # type: ignore[attr-defined]
|
|
93
|
+
@classmethod
|
|
94
|
+
def _coerce_field_names_to_aliases(cls, data: Any) -> Any:
|
|
95
|
+
"""
|
|
96
|
+
Accept Python field names in input by rewriting them to their Pydantic aliases,
|
|
97
|
+
while avoiding silent collisions when a key could refer to multiple fields.
|
|
98
|
+
"""
|
|
99
|
+
if not isinstance(data, Mapping):
|
|
100
|
+
return data
|
|
101
|
+
|
|
102
|
+
fields = getattr(cls, "model_fields", {}) # type: ignore[attr-defined]
|
|
103
|
+
name_to_alias: Dict[str, str] = {}
|
|
104
|
+
alias_to_name: Dict[str, str] = {}
|
|
105
|
+
|
|
106
|
+
for name, field_info in fields.items():
|
|
107
|
+
alias = getattr(field_info, "alias", None) or name
|
|
108
|
+
name_to_alias[name] = alias
|
|
109
|
+
if alias != name:
|
|
110
|
+
alias_to_name[alias] = name
|
|
111
|
+
|
|
112
|
+
# Detect ambiguous keys: a key that is an alias for one field and a name for another.
|
|
113
|
+
ambiguous_keys = set(alias_to_name.keys()).intersection(set(name_to_alias.keys()))
|
|
114
|
+
for key in ambiguous_keys:
|
|
115
|
+
if key in data and name_to_alias[key] not in data:
|
|
116
|
+
raise ValueError(
|
|
117
|
+
f"Ambiguous input key '{key}': it is both a field name and an alias. "
|
|
118
|
+
"Provide the explicit alias key to disambiguate."
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
original_keys = set(data.keys())
|
|
122
|
+
rewritten: Dict[str, Any] = dict(data)
|
|
123
|
+
for name, alias in name_to_alias.items():
|
|
124
|
+
if alias != name and name in original_keys and alias not in rewritten:
|
|
125
|
+
rewritten[alias] = rewritten.pop(name)
|
|
126
|
+
|
|
127
|
+
return rewritten
|
|
128
|
+
|
|
62
129
|
@pydantic.model_serializer(mode="plain", when_used="json") # type: ignore[attr-defined]
|
|
63
130
|
def serialize_model(self) -> Any: # type: ignore[name-defined]
|
|
64
|
-
serialized = self.
|
|
131
|
+
serialized = self.dict() # type: ignore[attr-defined]
|
|
65
132
|
data = {k: serialize_datetime(v) if isinstance(v, dt.datetime) else v for k, v in serialized.items()}
|
|
66
133
|
return data
|
|
67
134
|
|
|
@@ -71,6 +138,40 @@ class UniversalBaseModel(pydantic.BaseModel):
|
|
|
71
138
|
smart_union = True
|
|
72
139
|
json_encoders = {dt.datetime: serialize_datetime}
|
|
73
140
|
|
|
141
|
+
@pydantic.root_validator(pre=True)
|
|
142
|
+
def _coerce_field_names_to_aliases(cls, values: Any) -> Any:
|
|
143
|
+
"""
|
|
144
|
+
Pydantic v1 equivalent of _coerce_field_names_to_aliases.
|
|
145
|
+
"""
|
|
146
|
+
if not isinstance(values, Mapping):
|
|
147
|
+
return values
|
|
148
|
+
|
|
149
|
+
fields = getattr(cls, "__fields__", {})
|
|
150
|
+
name_to_alias: Dict[str, str] = {}
|
|
151
|
+
alias_to_name: Dict[str, str] = {}
|
|
152
|
+
|
|
153
|
+
for name, field in fields.items():
|
|
154
|
+
alias = getattr(field, "alias", None) or name
|
|
155
|
+
name_to_alias[name] = alias
|
|
156
|
+
if alias != name:
|
|
157
|
+
alias_to_name[alias] = name
|
|
158
|
+
|
|
159
|
+
ambiguous_keys = set(alias_to_name.keys()).intersection(set(name_to_alias.keys()))
|
|
160
|
+
for key in ambiguous_keys:
|
|
161
|
+
if key in values and name_to_alias[key] not in values:
|
|
162
|
+
raise ValueError(
|
|
163
|
+
f"Ambiguous input key '{key}': it is both a field name and an alias. "
|
|
164
|
+
"Provide the explicit alias key to disambiguate."
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
original_keys = set(values.keys())
|
|
168
|
+
rewritten: Dict[str, Any] = dict(values)
|
|
169
|
+
for name, alias in name_to_alias.items():
|
|
170
|
+
if alias != name and name in original_keys and alias not in rewritten:
|
|
171
|
+
rewritten[alias] = rewritten.pop(name)
|
|
172
|
+
|
|
173
|
+
return rewritten
|
|
174
|
+
|
|
74
175
|
@classmethod
|
|
75
176
|
def model_construct(cls: Type["Model"], _fields_set: Optional[Set[str]] = None, **values: Any) -> "Model":
|
|
76
177
|
dealiased_object = convert_and_respect_annotation_metadata(object_=values, annotation=cls, direction="read")
|
|
@@ -147,7 +248,10 @@ class UniversalBaseModel(pydantic.BaseModel):
|
|
|
147
248
|
|
|
148
249
|
dict_dump = super().dict(**kwargs_with_defaults_exclude_unset_include_fields)
|
|
149
250
|
|
|
150
|
-
return
|
|
251
|
+
return cast(
|
|
252
|
+
Dict[str, Any],
|
|
253
|
+
convert_and_respect_annotation_metadata(object_=dict_dump, annotation=self.__class__, direction="write"),
|
|
254
|
+
)
|
|
151
255
|
|
|
152
256
|
|
|
153
257
|
def _union_list_of_pydantic_dicts(source: List[Any], destination: List[Any]) -> List[Any]:
|
|
@@ -217,7 +321,9 @@ def universal_root_validator(
|
|
|
217
321
|
) -> Callable[[AnyCallable], AnyCallable]:
|
|
218
322
|
def decorator(func: AnyCallable) -> AnyCallable:
|
|
219
323
|
if IS_PYDANTIC_V2:
|
|
220
|
-
|
|
324
|
+
# In Pydantic v2, for RootModel we always use "before" mode
|
|
325
|
+
# The custom validators transform the input value before the model is created
|
|
326
|
+
return cast(AnyCallable, pydantic.model_validator(mode="before")(func)) # type: ignore[attr-defined]
|
|
221
327
|
return cast(AnyCallable, pydantic.root_validator(pre=pre)(func)) # type: ignore[call-overload]
|
|
222
328
|
|
|
223
329
|
return decorator
|
sarvamai/errors/__init__.py
CHANGED
|
@@ -2,12 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
# isort: skip_file
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
from
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from .
|
|
10
|
-
from .
|
|
5
|
+
import typing
|
|
6
|
+
from importlib import import_module
|
|
7
|
+
|
|
8
|
+
if typing.TYPE_CHECKING:
|
|
9
|
+
from .bad_request_error import BadRequestError
|
|
10
|
+
from .forbidden_error import ForbiddenError
|
|
11
|
+
from .internal_server_error import InternalServerError
|
|
12
|
+
from .service_unavailable_error import ServiceUnavailableError
|
|
13
|
+
from .too_many_requests_error import TooManyRequestsError
|
|
14
|
+
from .unprocessable_entity_error import UnprocessableEntityError
|
|
15
|
+
_dynamic_imports: typing.Dict[str, str] = {
|
|
16
|
+
"BadRequestError": ".bad_request_error",
|
|
17
|
+
"ForbiddenError": ".forbidden_error",
|
|
18
|
+
"InternalServerError": ".internal_server_error",
|
|
19
|
+
"ServiceUnavailableError": ".service_unavailable_error",
|
|
20
|
+
"TooManyRequestsError": ".too_many_requests_error",
|
|
21
|
+
"UnprocessableEntityError": ".unprocessable_entity_error",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def __getattr__(attr_name: str) -> typing.Any:
|
|
26
|
+
module_name = _dynamic_imports.get(attr_name)
|
|
27
|
+
if module_name is None:
|
|
28
|
+
raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
|
|
29
|
+
try:
|
|
30
|
+
module = import_module(module_name, __package__)
|
|
31
|
+
if module_name == f".{attr_name}":
|
|
32
|
+
return module
|
|
33
|
+
else:
|
|
34
|
+
return getattr(module, attr_name)
|
|
35
|
+
except ImportError as e:
|
|
36
|
+
raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
|
|
37
|
+
except AttributeError as e:
|
|
38
|
+
raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def __dir__():
|
|
42
|
+
lazy_attrs = list(_dynamic_imports.keys())
|
|
43
|
+
return sorted(lazy_attrs)
|
|
44
|
+
|
|
11
45
|
|
|
12
46
|
__all__ = [
|
|
13
47
|
"BadRequestError",
|
|
@@ -6,5 +6,5 @@ from ..core.api_error import ApiError
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class BadRequestError(ApiError):
|
|
9
|
-
def __init__(self, body: typing.
|
|
9
|
+
def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
|
|
10
10
|
super().__init__(status_code=400, headers=headers, body=body)
|
|
@@ -6,5 +6,5 @@ from ..core.api_error import ApiError
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class ForbiddenError(ApiError):
|
|
9
|
-
def __init__(self, body: typing.
|
|
9
|
+
def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
|
|
10
10
|
super().__init__(status_code=403, headers=headers, body=body)
|
|
@@ -6,5 +6,5 @@ from ..core.api_error import ApiError
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class InternalServerError(ApiError):
|
|
9
|
-
def __init__(self, body: typing.
|
|
9
|
+
def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
|
|
10
10
|
super().__init__(status_code=500, headers=headers, body=body)
|
|
@@ -6,5 +6,5 @@ from ..core.api_error import ApiError
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class ServiceUnavailableError(ApiError):
|
|
9
|
-
def __init__(self, body: typing.
|
|
9
|
+
def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
|
|
10
10
|
super().__init__(status_code=503, headers=headers, body=body)
|
|
@@ -6,5 +6,5 @@ from ..core.api_error import ApiError
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class TooManyRequestsError(ApiError):
|
|
9
|
-
def __init__(self, body: typing.
|
|
9
|
+
def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
|
|
10
10
|
super().__init__(status_code=429, headers=headers, body=body)
|
|
@@ -6,5 +6,5 @@ from ..core.api_error import ApiError
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class UnprocessableEntityError(ApiError):
|
|
9
|
-
def __init__(self, body: typing.
|
|
9
|
+
def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
|
|
10
10
|
super().__init__(status_code=422, headers=headers, body=body)
|
sarvamai/requests/__init__.py
CHANGED
|
@@ -2,68 +2,156 @@
|
|
|
2
2
|
|
|
3
3
|
# isort: skip_file
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
from
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from .
|
|
10
|
-
from .
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
13
|
-
from .
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
from .
|
|
24
|
-
from .
|
|
25
|
-
from .
|
|
26
|
-
from .
|
|
27
|
-
from .
|
|
28
|
-
from .
|
|
29
|
-
from .
|
|
30
|
-
from .
|
|
31
|
-
from .
|
|
32
|
-
from .
|
|
33
|
-
from .
|
|
34
|
-
from .
|
|
35
|
-
from .
|
|
36
|
-
from .
|
|
37
|
-
from .
|
|
38
|
-
from .
|
|
39
|
-
from .
|
|
40
|
-
from .
|
|
41
|
-
from .
|
|
42
|
-
from .
|
|
43
|
-
from .
|
|
44
|
-
from .
|
|
45
|
-
from .
|
|
46
|
-
from .
|
|
47
|
-
from .
|
|
48
|
-
from .
|
|
49
|
-
from .
|
|
50
|
-
from .
|
|
51
|
-
from .
|
|
52
|
-
from .
|
|
53
|
-
from .
|
|
54
|
-
from .
|
|
55
|
-
from .
|
|
56
|
-
from .
|
|
57
|
-
from .
|
|
58
|
-
from .
|
|
59
|
-
from .
|
|
60
|
-
from .
|
|
61
|
-
from .
|
|
62
|
-
from .
|
|
63
|
-
from .
|
|
64
|
-
from .
|
|
65
|
-
from .
|
|
66
|
-
from .
|
|
5
|
+
import typing
|
|
6
|
+
from importlib import import_module
|
|
7
|
+
|
|
8
|
+
if typing.TYPE_CHECKING:
|
|
9
|
+
from .audio_data import AudioDataParams
|
|
10
|
+
from .audio_message import AudioMessageParams
|
|
11
|
+
from .audio_output import AudioOutputParams
|
|
12
|
+
from .audio_output_data import AudioOutputDataParams
|
|
13
|
+
from .base_job_parameters import BaseJobParametersParams
|
|
14
|
+
from .bulk_job_callback import BulkJobCallbackParams
|
|
15
|
+
from .bulk_job_init_response_v_1 import BulkJobInitResponseV1Params
|
|
16
|
+
from .chat_completion_request_assistant_message import ChatCompletionRequestAssistantMessageParams
|
|
17
|
+
from .chat_completion_request_message import (
|
|
18
|
+
ChatCompletionRequestMessageParams,
|
|
19
|
+
ChatCompletionRequestMessage_AssistantParams,
|
|
20
|
+
ChatCompletionRequestMessage_SystemParams,
|
|
21
|
+
ChatCompletionRequestMessage_UserParams,
|
|
22
|
+
)
|
|
23
|
+
from .chat_completion_request_system_message import ChatCompletionRequestSystemMessageParams
|
|
24
|
+
from .chat_completion_request_user_message import ChatCompletionRequestUserMessageParams
|
|
25
|
+
from .chat_completion_response_message import ChatCompletionResponseMessageParams
|
|
26
|
+
from .choice import ChoiceParams
|
|
27
|
+
from .completion_usage import CompletionUsageParams
|
|
28
|
+
from .config_message import ConfigMessageParams
|
|
29
|
+
from .configure_connection import ConfigureConnectionParams
|
|
30
|
+
from .configure_connection_data import ConfigureConnectionDataParams
|
|
31
|
+
from .create_chat_completion_response import CreateChatCompletionResponseParams
|
|
32
|
+
from .diarized_entry import DiarizedEntryParams
|
|
33
|
+
from .diarized_transcript import DiarizedTranscriptParams
|
|
34
|
+
from .error_data import ErrorDataParams
|
|
35
|
+
from .error_details import ErrorDetailsParams
|
|
36
|
+
from .error_message import ErrorMessageParams
|
|
37
|
+
from .error_response import ErrorResponseParams
|
|
38
|
+
from .error_response_data import ErrorResponseDataParams
|
|
39
|
+
from .event_response import EventResponseParams
|
|
40
|
+
from .event_response_data import EventResponseDataParams
|
|
41
|
+
from .events_data import EventsDataParams
|
|
42
|
+
from .file_signed_url_details import FileSignedUrlDetailsParams
|
|
43
|
+
from .files_download_response import FilesDownloadResponseParams
|
|
44
|
+
from .files_request import FilesRequestParams
|
|
45
|
+
from .files_upload_response import FilesUploadResponseParams
|
|
46
|
+
from .flush_signal import FlushSignalParams
|
|
47
|
+
from .job_status_v_1_response import JobStatusV1ResponseParams
|
|
48
|
+
from .language_identification_response import LanguageIdentificationResponseParams
|
|
49
|
+
from .ping_signal import PingSignalParams
|
|
50
|
+
from .send_text import SendTextParams
|
|
51
|
+
from .send_text_data import SendTextDataParams
|
|
52
|
+
from .speech_to_text_job_parameters import SpeechToTextJobParametersParams
|
|
53
|
+
from .speech_to_text_response import SpeechToTextResponseParams
|
|
54
|
+
from .speech_to_text_response_data import SpeechToTextResponseDataParams
|
|
55
|
+
from .speech_to_text_streaming_response import SpeechToTextStreamingResponseParams
|
|
56
|
+
from .speech_to_text_transcription_data import SpeechToTextTranscriptionDataParams
|
|
57
|
+
from .speech_to_text_translate_job_parameters import SpeechToTextTranslateJobParametersParams
|
|
58
|
+
from .speech_to_text_translate_response import SpeechToTextTranslateResponseParams
|
|
59
|
+
from .speech_to_text_translate_response_data import SpeechToTextTranslateResponseDataParams
|
|
60
|
+
from .speech_to_text_translate_streaming_response import SpeechToTextTranslateStreamingResponseParams
|
|
61
|
+
from .speech_to_text_translate_transcription_data import SpeechToTextTranslateTranscriptionDataParams
|
|
62
|
+
from .stop_configuration import StopConfigurationParams
|
|
63
|
+
from .stt_flush_signal import SttFlushSignalParams
|
|
64
|
+
from .task_detail_v_1 import TaskDetailV1Params
|
|
65
|
+
from .task_file_details import TaskFileDetailsParams
|
|
66
|
+
from .text_to_speech_response import TextToSpeechResponseParams
|
|
67
|
+
from .timestamps_model import TimestampsModelParams
|
|
68
|
+
from .transcription_metrics import TranscriptionMetricsParams
|
|
69
|
+
from .translation_response import TranslationResponseParams
|
|
70
|
+
from .transliteration_response import TransliterationResponseParams
|
|
71
|
+
_dynamic_imports: typing.Dict[str, str] = {
|
|
72
|
+
"AudioDataParams": ".audio_data",
|
|
73
|
+
"AudioMessageParams": ".audio_message",
|
|
74
|
+
"AudioOutputDataParams": ".audio_output_data",
|
|
75
|
+
"AudioOutputParams": ".audio_output",
|
|
76
|
+
"BaseJobParametersParams": ".base_job_parameters",
|
|
77
|
+
"BulkJobCallbackParams": ".bulk_job_callback",
|
|
78
|
+
"BulkJobInitResponseV1Params": ".bulk_job_init_response_v_1",
|
|
79
|
+
"ChatCompletionRequestAssistantMessageParams": ".chat_completion_request_assistant_message",
|
|
80
|
+
"ChatCompletionRequestMessageParams": ".chat_completion_request_message",
|
|
81
|
+
"ChatCompletionRequestMessage_AssistantParams": ".chat_completion_request_message",
|
|
82
|
+
"ChatCompletionRequestMessage_SystemParams": ".chat_completion_request_message",
|
|
83
|
+
"ChatCompletionRequestMessage_UserParams": ".chat_completion_request_message",
|
|
84
|
+
"ChatCompletionRequestSystemMessageParams": ".chat_completion_request_system_message",
|
|
85
|
+
"ChatCompletionRequestUserMessageParams": ".chat_completion_request_user_message",
|
|
86
|
+
"ChatCompletionResponseMessageParams": ".chat_completion_response_message",
|
|
87
|
+
"ChoiceParams": ".choice",
|
|
88
|
+
"CompletionUsageParams": ".completion_usage",
|
|
89
|
+
"ConfigMessageParams": ".config_message",
|
|
90
|
+
"ConfigureConnectionDataParams": ".configure_connection_data",
|
|
91
|
+
"ConfigureConnectionParams": ".configure_connection",
|
|
92
|
+
"CreateChatCompletionResponseParams": ".create_chat_completion_response",
|
|
93
|
+
"DiarizedEntryParams": ".diarized_entry",
|
|
94
|
+
"DiarizedTranscriptParams": ".diarized_transcript",
|
|
95
|
+
"ErrorDataParams": ".error_data",
|
|
96
|
+
"ErrorDetailsParams": ".error_details",
|
|
97
|
+
"ErrorMessageParams": ".error_message",
|
|
98
|
+
"ErrorResponseDataParams": ".error_response_data",
|
|
99
|
+
"ErrorResponseParams": ".error_response",
|
|
100
|
+
"EventResponseDataParams": ".event_response_data",
|
|
101
|
+
"EventResponseParams": ".event_response",
|
|
102
|
+
"EventsDataParams": ".events_data",
|
|
103
|
+
"FileSignedUrlDetailsParams": ".file_signed_url_details",
|
|
104
|
+
"FilesDownloadResponseParams": ".files_download_response",
|
|
105
|
+
"FilesRequestParams": ".files_request",
|
|
106
|
+
"FilesUploadResponseParams": ".files_upload_response",
|
|
107
|
+
"FlushSignalParams": ".flush_signal",
|
|
108
|
+
"JobStatusV1ResponseParams": ".job_status_v_1_response",
|
|
109
|
+
"LanguageIdentificationResponseParams": ".language_identification_response",
|
|
110
|
+
"PingSignalParams": ".ping_signal",
|
|
111
|
+
"SendTextDataParams": ".send_text_data",
|
|
112
|
+
"SendTextParams": ".send_text",
|
|
113
|
+
"SpeechToTextJobParametersParams": ".speech_to_text_job_parameters",
|
|
114
|
+
"SpeechToTextResponseDataParams": ".speech_to_text_response_data",
|
|
115
|
+
"SpeechToTextResponseParams": ".speech_to_text_response",
|
|
116
|
+
"SpeechToTextStreamingResponseParams": ".speech_to_text_streaming_response",
|
|
117
|
+
"SpeechToTextTranscriptionDataParams": ".speech_to_text_transcription_data",
|
|
118
|
+
"SpeechToTextTranslateJobParametersParams": ".speech_to_text_translate_job_parameters",
|
|
119
|
+
"SpeechToTextTranslateResponseDataParams": ".speech_to_text_translate_response_data",
|
|
120
|
+
"SpeechToTextTranslateResponseParams": ".speech_to_text_translate_response",
|
|
121
|
+
"SpeechToTextTranslateStreamingResponseParams": ".speech_to_text_translate_streaming_response",
|
|
122
|
+
"SpeechToTextTranslateTranscriptionDataParams": ".speech_to_text_translate_transcription_data",
|
|
123
|
+
"StopConfigurationParams": ".stop_configuration",
|
|
124
|
+
"SttFlushSignalParams": ".stt_flush_signal",
|
|
125
|
+
"TaskDetailV1Params": ".task_detail_v_1",
|
|
126
|
+
"TaskFileDetailsParams": ".task_file_details",
|
|
127
|
+
"TextToSpeechResponseParams": ".text_to_speech_response",
|
|
128
|
+
"TimestampsModelParams": ".timestamps_model",
|
|
129
|
+
"TranscriptionMetricsParams": ".transcription_metrics",
|
|
130
|
+
"TranslationResponseParams": ".translation_response",
|
|
131
|
+
"TransliterationResponseParams": ".transliteration_response",
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def __getattr__(attr_name: str) -> typing.Any:
|
|
136
|
+
module_name = _dynamic_imports.get(attr_name)
|
|
137
|
+
if module_name is None:
|
|
138
|
+
raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
|
|
139
|
+
try:
|
|
140
|
+
module = import_module(module_name, __package__)
|
|
141
|
+
if module_name == f".{attr_name}":
|
|
142
|
+
return module
|
|
143
|
+
else:
|
|
144
|
+
return getattr(module, attr_name)
|
|
145
|
+
except ImportError as e:
|
|
146
|
+
raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
|
|
147
|
+
except AttributeError as e:
|
|
148
|
+
raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def __dir__():
|
|
152
|
+
lazy_attrs = list(_dynamic_imports.keys())
|
|
153
|
+
return sorted(lazy_attrs)
|
|
154
|
+
|
|
67
155
|
|
|
68
156
|
__all__ = [
|
|
69
157
|
"AudioDataParams",
|
sarvamai/requests/audio_data.py
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import typing
|
|
4
4
|
|
|
5
5
|
import typing_extensions
|
|
6
|
-
from ..types.audio_data_input_audio_codec import AudioDataInputAudioCodec
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
class AudioDataParams(typing_extensions.TypedDict):
|
|
@@ -27,8 +26,3 @@ class AudioDataParams(typing_extensions.TypedDict):
|
|
|
27
26
|
"""
|
|
28
27
|
Audio encoding format
|
|
29
28
|
"""
|
|
30
|
-
|
|
31
|
-
input_audio_codec: typing_extensions.NotRequired[AudioDataInputAudioCodec]
|
|
32
|
-
"""
|
|
33
|
-
Audio codec/format of the input file. Our API automatically detects all codec formats, but for PCM files specifically (pcm_s16le, pcm_l16, pcm_raw), you must pass this parameter. PCM files supports sample rate 16000 and 8000.
|
|
34
|
-
"""
|
|
@@ -12,7 +12,7 @@ class ErrorResponseDataParams(typing_extensions.TypedDict):
|
|
|
12
12
|
Optional error code for programmatic error handling
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
details: typing_extensions.NotRequired[typing.Dict[str, typing.
|
|
15
|
+
details: typing_extensions.NotRequired[typing.Dict[str, typing.Any]]
|
|
16
16
|
"""
|
|
17
17
|
Additional error details and context information
|
|
18
18
|
"""
|
|
@@ -7,4 +7,4 @@ import typing_extensions
|
|
|
7
7
|
|
|
8
8
|
class FileSignedUrlDetailsParams(typing_extensions.TypedDict):
|
|
9
9
|
file_url: str
|
|
10
|
-
file_metadata: typing_extensions.NotRequired[typing.Dict[str, typing.
|
|
10
|
+
file_metadata: typing_extensions.NotRequired[typing.Dict[str, typing.Any]]
|