dashscope 1.8.0__py3-none-any.whl → 1.25.6__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 (110) hide show
  1. dashscope/__init__.py +61 -14
  2. dashscope/aigc/__init__.py +10 -3
  3. dashscope/aigc/chat_completion.py +282 -0
  4. dashscope/aigc/code_generation.py +145 -0
  5. dashscope/aigc/conversation.py +71 -12
  6. dashscope/aigc/generation.py +288 -16
  7. dashscope/aigc/image_synthesis.py +473 -31
  8. dashscope/aigc/multimodal_conversation.py +299 -14
  9. dashscope/aigc/video_synthesis.py +610 -0
  10. dashscope/api_entities/aiohttp_request.py +8 -5
  11. dashscope/api_entities/api_request_data.py +4 -2
  12. dashscope/api_entities/api_request_factory.py +68 -20
  13. dashscope/api_entities/base_request.py +20 -3
  14. dashscope/api_entities/chat_completion_types.py +344 -0
  15. dashscope/api_entities/dashscope_response.py +243 -15
  16. dashscope/api_entities/encryption.py +179 -0
  17. dashscope/api_entities/http_request.py +216 -62
  18. dashscope/api_entities/websocket_request.py +43 -34
  19. dashscope/app/__init__.py +5 -0
  20. dashscope/app/application.py +203 -0
  21. dashscope/app/application_response.py +246 -0
  22. dashscope/assistants/__init__.py +16 -0
  23. dashscope/assistants/assistant_types.py +175 -0
  24. dashscope/assistants/assistants.py +311 -0
  25. dashscope/assistants/files.py +197 -0
  26. dashscope/audio/__init__.py +4 -2
  27. dashscope/audio/asr/__init__.py +17 -1
  28. dashscope/audio/asr/asr_phrase_manager.py +203 -0
  29. dashscope/audio/asr/recognition.py +167 -27
  30. dashscope/audio/asr/transcription.py +107 -14
  31. dashscope/audio/asr/translation_recognizer.py +1006 -0
  32. dashscope/audio/asr/vocabulary.py +177 -0
  33. dashscope/audio/qwen_asr/__init__.py +7 -0
  34. dashscope/audio/qwen_asr/qwen_transcription.py +189 -0
  35. dashscope/audio/qwen_omni/__init__.py +11 -0
  36. dashscope/audio/qwen_omni/omni_realtime.py +524 -0
  37. dashscope/audio/qwen_tts/__init__.py +5 -0
  38. dashscope/audio/qwen_tts/speech_synthesizer.py +77 -0
  39. dashscope/audio/qwen_tts_realtime/__init__.py +10 -0
  40. dashscope/audio/qwen_tts_realtime/qwen_tts_realtime.py +355 -0
  41. dashscope/audio/tts/__init__.py +2 -0
  42. dashscope/audio/tts/speech_synthesizer.py +5 -0
  43. dashscope/audio/tts_v2/__init__.py +12 -0
  44. dashscope/audio/tts_v2/enrollment.py +179 -0
  45. dashscope/audio/tts_v2/speech_synthesizer.py +886 -0
  46. dashscope/cli.py +157 -37
  47. dashscope/client/base_api.py +652 -87
  48. dashscope/common/api_key.py +2 -0
  49. dashscope/common/base_type.py +135 -0
  50. dashscope/common/constants.py +13 -16
  51. dashscope/common/env.py +2 -0
  52. dashscope/common/error.py +58 -22
  53. dashscope/common/logging.py +2 -0
  54. dashscope/common/message_manager.py +2 -0
  55. dashscope/common/utils.py +276 -46
  56. dashscope/customize/__init__.py +0 -0
  57. dashscope/customize/customize_types.py +192 -0
  58. dashscope/customize/deployments.py +146 -0
  59. dashscope/customize/finetunes.py +234 -0
  60. dashscope/embeddings/__init__.py +5 -1
  61. dashscope/embeddings/batch_text_embedding.py +208 -0
  62. dashscope/embeddings/batch_text_embedding_response.py +65 -0
  63. dashscope/embeddings/multimodal_embedding.py +118 -10
  64. dashscope/embeddings/text_embedding.py +13 -1
  65. dashscope/{file.py → files.py} +19 -4
  66. dashscope/io/input_output.py +2 -0
  67. dashscope/model.py +11 -2
  68. dashscope/models.py +43 -0
  69. dashscope/multimodal/__init__.py +20 -0
  70. dashscope/multimodal/dialog_state.py +56 -0
  71. dashscope/multimodal/multimodal_constants.py +28 -0
  72. dashscope/multimodal/multimodal_dialog.py +648 -0
  73. dashscope/multimodal/multimodal_request_params.py +313 -0
  74. dashscope/multimodal/tingwu/__init__.py +10 -0
  75. dashscope/multimodal/tingwu/tingwu.py +80 -0
  76. dashscope/multimodal/tingwu/tingwu_realtime.py +579 -0
  77. dashscope/nlp/__init__.py +0 -0
  78. dashscope/nlp/understanding.py +64 -0
  79. dashscope/protocol/websocket.py +3 -0
  80. dashscope/rerank/__init__.py +0 -0
  81. dashscope/rerank/text_rerank.py +69 -0
  82. dashscope/resources/qwen.tiktoken +151643 -0
  83. dashscope/threads/__init__.py +26 -0
  84. dashscope/threads/messages/__init__.py +0 -0
  85. dashscope/threads/messages/files.py +113 -0
  86. dashscope/threads/messages/messages.py +220 -0
  87. dashscope/threads/runs/__init__.py +0 -0
  88. dashscope/threads/runs/runs.py +501 -0
  89. dashscope/threads/runs/steps.py +112 -0
  90. dashscope/threads/thread_types.py +665 -0
  91. dashscope/threads/threads.py +212 -0
  92. dashscope/tokenizers/__init__.py +7 -0
  93. dashscope/tokenizers/qwen_tokenizer.py +111 -0
  94. dashscope/tokenizers/tokenization.py +125 -0
  95. dashscope/tokenizers/tokenizer.py +45 -0
  96. dashscope/tokenizers/tokenizer_base.py +32 -0
  97. dashscope/utils/__init__.py +0 -0
  98. dashscope/utils/message_utils.py +838 -0
  99. dashscope/utils/oss_utils.py +243 -0
  100. dashscope/utils/param_utils.py +29 -0
  101. dashscope/version.py +3 -1
  102. {dashscope-1.8.0.dist-info → dashscope-1.25.6.dist-info}/METADATA +53 -50
  103. dashscope-1.25.6.dist-info/RECORD +112 -0
  104. {dashscope-1.8.0.dist-info → dashscope-1.25.6.dist-info}/WHEEL +1 -1
  105. {dashscope-1.8.0.dist-info → dashscope-1.25.6.dist-info}/entry_points.txt +0 -1
  106. {dashscope-1.8.0.dist-info → dashscope-1.25.6.dist-info/licenses}/LICENSE +2 -4
  107. dashscope/deployment.py +0 -129
  108. dashscope/finetune.py +0 -149
  109. dashscope-1.8.0.dist-info/RECORD +0 -49
  110. {dashscope-1.8.0.dist-info → dashscope-1.25.6.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,17 @@
1
+ # Copyright (c) Alibaba, Inc. and its affiliates.
2
+ from urllib.parse import urlencode
3
+
1
4
  import dashscope
2
5
  from dashscope.api_entities.api_request_data import ApiRequestData
3
6
  from dashscope.api_entities.http_request import HttpRequest
4
7
  from dashscope.api_entities.websocket_request import WebSocketRequest
5
8
  from dashscope.common.constants import (REQUEST_TIMEOUT_KEYWORD,
6
9
  SERVICE_API_PATH, ApiProtocol,
7
- HTTPMethod, StreamResultMode)
10
+ HTTPMethod)
8
11
  from dashscope.common.error import InputDataRequired, UnsupportedApiProtocol
