sarvamai 0.1.5a0__py3-none-any.whl → 0.1.5a3__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.
Files changed (67) hide show
  1. sarvamai/__init__.py +2 -0
  2. sarvamai/chat/__init__.py +2 -0
  3. sarvamai/chat/client.py +9 -22
  4. sarvamai/chat/raw_client.py +48 -47
  5. sarvamai/client.py +10 -31
  6. sarvamai/core/__init__.py +5 -0
  7. sarvamai/core/api_error.py +13 -5
  8. sarvamai/core/client_wrapper.py +17 -20
  9. sarvamai/core/events.py +30 -0
  10. sarvamai/core/force_multipart.py +16 -0
  11. sarvamai/core/http_client.py +70 -24
  12. sarvamai/core/http_response.py +19 -11
  13. sarvamai/core/pydantic_utilities.py +69 -108
  14. sarvamai/environment.py +10 -3
  15. sarvamai/errors/__init__.py +2 -0
  16. sarvamai/errors/bad_request_error.py +4 -3
  17. sarvamai/errors/forbidden_error.py +4 -3
  18. sarvamai/errors/internal_server_error.py +4 -3
  19. sarvamai/errors/service_unavailable_error.py +4 -2
  20. sarvamai/errors/too_many_requests_error.py +4 -3
  21. sarvamai/errors/unprocessable_entity_error.py +4 -3
  22. sarvamai/requests/__init__.py +2 -0
  23. sarvamai/requests/chat_completion_request_message.py +3 -1
  24. sarvamai/requests/create_chat_completion_response.py +2 -2
  25. sarvamai/requests/diarized_transcript.py +2 -1
  26. sarvamai/requests/error_details.py +0 -1
  27. sarvamai/requests/language_identification_response.py +0 -1
  28. sarvamai/requests/speech_to_text_response.py +1 -2
  29. sarvamai/requests/speech_to_text_translate_response.py +0 -1
  30. sarvamai/requests/text_to_speech_response.py +2 -2
  31. sarvamai/requests/timestamps_model.py +2 -1
  32. sarvamai/requests/translation_response.py +0 -1
  33. sarvamai/requests/transliteration_response.py +0 -1
  34. sarvamai/speech_to_text/__init__.py +2 -0
  35. sarvamai/speech_to_text/client.py +13 -14
  36. sarvamai/speech_to_text/raw_client.py +99 -68
  37. sarvamai/text/__init__.py +2 -0
  38. sarvamai/text/client.py +23 -24
  39. sarvamai/text/raw_client.py +126 -91
  40. sarvamai/text_to_speech/__init__.py +2 -0
  41. sarvamai/text_to_speech/client.py +10 -11
  42. sarvamai/text_to_speech/raw_client.py +49 -38
  43. sarvamai/types/__init__.py +2 -0
  44. sarvamai/types/chat_completion_request_assistant_message.py +3 -3
  45. sarvamai/types/chat_completion_request_message.py +3 -2
  46. sarvamai/types/chat_completion_request_system_message.py +3 -3
  47. sarvamai/types/chat_completion_request_user_message.py +3 -3
  48. sarvamai/types/chat_completion_response_message.py +3 -3
  49. sarvamai/types/choice.py +4 -4
  50. sarvamai/types/completion_usage.py +3 -3
  51. sarvamai/types/create_chat_completion_response.py +3 -3
  52. sarvamai/types/diarized_entry.py +3 -3
  53. sarvamai/types/diarized_transcript.py +3 -3
  54. sarvamai/types/error_details.py +3 -3
  55. sarvamai/types/error_message.py +4 -4
  56. sarvamai/types/language_identification_response.py +2 -2
  57. sarvamai/types/speech_to_text_response.py +3 -3
  58. sarvamai/types/speech_to_text_translate_response.py +3 -3
  59. sarvamai/types/text_to_speech_response.py +2 -2
  60. sarvamai/types/timestamps_model.py +2 -2
  61. sarvamai/types/translation_response.py +2 -2
  62. sarvamai/types/transliteration_response.py +2 -2
  63. sarvamai-0.1.5a3.dist-info/METADATA +27 -0
  64. sarvamai-0.1.5a3.dist-info/RECORD +108 -0
  65. sarvamai-0.1.5a0.dist-info/METADATA +0 -174
  66. sarvamai-0.1.5a0.dist-info/RECORD +0 -106
  67. {sarvamai-0.1.5a0.dist-info → sarvamai-0.1.5a3.dist-info}/WHEEL +0 -0
