dashscope 1.17.0__py3-none-any.whl → 1.18.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.
- dashscope/aigc/image_synthesis.py +5 -0
- dashscope/api_entities/http_request.py +3 -22
- dashscope/app/application.py +5 -0
- dashscope/client/base_api.py +15 -3
- dashscope/common/utils.py +146 -30
- dashscope/threads/runs/runs.py +80 -5
- dashscope/threads/thread_types.py +85 -5
- dashscope/version.py +1 -1
- {dashscope-1.17.0.dist-info → dashscope-1.18.0.dist-info}/METADATA +1 -1
- {dashscope-1.17.0.dist-info → dashscope-1.18.0.dist-info}/RECORD +14 -14
- {dashscope-1.17.0.dist-info → dashscope-1.18.0.dist-info}/LICENSE +0 -0
- {dashscope-1.17.0.dist-info → dashscope-1.18.0.dist-info}/WHEEL +0 -0
- {dashscope-1.17.0.dist-info → dashscope-1.18.0.dist-info}/entry_points.txt +0 -0
- {dashscope-1.17.0.dist-info → dashscope-1.18.0.dist-info}/top_level.txt +0 -0
|
@@ -24,6 +24,7 @@ class ImageSynthesis(BaseAsyncApi):
|
|
|
24
24
|
images: List[str] = None,
|
|
25
25
|
api_key: str = None,
|
|
26
26
|
sketch_image_url: str = None,
|
|
27
|
+
ref_img: str = None,
|
|
27
28
|
workspace: str = None,
|
|
28
29
|
**kwargs) -> ImageSynthesisResponse:
|
|
29
30
|
"""Call image(s) synthesis service and get result.
|
|
@@ -61,6 +62,7 @@ class ImageSynthesis(BaseAsyncApi):
|
|
|
61
62
|
images,
|
|
62
63
|
api_key=api_key,
|
|
63
64
|
sketch_image_url=sketch_image_url,
|
|
65
|
+
ref_img=ref_img,
|
|
64
66
|
workspace=workspace,
|
|
65
67
|
**kwargs)
|
|
66
68
|
|
|
@@ -72,6 +74,7 @@ class ImageSynthesis(BaseAsyncApi):
|
|
|
72
74
|
images: List[str] = None,
|
|
73
75
|
api_key: str = None,
|
|
74
76
|
sketch_image_url: str = None,
|
|
77
|
+
ref_img: str = None,
|
|
75
78
|
workspace: str = None,
|
|
76
79
|
**kwargs) -> ImageSynthesisResponse:
|
|
77
80
|
"""Create a image(s) synthesis task, and return task information.
|
|
@@ -113,6 +116,8 @@ class ImageSynthesis(BaseAsyncApi):
|
|
|
113
116
|
input[IMAGES] = images
|
|
114
117
|
if sketch_image_url is not None and sketch_image_url:
|
|
115
118
|
input['sketch_image_url'] = sketch_image_url
|
|
119
|
+
if ref_img is not None and ref_img:
|
|
120
|
+
input['ref_img'] == ref_img
|
|
116
121
|
response = super().async_call(model=model,
|
|
117
122
|
task_group=task_group,
|
|
118
123
|
task=ImageSynthesis.task,
|
|
@@ -9,6 +9,7 @@ from dashscope.common.constants import (DEFAULT_REQUEST_TIMEOUT_SECONDS,
|
|
|
9
9
|
SSE_CONTENT_TYPE, HTTPMethod)
|
|
10
10
|
from dashscope.common.error import UnsupportedHTTPMethod
|
|
11
11
|
from dashscope.common.logging import logger
|
|
12
|
+
from dashscope.common.utils import _handle_stream
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class HttpRequest(BaseRequest):
|
|
@@ -83,34 +84,14 @@ class HttpRequest(BaseRequest):
|
|
|
83
84
|
pass
|
|
84
85
|
return output
|
|
85
86
|
|
|
86
|
-
def _handle_stream(self, response: requests.Response):
|
|
87
|
-
# TODO define done message.
|
|
88
|
-
is_error = False
|
|
89
|
-
status_code = HTTPStatus.INTERNAL_SERVER_ERROR
|
|
90
|
-
for line in response.iter_lines():
|
|
91
|
-
if line:
|
|
92
|
-
line = line.decode('utf8')
|
|
93
|
-
line = line.rstrip('\n').rstrip('\r')
|
|
94
|
-
if line.startswith('event:error'):
|
|
95
|
-
is_error = True
|
|
96
|
-
elif line.startswith('status:'):
|
|
97
|
-
status_code = line[len('status:'):]
|
|
98
|
-
status_code = int(status_code.strip())
|
|
99
|
-
elif line.startswith('data:'):
|
|
100
|
-
line = line[len('data:'):]
|
|
101
|
-
yield (is_error, status_code, line)
|
|
102
|
-
if is_error:
|
|
103
|
-
break
|
|
104
|
-
else:
|
|
105
|
-
continue # ignore heartbeat...
|
|
106
|
-
|
|
107
87
|
def _handle_response(self, response: requests.Response):
|
|
108
88
|
request_id = ''
|
|
109
89
|
if (response.status_code == HTTPStatus.OK and self.stream
|
|
110
90
|
and SSE_CONTENT_TYPE in response.headers.get(
|
|
111
91
|
'content-type', '')):
|
|
112
|
-
for is_error, status_code,
|
|
92
|
+
for is_error, status_code, event in _handle_stream(response):
|
|
113
93
|
try:
|
|
94
|
+
data = event.data
|
|
114
95
|
output = None
|
|
115
96
|
usage = None
|
|
116
97
|
msg = json.loads(data)
|
dashscope/app/application.py
CHANGED
|
@@ -112,6 +112,11 @@ class Application(BaseApi):
|
|
|
112
112
|
if prompt is None or not prompt:
|
|
113
113
|
raise InputRequired('prompt is required!')
|
|
114
114
|
|
|
115
|
+
if workspace is not None and workspace:
|
|
116
|
+
headers = kwargs.pop('headers', {})
|
|
117
|
+
headers['X-DashScope-WorkSpace'] = workspace
|
|
118
|
+
kwargs['headers'] = headers
|
|
119
|
+
|
|
115
120
|
input, parameters = cls._build_input_parameters(
|
|
116
121
|
prompt, history, **kwargs)
|
|
117
122
|
request = _build_api_request(model='',
|
dashscope/client/base_api.py
CHANGED
|
@@ -15,8 +15,9 @@ from dashscope.common.constants import (DEFAULT_REQUEST_TIMEOUT_SECONDS,
|
|
|
15
15
|
from dashscope.common.error import InvalidParameter, InvalidTask, ModelRequired
|
|
16
16
|
from dashscope.common.logging import logger
|
|
17
17
|
from dashscope.common.utils import (_handle_http_failed_response,
|
|
18
|
-
_handle_http_response,
|
|
19
|
-
|
|
18
|
+
_handle_http_response,
|
|
19
|
+
_handle_http_stream_response,
|
|
20
|
+
default_headers, join_url)
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class BaseAioApi():
|
|
@@ -720,6 +721,7 @@ class CreateMixin():
|
|
|
720
721
|
data: object,
|
|
721
722
|
api_key: str = None,
|
|
722
723
|
path: str = None,
|
|
724
|
+
stream: bool = False,
|
|
723
725
|
workspace: str = None,
|
|
724
726
|
**kwargs) -> Union[DashScopeAPIResponse, Dict]:
|
|
725
727
|
"""Create a object
|
|
@@ -741,6 +743,7 @@ class CreateMixin():
|
|
|
741
743
|
logger.debug('Starting request: %s' % url)
|
|
742
744
|
response = session.post(url,
|
|
743
745
|
json=data,
|
|
746
|
+
stream=stream,
|
|
744
747
|
headers={
|
|
745
748
|
**_workspace_header(workspace),
|
|
746
749
|
**default_headers(api_key),
|
|
@@ -748,7 +751,16 @@ class CreateMixin():
|
|
|
748
751
|
},
|
|
749
752
|
timeout=timeout)
|
|
750
753
|
logger.debug('Starting processing response: %s' % url)
|
|
751
|
-
|
|
754
|
+
response = _handle_http_stream_response(response, flattened_output)
|
|
755
|
+
if stream:
|
|
756
|
+
return (item for item in response)
|
|
757
|
+
else:
|
|
758
|
+
_, output = next(response)
|
|
759
|
+
try:
|
|
760
|
+
next(response)
|
|
761
|
+
except StopIteration:
|
|
762
|
+
pass
|
|
763
|
+
return output
|
|
752
764
|
|
|
753
765
|
|
|
754
766
|
class UpdateMixin():
|
dashscope/common/utils.py
CHANGED
|
@@ -2,6 +2,7 @@ import asyncio
|
|
|
2
2
|
import json
|
|
3
3
|
import os
|
|
4
4
|
import platform
|
|
5
|
+
from dataclasses import dataclass
|
|
5
6
|
from http import HTTPStatus
|
|
6
7
|
from typing import Dict
|
|
7
8
|
from urllib.parse import urlparse
|
|
@@ -11,6 +12,8 @@ import requests
|
|
|
11
12
|
|
|
12
13
|
from dashscope.api_entities.dashscope_response import DashScopeAPIResponse
|
|
13
14
|
from dashscope.common.api_key import get_default_api_key
|
|
15
|
+
from dashscope.common.constants import SSE_CONTENT_TYPE
|
|
16
|
+
from dashscope.common.logging import logger
|
|
14
17
|
from dashscope.version import __version__
|
|
15
18
|
|
|
16
19
|
|
|
@@ -163,6 +166,52 @@ async def _handle_aiohttp_response(response: aiohttp.ClientResponse):
|
|
|
163
166
|
message=msg)
|
|
164
167
|
|
|
165
168
|
|
|
169
|
+
@dataclass
|
|
170
|
+
class SSEEvent:
|
|
171
|
+
id: str
|
|
172
|
+
eventType: str
|
|
173
|
+
data: str
|
|
174
|
+
|
|
175
|
+
def __init__(self, id: str, type: str, data: str):
|
|
176
|
+
self.id = id
|
|
177
|
+
self.eventType = type
|
|
178
|
+
self.data = data
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _handle_stream(response: requests.Response):
|
|
182
|
+
# TODO define done message.
|
|
183
|
+
is_error = False
|
|
184
|
+
status_code = HTTPStatus.INTERNAL_SERVER_ERROR
|
|
185
|
+
event = SSEEvent(None, None, None)
|
|
186
|
+
eventType = None
|
|
187
|
+
for line in response.iter_lines():
|
|
188
|
+
if line:
|
|
189
|
+
line = line.decode('utf8')
|
|
190
|
+
line = line.rstrip('\n').rstrip('\r')
|
|
191
|
+
print(line)
|
|
192
|
+
if line.startswith('id:'):
|
|
193
|
+
id = line[len('id:'):]
|
|
194
|
+
event.id = id.strip()
|
|
195
|
+
elif line.startswith('event:'):
|
|
196
|
+
eventType = line[len('event:'):]
|
|
197
|
+
event.eventType = eventType.strip()
|
|
198
|
+
if eventType == 'error':
|
|
199
|
+
is_error = True
|
|
200
|
+
elif line.startswith('status:'):
|
|
201
|
+
status_code = line[len('status:'):]
|
|
202
|
+
status_code = int(status_code.strip())
|
|
203
|
+
elif line.startswith('data:'):
|
|
204
|
+
line = line[len('data:'):]
|
|
205
|
+
event.data = line.strip()
|
|
206
|
+
if eventType is not None and eventType == 'done':
|
|
207
|
+
continue
|
|
208
|
+
yield (is_error, status_code, event)
|
|
209
|
+
if is_error:
|
|
210
|
+
break
|
|
211
|
+
else:
|
|
212
|
+
continue # ignore heartbeat...
|
|
213
|
+
|
|
214
|
+
|
|
166
215
|
def _handle_http_failed_response(
|
|
167
216
|
response: requests.Response,
|
|
168
217
|
flattened_output: bool = False) -> DashScopeAPIResponse:
|
|
@@ -198,38 +247,105 @@ def _handle_http_failed_response(
|
|
|
198
247
|
|
|
199
248
|
def _handle_http_response(response: requests.Response,
|
|
200
249
|
flattened_output: bool = False):
|
|
250
|
+
response = _handle_http_stream_response(response, flattened_output)
|
|
251
|
+
_, output = next(response)
|
|
252
|
+
try:
|
|
253
|
+
next(response)
|
|
254
|
+
except StopIteration:
|
|
255
|
+
pass
|
|
256
|
+
return output
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def _handle_http_stream_response(response: requests.Response,
|
|
260
|
+
flattened_output: bool = False):
|
|
201
261
|
request_id = ''
|
|
202
|
-
if response.status_code == HTTPStatus.OK
|
|
262
|
+
if (response.status_code == HTTPStatus.OK
|
|
263
|
+
and SSE_CONTENT_TYPE in response.headers.get('content-type', '')):
|
|
264
|
+
for is_error, status_code, event in _handle_stream(response):
|
|
265
|
+
if not is_error:
|
|
266
|
+
try:
|
|
267
|
+
output = None
|
|
268
|
+
usage = None
|
|
269
|
+
msg = json.loads(event.data)
|
|
270
|
+
if flattened_output:
|
|
271
|
+
msg['status_code'] = response.status_code
|
|
272
|
+
yield event.eventType, msg
|
|
273
|
+
else:
|
|
274
|
+
logger.debug('Stream message: %s' % msg)
|
|
275
|
+
if not is_error:
|
|
276
|
+
if 'output' in msg:
|
|
277
|
+
output = msg['output']
|
|
278
|
+
if 'usage' in msg:
|
|
279
|
+
usage = msg['usage']
|
|
280
|
+
if 'request_id' in msg:
|
|
281
|
+
request_id = msg['request_id']
|
|
282
|
+
yield event.eventType, DashScopeAPIResponse(
|
|
283
|
+
request_id=request_id,
|
|
284
|
+
status_code=HTTPStatus.OK,
|
|
285
|
+
output=output,
|
|
286
|
+
usage=usage)
|
|
287
|
+
except json.JSONDecodeError as e:
|
|
288
|
+
if flattened_output:
|
|
289
|
+
yield event.eventType, {
|
|
290
|
+
'status_code': response.status_code,
|
|
291
|
+
'message': e.message
|
|
292
|
+
}
|
|
293
|
+
else:
|
|
294
|
+
yield event.eventType, DashScopeAPIResponse(
|
|
295
|
+
request_id=request_id,
|
|
296
|
+
status_code=HTTPStatus.BAD_REQUEST,
|
|
297
|
+
output=None,
|
|
298
|
+
code='Unknown',
|
|
299
|
+
message=event.data)
|
|
300
|
+
continue
|
|
301
|
+
else:
|
|
302
|
+
if flattened_output:
|
|
303
|
+
yield event.eventType, {
|
|
304
|
+
'status_code': status_code,
|
|
305
|
+
'message': event.data
|
|
306
|
+
}
|
|
307
|
+
else:
|
|
308
|
+
msg = json.loads(event.eventType)
|
|
309
|
+
yield event.eventType, DashScopeAPIResponse(
|
|
310
|
+
request_id=request_id,
|
|
311
|
+
status_code=status_code,
|
|
312
|
+
output=None,
|
|
313
|
+
code=msg['code']
|
|
314
|
+
if 'code' in msg else None, # noqa E501
|
|
315
|
+
message=msg['message']
|
|
316
|
+
if 'message' in msg else None) # noqa E501
|
|
317
|
+
elif response.status_code == HTTPStatus.OK or response.status_code == HTTPStatus.CREATED:
|
|
203
318
|
json_content = response.json()
|
|
204
319
|
if flattened_output:
|
|
205
320
|
json_content['status_code'] = response.status_code
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
code
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
output
|
|
219
|
-
|
|
220
|
-
usage
|
|
221
|
-
|
|
222
|
-
request_id
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
output
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
321
|
+
yield None, json_content
|
|
322
|
+
else:
|
|
323
|
+
output = None
|
|
324
|
+
usage = None
|
|
325
|
+
code = None
|
|
326
|
+
msg = ''
|
|
327
|
+
if 'data' in json_content:
|
|
328
|
+
output = json_content['data']
|
|
329
|
+
if 'code' in json_content:
|
|
330
|
+
code = json_content['code']
|
|
331
|
+
if 'message' in json_content:
|
|
332
|
+
msg = json_content['message']
|
|
333
|
+
if 'output' in json_content:
|
|
334
|
+
output = json_content['output']
|
|
335
|
+
if 'usage' in json_content:
|
|
336
|
+
usage = json_content['usage']
|
|
337
|
+
if 'request_id' in json_content:
|
|
338
|
+
request_id = json_content['request_id']
|
|
339
|
+
json_content.pop('request_id', None)
|
|
340
|
+
|
|
341
|
+
if 'data' not in json_content and 'output' not in json_content:
|
|
342
|
+
output = json_content
|
|
343
|
+
|
|
344
|
+
yield None, DashScopeAPIResponse(request_id=request_id,
|
|
345
|
+
status_code=response.status_code,
|
|
346
|
+
code=code,
|
|
347
|
+
output=output,
|
|
348
|
+
usage=usage,
|
|
349
|
+
message=msg)
|
|
234
350
|
else:
|
|
235
|
-
|
|
351
|
+
yield None, _handle_http_failed_response(response, flattened_output)
|
dashscope/threads/runs/runs.py
CHANGED
|
@@ -7,7 +7,9 @@ from dashscope.client.base_api import (CancelMixin, CreateMixin,
|
|
|
7
7
|
UpdateMixin)
|
|
8
8
|
from dashscope.common.error import InputRequired, TimeoutException
|
|
9
9
|
from dashscope.common.logging import logger
|
|
10
|
-
from dashscope.threads.thread_types import Run, RunList
|
|
10
|
+
from dashscope.threads.thread_types import (Run, RunList, RunStep,
|
|
11
|
+
RunStepDelta, Thread,
|
|
12
|
+
ThreadMessage, ThreadMessageDelta)
|
|
11
13
|
|
|
12
14
|
__all__ = ['Runs']
|
|
13
15
|
|
|
@@ -25,8 +27,10 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
|
|
|
25
27
|
instructions: Optional[str] = None,
|
|
26
28
|
additional_instructions: Optional[str] = None,
|
|
27
29
|
tools: Optional[List[Dict]] = None,
|
|
30
|
+
stream: Optional[bool] = False,
|
|
28
31
|
metadata: Optional[Dict] = None,
|
|
29
32
|
workspace: str = None,
|
|
33
|
+
extra_body: Optional[Dict] = None,
|
|
30
34
|
api_key: str = None,
|
|
31
35
|
**kwargs) -> Run:
|
|
32
36
|
if not assistant_id:
|
|
@@ -44,14 +48,22 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
|
|
|
44
48
|
data['tools'] = tools
|
|
45
49
|
if metadata:
|
|
46
50
|
data['metadata'] = metadata
|
|
51
|
+
data['stream'] = stream
|
|
52
|
+
if extra_body is not None and extra_body:
|
|
53
|
+
data = {**data, **extra_body}
|
|
47
54
|
|
|
48
55
|
response = super().call(data=data,
|
|
49
56
|
path='threads/runs',
|
|
50
57
|
api_key=api_key,
|
|
51
58
|
flattened_output=True,
|
|
59
|
+
stream=stream,
|
|
52
60
|
workspace=workspace,
|
|
53
61
|
**kwargs)
|
|
54
|
-
|
|
62
|
+
if stream:
|
|
63
|
+
return ((event_type, cls.convert_stream_object(event_type, item))
|
|
64
|
+
for event_type, item in response)
|
|
65
|
+
else:
|
|
66
|
+
return Run(**response)
|
|
55
67
|
|
|
56
68
|
@classmethod
|
|
57
69
|
def create(cls,
|
|
@@ -63,7 +75,9 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
|
|
|
63
75
|
additional_instructions: Optional[str] = None,
|
|
64
76
|
tools: Optional[List[Dict]] = None,
|
|
65
77
|
metadata: Optional[Dict] = None,
|
|
78
|
+
stream: Optional[bool] = False,
|
|
66
79
|
workspace: str = None,
|
|
80
|
+
extra_body: Optional[Dict] = None,
|
|
67
81
|
api_key: str = None,
|
|
68
82
|
**kwargs) -> Run:
|
|
69
83
|
"""Create a run.
|
|
@@ -101,14 +115,53 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
|
|
|
101
115
|
data['tools'] = tools
|
|
102
116
|
if metadata:
|
|
103
117
|
data['metadata'] = metadata
|
|
118
|
+
data['stream'] = stream
|
|
119
|
+
if extra_body is not None and extra_body:
|
|
120
|
+
data = {**data, **extra_body}
|
|
104
121
|
|
|
105
122
|
response = super().call(data=data,
|
|
106
123
|
path=f'threads/{thread_id}/runs',
|
|
107
124
|
api_key=api_key,
|
|
108
125
|
flattened_output=True,
|
|
126
|
+
stream=stream,
|
|
109
127
|
workspace=workspace,
|
|
110
128
|
**kwargs)
|
|
111
|
-
|
|
129
|
+
if stream:
|
|
130
|
+
return ((event_type, cls.convert_stream_object(event_type, item))
|
|
131
|
+
for event_type, item in response)
|
|
132
|
+
else:
|
|
133
|
+
return Run(**response)
|
|
134
|
+
|
|
135
|
+
@classmethod
|
|
136
|
+
def convert_stream_object(cls, event, item):
|
|
137
|
+
event_object_map = {
|
|
138
|
+
'thread.created': Thread,
|
|
139
|
+
'thread.run.created': Run,
|
|
140
|
+
'thread.run.queued': Run,
|
|
141
|
+
'thread.run.in_progress': Run,
|
|
142
|
+
'thread.run.requires_action': Run,
|
|
143
|
+
'thread.run.completed': Run,
|
|
144
|
+
'thread.run.failed': Run,
|
|
145
|
+
'thread.run.cancelled': Run,
|
|
146
|
+
'thread.run.expired': Run,
|
|
147
|
+
'thread.run.step.created': RunStep,
|
|
148
|
+
'thread.run.step.in_progress': RunStep,
|
|
149
|
+
'thread.run.step.delta': RunStepDelta,
|
|
150
|
+
'thread.run.step.completed': RunStep,
|
|
151
|
+
'thread.run.step.failed': RunStep,
|
|
152
|
+
'thread.run.step.cancelled': RunStep,
|
|
153
|
+
'thread.run.step.expired': RunStep,
|
|
154
|
+
'thread.message.created': ThreadMessage,
|
|
155
|
+
'thread.message.in_progress': ThreadMessage,
|
|
156
|
+
'thread.message.delta': ThreadMessageDelta,
|
|
157
|
+
'thread.message.completed': ThreadMessage,
|
|
158
|
+
'thread.message.incomplete': ThreadMessage,
|
|
159
|
+
'error': item,
|
|
160
|
+
}
|
|
161
|
+
if (event in event_object_map):
|
|
162
|
+
return event_object_map[event](**item)
|
|
163
|
+
else:
|
|
164
|
+
return item
|
|
112
165
|
|
|
113
166
|
@classmethod
|
|
114
167
|
def call(cls,
|
|
@@ -119,8 +172,10 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
|
|
|
119
172
|
instructions: Optional[str] = None,
|
|
120
173
|
additional_instructions: Optional[str] = None,
|
|
121
174
|
tools: Optional[List[Dict]] = None,
|
|
175
|
+
stream: Optional[bool] = False,
|
|
122
176
|
metadata: Optional[Dict] = None,
|
|
123
177
|
workspace: str = None,
|
|
178
|
+
extra_body: Optional[Dict] = None,
|
|
124
179
|
api_key: str = None,
|
|
125
180
|
**kwargs) -> Run:
|
|
126
181
|
"""Create a run.
|
|
@@ -151,8 +206,10 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
|
|
|
151
206
|
instructions=instructions,
|
|
152
207
|
additional_instructions=additional_instructions,
|
|
153
208
|
tools=tools,
|
|
209
|
+
stream=stream,
|
|
154
210
|
metadata=metadata,
|
|
155
211
|
workspace=workspace,
|
|
212
|
+
extra_body=extra_body,
|
|
156
213
|
api_key=api_key,
|
|
157
214
|
**kwargs)
|
|
158
215
|
|
|
@@ -254,7 +311,9 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
|
|
|
254
311
|
*,
|
|
255
312
|
thread_id: str,
|
|
256
313
|
tool_outputs: List[Dict],
|
|
314
|
+
stream: Optional[bool] = False,
|
|
257
315
|
workspace: str = None,
|
|
316
|
+
extra_body: Optional[Dict] = None,
|
|
258
317
|
api_key: str = None,
|
|
259
318
|
**kwargs) -> Run:
|
|
260
319
|
"""_summary_
|
|
@@ -278,14 +337,24 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
|
|
|
278
337
|
if not thread_id or not run_id:
|
|
279
338
|
raise InputRequired('thread_id and run_id are required!')
|
|
280
339
|
|
|
340
|
+
data = {'tool_outputs': tool_outputs}
|
|
341
|
+
data['stream'] = stream
|
|
342
|
+
if extra_body is not None and extra_body:
|
|
343
|
+
data = {**data, **extra_body}
|
|
344
|
+
|
|
281
345
|
response = super().call(
|
|
282
|
-
|
|
346
|
+
data,
|
|
283
347
|
path=f'threads/{thread_id}/runs/{run_id}/submit_tool_outputs',
|
|
284
348
|
workspace=workspace,
|
|
285
349
|
api_key=api_key,
|
|
350
|
+
stream=stream,
|
|
286
351
|
flattened_output=True,
|
|
287
352
|
**kwargs)
|
|
288
|
-
|
|
353
|
+
if stream:
|
|
354
|
+
return ((event_type, cls.convert_stream_object(event_type, item))
|
|
355
|
+
for event_type, item in response)
|
|
356
|
+
else:
|
|
357
|
+
return Run(**response)
|
|
289
358
|
|
|
290
359
|
@classmethod
|
|
291
360
|
def wait(cls,
|
|
@@ -316,6 +385,12 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
|
|
|
316
385
|
thread_id=thread_id,
|
|
317
386
|
workspace=workspace,
|
|
318
387
|
api_key=api_key)
|
|
388
|
+
import json
|
|
389
|
+
print(
|
|
390
|
+
json.dumps(run,
|
|
391
|
+
default=lambda o: o.__dict__,
|
|
392
|
+
sort_keys=True,
|
|
393
|
+
indent=4))
|
|
319
394
|
if run.status_code == HTTPStatus.OK:
|
|
320
395
|
if hasattr(run, 'status'):
|
|
321
396
|
if run.status in [
|
|
@@ -85,6 +85,8 @@ class Text(BaseObjectMixin):
|
|
|
85
85
|
self.annotations = []
|
|
86
86
|
for annotation in annotations:
|
|
87
87
|
self.annotations.append(annotation)
|
|
88
|
+
else:
|
|
89
|
+
self.annotations = annotations
|
|
88
90
|
super().__init__(**kwargs)
|
|
89
91
|
|
|
90
92
|
|
|
@@ -108,6 +110,42 @@ MESSAGE_SUPPORT_CONTENT = {
|
|
|
108
110
|
Content = Union[MessageContentImageFile, MessageContentText]
|
|
109
111
|
|
|
110
112
|
|
|
113
|
+
@dataclass(init=False)
|
|
114
|
+
class ThreadMessageDeltaContent(BaseObjectMixin):
|
|
115
|
+
content: Content
|
|
116
|
+
role: str
|
|
117
|
+
|
|
118
|
+
def __init__(self, **kwargs):
|
|
119
|
+
contents = kwargs.pop('content', None)
|
|
120
|
+
if contents:
|
|
121
|
+
for item in contents:
|
|
122
|
+
if item['type'] == 'text':
|
|
123
|
+
self.content = MessageContentText(**item)
|
|
124
|
+
elif item['type'] == 'image_file':
|
|
125
|
+
self.content = MessageContentImageFile(**item)
|
|
126
|
+
else:
|
|
127
|
+
self.content = item
|
|
128
|
+
else:
|
|
129
|
+
self.content = contents
|
|
130
|
+
super().__init__(**kwargs)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@dataclass(init=False)
|
|
134
|
+
class ThreadMessageDelta(BaseObjectMixin):
|
|
135
|
+
status_code: int
|
|
136
|
+
id: str
|
|
137
|
+
object: str = 'thread.message.delta'
|
|
138
|
+
delta: ThreadMessageDeltaContent
|
|
139
|
+
|
|
140
|
+
def __init__(self, **kwargs):
|
|
141
|
+
content = kwargs.pop('delta', None)
|
|
142
|
+
if content:
|
|
143
|
+
self.delta = ThreadMessageDeltaContent(**content)
|
|
144
|
+
else:
|
|
145
|
+
self.delta = None
|
|
146
|
+
super().__init__(**kwargs)
|
|
147
|
+
|
|
148
|
+
|
|
111
149
|
@dataclass(init=False)
|
|
112
150
|
class ThreadMessage(BaseObjectMixin):
|
|
113
151
|
status_code: int
|
|
@@ -137,6 +175,8 @@ class ThreadMessage(BaseObjectMixin):
|
|
|
137
175
|
else:
|
|
138
176
|
content_list.append(content)
|
|
139
177
|
self.content = content_list
|
|
178
|
+
else:
|
|
179
|
+
self.content = input_content
|
|
140
180
|
|
|
141
181
|
super().__init__(**kwargs)
|
|
142
182
|
|
|
@@ -203,6 +243,8 @@ class RequiredActionSubmitToolOutputs(BaseObjectMixin):
|
|
|
203
243
|
self.tool_calls = []
|
|
204
244
|
for tc in tcs:
|
|
205
245
|
self.tool_calls.append(RequiredActionFunctionToolCall(**tc))
|
|
246
|
+
else:
|
|
247
|
+
self.tool_calls = tcs
|
|
206
248
|
super().__init__(**kwargs)
|
|
207
249
|
|
|
208
250
|
|
|
@@ -265,6 +307,8 @@ class Run(BaseObjectMixin):
|
|
|
265
307
|
actions = kwargs.pop('required_action', None)
|
|
266
308
|
if actions:
|
|
267
309
|
self.required_action = RequiredAction(**actions)
|
|
310
|
+
else:
|
|
311
|
+
self.required_action = actions
|
|
268
312
|
|
|
269
313
|
super().__init__(**kwargs)
|
|
270
314
|
|
|
@@ -387,10 +431,10 @@ class RetrievalToolCall(BaseObjectMixin):
|
|
|
387
431
|
retrieval: object
|
|
388
432
|
"""For now, this is always going to be an empty object."""
|
|
389
433
|
|
|
390
|
-
type: Literal['
|
|
434
|
+
type: Literal['quark_search']
|
|
391
435
|
"""The type of tool call.
|
|
392
436
|
|
|
393
|
-
This is always going to be `
|
|
437
|
+
This is always going to be `quark_search` for this type of tool call.
|
|
394
438
|
"""
|
|
395
439
|
def __init__(self, **kwargs):
|
|
396
440
|
super().__init__(**kwargs)
|
|
@@ -469,9 +513,34 @@ def convert_step_details_dict_to_objects(step_details):
|
|
|
469
513
|
return step_details
|
|
470
514
|
|
|
471
515
|
|
|
516
|
+
@dataclass(init=False)
|
|
517
|
+
class RunStepDeltaContent(BaseObjectMixin):
|
|
518
|
+
step_details: StepDetails
|
|
519
|
+
|
|
520
|
+
def __init__(self, **kwargs):
|
|
521
|
+
self.step_details = convert_step_details_dict_to_objects(
|
|
522
|
+
kwargs.pop('step_details', {}))
|
|
523
|
+
super().__init__(**kwargs)
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
@dataclass(init=False)
|
|
527
|
+
class RunStepDelta(BaseObjectMixin):
|
|
528
|
+
id: str
|
|
529
|
+
object: str = 'thread.run.step.delta'
|
|
530
|
+
delta: RunStepDeltaContent
|
|
531
|
+
|
|
532
|
+
def __init__(self, **kwargs):
|
|
533
|
+
delta = kwargs.pop('delta', None)
|
|
534
|
+
if delta:
|
|
535
|
+
self.delta = RunStepDeltaContent(**delta)
|
|
536
|
+
else:
|
|
537
|
+
self.delta = delta
|
|
538
|
+
super().__init__(**kwargs)
|
|
539
|
+
|
|
540
|
+
|
|
472
541
|
@dataclass(init=False)
|
|
473
542
|
class RunStep(BaseObjectMixin):
|
|
474
|
-
status_code: int
|
|
543
|
+
status_code: int = None
|
|
475
544
|
id: str
|
|
476
545
|
"""The identifier of the run step, which can be referenced in API endpoints."""
|
|
477
546
|
|
|
@@ -547,10 +616,15 @@ class RunStep(BaseObjectMixin):
|
|
|
547
616
|
def __init__(self, **kwargs):
|
|
548
617
|
self.step_details = convert_step_details_dict_to_objects(
|
|
549
618
|
kwargs.pop('step_details', {}))
|
|
550
|
-
|
|
619
|
+
if 'usage' in kwargs and kwargs['usage'] is not None and kwargs['usage']:
|
|
620
|
+
self.usage = Usage(**kwargs.pop('usage', {}))
|
|
621
|
+
else:
|
|
622
|
+
self.usage = None
|
|
551
623
|
last_error = kwargs.pop('last_error', None)
|
|
552
624
|
if last_error:
|
|
553
625
|
self.last_error = LastError(**last_error)
|
|
626
|
+
else:
|
|
627
|
+
last_error = last_error
|
|
554
628
|
super().__init__(**kwargs)
|
|
555
629
|
|
|
556
630
|
|
|
@@ -564,8 +638,14 @@ class RunStepList(BaseList):
|
|
|
564
638
|
first_id: Optional[str] = None,
|
|
565
639
|
data: List[RunStep] = [],
|
|
566
640
|
**kwargs):
|
|
641
|
+
if data:
|
|
642
|
+
steps = []
|
|
643
|
+
for step in data:
|
|
644
|
+
steps.append(RunStep(**step))
|
|
645
|
+
self.data = steps
|
|
646
|
+
else:
|
|
647
|
+
self.data = []
|
|
567
648
|
super().__init__(has_more=has_more,
|
|
568
649
|
last_id=last_id,
|
|
569
650
|
first_id=first_id,
|
|
570
|
-
data=data,
|
|
571
651
|
**kwargs)
|
dashscope/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '1.
|
|
1
|
+
__version__ = '1.18.0'
|
|
@@ -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=UPOn1qMYFhX-ovXi3BMxZEBk8qOK7WLJOYHMbPZwYBo,1440
|
|
9
|
-
dashscope/version.py,sha256=
|
|
9
|
+
dashscope/version.py,sha256=q8fI5ieuQmE0i1govJ0GSDS7ZYmdLjENalxa2NdG9VQ,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=9PMAhSy5Ht5eizUGXnDdk8Jl3yIDM4fR8eSxn1W4c-U,10051
|
|
14
|
-
dashscope/aigc/image_synthesis.py,sha256=
|
|
14
|
+
dashscope/aigc/image_synthesis.py,sha256=7A5txSkKBkg5pN5F7IP5C90277Yk8fkKAWu30YhskdM,9994
|
|
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,10 +19,10 @@ 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=
|
|
22
|
+
dashscope/api_entities/http_request.py,sha256=Y9z4PcRAPlp6Ozfz9P3IVP3y9cufhhIFjXaJOF6xCtQ,9043
|
|
23
23
|
dashscope/api_entities/websocket_request.py,sha256=IaydqRvOSr5IdSSpnX8Vc8rRoVldjfcrLvDxTnPep9g,14676
|
|
24
24
|
dashscope/app/__init__.py,sha256=OOV2rFy0QlA9Gu3XVPtWJoBwK1J11BdGhkEdX_sdYGU,68
|
|
25
|
-
dashscope/app/application.py,sha256=
|
|
25
|
+
dashscope/app/application.py,sha256=AegGVsk3dDzYACoYRNNjo3eG-2wrDd0dlOjYHpF0r2Y,7949
|
|
26
26
|
dashscope/app/application_response.py,sha256=pIuDSu_SAcX1Y_gK6ZYaadaMXV52XBZoM1uN4tTZ3FA,6739
|
|
27
27
|
dashscope/assistants/__init__.py,sha256=i9N5OxHgY7edlOhTdPyC0N5Uc0uMCkB2vbMPDCD1zX0,383
|
|
28
28
|
dashscope/assistants/assistant_types.py,sha256=1jNL30TOlrkiYhvCaB3E8jkPLG8CnQ6I3tHpYXZCsD0,4211
|
|
@@ -36,7 +36,7 @@ dashscope/audio/asr/transcription.py,sha256=e5O1U51GT-OQPu-wWN2w_T7l6IopWuGMVkhe
|
|
|
36
36
|
dashscope/audio/tts/__init__.py,sha256=fbnieZX9yNFNh5BsxLpLXb63jlxzxrdCJakV3ignjlQ,194
|
|
37
37
|
dashscope/audio/tts/speech_synthesizer.py,sha256=dnKx9FDDdO_ETHAjhK8zaMVaH6SfoTtN5YxXXqgY1JA,7571
|
|
38
38
|
dashscope/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
-
dashscope/client/base_api.py,sha256=
|
|
39
|
+
dashscope/client/base_api.py,sha256=UDxvwlxiR0KZwj_AI0jACfkLErJ55voure82OmOiDMk,41034
|
|
40
40
|
dashscope/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
41
|
dashscope/common/api_key.py,sha256=5Stp0odL5JSuIO3qJBp23QNppuGbqhhvKPS66qbMs0I,1986
|
|
42
42
|
dashscope/common/base_type.py,sha256=wKqLGrr2o9bpI43ws1P0YCuJmoS17J9_Rw_uuYHjIFQ,4531
|
|
@@ -45,7 +45,7 @@ dashscope/common/env.py,sha256=oQOZW5JyEeTSde394un2lpDJ5RBh4fMU9hBfbtrKKkc,869
|
|
|
45
45
|
dashscope/common/error.py,sha256=eFUSBNERfXYQ4g3bVka_IGuRG1A06Zf6njObBtR2z6E,1951
|
|
46
46
|
dashscope/common/logging.py,sha256=ecGxylG3bWES_Xv5-BD6ep4_0Ciu7F6ZPBjiZtu9Jx4,984
|
|
47
47
|
dashscope/common/message_manager.py,sha256=i5149WzDk6nWmdFaHzYx4USXMBeX18GKSI-F4fLwbN0,1097
|
|
48
|
-
dashscope/common/utils.py,sha256=
|
|
48
|
+
dashscope/common/utils.py,sha256=AqpU4Lh6C64-Uy-BLybpRz01HqlmcAgVqlqN73tD1I0,12041
|
|
49
49
|
dashscope/embeddings/__init__.py,sha256=-dxHaoxZZVuP-wAGUIa3sNNh8CQwaeWj2UlqsDy1sV4,240
|
|
50
50
|
dashscope/embeddings/batch_text_embedding.py,sha256=P32LFO9v7ehdJsl0c32In94hUET6K6AaGJ_pDRtFqco,8791
|
|
51
51
|
dashscope/embeddings/batch_text_embedding_response.py,sha256=WziXlQsFIkL1kPc_7lRG1HtqgkO5vVThtnNqExJggNU,2000
|
|
@@ -61,13 +61,13 @@ dashscope/rerank/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
|
61
61
|
dashscope/rerank/text_rerank.py,sha256=1L-RLUxMCvNhbMud1FUG6YFWT7ZV979fzhMEuVjJ1oI,2398
|
|
62
62
|
dashscope/resources/qwen.tiktoken,sha256=srG437XMXwJLr8NzEhxquj9m-aWgJp4kNHCh3hajMYY,2561218
|
|
63
63
|
dashscope/threads/__init__.py,sha256=md5bsHekHHGOg3uQrBCk8f4BCNnA1AuI_-LDf92pNVU,621
|
|
64
|
-
dashscope/threads/thread_types.py,sha256=
|
|
64
|
+
dashscope/threads/thread_types.py,sha256=SwAJNi-RbqFXlrztDUCt0q0MfgfJLHyYl9qWrQDmQQo,18280
|
|
65
65
|
dashscope/threads/threads.py,sha256=dD72xklN71KFGBVoBVHEbCbZADwLbi9yGS9LbFpnlAI,7665
|
|
66
66
|
dashscope/threads/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
67
|
dashscope/threads/messages/files.py,sha256=wi0nJ2zsPWOw2Jn-ZkxA3URZBIrkGxqM_uAPfXY1xv0,3820
|
|
68
68
|
dashscope/threads/messages/messages.py,sha256=Zjmyf3rT1XSdn33hPrqOY6DSWUVL7pDEapG03FREPV8,8419
|
|
69
69
|
dashscope/threads/runs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
70
|
-
dashscope/threads/runs/runs.py,sha256=
|
|
70
|
+
dashscope/threads/runs/runs.py,sha256=24zFdIldjKUMN2EFiHv9unm9fgnD5irkurYtRfm0gQ0,18698
|
|
71
71
|
dashscope/threads/runs/steps.py,sha256=pLNR-5g7zvYkvC-p4sZGVgYHd1jqxBerM2WFyB358H8,3638
|
|
72
72
|
dashscope/tokenizers/__init__.py,sha256=Oy5FMT37Non6e1YxdHQ89U93Dy3CG1Ez0gBa771KZo0,200
|
|
73
73
|
dashscope/tokenizers/qwen_tokenizer.py,sha256=dCnT9-9NrqPS85bEhjlPULUfDADVRhlleYwM_ILgCeI,4111
|
|
@@ -76,9 +76,9 @@ dashscope/tokenizers/tokenizer.py,sha256=y6P91qTCYo__pEx_0VHAcj9YECfbUdRqZU1fdGT
|
|
|
76
76
|
dashscope/tokenizers/tokenizer_base.py,sha256=REDhzRyDT13iequ61-a6_KcTy0GFKlihQve5HkyoyRs,656
|
|
77
77
|
dashscope/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
78
78
|
dashscope/utils/oss_utils.py,sha256=fi8-PPsN-iR-iv5k2NS5Z8nlWkpgUhr56FRWm4BDh4A,6984
|
|
79
|
-
dashscope-1.
|
|
80
|
-
dashscope-1.
|
|
81
|
-
dashscope-1.
|
|
82
|
-
dashscope-1.
|
|
83
|
-
dashscope-1.
|
|
84
|
-
dashscope-1.
|
|
79
|
+
dashscope-1.18.0.dist-info/LICENSE,sha256=Izp5L1DF1Mbza6qojkqNNWlE_mYLnr4rmzx2EBF8YFw,11413
|
|
80
|
+
dashscope-1.18.0.dist-info/METADATA,sha256=O7GFznTd2fn-87dJSUvcIfZkhTcGv_KBxPf9s3Cvbiw,6609
|
|
81
|
+
dashscope-1.18.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
|
82
|
+
dashscope-1.18.0.dist-info/entry_points.txt,sha256=raEp5dOuj8whJ7yqZlDM8WQ5p2RfnGrGNo0QLQEnatY,50
|
|
83
|
+
dashscope-1.18.0.dist-info/top_level.txt,sha256=woqavFJK9zas5xTqynmALqOtlafghjsk63Xk86powTU,10
|
|
84
|
+
dashscope-1.18.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|