12
+ from dashscope.common.logging import logger
9
13
  from dashscope.protocol.websocket import WebsocketStreamingMode
10
-
14
+ from dashscope.api_entities.encryption import Encryption
11
15
 
12
16
  def _get_protocol_params(kwargs):
13
17
  api_protocol = kwargs.pop('api_protocol', ApiProtocol.HTTPS)
@@ -15,31 +19,55 @@ def _get_protocol_params(kwargs):
15
19
  is_binary_input = kwargs.pop('is_binary_input', False)
16
20
  http_method = kwargs.pop('http_method', HTTPMethod.POST)
17
21
  stream = kwargs.pop('stream', False)
22
+ if not stream and ws_stream_mode == WebsocketStreamingMode.OUT:
23
+ ws_stream_mode = WebsocketStreamingMode.NONE
24
+
18
25
  async_request = kwargs.pop('async_request', False)
19
26
  query = kwargs.pop('query', False)
20
27
  headers = kwargs.pop('headers', None)
21
28
  request_timeout = kwargs.pop(REQUEST_TIMEOUT_KEYWORD, None)
22
- stream_result_mode = kwargs.pop('stream_result_mode',
23
- StreamResultMode.ACCUMULATE)
24
29
  form = kwargs.pop('form', None)
25
30
  resources = kwargs.pop('resources', None)