sarvamai/__init__.py CHANGED
@@ -1,5 +1,7 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ # isort: skip_file
4
+
3
5
  from .types import (
4
6
  ChatCompletionRequestAssistantMessage,
5
7
  ChatCompletionRequestMessage,
sarvamai/chat/__init__.py CHANGED
@@ -1,2 +1,4 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ # isort: skip_file
4
+
sarvamai/chat/client.py CHANGED
@@ -1,15 +1,14 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  import typing
4
- from ..core.client_wrapper import SyncClientWrapper
5
- from .raw_client import RawChatClient
4
+
5
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
6
+ from ..core.request_options import RequestOptions
6
7
  from ..requests.chat_completion_request_message import ChatCompletionRequestMessageParams
7
- from ..types.reasoning_effort import ReasoningEffort
8
8
  from ..requests.stop_configuration import StopConfigurationParams
9
- from ..core.request_options import RequestOptions
10
9
  from ..types.create_chat_completion_response import CreateChatCompletionResponse
11
- from ..core.client_wrapper import AsyncClientWrapper
12
- from .raw_client import AsyncRawChatClient
10
+ from ..types.reasoning_effort import ReasoningEffort
11
+ from .raw_client import AsyncRawChatClient, RawChatClient
13
12
 
14
13
  # this is used as the default value for optional parameters
15
14
  OMIT = typing.cast(typing.Any, ...)
@@ -33,7 +32,6 @@ class ChatClient:
33
32
  def completions(
34
33
  self,
35
34
  *,
36
- authorization: str,
37
35
  messages: typing.Sequence[ChatCompletionRequestMessageParams],
38
36
  temperature: typing.Optional[float] = OMIT,
39
37
  top_p: typing.Optional[float] = OMIT,
@@ -53,9 +51,6 @@ class ChatClient:
53
51
 
54
52
  Parameters
55
53
  ----------
56
- authorization : str
57
- Bearer token for authentication. Format: "Bearer <token>"
58
-
59
54
  messages : typing.Sequence[ChatCompletionRequestMessageParams]
60
55
  A list of messages comprising the conversation so far.
61
56
 
@@ -119,12 +114,10 @@ class ChatClient:
119
114
  api_subscription_key="YOUR_API_SUBSCRIPTION_KEY",
120
115
  )
121
116
  client.chat.completions(
122
- authorization="Authorization",
123
117
  messages=[{"content": "content", "role": "assistant"}],
124
118
  )
125
119
  """
126
- response = self._raw_client.completions(
127
- authorization=authorization,
120
+ _response = self._raw_client.completions(
128
121
  messages=messages,
129
122
  temperature=temperature,
130
123
  top_p=top_p,
@@ -139,7 +132,7 @@ class ChatClient:
139
132
  wiki_grounding=wiki_grounding,
140
133
  request_options=request_options,
141
134
  )
142
- return response.data
135
+ return _response.data
143
136
 
144
137
 
145
138
  class AsyncChatClient:
@@ -160,7 +153,6 @@ class AsyncChatClient:
160
153
  async def completions(
161
154
  self,
162
155
  *,
163
- authorization: str,
164
156
  messages: typing.Sequence[ChatCompletionRequestMessageParams],
165
157
  temperature: typing.Optional[float] = OMIT,
166
158
  top_p: typing.Optional[float] = OMIT,
@@ -180,9 +172,6 @@ class AsyncChatClient:
180
172
 
181
173
  Parameters
182
174
  ----------
183
- authorization : str
184
- Bearer token for authentication. Format: "Bearer <token>"
185
-
186
175
  messages : typing.Sequence[ChatCompletionRequestMessageParams]
187
176
  A list of messages comprising the conversation so far.
188
177
 
@@ -251,15 +240,13 @@ class AsyncChatClient:
251
240
 
252
241
  async def main() -> None:
253
242
  await client.chat.completions(
254
- authorization="Authorization",
255
243
  messages=[{"content": "content", "role": "assistant"}],
256
244
  )
257
245
 
258
246
 
259
247
  asyncio.run(main())
260
248
  """
261
- response = await self._raw_client.completions(
262
- authorization=authorization,
249
+ _response = await self._raw_client.completions(
263
250
  messages=messages,
264
251
  temperature=temperature,
265
252
  top_p=top_p,
@@ -274,4 +261,4 @@ class AsyncChatClient:
274
261
  wiki_grounding=wiki_grounding,
275
262
  request_options=request_options,
276
263
  )
277
- return response.data
264
+ return _response.data
@@ -1,24 +1,23 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  import typing
4
- from ..core.client_wrapper import SyncClientWrapper
5
- from ..requests.chat_completion_request_message import ChatCompletionRequestMessageParams
6
- from ..types.reasoning_effort import ReasoningEffort
7
- from ..requests.stop_configuration import StopConfigurationParams
4
+ from json.decoder import JSONDecodeError
5
+
6
+ from ..core.api_error import ApiError
7
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
+ from ..core.http_response import AsyncHttpResponse, HttpResponse
9
+ from ..core.pydantic_utilities import parse_obj_as
8
10
  from ..core.request_options import RequestOptions
9
- from ..core.http_response import HttpResponse
10
- from ..types.create_chat_completion_response import CreateChatCompletionResponse
11
11
  from ..core.serialization import convert_and_respect_annotation_metadata
12
- from ..core.pydantic_utilities import parse_obj_as
13
12
  from ..errors.bad_request_error import BadRequestError
14
13
  from ..errors.forbidden_error import ForbiddenError
15
- from ..errors.unprocessable_entity_error import UnprocessableEntityError
16
- from ..errors.too_many_requests_error import TooManyRequestsError
17
14
  from ..errors.internal_server_error import InternalServerError
18
- from json.decoder import JSONDecodeError
19
- from ..core.api_error import ApiError
20
- from ..core.client_wrapper import AsyncClientWrapper
21
- from ..core.http_response import AsyncHttpResponse
15
+ from ..errors.too_many_requests_error import TooManyRequestsError
16
+ from ..errors.unprocessable_entity_error import UnprocessableEntityError
17
+ from ..requests.chat_completion_request_message import ChatCompletionRequestMessageParams
18
+ from ..requests.stop_configuration import StopConfigurationParams
19
+ from ..types.create_chat_completion_response import CreateChatCompletionResponse
20
+ from ..types.reasoning_effort import ReasoningEffort
22
21
 
23
22
  # this is used as the default value for optional parameters
24
23
  OMIT = typing.cast(typing.Any, ...)
@@ -31,7 +30,6 @@ class RawChatClient:
31
30
  def completions(
32
31
  self,
33
32
  *,
34
- authorization: str,
35
33
  messages: typing.Sequence[ChatCompletionRequestMessageParams],
36
34
  temperature: typing.Optional[float] = OMIT,
37
35
  top_p: typing.Optional[float] = OMIT,
@@ -51,9 +49,6 @@ class RawChatClient:
51
49
 
52
50
  Parameters
53
51
  ----------
54
- authorization : str
55
- Bearer token for authentication. Format: "Bearer <token>"
56
-
57
52
  messages : typing.Sequence[ChatCompletionRequestMessageParams]
58
53
  A list of messages comprising the conversation so far.
59
54
 
@@ -111,6 +106,7 @@ class RawChatClient:
111
106
  """
112
107
  _response = self._client_wrapper.httpx_client.request(
113
108
  "v1/chat/completions",
109
+ base_url=self._client_wrapper.get_environment().base,
114
110
  method="POST",
115
111
  json={
116
112
  "messages": convert_and_respect_annotation_metadata(
@@ -133,7 +129,6 @@ class RawChatClient:
133
129
  },
134
130
  headers={
135
131
  "content-type": "application/json",
136
- "Authorization": str(authorization) if authorization is not None else None,
137
132
  },
138
133
  request_options=request_options,
139
134
  omit=OMIT,
@@ -150,58 +145,63 @@ class RawChatClient:
150
145
  return HttpResponse(response=_response, data=_data)
151
146
  if _response.status_code == 400:
152
147
  raise BadRequestError(
153
- typing.cast(
148
+ headers=dict(_response.headers),
149
+ body=typing.cast(
154
150
  typing.Optional[typing.Any],
155
151
  parse_obj_as(
156
152
  type_=typing.Optional[typing.Any], # type: ignore
157
153
  object_=_response.json(),
158
154
  ),
159
- )
155
+ ),
160
156
  )
161
157
  if _response.status_code == 403:
162
158
  raise ForbiddenError(
163
- typing.cast(
159
+ headers=dict(_response.headers),
160
+ body=typing.cast(
164
161
  typing.Optional[typing.Any],
165
162
  parse_obj_as(
166
163
  type_=typing.Optional[typing.Any], # type: ignore
167
164
  object_=_response.json(),
168
165
  ),
169
- )
166
+ ),
170
167
  )
171
168
  if _response.status_code == 422:
172
169
  raise UnprocessableEntityError(
173
- typing.cast(
170
+ headers=dict(_response.headers),
171
+ body=typing.cast(
174
172
  typing.Optional[typing.Any],
175
173
  parse_obj_as(
176
174
  type_=typing.Optional[typing.Any], # type: ignore
177
175
  object_=_response.json(),
178
176
  ),
179
- )
177
+ ),
180
178
  )
181
179
  if _response.status_code == 429:
182
180
  raise TooManyRequestsError(
183
- typing.cast(
181
+ headers=dict(_response.headers),
182
+ body=typing.cast(
184
183
  typing.Optional[typing.Any],
185
184
  parse_obj_as(
186
185
  type_=typing.Optional[typing.Any], # type: ignore
187
186
  object_=_response.json(),
188
187
  ),
189
- )
188
+ ),
190
189
  )
191
190
  if _response.status_code == 500:
192
191
  raise InternalServerError(
193
- typing.cast(
192
+ headers=dict(_response.headers),
193
+ body=typing.cast(
194
194
  typing.Optional[typing.Any],
195
195
  parse_obj_as(
196
196
  type_=typing.Optional[typing.Any], # type: ignore
197
197
  object_=_response.json(),
198
198
  ),
199
- )
199
+ ),
200
200
  )
201
201
  _response_json = _response.json()
202
202
  except JSONDecodeError:
203
- raise ApiError(status_code=_response.status_code, body=_response.text)
204
- raise ApiError(status_code=_response.status_code, body=_response_json)
203
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
204
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
205
205
 
206
206
 
207
207
  class AsyncRawChatClient:
@@ -211,7 +211,6 @@ class AsyncRawChatClient:
211
211
  async def completions(
212
212
  self,
213
213
  *,
214
- authorization: str,
215
214
  messages: typing.Sequence[ChatCompletionRequestMessageParams],
216
215
  temperature: typing.Optional[float] = OMIT,
217
216
  top_p: typing.Optional[float] = OMIT,
@@ -231,9 +230,6 @@ class AsyncRawChatClient:
231
230
 
232
231
  Parameters
233
232
  ----------
234
- authorization : str
235
- Bearer token for authentication. Format: "Bearer <token>"
236
-
237
233
  messages : typing.Sequence[ChatCompletionRequestMessageParams]
238
234
  A list of messages comprising the conversation so far.
239
235
 
@@ -291,6 +287,7 @@ class AsyncRawChatClient:
291
287
  """
292
288
  _response = await self._client_wrapper.httpx_client.request(
293
289
  "v1/chat/completions",
290
+ base_url=self._client_wrapper.get_environment().base,
294
291
  method="POST",
295
292
  json={
296
293
  "messages": convert_and_respect_annotation_metadata(
@@ -313,7 +310,6 @@ class AsyncRawChatClient:
313
310
  },
314
311
  headers={
315
312
  "content-type": "application/json",
316
- "Authorization": str(authorization) if authorization is not None else None,
317
313
  },
318
314
  request_options=request_options,
319
315
  omit=OMIT,
@@ -330,55 +326,60 @@ class AsyncRawChatClient:
330
326
  return AsyncHttpResponse(response=_response, data=_data)
331
327
  if _response.status_code == 400:
332
328
  raise BadRequestError(
333
- typing.cast(
329
+ headers=dict(_response.headers),
330
+ body=typing.cast(
334
331
  typing.Optional[typing.Any],
335
332
  parse_obj_as(
336
333
  type_=typing.Optional[typing.Any], # type: ignore
337
334
  object_=_response.json(),
338
335
  ),
339
- )
336
+ ),
340
337
  )
341
338
  if _response.status_code == 403:
342
339
  raise ForbiddenError(
343
- typing.cast(
340
+ headers=dict(_response.headers),
341
+ body=typing.cast(
344
342
  typing.Optional[typing.Any],
345
343
  parse_obj_as(
346
344
  type_=typing.Optional[typing.Any], # type: ignore
347
345
  object_=_response.json(),
348
346
  ),
349
- )
347
+ ),
350
348
  )
351
349
  if _response.status_code == 422:
352
350
  raise UnprocessableEntityError(
353
- typing.cast(
351
+ headers=dict(_response.headers),
352
+ body=typing.cast(
354
353
  typing.Optional[typing.Any],
355
354
  parse_obj_as(
356
355
  type_=typing.Optional[typing.Any], # type: ignore
357
356
  object_=_response.json(),
358
357
  ),
359
- )
358
+ ),
360
359
  )
361
360
  if _response.status_code == 429:
362
361
  raise TooManyRequestsError(
363
- typing.cast(
362
+ headers=dict(_response.headers),
363
+ body=typing.cast(
364
364
  typing.Optional[typing.Any],
365
365
  parse_obj_as(
366
366
  type_=typing.Optional[typing.Any], # type: ignore
367
367
  object_=_response.json(),
368
368
  ),
369
- )
369
+ ),
370
370
  )
371
371
  if _response.status_code == 500:
372
372
  raise InternalServerError(
373
- typing.cast(
373
+ headers=dict(_response.headers),
374
+ body=typing.cast(
374
375
  typing.Optional[typing.Any],
375
376
  parse_obj_as(
376
377
  type_=typing.Optional[typing.Any], # type: ignore
377
378
  object_=_response.json(),
378
379
  ),
379
- )
380
+ ),
380
381
  )
381
382
  _response_json = _response.json()
382
383
  except JSONDecodeError:
383
- raise ApiError(status_code=_response.status_code, body=_response.text)
384
- raise ApiError(status_code=_response.status_code, body=_response_json)
384
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
385
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
sarvamai/client.py CHANGED
@@ -1,20 +1,16 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- import typing
4
- from .environment import SarvamAIEnvironment
5
3
  import os
4
+ import typing
5
+
6
6
  import httpx
7
+ from .chat.client import AsyncChatClient, ChatClient
7
8
  from .core.api_error import ApiError
8
- from .core.client_wrapper import SyncClientWrapper
9
- from .text.client import TextClient
10
- from .speech_to_text.client import SpeechToTextClient
11
- from .text_to_speech.client import TextToSpeechClient
12
- from .chat.client import ChatClient
13
- from .core.client_wrapper import AsyncClientWrapper
14
- from .text.client import AsyncTextClient
15
- from .speech_to_text.client import AsyncSpeechToTextClient
16
- from .text_to_speech.client import AsyncTextToSpeechClient
17
- from .chat.client import AsyncChatClient
9
+ from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
10
+ from .environment import SarvamAIEnvironment
11
+ from .speech_to_text.client import AsyncSpeechToTextClient, SpeechToTextClient
12
+ from .text.client import AsyncTextClient, TextClient
13
+ from .text_to_speech.client import AsyncTextToSpeechClient, TextToSpeechClient
18
14
 
19
15
 
20
16
  class SarvamAI:
@@ -23,9 +19,6 @@ class SarvamAI:
23
19
 
24
20
  Parameters
25
21
  ----------
26
- base_url : typing.Optional[str]
27
- The base url to use for requests from the client.
28
-
29
22
  environment : SarvamAIEnvironment
30
23
  The environment to use for requests from the client. from .environment import SarvamAIEnvironment
31
24
 
@@ -57,7 +50,6 @@ class SarvamAI:
57
50
  def __init__(
58
51
  self,
59
52
  *,
60
- base_url: typing.Optional[str] = None,
61
53
  environment: SarvamAIEnvironment = SarvamAIEnvironment.PRODUCTION,
62
54
  api_subscription_key: typing.Optional[str] = os.getenv("SARVAM_API_KEY"),
63
55
  timeout: typing.Optional[float] = None,
@@ -72,7 +64,7 @@ class SarvamAI:
72
64
  body="The client must be instantiated be either passing in api_subscription_key or setting SARVAM_API_KEY"
73
65
  )
74
66
  self._client_wrapper = SyncClientWrapper(
75
- base_url=_get_base_url(base_url=base_url, environment=environment),
67
+ environment=environment,
76
68
  api_subscription_key=api_subscription_key,
77
69
  httpx_client=httpx_client
78
70
  if httpx_client is not None
@@ -93,9 +85,6 @@ class AsyncSarvamAI:
93
85
 
94
86
  Parameters
95
87
  ----------
96
- base_url : typing.Optional[str]
97
- The base url to use for requests from the client.
98
-
99
88
  environment : SarvamAIEnvironment
100
89
  The environment to use for requests from the client. from .environment import SarvamAIEnvironment
101
90
 
@@ -127,7 +116,6 @@ class AsyncSarvamAI:
127
116
  def __init__(
128
117
  self,
129
118
  *,
130
- base_url: typing.Optional[str] = None,
131
119
  environment: SarvamAIEnvironment = SarvamAIEnvironment.PRODUCTION,
132
120
  api_subscription_key: typing.Optional[str] = os.getenv("SARVAM_API_KEY"),
133
121
  timeout: typing.Optional[float] = None,
@@ -142,7 +130,7 @@ class AsyncSarvamAI:
142
130
  body="The client must be instantiated be either passing in api_subscription_key or setting SARVAM_API_KEY"
143
131
  )
144
132
  self._client_wrapper = AsyncClientWrapper(
145
- base_url=_get_base_url(base_url=base_url, environment=environment),
133
+ environment=environment,
146
134
  api_subscription_key=api_subscription_key,
147
135
  httpx_client=httpx_client
148
136
  if httpx_client is not None
@@ -155,12 +143,3 @@ class AsyncSarvamAI:
155
143
  self.speech_to_text = AsyncSpeechToTextClient(client_wrapper=self._client_wrapper)
156
144
  self.text_to_speech = AsyncTextToSpeechClient(client_wrapper=self._client_wrapper)
157
145
  self.chat = AsyncChatClient(client_wrapper=self._client_wrapper)
158
-
159
-
160
- def _get_base_url(*, base_url: typing.Optional[str] = None, environment: SarvamAIEnvironment) -> str:
161
- if base_url is not None:
162
- return base_url
163
- elif environment is not None:
164
- return environment.value
165
- else:
166
- raise Exception("Please pass in either base_url or environment to construct the client")
sarvamai/core/__init__.py CHANGED
@@ -1,8 +1,11 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ # isort: skip_file
4
+
3
5
  from .api_error import ApiError
4
6
  from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
5
7
  from .datetime_utils import serialize_datetime
8
+ from .events import EventEmitterMixin, EventType
6
9
  from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
7
10
  from .http_client import AsyncHttpClient, HttpClient
8
11
  from .http_response import AsyncHttpResponse, HttpResponse
@@ -27,6 +30,8 @@ __all__ = [
27
30
  "AsyncHttpClient",
28
31
  "AsyncHttpResponse",
29
32
  "BaseClientWrapper",
33
+ "EventEmitterMixin",
34
+ "EventType",
30
35
  "FieldMetadata",
31
36
  "File",
32
37
  "HttpClient",
@@ -1,15 +1,23 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- import typing
3
+ from typing import Any, Dict, Optional
4
4
 
5
5
 
6
6
  class ApiError(Exception):
7
- status_code: typing.Optional[int]
8
- body: typing.Any
7
+ headers: Optional[Dict[str, str]]
8
+ status_code: Optional[int]
9
+ body: Any
9
10
 
10
- def __init__(self, *, status_code: typing.Optional[int] = None, body: typing.Any = None):
11
+ def __init__(
12
+ self,
13
+ *,
14
+ headers: Optional[Dict[str, str]] = None,
15
+ status_code: Optional[int] = None,
16
+ body: Any = None,
17
+ ) -> None:
18
+ self.headers = headers
11
19
  self.status_code = status_code
12
20
  self.body = body
13
21
 
14
22
  def __str__(self) -> str:
15
- return f"status_code: {self.status_code}, body: {self.body}"
23
+ return f"headers: {self.headers}, status_code: {self.status_code}, body: {self.body}"
@@ -1,29 +1,32 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  import typing
4
+
4
5
  import httpx
5
- from .http_client import HttpClient
6
- from .http_client import AsyncHttpClient
6
+ from ..environment import SarvamAIEnvironment
7
+ from .http_client import AsyncHttpClient, HttpClient
7
8
 
8
9
 
9
10
  class BaseClientWrapper:
10
- def __init__(self, *, api_subscription_key: str, base_url: str, timeout: typing.Optional[float] = None):
11
+ def __init__(
12
+ self, *, api_subscription_key: str, environment: SarvamAIEnvironment, timeout: typing.Optional[float] = None
13
+ ):
11
14
  self.api_subscription_key = api_subscription_key
12
- self._base_url = base_url
15
+ self._environment = environment
13
16
  self._timeout = timeout
14
17
 
15
18
  def get_headers(self) -> typing.Dict[str, str]:
16
19
  headers: typing.Dict[str, str] = {
17
- "User-Agent": "sarvamai/0.1.5a0",
20
+ "User-Agent": "sarvamai/0.1.5a3",
18
21
  "X-Fern-Language": "Python",
19
22
  "X-Fern-SDK-Name": "sarvamai",
20
- "X-Fern-SDK-Version": "0.1.5a0",
23
+ "X-Fern-SDK-Version": "0.1.5a3",
21
24
  }
22
25
  headers["api-subscription-key"] = self.api_subscription_key
23
26
  return headers
24
27
 
25
- def get_base_url(self) -> str:
26
- return self._base_url
28
+ def get_environment(self) -> SarvamAIEnvironment:
29
+ return self._environment
27
30
 
28
31
  def get_timeout(self) -> typing.Optional[float]:
29
32
  return self._timeout
@@ -34,16 +37,13 @@ class SyncClientWrapper(BaseClientWrapper):
34
37
  self,
35
38
  *,
36
39
  api_subscription_key: str,
37
- base_url: str,
40
+ environment: SarvamAIEnvironment,
38
41
  timeout: typing.Optional[float] = None,
39
42
  httpx_client: httpx.Client,
40
43
  ):
41
- super().__init__(api_subscription_key=api_subscription_key, base_url=base_url, timeout=timeout)
44
+ super().__init__(api_subscription_key=api_subscription_key, environment=environment, timeout=timeout)
42
45
  self.httpx_client = HttpClient(
43
- httpx_client=httpx_client,
44
- base_headers=self.get_headers,
45
- base_timeout=self.get_timeout,
46
- base_url=self.get_base_url,
46
+ httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout
47
47
  )
48
48
 
49
49
 
@@ -52,14 +52,11 @@ class AsyncClientWrapper(BaseClientWrapper):
52
52
  self,
53
53
  *,
54
54
  api_subscription_key: str,
55
- base_url: str,
55
+ environment: SarvamAIEnvironment,
56
56
  timeout: typing.Optional[float] = None,
57
57
  httpx_client: httpx.AsyncClient,
58
58
  ):
59
- super().__init__(api_subscription_key=api_subscription_key, base_url=base_url, timeout=timeout)
59
+ super().__init__(api_subscription_key=api_subscription_key, environment=environment, timeout=timeout)
60
60
  self.httpx_client = AsyncHttpClient(
61
- httpx_client=httpx_client,
62
- base_headers=self.get_headers,
63
- base_timeout=self.get_timeout,
64
- base_url=self.get_base_url,
61
+ httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout
65
62
  )
@@ -0,0 +1,30 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from enum import Enum
5
+
6
+
7
+ class EventType(str, Enum):
8
+ OPEN = "open"
9
+ MESSAGE = "message"
10
+ ERROR = "error"
11
+ CLOSE = "close"
12
+
13
+
14
+ class EventEmitterMixin:
15
+ """
16
+ Simple mixin for registering and emitting events.
17
+ """
18
+
19
+ def __init__(self) -> None:
20
+ self._callbacks: typing.Dict[EventType, typing.List[typing.Callable]] = {}
21
+
22
+ def on(self, event_name: EventType, callback: typing.Callable[[typing.Any], None]) -> None:
23
+ if event_name not in self._callbacks:
24
+ self._callbacks[event_name] = []
25
+ self._callbacks[event_name].append(callback)
26
+
27
+ def _emit(self, event_name: EventType, data: typing.Any) -> None:
28
+ if event_name in self._callbacks:
29
+ for cb in self._callbacks[event_name]:
30
+ cb(data)
@@ -0,0 +1,16 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+
4
+ class ForceMultipartDict(dict):
5
+ """
6
+ A dictionary subclass that always evaluates to True in boolean contexts.
7
+
8
+ This is used to force multipart/form-data encoding in HTTP requests even when
9
+ the dictionary is empty, which would normally evaluate to False.
10
+ """
11
+
12
+ def __bool__(self):
13
+ return True
14
+
15
+
16
+ FORCE_MULTIPART = ForceMultipartDict()