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

@@ -2,7 +2,6 @@ import json
2
2
  from http import HTTPStatus
3
3
 
4
4
  import aiohttp
5
-
6
5
  from dashscope.api_entities.base_request import AioBaseRequest
7
6
  from dashscope.api_entities.dashscope_response import DashScopeAPIResponse
8
7
  from dashscope.common.constants import (DEFAULT_REQUEST_TIMEOUT_SECONDS,
@@ -2,7 +2,6 @@ import json
2
2
  from urllib.parse import urlencode
3
3
 
4
4
  import aiohttp
5
-
6
5
  from dashscope.common.constants import ApiProtocol
7
6
  from dashscope.io.input_output import InputResolver
8
7
 
@@ -81,13 +81,15 @@ def _build_api_request(model: str,
81
81
  websocket_url = base_address
82
82
  else:
83
83
  websocket_url = dashscope.base_websocket_api_url
84
+ pre_task_id = kwargs.pop('pre_task_id', None)
84
85
  request = WebSocketRequest(url=websocket_url,
85
86
  api_key=api_key,
86
87
  stream=stream,
87
88
  ws_stream_mode=ws_stream_mode,
88
89
  is_binary_input=is_binary_input,
89
90
  timeout=request_timeout,
90
- flattened_output=flattened_output)
91
+ flattened_output=flattened_output,
92
+ pre_task_id=pre_task_id)
91
93
  else:
92
94
  raise UnsupportedApiProtocol(
93
95
  'Unsupported protocol: %s, support [http, https, websocket]' %
@@ -3,7 +3,6 @@ from http import HTTPStatus
3
3
 
4
4
  import aiohttp
5
5
  import requests
6
-
7
6
  from dashscope.api_entities.base_request import AioBaseRequest
8
7
  from dashscope.api_entities.dashscope_response import DashScopeAPIResponse
9
8
  from dashscope.common.constants import (DEFAULT_REQUEST_TIMEOUT_SECONDS,
@@ -5,7 +5,6 @@ from http import HTTPStatus
5
5
  from typing import Tuple, Union
6
6
 
7
7
  import aiohttp
8
-
9
8
  from dashscope.api_entities.base_request import AioBaseRequest
10
9
  from dashscope.api_entities.dashscope_response import DashScopeAPIResponse
11
10
  from dashscope.common.constants import (DEFAULT_REQUEST_TIMEOUT_SECONDS,
@@ -31,6 +30,7 @@ class WebSocketRequest(AioBaseRequest):
31
30
  is_binary_input: bool = False,
32
31
  timeout: int = DEFAULT_REQUEST_TIMEOUT_SECONDS,
33
32
  flattened_output: bool = False,
33
+ pre_task_id=None,
34
34
  ) -> None:
35
35
  super().__init__()
36
36
  """HttpRequest.
@@ -61,6 +61,7 @@ class WebSocketRequest(AioBaseRequest):
61
61
  self.task_headers = {
62
62
  'streaming': self.ws_stream_mode,
63
63
  }
64
+ self.pre_task_id = pre_task_id
64
65
 
65
66
  def add_headers(self, headers):
66
67
  self.headers = {**self.headers, **headers}
@@ -77,6 +78,10 @@ class WebSocketRequest(AioBaseRequest):
77
78
  pass
78
79
  return output
79
80
 
81
+ async def close(self):
82
+ if self.ws is not None and not self.ws.closed:
83
+ await self.ws.close()
84
+
80
85
  async def aio_call(self):
81
86
  response = self.connection_handler()
82
87
  if self.stream:
@@ -140,7 +145,11 @@ class WebSocketRequest(AioBaseRequest):
140
145
  code=e.name,
141
146
  message=e.message)
142
147
  except aiohttp.ClientConnectorError as e:
143
- raise e
148
+ logger.exception(e)
149
+ yield DashScopeAPIResponse(request_id='',
150
+ status_code=-1,
151
+ code='ClientConnectorError',
152
+ message=str(e))
144
153
  except aiohttp.WSServerHandshakeError as e:
145
154
  code = e.status
146
155
  msg = e.message
@@ -227,17 +236,22 @@ class WebSocketRequest(AioBaseRequest):
227
236
  raise error
228
237
 
229
238
  async def _start_task(self, ws):
230
- self.task_headers['task_id'] = uuid.uuid4().hex # create task id.
239
+ if self.pre_task_id is not None:
240
+ self.task_headers['task_id'] = self.pre_task_id
241
+ else:
242
+ self.task_headers['task_id'] = uuid.uuid4().hex # create task id.
231
243
  task_header = {**self.task_headers, ACTION_KEY: ActionType.START}
232
244
  # for binary data, the start action has no input, only parameters.
233
245
  start_data = self.data.get_websocket_start_data()
234
246
  message = self._build_up_message(task_header, start_data)
247
+ logger.debug('Send start task: {}'.format(message))
235
248
  await ws.send_str(message)
236
249
 
237
250
  async def _send_finished_task(self, ws):
238
251
  task_header = {**self.task_headers, ACTION_KEY: ActionType.FINISHED}
239
252
  payload = {'input': {}}
240
253
  message = self._build_up_message(task_header, payload)
254
+ logger.debug('Send finish task: {}'.format(message))
241
255
  await ws.send_str(message)
242
256
 
243
257
  async def _send_continue_task_data(self, ws):
@@ -250,12 +264,19 @@ class WebSocketRequest(AioBaseRequest):
250
264
  if len(input) > 0:
251
265
  if isinstance(input, bytes):
252
266
  await ws.send_bytes(input)
267
+ logger.debug(
268
+ 'Send continue task with bytes: {}'.format(
269
+ len(input)))
253
270
  else:
254
271
  await ws.send_bytes(list(input.values())[0])
272
+ logger.debug(
273
+ 'Send continue task with list[byte]: {}'.format(
274
+ len(input)))
255
275
  else:
256
276
  if len(input) > 0:
257
277
  message = self._build_up_message(headers=headers,
258
278
  payload=input)
279
+ logger.debug('Send continue task: {}'.format(message))
259
280
  await ws.send_str(message)
260
281
  await asyncio.sleep(0.000001)
261
282
 
@@ -1,9 +1,18 @@
1
1
  from .asr_phrase_manager import AsrPhraseManager
2
2
  from .recognition import Recognition, RecognitionCallback, RecognitionResult
3
3
  from .transcription import Transcription
4
+ from .translation_recognizer import (TranscriptionResult, Translation,
5
+ TranslationRecognizerCallback,
6
+ TranslationRecognizerChat,
7
+ TranslationRecognizerRealtime,
8
+ TranslationRecognizerResultPack,
9
+ TranslationResult)
4
10
  from .vocabulary import VocabularyService, VocabularyServiceException
5
11
 
6
12
  __all__ = [
7
13
  'Transcription', 'Recognition', 'RecognitionCallback', 'RecognitionResult',
8
- 'AsrPhraseManager', 'VocabularyServiceException', 'VocabularyService'
14
+ 'AsrPhraseManager', 'VocabularyServiceException', 'VocabularyService',
15
+ 'TranslationRecognizerRealtime', 'TranslationRecognizerChat',
16
+ 'TranslationRecognizerCallback', 'Translation', 'TranslationResult',
17
+ 'TranscriptionResult', 'TranslationRecognizerResultPack'
9
18
  ]
@@ -2,7 +2,9 @@ import json
2
2
  import os
3
3
  import threading
4
4
  import time
5
+ import uuid
5
6
  from http import HTTPStatus
7
+ from queue import Queue
6
8
  from threading import Timer
7
9
  from typing import Any, Dict, List, Union
8
10
 
@@ -153,18 +155,22 @@ class Recognition(BaseApi):
153
155
  self._recognition_once = False
154
156
  self._callback = callback
155
157
  self._running = False
156
- self._stream_data = []
158
+ self._stream_data = Queue()
157
159
  self._worker = None
158
160
  self._silence_timer = None
159
161
  self._kwargs = kwargs
160
162
  self._workspace = workspace
161
163
  self._start_stream_timestamp = -1
162
164
  self._first_package_timestamp = -1
165
+ self._stop_stream_timestamp = -1
166
+ self._on_complete_timestamp = -1
167
+ self.request_id_confirmed = False
168
+ self.last_request_id = uuid.uuid4().hex
163
169
 
164
170
  def __del__(self):
165
171
  if self._running:
166
172
  self._running = False
167
- self._stream_data.clear()
173
+ self._stream_data = Queue()
168
174
  if self._worker is not None and self._worker.is_alive():
169
175
  self._worker.join()
170
176
  if self._silence_timer is not None and self._silence_timer.is_alive( # noqa E501
@@ -182,6 +188,9 @@ class Recognition(BaseApi):
182
188
  for part in responses:
183
189
  if part.status_code == HTTPStatus.OK:
184
190
  if len(part.output) == 0:
191
+ self._on_complete_timestamp = time.time() * 1000
192
+ logger.debug('last package delay {}'.format(
193
+ self.get_last_package_delay()))
185
194
  self._callback.on_complete()
186
195
  else:
187
196
  usage: Dict[str, Any] = None
@@ -190,12 +199,12 @@ class Recognition(BaseApi):
190
199
  if (self._first_package_timestamp < 0):
191
200
  self._first_package_timestamp = time.time() * 1000
192
201
  logger.debug('first package delay {}'.format(
193
- self._first_package_timestamp -
194
- self._start_stream_timestamp))
202
+ self.get_first_package_delay()))
195
203
  sentence = part.output['sentence']
196
- logger.debug('Recv Result :{}, isEnd: {}'.format(
197
- sentence,
198
- RecognitionResult.is_sentence_end(sentence)))
204
+ logger.debug(
205
+ 'Recv Result [rid:{}]:{}, isEnd: {}'.format(
206
+ part.request_id, sentence,
207
+ RecognitionResult.is_sentence_end(sentence)))
199
208
  if part.usage is not None:
200
209
  usage = {
201
210
  'end_time':
@@ -203,6 +212,9 @@ class Recognition(BaseApi):
203
212
  'usage': part.usage
204
213
  }
205
214
  usages = [usage]
215
+ if self.request_id_confirmed is False and part.request_id is not None:
216
+ self.last_request_id = part.request_id
217
+ self.request_id_confirmed = True
206
218
 
207
219
  self._callback.on_event(
208
220
  RecognitionResult(
@@ -210,7 +222,7 @@ class Recognition(BaseApi):
210
222
  usages=usages))
211
223
  else:
212
224
  self._running = False
213
- self._stream_data.clear()
225
+ self._stream_data = Queue()
214
226
  self._callback.on_error(
215
227
  RecognitionResult(
216
228
  RecognitionResponse.from_api_response(part)))
@@ -242,6 +254,7 @@ class Recognition(BaseApi):
242
254
  format=self.format,
243
255
  stream=True,
244
256
  workspace=self._workspace,
257
+ pre_task_id=self.last_request_id,
245
258
  **self._kwargs)
246
259
  return responses
247
260
 
@@ -276,6 +289,8 @@ class Recognition(BaseApi):
276
289
 
277
290
  self._start_stream_timestamp = -1
278
291
  self._first_package_timestamp = -1
292
+ self._stop_stream_timestamp = -1
293
+ self._on_complete_timestamp = -1
279
294
  self._phrase = phrase_id
280
295
  self._kwargs.update(**kwargs)
281
296
  self._recognition_once = False
@@ -334,7 +349,7 @@ class Recognition(BaseApi):
334
349
  raise FileNotFoundError('No such file or directory: ' + file)
335
350
 
336
351
  self._recognition_once = True
337
- self._stream_data.clear()
352
+ self._stream_data = Queue()
338
353
  self._phrase = phrase_id
339
354
  self._kwargs.update(**kwargs)
340
355
  error_flag: bool = False
@@ -352,16 +367,17 @@ class Recognition(BaseApi):
352
367
  if not audio_data:
353
368
  break
354
369
  else:
355
- self._stream_data = self._stream_data + [audio_data]
370
+ self._stream_data.put(audio_data)
356
371
  else:
357
372
  raise InputDataRequired(
358
373
  'The supplied file was empty (zero bytes long)')
359
374
  f.close()
375
+ self._stop_stream_timestamp = time.time() * 1000
360
376
  except Exception as e:
361
377
  logger.error(e)
362
378
  raise e
363
379
 
364
- if self._stream_data is not None and len(self._stream_data) > 0:
380
+ if not self._stream_data.empty():
365
381
  self._running = True
366
382
  responses = self.__launch_request()
367
383
  for part in responses:
@@ -373,9 +389,10 @@ class Recognition(BaseApi):
373
389
  self._first_package_timestamp -
374
390
  self._start_stream_timestamp))
375
391
  sentence = part.output['sentence']
376
- logger.debug('Recv Result :{}, isEnd: {}'.format(
377
- sentence,
378
- RecognitionResult.is_sentence_end(sentence)))
392
+ logger.debug(
393
+ 'Recv Result [rid:{}]:{}, isEnd: {}'.format(
394
+ part.request_id, sentence,
395
+ RecognitionResult.is_sentence_end(sentence)))
379
396
  if RecognitionResult.is_sentence_end(sentence):
380
397
  sentences.append(sentence)
381
398
 
@@ -394,12 +411,16 @@ class Recognition(BaseApi):
394
411
  error_flag = True
395
412
  break
396
413
 
414
+ self._on_complete_timestamp = time.time() * 1000
415
+ logger.debug('last package delay {}'.format(
416
+ self.get_last_package_delay()))
417
+
397
418
  if error_flag:
398
419
  result = RecognitionResult(response)
399
420
  else:
400
421
  result = RecognitionResult(response, sentences, usages)
401
422
 
402
- self._stream_data.clear()
423
+ self._stream_data = Queue()
403
424
  self._recognition_once = False
404
425
  self._running = False
405
426
 
@@ -414,10 +435,12 @@ class Recognition(BaseApi):
414
435
  if self._running is False:
415
436
  raise InvalidParameter('Speech recognition has stopped.')
416
437
 
438
+ self._stop_stream_timestamp = time.time() * 1000
439
+
417
440
  self._running = False
418
441
  if self._worker is not None and self._worker.is_alive():
419
442
  self._worker.join()
420
- self._stream_data.clear()
443
+ self._stream_data = Queue()
421
444
  if self._silence_timer is not None and self._silence_timer.is_alive():
422
445
  self._silence_timer.cancel()
423
446
  self._silence_timer = None
@@ -436,7 +459,7 @@ class Recognition(BaseApi):
436
459
  if (self._start_stream_timestamp < 0):
437
460
  self._start_stream_timestamp = time.time() * 1000
438
461
  logger.debug('send_audio_frame: {}'.format(len(buffer)))
439
- self._stream_data = self._stream_data + [buffer]
462
+ self._stream_data.put(buffer)
440
463
 
441
464
  def _tidy_kwargs(self):
442
465
  for k in self._kwargs.copy():
@@ -445,8 +468,9 @@ class Recognition(BaseApi):
445
468
 
446
469
  def _input_stream_cycle(self):
447
470
  while self._running:
448
- while len(self._stream_data) == 0:
471
+ while self._stream_data.empty():
449
472
  if self._running:
473
+ time.sleep(0.01)
450
474
  continue
451
475
  else:
452
476
  break
@@ -459,16 +483,17 @@ class Recognition(BaseApi):
459
483
  self._silence_stop_timer)
460
484
  self._silence_timer.start()
461
485
 
462
- for frame in self._stream_data:
486
+ while not self._stream_data.empty():
487
+ frame = self._stream_data.get()
463
488
  yield bytes(frame)
464
- self._stream_data.clear()
465
489
 
466
490
  if self._recognition_once:
467
491
  self._running = False
468
492
 
469
493
  # drain all audio data when invoking stop().
470
494
  if self._recognition_once is False:
471
- for frame in self._stream_data:
495
+ while not self._stream_data.empty():
496
+ frame = self._stream_data.get()
472
497
  yield bytes(frame)
473
498
 
474
499
  def _silence_stop_timer(self):
@@ -480,4 +505,18 @@ class Recognition(BaseApi):
480
505
  self._silence_timer = None
481
506
  if self._worker is not None and self._worker.is_alive():
482
507
  self._worker.join()
483
- self._stream_data.clear()
508
+ self._stream_data = Queue()
509
+
510
+ def get_first_package_delay(self):
511
+ """First Package Delay is the time between start sending audio and receive first words package
512
+ """
513
+ return self._first_package_timestamp - self._start_stream_timestamp
514
+
515
+ def get_last_package_delay(self):
516
+ """Last Package Delay is the time between stop sending audio and receive last words package
517
+ """
518
+ return self._on_complete_timestamp - self._stop_stream_timestamp
519
+
520
+ # 获取上一个任务的taskId
521
+ def get_last_request_id(self):
522
+ return self.last_request_id