31
+ base_address = kwargs.pop('base_address', None)
32
+ flattened_output = kwargs.pop('flattened_output', False)
33
+ extra_url_parameters = kwargs.pop('extra_url_parameters', None)
34
+
35
+ # Extract user-agent from headers if present
36
+ user_agent = ''
37
+ if headers and 'user-agent' in headers:
38
+ user_agent = headers.pop('user-agent')
39
+
26
40
  return (api_protocol, ws_stream_mode, is_binary_input, http_method, stream,
27
- async_request, query, headers, request_timeout, stream_result_mode,
28
- form, resources)
41
+ async_request, query, headers, request_timeout, form, resources,
42
+ base_address, flattened_output, extra_url_parameters, user_agent)
29
43
 
30
44
 
31
- def _build_api_request(model: str, input: object, task_group: str, task: str,
32
- function: str, api_key: str, **kwargs):
45
+ def _build_api_request(model: str,
46
+ input: object,
47
+ task_group: str,
48
+ task: str,
49
+ function: str,
50
+ api_key: str,
51
+ is_service=True,
52
+ **kwargs):
33
53
  (api_protocol, ws_stream_mode, is_binary_input, http_method, stream,
34
- async_request, query, headers, request_timeout, stream_result_mode,
35
- form, resources) = _get_protocol_params(kwargs)
54
+ async_request, query, headers, request_timeout, form, resources,
55
+ base_address, flattened_output, extra_url_parameters,
56
+ user_agent) = _get_protocol_params(kwargs)
36
57
  task_id = kwargs.pop('task_id', None)
58
+ enable_encryption = kwargs.pop('enable_encryption', False)
59
+ encryption = None
60
+
37
61
  if api_protocol in [ApiProtocol.HTTP, ApiProtocol.HTTPS]:
38
- if not dashscope.base_http_api_url.endswith('/'):
39
- http_url = dashscope.base_http_api_url + '/' + SERVICE_API_PATH
62
+ if base_address is None:
63
+ base_address = dashscope.base_http_api_url
64
+ if not base_address.endswith('/'):
65
+ http_url = base_address + '/'
40
66
  else:
41
- http_url = dashscope.base_http_api_url + SERVICE_API_PATH
42
- http_url += '/'
67
+ http_url = base_address
68
+
69
+ if is_service:
70
+ http_url = http_url + SERVICE_API_PATH + '/'
43
71
 
44
72
  if task_group:
45
73
  http_url += '%s/' % task_group
