dashscope 1.19.3__py3-none-any.whl → 1.20.1__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.

Potentially problematic release.


This version of dashscope might be problematic. Click here for more details.

@@ -27,6 +27,7 @@ class ImageSynthesis(BaseAsyncApi):
27
27
  ref_img: str = None,
28
28
  workspace: str = None,
29
29
  extra_input: Dict = None,
30
+ task: str = None,
30
31
  **kwargs) -> ImageSynthesisResponse:
31
32
  """Call image(s) synthesis service and get result.
32
33
 
@@ -41,6 +42,7 @@ class ImageSynthesis(BaseAsyncApi):
41
42
  Defaults to None.
42
43
  workspace (str): The dashscope workspace id.
43
44
  extra_input (Dict): The extra input parameters.
45
+ task (str): The task of api, ref doc.
44
46
  **kwargs:
45
47
  n(int, `optional`): Number of images to synthesis.
46
48
  size(str, `optional`): The output image(s) size(width*height).
@@ -67,6 +69,7 @@ class ImageSynthesis(BaseAsyncApi):
67
69
  ref_img=ref_img,
68
70
  workspace=workspace,
69
71
  extra_input=extra_input,
72
+ task=task,
70
73
  **kwargs)
71
74
 
72
75
  @classmethod
@@ -80,6 +83,7 @@ class ImageSynthesis(BaseAsyncApi):
80
83
  ref_img: str = None,
81
84
  workspace: str = None,
82
85
  extra_input: Dict = None,
86
+ task: str = None,
83
87
  **kwargs) -> ImageSynthesisResponse:
84
88
  """Create a image(s) synthesis task, and return task information.
85
89
 
@@ -93,6 +97,7 @@ class ImageSynthesis(BaseAsyncApi):
93
97
  Defaults to None.
94
98
  workspace (str): The dashscope workspace id.
95
99
  extra_input (Dict): The extra input parameters.
100
+ task (str): The task of api, ref doc.
96
101
  **kwargs(wanx-v1):
97
102
  n(int, `optional`): Number of images to synthesis.
98
103
  size: The output image(s) size, Default 1024*1024
@@ -126,14 +131,15 @@ class ImageSynthesis(BaseAsyncApi):
126
131
  if extra_input is not None and extra_input:
127
132
  input = {**input, **extra_input}
128
133
 
129
- response = super().async_call(model=model,
130
- task_group=task_group,
131
- task=ImageSynthesis.task,
132
- function=function,
133
- api_key=api_key,
134
- input=input,
135
- workspace=workspace,
136
- **kwargs)
134
+ response = super().async_call(
135
+ model=model,
136
+ task_group=task_group,
137
+ task=ImageSynthesis.task if task is None else task,
138
+ function=function,
139
+ api_key=api_key,
140
+ input=input,
141
+ workspace=workspace,
142
+ **kwargs)
137
143
  return ImageSynthesisResponse.from_api_response(response)
138
144
 
139
145
  @classmethod
@@ -130,19 +130,11 @@ class HttpRequest(AioBaseRequest):
130
130
  async for rsp in self._handle_aio_response(response):
131
131
  yield rsp
132
132
  except aiohttp.ClientConnectorError as e:
133
- logger.exception(e)
134
- yield DashScopeAPIResponse(-1,
135
- '',
136
- 'Unknown',
137
- message='Error type: %s, message: %s' %
138
- (type(e), e))
133
+ logger.error(e)
134
+ raise e
139
135
  except BaseException as e:
140
- logger.exception(e)
141
- yield DashScopeAPIResponse(-1,
142
- '',
143
- 'Unknown',
144
- message='Error type: %s, message: %s' %
145
- (type(e), e))
136
+ logger.error(e)
137
+ raise e
146
138
 
147
139
  async def _handle_aio_response(self, response: aiohttp.ClientResponse):
148
140
  request_id = ''
@@ -308,8 +300,4 @@ class HttpRequest(AioBaseRequest):
308
300
  yield rsp
309
301
  except BaseException as e:
310
302
  logger.error(e)
311
- yield DashScopeAPIResponse(-1,
312
- '',
313
- 'Unknown',
314
- message='Error type: %s, message: %s' %
315
- (type(e), e))
303
+ raise e
@@ -1,3 +1,3 @@
1
- from . import asr, tts
1
+ from . import asr, tts, tts_v2
2
2
 
3
- __all__ = [asr, tts]
3
+ __all__ = [asr, tts, tts_v2]
@@ -114,6 +114,7 @@ class Transcription(BaseAsyncApi):
114
114
  task: Union[str, TranscriptionResponse],
115
115
  api_key: str = None,
116
116
  workspace: str = None,
117
+ **kwargs
117
118
  ) -> TranscriptionResponse:
118
119
  """Fetch the status of task, including results of batch transcription when task_status is SUCCEEDED. # noqa: E501
119
120
 
@@ -131,7 +132,8 @@ class Transcription(BaseAsyncApi):
131
132
  try:
132
133
  response = super().fetch(task,
133
134
  api_key=api_key,
134
- workspace=workspace)
135
+ workspace=workspace,
136
+ **kwargs)
135
137
  except (asyncio.TimeoutError, aiohttp.ClientConnectorError) as e:
136
138
  logger.error(e)
137
139
  try_count += 1
@@ -150,6 +152,7 @@ class Transcription(BaseAsyncApi):
150
152
  task: Union[str, TranscriptionResponse],
151
153
  api_key: str = None,
152
154
  workspace: str = None,
155
+ **kwargs
153
156
  ) -> TranscriptionResponse:
154
157
  """Poll task until the final results of transcription is obtained.
155
158
 
@@ -161,7 +164,7 @@ class Transcription(BaseAsyncApi):
161
164
  Returns:
162
165
  TranscriptionResponse: The result of batch transcription.
163
166
  """
164
- response = super().wait(task, api_key=api_key, workspace=workspace)
167
+ response = super().wait(task, api_key=api_key, workspace=workspace, **kwargs)
165
168
  return TranscriptionResponse.from_api_response(response)
166
169
 
167
170
  @classmethod
@@ -0,0 +1,7 @@
1
+ from .speech_synthesizer import AudioFormat, ResultCallback, SpeechSynthesizer
2
+
3
+ __all__ = ['SpeechSynthesizer', 'ResultCallback', 'AudioFormat']
4
+
5
+ # from .speech_synthesizer import (SpeechSynthesizer, ResultCallback, SpeechSynthesisResult, AudioFormat)
6
+
7
+ # __all__ = ['SpeechSynthesizer', 'ResultCallback', 'SpeechSynthesisResult', 'AudioFormat']
@@ -0,0 +1,481 @@
1
+ import json
2
+ import platform
3
+ import threading
4
+ import time
5
+ import uuid
6
+ from enum import Enum, unique
7
+
8
+ import websocket
9
+
10
+ import dashscope
11
+ from dashscope.common.error import InputRequired, InvalidTask, ModelRequired
12
+ from dashscope.common.logging import logger
13
+ from dashscope.protocol.websocket import (ACTION_KEY, EVENT_KEY, HEADER,
14
+ TASK_ID, ActionType, EventType,
15
+ WebsocketStreamingMode)
16
+
17
+
18
+ class ResultCallback:
19
+ """
20
+ An interface that defines callback methods for getting speech synthesis results. # noqa E501
21
+ Derive from this class and implement its function to provide your own data.
22
+ """
23
+ def on_open(self) -> None:
24
+ pass
25
+
26
+ def on_complete(self) -> None:
27
+ pass
28
+
29
+ def on_error(self, message) -> None:
30
+ pass
31
+
32
+ def on_close(self) -> None:
33
+ pass
34
+
35
+ def on_event(self, message: str) -> None:
36
+ pass
37
+
38
+ def on_data(self, data: bytes) -> None:
39
+ pass
40
+
41
+
42
+ @unique
43
+ class AudioFormat(Enum):
44
+ DEFAULT = ('Default', 0, '0', '0')
45
+ WAV_8000HZ_MONO_16BIT = ('wav', 8000, 'mono', '16bit')
46
+ WAV_16000HZ_MONO_16BIT = ('wav', 16000, 'mono', '16bit')
47
+ WAV_22050HZ_MONO_16BIT = ('wav', 22050, 'mono', '16bit')
48
+ WAV_24000HZ_MONO_16BIT = ('wav', 24000, 'mono', '16bit')
49
+ WAV_44100HZ_MONO_16BIT = ('wav', 44100, 'mono', '16bit')
50
+ WAV_48000HZ_MONO_16BIT = ('wav', 48000, 'mono', '16bit')
51
+
52
+ MP3_8000HZ_MONO_128KBPS = ('mp3', 8000, 'mono', '128kbps')
53
+ MP3_16000HZ_MONO_128KBPS = ('mp3', 16000, 'mono', '128kbps')
54
+ MP3_22050HZ_MONO_256KBPS = ('mp3', 22050, 'mono', '256kbps')
55
+ MP3_24000HZ_MONO_256KBPS = ('mp3', 24000, 'mono', '256kbps')
56
+ MP3_44100HZ_MONO_256KBPS = ('mp3', 44100, 'mono', '256kbps')
57
+ MP3_48000HZ_MONO_256KBPS = ('mp3', 48000, 'mono', '256kbps')
58
+
59
+ PCM_8000HZ_MONO_16BIT = ('pcm', 8000, 'mono', '16bit')
60
+ PCM_16000HZ_MONO_16BIT = ('pcm', 16000, 'mono', '16bit')
61
+ PCM_22050HZ_MONO_16BIT = ('pcm', 22050, 'mono', '16bit')
62
+ PCM_24000HZ_MONO_16BIT = ('pcm', 24000, 'mono', '16bit')
63
+ PCM_44100HZ_MONO_16BIT = ('pcm', 44100, 'mono', '16bit')
64
+ PCM_48000HZ_MONO_16BIT = ('pcm', 48000, 'mono', '16bit')
65
+
66
+ def __init__(self, format, sample_rate, channels, bit_rate):
67
+ self.format = format
68
+ self.sample_rate = sample_rate
69
+ self.channels = channels
70
+ self.bit_rate = bit_rate
71
+
72
+ def __str__(self):
73
+ return f'{self.format.upper()} with {self.sample_rate}Hz sample rate, {self.channels} channel, {self.bit_rate}'
74
+
75
+
76
+ class Request:
77
+ def __init__(
78
+ self,
79
+ apikey,
80
+ model,
81
+ voice,
82
+ format='wav',
83
+ sample_rate=16000,
84
+ volumn=50,
85
+ speech_rate=1.0,
86
+ pitch_rate=1.0,
87
+ ):
88
+ self.task_id = self.genUid()
89
+ self.apikey = apikey
90
+ self.voice = voice
91
+ self.model = model
92
+ self.format = format
93
+ self.sample_rate = sample_rate
94
+ self.volumn = volumn
95
+ self.speech_rate = speech_rate
96
+ self.pitch_rate = pitch_rate
97
+
98
+ def genUid(self):
99
+ # 生成随机UUID
100
+ return uuid.uuid4().hex
101
+
102
+ def getWebsocketHeaders(self, headers, workspace):
103
+ ua = 'dashscope/%s; python/%s; platform/%s; processor/%s' % (
104
+ '1.18.0', # dashscope version
105
+ platform.python_version(),
106
+ platform.platform(),
107
+ platform.processor(),
108
+ )
109
+ self.headers = {
110
+ 'user-agent': ua,
111
+ 'Authorization': 'bearer ' + self.apikey,
112
+ }
113
+ if headers:
114
+ self.headers = {**self.headers, **headers}
115
+ if workspace:
116
+ self.headers = {
117
+ **self.headers,
118
+ 'X-DashScope-WorkSpace': workspace,
119
+ }
120
+ return self.headers
121
+
122
+ def getStartRequest(self, additional_params=None):
123
+
124
+ cmd = {
125
+ HEADER: {
126
+ ACTION_KEY: ActionType.START,
127
+ TASK_ID: self.task_id,
128
+ 'streaming': WebsocketStreamingMode.DUPLEX,
129
+ },
130
+ 'payload': {
131
+ 'model': self.model,
132
+ 'task_group': 'audio',
133
+ 'task': 'tts',
134
+ 'function': 'SpeechSynthesizer',
135
+ 'input': {
136
+ 'text': ''
137
+ },
138
+ 'parameters': {
139
+ 'voice': self.voice,
140
+ 'volume': self.volumn,
141
+ 'text_type': 'PlainText',
142
+ 'sample_rate': self.sample_rate,
143
+ 'rate': self.speech_rate,
144
+ 'format': self.format,
145
+ 'pitch': self.pitch_rate,
146
+ },
147
+ },
148
+ }
149
+ if additional_params:
150
+ cmd['payload']['parameters'].update(additional_params)
151
+ return json.dumps(cmd)
152
+
153
+ def getContinueRequest(self, text):
154
+ cmd = {
155
+ HEADER: {
156
+ ACTION_KEY: ActionType.CONTINUE,
157
+ TASK_ID: self.task_id,
158
+ 'streaming': WebsocketStreamingMode.DUPLEX,
159
+ },
160
+ 'payload': {
161
+ 'model': self.model,
162
+ 'task_group': 'audio',
163
+ 'task': 'tts',
164
+ 'function': 'SpeechSynthesizer',
165
+ 'input': {
166
+ 'text': text
167
+ },
168
+ },
169
+ }
170
+ return json.dumps(cmd)
171
+
172
+ def getFinishRequest(self):
173
+ cmd = {
174
+ HEADER: {
175
+ ACTION_KEY: ActionType.FINISHED,
176
+ TASK_ID: self.task_id,
177
+ 'streaming': WebsocketStreamingMode.DUPLEX,
178
+ },
179
+ 'payload': {
180
+ 'input': {
181
+ 'text': ''
182
+ },
183
+ },
184
+ }
185
+ return json.dumps(cmd)
186
+
187
+
188
+ class SpeechSynthesizer:
189
+ def __init__(
190
+ self,
191
+ model,
192
+ voice,
193
+ format: AudioFormat = AudioFormat.DEFAULT,
194
+ volumn=50,
195
+ speech_rate=1.0,
196
+ pitch_rate=1.0,
197
+ headers=None,
198
+ callback: ResultCallback = None,
199
+ workspace=None,
200
+ url=None,
201
+ additional_params=None,
202
+ ):
203
+ """
204
+ CosyVoice Speech Synthesis SDK
205
+ Parameters:
206
+ -----------
207
+ model: str
208
+ Model name.
209
+ voice: str
210
+ Voice name.
211
+ format: AudioFormat
212
+ Synthesis audio format.
213
+ volume: int
214
+ The volume of the synthesized audio, with a range from 0 to 100. Default is 50.
215
+ rate: float
216
+ The speech rate of the synthesized audio, with a range from 0.5 to 2. Default is 1.0.
217
+ pitch: float
218
+ The pitch of the synthesized audio, with a range from 0.5 to 2. Default is 1.0.
219
+ headers: Dict
220
+ User-defined headers.
221
+ callback: ResultCallback
222
+ Callback to receive real-time synthesis results.
223
+ workspace: str
224
+ Dashscope workspace ID.
225
+ url: str
226
+ Dashscope WebSocket URL.
227
+ additional_params: Dict
228
+ Additional parameters for the Dashscope API.
229
+ """
230
+
231
+ if model is None:
232
+ raise ModelRequired('Model is required!')
233
+ if format is None:
234
+ raise InputRequired('format is required!')
235
+ if url is None:
236
+ url = dashscope.base_websocket_api_url
237
+ self.url = url
238
+ self.apikey = dashscope.api_key
239
+ self.headers = headers
240
+ self.workspace = workspace
241
+ self.additional_params = additional_params
242
+
243
+ self.request = Request(
244
+ apikey=self.apikey,
245
+ model=model,
246
+ voice=voice,
247
+ format=format.format,
248
+ sample_rate=format.sample_rate,
249
+ volumn=volumn,
250
+ speech_rate=speech_rate,
251
+ pitch_rate=pitch_rate,
252
+ )
253
+ self.last_request_id = self.request.task_id
254
+ self.start_event = threading.Event()
255
+ self.complete_event = threading.Event()
256
+ self._stopped = threading.Event()
257
+ self._audio_data: bytes = None
258
+ self._is_started = False
259
+ self._cancel = False
260
+ self._cancel_lock = threading.Lock()
261
+ self.async_call = True
262
+ self.callback = callback
263
+ self._is_first = True
264
+ self.async_call = True
265
+ # since dashscope sdk will send first text in run-task
266
+ if not self.callback:
267
+ self.async_call = False
268
+
269
+ def __send_str(self, data: str):
270
+ logger.debug('>>>send {}'.format(data))
271
+ self.ws.send(data)
272
+
273
+ def __start_stream(self, ):
274
+ if self.callback is None:
275
+ raise InputRequired('callback is required!')
276
+ # reset inner params
277
+ self._stopped.clear()
278
+ self._stream_data = ['']
279
+ self._worker = None
280
+ self._audio_data: bytes = None
281
+
282
+ if self._is_started:
283
+ raise InvalidTask('task has already started.')
284
+
285
+ self.ws = websocket.WebSocketApp(
286
+ self.url,
287
+ header=self.request.getWebsocketHeaders(headers=self.headers,
288
+ workspace=self.workspace),
289
+ on_message=self.on_message,
290
+ on_error=self.on_error,
291
+ on_close=self.on_close,
292
+ )
293
+ self.thread = threading.Thread(target=self.ws.run_forever)
294
+ self.thread.daemon = True
295
+ self.thread.start()
296
+ request = self.request.getStartRequest(self.additional_params)
297
+ # 等待连接建立
298
+ timeout = 5 # 最长等待时间(秒)
299
+ start_time = time.time()
300
+ while (not (self.ws.sock and self.ws.sock.connected)
301
+ and (time.time() - start_time) < timeout):
302
+ time.sleep(0.1) # 短暂休眠,避免密集轮询
303
+ self.__send_str(request)
304
+ if not self.start_event.wait(10):
305
+ raise TimeoutError('start speech synthesizer failed within 5s.')
306
+ self._is_started = True
307
+ if self.callback:
308
+ self.callback.on_open()
309
+
310
+ def __submit_text(self, text):
311
+ if not self._is_started:
312
+ raise InvalidTask('speech synthesizer has not been started.')
313
+
314
+ if self._stopped.is_set():
315
+ raise InvalidTask('speech synthesizer task has stopped.')
316
+ request = self.request.getContinueRequest(text)
317
+ self.__send_str(request)
318
+
319
+ def streaming_call(self, text: str):
320
+ """
321
+ Streaming input mode: You can call the stream_call function multiple times to send text.
322
+ A session will be created on the first call.
323
+ The session ends after calling streaming_complete.
324
+ Parameters:
325
+ -----------
326
+ text: str
327
+ utf-8 encoded text
328
+ """
329
+ if self._is_first:
330
+ self._is_first = False
331
+ self.__start_stream()
332
+ self.__submit_text(text)
333
+ return None
334
+
335
+ def streaming_complete(self, complete_timeout_millie=10000):
336
+ """
337
+ Synchronously stop the streaming input speech synthesis task.
338
+ Wait for all remaining synthesized audio before returning
339
+
340
+ Parameters:
341
+ -----------
342
+ complete_timeout_millis: int
343
+ Throws TimeoutError exception if it times out.
344
+ """
345
+ if not self._is_started:
346
+ raise InvalidTask('speech synthesizer has not been started.')
347
+ if self._stopped.is_set():
348
+ raise InvalidTask('speech synthesizer task has stopped.')
349
+ request = self.request.getFinishRequest()
350
+ self.__send_str(request)
351
+ if not self.complete_event.wait(timeout=complete_timeout_millie):
352
+ raise TimeoutError(
353
+ 'speech synthesizer wait for complete timeout {}ms'.format(
354
+ complete_timeout_millie))
355
+ self.close()
356
+ self._stopped.set()
357
+ self._is_started = False
358
+
359
+ def __waiting_for_complete(self):
360
+ if not self.complete_event.wait(timeout=10000):
361
+ raise TimeoutError(
362
+ 'speech synthesizer wait for complete timeout 10000ms')
363
+ self.close()
364
+ self._stopped.set()
365
+ self._is_started = False
366
+
367
+ def async_streaming_complete(self):
368
+ """
369
+ Asynchronously stop the streaming input speech synthesis task, returns immediately.
370
+ You need to listen and handle the STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE event in the on_event callback.
371
+ Do not destroy the object and callback before this event.
372
+ """
373
+
374
+ if not self._is_started:
375
+ raise InvalidTask('speech synthesizer has not been started.')
376
+ if self._stopped.is_set():
377
+ raise InvalidTask('speech synthesizer task has stopped.')
378
+ request = self.request.getFinishRequest()
379
+ self.__send_str(request)
380
+ thread = threading.Thread(target=self.__waiting_for_complete)
381
+ thread.start()
382
+
383
+ def streaming_cancel(self):
384
+ """
385
+ Immediately terminate the streaming input speech synthesis task
386
+ and discard any remaining audio that is not yet delivered.
387
+ """
388
+
389
+ if not self._is_started:
390
+ raise InvalidTask('speech synthesizer has not been started.')
391
+ if self._stopped.is_set():
392
+ return
393
+ request = self.request.getFinishRequest()
394
+ self.__send_str(request)
395
+ self.close()
396
+
397
+ # 监听消息的回调函数
398
+ def on_message(self, ws, message):
399
+ if isinstance(message, str):
400
+ logger.debug('<<<recv {}'.format(message))
401
+ try:
402
+ # 尝试将消息解析为JSON
403
+ json_data = json.loads(message)
404
+ event = json_data['header'][EVENT_KEY]
405
+ # 调用JSON回调
406
+ if EventType.STARTED == event:
407
+ self.start_event.set()
408
+ elif EventType.FINISHED == event:
409
+ self.complete_event.set()
410
+ if self.callback:
411
+ self.callback.on_complete()
412
+ self.callback.on_close()
413
+ elif EventType.FAILED == event:
414
+ self.start_event.set()
415
+ self.complete_event.set()
416
+ if self.async_call:
417
+ self.callback.on_error(message)
418
+ self.callback.on_close()
419
+ else:
420
+ logger.error(f'TaskFailed: {message}')
421
+ elif EventType.GENERATED == event:
422
+ if self.callback:
423
+ self.callback.on_event(message)
424
+ else:
425
+ pass
426
+ except json.JSONDecodeError:
427
+ logger.error('Failed to parse message as JSON.')
428
+ elif isinstance(message, (bytes, bytearray)):
429
+ # 如果失败,认为是二进制消息
430
+ logger.debug('<<<recv binary {}'.format(len(message)))
431
+ # 只有在非异步调用的时候保存音频
432
+ if not self.async_call:
433
+ if self._audio_data is None:
434
+ self._audio_data = bytes(message)
435
+ else:
436
+ self._audio_data = self._audio_data + bytes(message)
437
+ if self.callback:
438
+ self.callback.on_data(message)
439
+
440
+ def call(self, text: str):
441
+ """
442
+ Speech synthesis.
443
+ If callback is set, the audio will be returned in real-time through the on_event interface.
444
+ Otherwise, this function blocks until all audio is received and then returns the complete audio data.
445
+
446
+ Parameters:
447
+ -----------
448
+ text: str
449
+ utf-8 encoded text
450
+ return: bytes
451
+ If a callback is not set during initialization, the complete audio is returned
452
+ as the function's return value. Otherwise, the return value is null.
453
+ """
454
+ # print('还不支持非流式语音合成sdk调用大模型,使用流式模拟')
455
+ if not self.callback:
456
+ self.callback = ResultCallback()
457
+ self.__start_stream()
458
+ self.__submit_text(text)
459
+ if self.async_call:
460
+ self.async_streaming_complete()
461
+ return None
462
+ else:
463
+ self.streaming_complete()
464
+ return self._audio_data
465
+
466
+ # WebSocket关闭的回调函数
467
+ def on_close(self, ws, close_status_code, close_msg):
468
+ pass
469
+ # print("### websocket closed msg [{}]{} ###".format(close_status_code, close_msg))
470
+
471
+ # WebSocket发生错误的回调函数
472
+ def on_error(self, ws, error):
473
+ raise Exception(f'websocket closed due to {error}')
474
+
475
+ # 关闭WebSocket连接
476
+ def close(self):
477
+ self.ws.close()
478
+
479
+ # 获取上一个任务的taskId
480
+ def get_last_request_id(self):
481
+ return self.last_request_id
@@ -171,13 +171,20 @@ class AsyncTaskGetMixin():
171
171
  **kwargs) -> DashScopeAPIResponse:
172
172
  base_url = kwargs.pop('base_address', None)
173
173
  status_url = _normalization_url(base_url, 'tasks', task_id)
174
+ custom_headers = kwargs.pop('headers', None)
175
+ headers = {
176
+ **_workspace_header(workspace),
177
+ **default_headers(api_key),
178
+ }
179
+ if custom_headers:
180
+ headers = {
181
+ **custom_headers,
182
+ **headers,
183
+ }
174
184
  with requests.Session() as session:
175
185
  logger.debug('Starting request: %s' % status_url)
176
186
  response = session.get(status_url,
177
- headers={
178
- **_workspace_header(workspace),
179
- **default_headers(api_key),
180
- },
187
+ headers=headers,
181
188
  timeout=DEFAULT_REQUEST_TIMEOUT_SECONDS)
182
189
  logger.debug('Starting processing response: %s' % status_url)
183
190
  return _handle_http_response(response)
dashscope/common/utils.py CHANGED
@@ -314,7 +314,7 @@ async def _handle_aiohttp_failed_response(
314
314
  flattened_output: bool = False) -> DashScopeAPIResponse:
315
315
  request_id = ''
316
316
  if 'application/json' in response.content_type:
317
- error = await response.json()
317
+ error = response.json()
318
318
  return _handle_error_message(error, response.status, flattened_output)
319
319
  elif SSE_CONTENT_TYPE in response.content_type:
320
320
  async for _, _, data in _handle_aio_stream(response):
@@ -12,6 +12,7 @@ class TextEmbedding(BaseApi):
12
12
  class Models:
13
13
  text_embedding_v1 = 'text-embedding-v1'
14
14
  text_embedding_v2 = 'text-embedding-v2'
15
+ text_embedding_v3 = 'text-embedding-v3'
15
16
 
16
17
  @classmethod
17
18
  def call(cls,
dashscope/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.19.3'
1
+ __version__ = '1.20.1'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dashscope
3
- Version: 1.19.3
3
+ Version: 1.20.1
4
4
  Summary: dashscope client sdk library
5
5
  Home-page: https://dashscope.aliyun.com/
6
6
  Author: Alibaba Cloud
@@ -20,6 +20,7 @@ Requires-Python: >=3.8.0
20
20
  Description-Content-Type: text/markdown
21
21
  Requires-Dist: aiohttp
22
22
  Requires-Dist: requests
23
+ Requires-Dist: websocket-client
23
24
  Provides-Extra: tokenizer
24
25
  Requires-Dist: tiktoken ; extra == 'tokenizer'
25
26
 
@@ -6,12 +6,12 @@ dashscope/files.py,sha256=QgJjwhtn9F548nCA8jD8OvE6aQEj-20hZqJgYXsUdQU,3930
6
6
  dashscope/finetune.py,sha256=_tflDUvu0KagSoCzLaf0hofpG_P8NU6PylL8CPjVhrA,6243
7
7
  dashscope/model.py,sha256=UPOn1qMYFhX-ovXi3BMxZEBk8qOK7WLJOYHMbPZwYBo,1440
8
8
  dashscope/models.py,sha256=1-bc-Ue68zurgu_y6RhfFr9uzeQMF5AZq-C32lJGMGU,1224
9
- dashscope/version.py,sha256=o0O8TUNeZCJQn0hikTg-d3E5wkaO7bDwzfCeRhs6R20,23
9
+ dashscope/version.py,sha256=50ZydhgZIM_dwezjbX2voC6nDV_wx5kxvUuz3Nl2Eig,23
10
10
  dashscope/aigc/__init__.py,sha256=s-MCA87KYiVumYtKtJi5IMN7xelSF6TqEU3s3_7RF-Y,327
11
11
  dashscope/aigc/code_generation.py,sha256=KAJVrGp6tiNFBBg64Ovs9RfcP5SrIhrbW3wdA89NKso,10885
12
12
  dashscope/aigc/conversation.py,sha256=xRoJlCR-IXHjSdkDrK74a9ut1FJg0FZhTNXZAJC18MA,14231
13
13
  dashscope/aigc/generation.py,sha256=53oMCmN5ZbqeqAsKxmdunXlRh-XP8ZtnA7hB2id4Koo,17897
14
- dashscope/aigc/image_synthesis.py,sha256=39exBCmJcQpKll7wAgcbLzxEMSSkGq7s5f9TWB6q1Vo,10355
14
+ dashscope/aigc/image_synthesis.py,sha256=Hg2r6H7Vj4MsXwm62lHf2lTpUb6nA3xWGEYX2o-2TLQ,10419
15
15
  dashscope/aigc/multimodal_conversation.py,sha256=SlNnnsUPV19gdx8fYJAtsMFWPNGY6vhk5IGHZ5ZczpI,5369
16
16
  dashscope/api_entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  dashscope/api_entities/aiohttp_request.py,sha256=aE3AeWba8Ig_xHMYjrAdkq0N61l_L2VFTG6HYh912X0,10229
@@ -19,7 +19,7 @@ dashscope/api_entities/api_request_data.py,sha256=JUMcfpJjKXEZLCBSFIDpgoaeQYk5uK
19
19
  dashscope/api_entities/api_request_factory.py,sha256=4p-qxMuvCA0CmUHdH19QaUCaHmlLHAM1X2Jd4YKt5c0,4661
20
20
  dashscope/api_entities/base_request.py,sha256=cXUL7xqSV8wBr5d-1kx65AO3IsRR9A_ps6Lok-v-MKM,926
21
21
  dashscope/api_entities/dashscope_response.py,sha256=Bp1T7HwVlkOvpMNg-AEjz-BScxhLUXMXlE8ApXTtfhQ,17872
22
- dashscope/api_entities/http_request.py,sha256=UeS8_rhApA_FnuPv56B2Ruu1l9O1Bd6NiB9KNboWW50,14011
22
+ dashscope/api_entities/http_request.py,sha256=pYE8qRMu9CaQDiugPlXeYoaj_diBv-ZDExCD3WNhehI,13259
23
23
  dashscope/api_entities/websocket_request.py,sha256=Xr6IJ9WqrIw5ouBQLpgoRSwL1C09jkb4u1EZdxhVQy0,15039
24
24
  dashscope/app/__init__.py,sha256=UiN_9i--z84Dw5wUehOh_Tkk_9Gq_td_Kbz1dobBEKg,62
25
25
  dashscope/app/application.py,sha256=AegGVsk3dDzYACoYRNNjo3eG-2wrDd0dlOjYHpF0r2Y,7949
@@ -28,15 +28,17 @@ dashscope/assistants/__init__.py,sha256=i9N5OxHgY7edlOhTdPyC0N5Uc0uMCkB2vbMPDCD1
28
28
  dashscope/assistants/assistant_types.py,sha256=1jNL30TOlrkiYhvCaB3E8jkPLG8CnQ6I3tHpYXZCsD0,4211
29
29
  dashscope/assistants/assistants.py,sha256=NYahIDqhtnOcQOmnhZsjc5F5jvBUQcce8-fbrJXHVnQ,10833
30
30
  dashscope/assistants/files.py,sha256=pwLVJ_pjpRFWyfI_MRvhH7Si7FzGDj4ChzZgWTpLOhg,6699
31
- dashscope/audio/__init__.py,sha256=vlw0TFVRdeRWfzmJxhzarVUqkMs-DZNf4GiMtm3C8XE,45
31
+ dashscope/audio/__init__.py,sha256=-ZRxrK-gV4QsUtlThIT-XwqB6vmyEsnhxIxdLmhCUuc,61
32
32
  dashscope/audio/asr/__init__.py,sha256=-s180qWn_JPSpCo1q0aDJJ5HQ3zTzD4z5yUwsRqH4aU,275
33
33
  dashscope/audio/asr/asr_phrase_manager.py,sha256=EjtbI3zz9UQGS1qv6Yb4zzEMj4OJJVXmwkqZyIrzvEA,7642
34
34
  dashscope/audio/asr/recognition.py,sha256=F2iz6hyXg16Z6DGlPwGpKfRNcAZIIsqXnNPtaZp4Fzo,17369
35
- dashscope/audio/asr/transcription.py,sha256=e5O1U51GT-OQPu-wWN2w_T7l6IopWuGMVkheOGdNCkk,8836
35
+ dashscope/audio/asr/transcription.py,sha256=1WAg9WH89antVzRYEKXb5LQP9xylZmX4YKp7v5oMYjY,8931
36
36
  dashscope/audio/tts/__init__.py,sha256=fbnieZX9yNFNh5BsxLpLXb63jlxzxrdCJakV3ignjlQ,194
37
37
  dashscope/audio/tts/speech_synthesizer.py,sha256=dnKx9FDDdO_ETHAjhK8zaMVaH6SfoTtN5YxXXqgY1JA,7571
38
+ dashscope/audio/tts_v2/__init__.py,sha256=ve5a81qTbWDcRaSuritZtJBzryOIol2_dxzfqqdCw-k,345
39
+ dashscope/audio/tts_v2/speech_synthesizer.py,sha256=sv5f4vi17rFcYDif5bSS4UuX_2eVUL2q5rTnXK1EoAg,16650
38
40
  dashscope/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- dashscope/client/base_api.py,sha256=rww7uoDJtKxgiFQlBpZ8p__J0087cJWhvUxtdb3rrTE,41064
41
+ dashscope/client/base_api.py,sha256=rXN97XGyDhCCaD_dz_clpFDjOJfpGjqiH7yX3LaD-GE,41233
40
42
  dashscope/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
43
  dashscope/common/api_key.py,sha256=5Stp0odL5JSuIO3qJBp23QNppuGbqhhvKPS66qbMs0I,1986
42
44
  dashscope/common/base_type.py,sha256=C9xP6WuN5pOzviZ2g3X2EPcigldtFE0VlaUmjyNnUUk,4619
@@ -45,7 +47,7 @@ dashscope/common/env.py,sha256=oQOZW5JyEeTSde394un2lpDJ5RBh4fMU9hBfbtrKKkc,869
45
47
  dashscope/common/error.py,sha256=Q7GRhniP-7ap4HBpU69frRdKgKLwmH4ySYxCtupsr60,2638
46
48
  dashscope/common/logging.py,sha256=ecGxylG3bWES_Xv5-BD6ep4_0Ciu7F6ZPBjiZtu9Jx4,984
47
49
  dashscope/common/message_manager.py,sha256=i5149WzDk6nWmdFaHzYx4USXMBeX18GKSI-F4fLwbN0,1097
48
- dashscope/common/utils.py,sha256=YHs9PvL2BInfzgJazMEDdzOfMzmhudf0J083ieNWXkc,15398
50
+ dashscope/common/utils.py,sha256=yIHbbHZlK5UUGVZDizzjFENYb9S6JeJ-qqefP5IdGr4,15392
49
51
  dashscope/customize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
52
  dashscope/customize/customize_types.py,sha256=ZtEwSXA4dbjIYr5vgQQNkMuXyC2BNmznGuaF6b7jwr0,4803
51
53
  dashscope/customize/deployments.py,sha256=LIkM-hmJHcJZCKV6WJIPSXQ5CAhB5PUxnt5mqKbVbfE,5189
@@ -54,7 +56,7 @@ dashscope/embeddings/__init__.py,sha256=-dxHaoxZZVuP-wAGUIa3sNNh8CQwaeWj2UlqsDy1
54
56
  dashscope/embeddings/batch_text_embedding.py,sha256=P32LFO9v7ehdJsl0c32In94hUET6K6AaGJ_pDRtFqco,8791
55
57
  dashscope/embeddings/batch_text_embedding_response.py,sha256=WziXlQsFIkL1kPc_7lRG1HtqgkO5vVThtnNqExJggNU,2000
56
58
  dashscope/embeddings/multimodal_embedding.py,sha256=yojtGNoT2N54g0jcAYUwNIiwzueun1ouqS0S0tvnyQc,3966
57
- dashscope/embeddings/text_embedding.py,sha256=xjG5wE97apwNPHrDNqjwfXuet1dCTkVLIr90O1IeYVc,1961
59
+ dashscope/embeddings/text_embedding.py,sha256=I3zRvuT2HWcaZYH-zrtGcAQmzuLQxFswIHJMiQXfaJQ,2009
58
60
  dashscope/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
61
  dashscope/io/input_output.py,sha256=iZ1X1x1btdoZK2VeC9JsKkag2eaXwqfNT3Q6SrmRi2w,3941
60
62
  dashscope/nlp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -80,9 +82,9 @@ dashscope/tokenizers/tokenizer.py,sha256=y6P91qTCYo__pEx_0VHAcj9YECfbUdRqZU1fdGT
80
82
  dashscope/tokenizers/tokenizer_base.py,sha256=REDhzRyDT13iequ61-a6_KcTy0GFKlihQve5HkyoyRs,656
81
83
  dashscope/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
84
  dashscope/utils/oss_utils.py,sha256=fi8-PPsN-iR-iv5k2NS5Z8nlWkpgUhr56FRWm4BDh4A,6984
83
- dashscope-1.19.3.dist-info/LICENSE,sha256=Izp5L1DF1Mbza6qojkqNNWlE_mYLnr4rmzx2EBF8YFw,11413
84
- dashscope-1.19.3.dist-info/METADATA,sha256=OACOQOVBMq9bH8iwifFRofb3osjSKCLDXwKeiwcNKHc,6609
85
- dashscope-1.19.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
86
- dashscope-1.19.3.dist-info/entry_points.txt,sha256=raEp5dOuj8whJ7yqZlDM8WQ5p2RfnGrGNo0QLQEnatY,50
87
- dashscope-1.19.3.dist-info/top_level.txt,sha256=woqavFJK9zas5xTqynmALqOtlafghjsk63Xk86powTU,10
88
- dashscope-1.19.3.dist-info/RECORD,,
85
+ dashscope-1.20.1.dist-info/LICENSE,sha256=Izp5L1DF1Mbza6qojkqNNWlE_mYLnr4rmzx2EBF8YFw,11413
86
+ dashscope-1.20.1.dist-info/METADATA,sha256=pcY6Qv8KtqGlNAiqRr0JEfAzXBH8N56KlUD3o3expoA,6641
87
+ dashscope-1.20.1.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
88
+ dashscope-1.20.1.dist-info/entry_points.txt,sha256=raEp5dOuj8whJ7yqZlDM8WQ5p2RfnGrGNo0QLQEnatY,50
89
+ dashscope-1.20.1.dist-info/top_level.txt,sha256=woqavFJK9zas5xTqynmALqOtlafghjsk63Xk86powTU,10
90
+ dashscope-1.20.1.dist-info/RECORD,,