@@ -47,24 +75,41 @@ def _build_api_request(model: str, input: object, task_group: str, task: str,
47
75
  http_url += '%s/' % task
48
76
  if function:
49
77
  http_url += function
78
+ if extra_url_parameters is not None and extra_url_parameters:
79
+ http_url += '?' + urlencode(extra_url_parameters)
80
+
81
+ if enable_encryption is True:
82
+ encryption = Encryption()
83
+ encryption.initialize()
84
+ if encryption.is_valid():
85
+ logger.debug('encryption enabled')
86
+
50
87
  request = HttpRequest(url=http_url,
51
88
  api_key=api_key,
52
89
  http_method=http_method,
53
90
  stream=stream,
54
91
  async_request=async_request,
55
92
  query=query,
56
- stream_result_mode=stream_result_mode,
57
93
  timeout=request_timeout,
58
- task_id=task_id)
94
+ task_id=task_id,
95
+ flattened_output=flattened_output,
96
+ encryption=encryption,
97
+ user_agent=user_agent)
59
98
  elif api_protocol == ApiProtocol.WEBSOCKET:
60
- websocket_url = dashscope.base_websocket_api_url
99
+ if base_address is not None:
100
+ websocket_url = base_address
101
+ else:
102
+ websocket_url = dashscope.base_websocket_api_url
103
+ pre_task_id = kwargs.pop('pre_task_id', None)
61
104
  request = WebSocketRequest(url=websocket_url,
62
105
  api_key=api_key,
63
106
  stream=stream,
64
107
  ws_stream_mode=ws_stream_mode,
65
108
  is_binary_input=is_binary_input,
66
- stream_result_mode=stream_result_mode,
67
- timeout=request_timeout)
109
+ timeout=request_timeout,
110
+ flattened_output=flattened_output,
111
+ pre_task_id=pre_task_id,
112
+ user_agent=user_agent)
68
113
  else:
69
114
  raise UnsupportedApiProtocol(
70
115
  'Unsupported protocol: %s, support [http, https, websocket]' %
@@ -76,6 +121,9 @@ def _build_api_request(model: str, input: object, task_group: str, task: str,
76
121
  if input is None and form is None:
77
122
  raise InputDataRequired('There is no input data and form data')
78
123
 
124
+ if encryption and encryption.is_valid():
125
+ input = encryption.encrypt(input)
126
+
79
127
  request_data = ApiRequestData(model,
80
128
  task_group=task_group,
81
129
  task=task,
@@ -87,4 +135,4 @@ def _build_api_request(model: str, input: object, task_group: str, task: str,
87
135
  request_data.add_resources(resources)
88
136
  request_data.add_parameters(**kwargs)
89
137
  request.data = request_data
90
- return request
138
+ return request
@@ -1,3 +1,5 @@
1
+ # Copyright (c) Alibaba, Inc. and its affiliates.
2
+
1
3
  import os
2
4
  import platform
3
5
  from abc import ABC, abstractmethod
@@ -7,13 +9,28 @@ from dashscope.version import __version__
7
9
 
8
10
 
9
11
  class BaseRequest(ABC):
10
- def __init__(self) -> None:
12
+ def __init__(self, user_agent: str = '') -> None:
13
+ try:
14
+ platform_info = platform.platform()
15
+ except Exception:
16
+ platform_info = "unknown"
17
+
18
+ try:
19
+ processor_info = platform.processor()
20
+ except Exception:
21
+ processor_info = "unknown"
22
+
11
23
  ua = 'dashscope/%s; python/%s; platform/%s; processor/%s' % (
12
24
  __version__,
13
25
  platform.python_version(),
14
- platform.platform(),
15
- platform.processor(),
26
+ platform_info,
27
+ processor_info,
16
28
  )
29
+
30
+ # Append user_agent if provided and not empty
31
+ if user_agent:
32
+ ua += '; ' + user_agent
33
+
17
34
  self.headers = {'user-agent': ua}
18
35
  disable_data_inspection = os.environ.get(
19
36
  DASHSCOPE_DISABLE_DATA_INSPECTION_ENV, 'true')
@@ -0,0 +1,344 @@
1
+ # Copyright (c) Alibaba, Inc. and its affiliates.
2
+
3
+ # adapter from openai sdk
4
+ from dataclasses import dataclass
5
+ from typing import List, Literal, Optional
6
+
7
+ from dashscope.common.base_type import BaseObjectMixin
8
+
9
+
10
+ @dataclass(init=False)
11
+ class CompletionUsage(BaseObjectMixin):
12
+ completion_tokens: int
13
+ """Number of tokens in the generated completion."""
14
+
15
+ prompt_tokens: int
16
+ """Number of tokens in the prompt."""
17
+
18
+ total_tokens: int
19
+ """Total number of tokens used in the request (prompt + completion)."""
20
+ def __init__(self, **kwargs):
21
+ super().__init__(**kwargs)
22
+
23
+
24
+ @dataclass(init=False)
25
+ class TopLogprob(BaseObjectMixin):
26
+ token: str
27
+ """The token."""
28
+
29
+ bytes: Optional[List[int]] = None
30
+ """A list of integers representing the UTF-8 bytes representation of the token.
31
+
32
+ Useful in instances where characters are represented by multiple tokens and
33
+ their byte representations must be combined to generate the correct text
34
+ representation. Can be `null` if there is no bytes representation for the token.
35
+ """
36
+
37
+ logprob: float
38
+ """The log probability of this token, if it is within the top 20 most likely
39
+ tokens.
40
+
41
+ Otherwise, the value `-9999.0` is used to signify that the token is very
42
+ unlikely.
43
+ """
44
+ def __init__(self, **kwargs):
45
+ super().__init__(**kwargs)
46
+
47
+
48
+ @dataclass(init=False)
49
+ class ChatCompletionTokenLogprob(BaseObjectMixin):
50
+ token: str
51
+ """The token."""
52
+
53
+ bytes: Optional[List[int]] = None
54
+ """A list of integers representing the UTF-8 bytes representation of the token.
55
+
56
+ Useful in instances where characters are represented by multiple tokens and
57
+ their byte representations must be combined to generate the correct text
58
+ representation. Can be `null` if there is no bytes representation for the token.
59
+ """
60
+
61
+ logprob: float
62
+ """The log probability of this token, if it is within the top 20 most likely
63
+ tokens.
64
+
65
+ Otherwise, the value `-9999.0` is used to signify that the token is very
66
+ unlikely.
67
+ """
68
+
69
+ top_logprobs: List[TopLogprob]
70
+ """List of the most likely tokens and their log probability, at this token
71
+ position.
72
+
73
+ In rare cases, there may be fewer than the number of requested `top_logprobs`
74
+ returned.
75
+ """
76
+ def __init__(self, **kwargs):
77
+ if 'top_logprobs' in kwargs and kwargs[
78
+ 'top_logprobs'] is not None and kwargs['top_logprobs']:
79
+ top_logprobs = []
80
+ for logprob in kwargs['top_logprobs']:
81
+ top_logprobs.append(ChatCompletionTokenLogprob(**logprob))
82
+ self.top_logprobs = top_logprobs
83
+ else:
84
+ self.top_logprobs = None
85
+
86
+ super().__init__(**kwargs)
87
+
88
+
89
+ @dataclass(init=False)
90
+ class ChoiceLogprobs(BaseObjectMixin):
91
+ content: Optional[List[ChatCompletionTokenLogprob]] = None
92
+ """A list of message content tokens with log probability information."""
93
+ def __init__(self, **kwargs):
94
+ if 'content' in kwargs and kwargs['content'] is not None and kwargs[
95
+ 'content']:
96
+ logprobs = []
97
+ for logprob in kwargs['content']:
98
+ logprobs.append(ChatCompletionTokenLogprob(**logprob))
99
+ self.content = logprobs
100
+ else:
101
+ self.content = None
102
+
103
+ super().__init__(**kwargs)
104
+
105
+
106
+ @dataclass(init=False)
107
+ class FunctionCall(BaseObjectMixin):
108
+ arguments: str
109
+ """
110
+ The arguments to call the function with, as generated by the model in JSON
111
+ format. Note that the model does not always generate valid JSON, and may
112
+ hallucinate parameters not defined by your function schema. Validate the
113
+ arguments in your code before calling your function.
114
+ """
115
+
116
+ name: str
117
+ """The name of the function to call."""
118
+ def __init__(self, **kwargs):
119
+ super().__init__(**kwargs)
120
+
121
+
122
+ @dataclass(init=False)
123
+ class Function(BaseObjectMixin):
124
+ arguments: str
125
+ """
126
+ The arguments to call the function with, as generated by the model in JSON
127
+ format. Note that the model does not always generate valid JSON, and may
128
+ hallucinate parameters not defined by your function schema. Validate the
129
+ arguments in your code before calling your function.
130
+ """
131
+
132
+ name: str
133
+ """The name of the function to call."""
134
+ def __init__(self, **kwargs):
135
+ super().__init__(**kwargs)
136
+
137
+
138
+ @dataclass(init=False)
139
+ class ChatCompletionMessageToolCall(BaseObjectMixin):
140
+ id: str
141
+ """The ID of the tool call."""
142
+
143
+ function: Function
144
+ """The function that the model called."""
145
+
146
+ type: Literal['function']
147
+ """The type of the tool. Currently, only `function` is supported."""
148
+ def __init__(self, **kwargs):
149
+ if 'function' in kwargs and kwargs['function'] is not None and kwargs[
150
+ 'function']:
151
+ self.function = Function(**kwargs.pop('function', {}))
152
+ else:
153
+ self.function = None
154
+
155
+ super().__init__(**kwargs)
156
+
157
+
158
+ @dataclass(init=False)
159
+ class ChatCompletionMessage(BaseObjectMixin):
160
+ content: Optional[str] = None
161
+ """The contents of the message."""
162
+
163
+ role: Literal['assistant']
164
+ """The role of the author of this message."""
165
+
166
+ function_call: Optional[FunctionCall] = None
167
+ """Deprecated and replaced by `tool_calls`.
168
+
169
+ The name and arguments of a function that should be called, as generated by the
170
+ model.
171
+ """
172
+
173
+ tool_calls: Optional[List[ChatCompletionMessageToolCall]] = None
174
+ """The tool calls generated by the model, such as function calls."""
175
+ def __init__(self, **kwargs):
176
+ if 'function_call' in kwargs and kwargs[
177
+ 'function_call'] is not None and kwargs['function_call']:
178
+ self.function_call = FunctionCall(
179
+ **kwargs.pop('function_call', {}))
180
+
181
+ if 'tool_calls' in kwargs and kwargs[
182
+ 'tool_calls'] is not None and kwargs['tool_calls']:
183
+ tool_calls = []
184
+ for tool_call in kwargs['tool_calls']:
185
+ tool_calls.append(ChatCompletionMessageToolCall(**tool_call))
186
+ self.tool_calls = tool_calls
187
+
188
+ super().__init__(**kwargs)
189
+
190
+
191
+ @dataclass(init=False)
192
+ class Choice(BaseObjectMixin):
193
+ finish_reason: Literal['stop', 'length', 'tool_calls', 'content_filter',
194
+ 'function_call']
195
+ """The reason the model stopped generating tokens.
196
+
197
+ This will be `stop` if the model hit a natural stop point or a provided stop
198
+ sequence, `length` if the maximum number of tokens specified in the request was
199
+ reached, `content_filter` if content was omitted due to a flag from our content
200
+ filters, `tool_calls` if the model called a tool, or `function_call`
201
+ (deprecated) if the model called a function.
202
+ """
203
+
204
+ index: int
205
+ """The index of the choice in the list of choices."""
206
+
207
+ logprobs: Optional[ChoiceLogprobs] = None
208
+ """Log probability information for the choice."""
209
+
210
+ message: ChatCompletionMessage
211
+ """A chat completion message generated by the model."""
212
+ def __init__(self, **kwargs):
213
+ if 'message' in kwargs and kwargs['message'] is not None and kwargs[
214
+ 'message']:
215
+ self.message = ChatCompletionMessage(**kwargs.pop('message', {}))
216
+ else:
217
+ self.message = None
218
+
219
+ if 'logprobs' in kwargs and kwargs['logprobs'] is not None and kwargs[
220
+ 'logprobs']:
221
+ self.logprobs = ChoiceLogprobs(**kwargs.pop('logprobs', {}))
222
+
223
+ super().__init__(**kwargs)
224
+
225
+
226
+ @dataclass(init=False)
227
+ class ChatCompletion(BaseObjectMixin):
228
+ status_code: int
229
+ """The call response status_code, 200 indicate create success.
230
+ """
231
+ code: str
232
+ """The request failed, this is the error code.
233
+ """
234
+ message: str
235
+ """The request failed, this is the error message.
236
+ """
237
+ id: str
238
+ """A unique identifier for the chat completion.
239
+ """
240
+ choices: List[Choice]
241
+ """A list of chat completion choices.
242
+
243
+ Can be more than one if `n` is greater than 1.
244
+ """
245
+
246
+ created: int
247
+ """The Unix timestamp (in seconds) of when the chat completion was created."""
248
+
249
+ model: str
250
+ """The model used for the chat completion."""
251
+
252
+ object: Literal['chat.completion']
253
+ """The object type, which is always `chat.completion`."""
254
+
255
+ system_fingerprint: Optional[str] = None
256
+ """This fingerprint represents the backend configuration that the model runs with.
257
+
258
+ Can be used in conjunction with the `seed` request parameter to understand when
259
+ backend changes have been made that might impact determinism.
260
+ """
261
+
262
+ usage: Optional[CompletionUsage] = None
263
+ """Usage statistics for the completion request."""
264
+ def __init__(self, **kwargs):
265
+ if 'usage' in kwargs and kwargs['usage'] is not None and kwargs[
266
+ 'usage']:
267
+ self.usage = CompletionUsage(**kwargs.pop('usage', {}))
268
+ else:
269
+ self.usage = None
270
+
271
+ if 'choices' in kwargs and kwargs['choices'] is not None and kwargs[
272
+ 'choices']:
273
+ choices = []
274
+ for choice in kwargs.pop('choices', []):
275
+ choices.append(Choice(**choice))
276
+ self.choices = choices
277
+ else:
278
+ self.choices = None
279
+ super().__init__(**kwargs)
280
+
281
+
282
+ @dataclass(init=False)
283
+ class ChatCompletionChunk(BaseObjectMixin):
284
+ status_code: int
285
+ """The call response status_code, 200 indicate create success.
286
+ """
287
+ code: str
288
+ """The request failed, this is the error code.
289
+ """
290
+ message: str
291
+ """The request failed, this is the error message.
292
+ """
293
+ id: str
294
+ """A unique identifier for the chat completion. Each chunk has the same ID."""
295
+
296
+ choices: List[Choice]
297
+ """A list of chat completion choices.
298
+
299
+ Can contain more than one elements if `n` is greater than 1. Can also be empty
300
+ for the last chunk if you set `stream_options: {"include_usage": true}`.
301
+ """
302
+
303
+ created: int
304
+ """The Unix timestamp (in seconds) of when the chat completion was created.
305
+
306
+ Each chunk has the same timestamp.
307
+ """
308
+
309
+ model: str
310
+ """The model to generate the completion."""
311
+
312
+ object: Literal['chat.completion.chunk']
313
+ """The object type, which is always `chat.completion.chunk`."""
314
+
315
+ system_fingerprint: Optional[str] = None
316
+ """
317
+ This fingerprint represents the backend configuration that the model runs with.
318
+ Can be used in conjunction with the `seed` request parameter to understand when
319
+ backend changes have been made that might impact determinism.
320
+ """
321
+
322
+ usage: Optional[CompletionUsage] = None
323
+ """
324
+ An optional field that will only be present when you set
325
+ `stream_options: {"include_usage": true}` in your request. When present, it
326
+ contains a null value except for the last chunk which contains the token usage
327
+ statistics for the entire request.
328
+ """
329
+ def __init__(self, **kwargs):
330
+ if 'usage' in kwargs and kwargs['usage'] is not None and kwargs[
331
+ 'usage']:
332
+ self.usage = CompletionUsage(**kwargs.pop('usage', {}))
333
+ else:
334
+ self.usage = None
335
+
336
+ if 'choices' in kwargs and kwargs['choices'] is not None and kwargs[
337
+ 'choices']:
338
+ choices = []
339
+ for choice in kwargs.pop('choices', []):
340
+ choices.append(Choice(**choice))
341
+ self.choices = choices
342
+ else:
343
+ self.choices = None
344
+ super().__init__(**kwargs)