|
2 | 2 |
|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
5 | | -from typing import Dict, List, Union, Iterable, Optional |
| 5 | +from typing import Dict, List, Type, Union, Iterable, Optional, cast |
6 | 6 | from functools import partial |
7 | 7 | from typing_extensions import Literal |
8 | 8 |
|
9 | 9 | import httpx |
10 | 10 |
|
| 11 | +from .... import _legacy_response |
11 | 12 | from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven |
| 13 | +from ...._utils import maybe_transform, async_maybe_transform |
| 14 | +from ...._compat import cached_property |
12 | 15 | from ...._resource import SyncAPIResource, AsyncAPIResource |
| 16 | +from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper |
13 | 17 | from ...._streaming import Stream |
14 | 18 | from ....types.chat import completion_create_params |
| 19 | +from ...._base_client import make_request_options |
15 | 20 | from ....lib._parsing import ( |
16 | 21 | ResponseFormatT, |
17 | 22 | validate_input_tools as _validate_input_tools, |
|
20 | 25 | ) |
21 | 26 | from ....types.chat_model import ChatModel |
22 | 27 | from ....lib.streaming.chat import ChatCompletionStreamManager, AsyncChatCompletionStreamManager |
| 28 | +from ....types.chat.chat_completion import ChatCompletion |
23 | 29 | from ....types.chat.chat_completion_chunk import ChatCompletionChunk |
24 | 30 | from ....types.chat.parsed_chat_completion import ParsedChatCompletion |
25 | 31 | from ....types.chat.chat_completion_tool_param import ChatCompletionToolParam |
|
31 | 37 |
|
32 | 38 |
|
33 | 39 | class Completions(SyncAPIResource): |
| 40 | + @cached_property |
| 41 | + def with_raw_response(self) -> CompletionsWithRawResponse: |
| 42 | + """ |
| 43 | + This property can be used as a prefix for any HTTP method call to return the |
| 44 | + the raw response object instead of the parsed content. |
| 45 | +
|
| 46 | + For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers |
| 47 | + """ |
| 48 | + return CompletionsWithRawResponse(self) |
| 49 | + |
| 50 | + @cached_property |
| 51 | + def with_streaming_response(self) -> CompletionsWithStreamingResponse: |
| 52 | + """ |
| 53 | + An alternative to `.with_raw_response` that doesn't eagerly read the response body. |
| 54 | +
|
| 55 | + For more information, see https://www.github.com/openai/openai-python#with_streaming_response |
| 56 | + """ |
| 57 | + return CompletionsWithStreamingResponse(self) |
| 58 | + |
34 | 59 | def parse( |
35 | 60 | self, |
36 | 61 | *, |
@@ -113,39 +138,55 @@ class MathResponse(BaseModel): |
113 | 138 | **(extra_headers or {}), |
114 | 139 | } |
115 | 140 |
|
116 | | - raw_completion = self._client.chat.completions.create( |
117 | | - messages=messages, |
118 | | - model=model, |
119 | | - response_format=_type_to_response_format(response_format), |
120 | | - frequency_penalty=frequency_penalty, |
121 | | - function_call=function_call, |
122 | | - functions=functions, |
123 | | - logit_bias=logit_bias, |
124 | | - logprobs=logprobs, |
125 | | - max_completion_tokens=max_completion_tokens, |
126 | | - max_tokens=max_tokens, |
127 | | - n=n, |
128 | | - parallel_tool_calls=parallel_tool_calls, |
129 | | - presence_penalty=presence_penalty, |
130 | | - seed=seed, |
131 | | - service_tier=service_tier, |
132 | | - stop=stop, |
133 | | - stream_options=stream_options, |
134 | | - temperature=temperature, |
135 | | - tool_choice=tool_choice, |
136 | | - tools=tools, |
137 | | - top_logprobs=top_logprobs, |
138 | | - top_p=top_p, |
139 | | - user=user, |
140 | | - extra_headers=extra_headers, |
141 | | - extra_query=extra_query, |
142 | | - extra_body=extra_body, |
143 | | - timeout=timeout, |
144 | | - ) |
145 | | - return _parse_chat_completion( |
146 | | - response_format=response_format, |
147 | | - chat_completion=raw_completion, |
148 | | - input_tools=tools, |
| 141 | + def parser(raw_completion: ChatCompletion) -> ParsedChatCompletion[ResponseFormatT]: |
| 142 | + return _parse_chat_completion( |
| 143 | + response_format=response_format, |
| 144 | + chat_completion=raw_completion, |
| 145 | + input_tools=tools, |
| 146 | + ) |
| 147 | + |
| 148 | + return self._post( |
| 149 | + "/chat/completions", |
| 150 | + body=maybe_transform( |
| 151 | + { |
| 152 | + "messages": messages, |
| 153 | + "model": model, |
| 154 | + "frequency_penalty": frequency_penalty, |
| 155 | + "function_call": function_call, |
| 156 | + "functions": functions, |
| 157 | + "logit_bias": logit_bias, |
| 158 | + "logprobs": logprobs, |
| 159 | + "max_completion_tokens": max_completion_tokens, |
| 160 | + "max_tokens": max_tokens, |
| 161 | + "n": n, |
| 162 | + "parallel_tool_calls": parallel_tool_calls, |
| 163 | + "presence_penalty": presence_penalty, |
| 164 | + "response_format": _type_to_response_format(response_format), |
| 165 | + "seed": seed, |
| 166 | + "service_tier": service_tier, |
| 167 | + "stop": stop, |
| 168 | + "stream": False, |
| 169 | + "stream_options": stream_options, |
| 170 | + "temperature": temperature, |
| 171 | + "tool_choice": tool_choice, |
| 172 | + "tools": tools, |
| 173 | + "top_logprobs": top_logprobs, |
| 174 | + "top_p": top_p, |
| 175 | + "user": user, |
| 176 | + }, |
| 177 | + completion_create_params.CompletionCreateParams, |
| 178 | + ), |
| 179 | + options=make_request_options( |
| 180 | + extra_headers=extra_headers, |
| 181 | + extra_query=extra_query, |
| 182 | + extra_body=extra_body, |
| 183 | + timeout=timeout, |
| 184 | + post_parser=parser, |
| 185 | + ), |
| 186 | + # we turn the `ChatCompletion` instance into a `ParsedChatCompletion` |
| 187 | + # in the `parser` function above |
| 188 | + cast_to=cast(Type[ParsedChatCompletion[ResponseFormatT]], ChatCompletion), |
| 189 | + stream=False, |
149 | 190 | ) |
150 | 191 |
|
151 | 192 | def stream( |
@@ -247,6 +288,25 @@ def stream( |
247 | 288 |
|
248 | 289 |
|
249 | 290 | class AsyncCompletions(AsyncAPIResource): |
| 291 | + @cached_property |
| 292 | + def with_raw_response(self) -> AsyncCompletionsWithRawResponse: |
| 293 | + """ |
| 294 | + This property can be used as a prefix for any HTTP method call to return the |
| 295 | + the raw response object instead of the parsed content. |
| 296 | +
|
| 297 | + For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers |
| 298 | + """ |
| 299 | + return AsyncCompletionsWithRawResponse(self) |
| 300 | + |
| 301 | + @cached_property |
| 302 | + def with_streaming_response(self) -> AsyncCompletionsWithStreamingResponse: |
| 303 | + """ |
| 304 | + An alternative to `.with_raw_response` that doesn't eagerly read the response body. |
| 305 | +
|
| 306 | + For more information, see https://www.github.com/openai/openai-python#with_streaming_response |
| 307 | + """ |
| 308 | + return AsyncCompletionsWithStreamingResponse(self) |
| 309 | + |
250 | 310 | async def parse( |
251 | 311 | self, |
252 | 312 | *, |
@@ -329,39 +389,55 @@ class MathResponse(BaseModel): |
329 | 389 | **(extra_headers or {}), |
330 | 390 | } |
331 | 391 |
|
332 | | - raw_completion = await self._client.chat.completions.create( |
333 | | - messages=messages, |
334 | | - model=model, |
335 | | - response_format=_type_to_response_format(response_format), |
336 | | - frequency_penalty=frequency_penalty, |
337 | | - function_call=function_call, |
338 | | - functions=functions, |
339 | | - logit_bias=logit_bias, |
340 | | - logprobs=logprobs, |
341 | | - max_completion_tokens=max_completion_tokens, |
342 | | - max_tokens=max_tokens, |
343 | | - n=n, |
344 | | - parallel_tool_calls=parallel_tool_calls, |
345 | | - presence_penalty=presence_penalty, |
346 | | - seed=seed, |
347 | | - service_tier=service_tier, |
348 | | - stop=stop, |
349 | | - stream_options=stream_options, |
350 | | - temperature=temperature, |
351 | | - tool_choice=tool_choice, |
352 | | - tools=tools, |
353 | | - top_logprobs=top_logprobs, |
354 | | - top_p=top_p, |
355 | | - user=user, |
356 | | - extra_headers=extra_headers, |
357 | | - extra_query=extra_query, |
358 | | - extra_body=extra_body, |
359 | | - timeout=timeout, |
360 | | - ) |
361 | | - return _parse_chat_completion( |
362 | | - response_format=response_format, |
363 | | - chat_completion=raw_completion, |
364 | | - input_tools=tools, |
| 392 | + def parser(raw_completion: ChatCompletion) -> ParsedChatCompletion[ResponseFormatT]: |
| 393 | + return _parse_chat_completion( |
| 394 | + response_format=response_format, |
| 395 | + chat_completion=raw_completion, |
| 396 | + input_tools=tools, |
| 397 | + ) |
| 398 | + |
| 399 | + return await self._post( |
| 400 | + "/chat/completions", |
| 401 | + body=await async_maybe_transform( |
| 402 | + { |
| 403 | + "messages": messages, |
| 404 | + "model": model, |
| 405 | + "frequency_penalty": frequency_penalty, |
| 406 | + "function_call": function_call, |
| 407 | + "functions": functions, |
| 408 | + "logit_bias": logit_bias, |
| 409 | + "logprobs": logprobs, |
| 410 | + "max_completion_tokens": max_completion_tokens, |
| 411 | + "max_tokens": max_tokens, |
| 412 | + "n": n, |
| 413 | + "parallel_tool_calls": parallel_tool_calls, |
| 414 | + "presence_penalty": presence_penalty, |
| 415 | + "response_format": _type_to_response_format(response_format), |
| 416 | + "seed": seed, |
| 417 | + "service_tier": service_tier, |
| 418 | + "stop": stop, |
| 419 | + "stream": False, |
| 420 | + "stream_options": stream_options, |
| 421 | + "temperature": temperature, |
| 422 | + "tool_choice": tool_choice, |
| 423 | + "tools": tools, |
| 424 | + "top_logprobs": top_logprobs, |
| 425 | + "top_p": top_p, |
| 426 | + "user": user, |
| 427 | + }, |
| 428 | + completion_create_params.CompletionCreateParams, |
| 429 | + ), |
| 430 | + options=make_request_options( |
| 431 | + extra_headers=extra_headers, |
| 432 | + extra_query=extra_query, |
| 433 | + extra_body=extra_body, |
| 434 | + timeout=timeout, |
| 435 | + post_parser=parser, |
| 436 | + ), |
| 437 | + # we turn the `ChatCompletion` instance into a `ParsedChatCompletion` |
| 438 | + # in the `parser` function above |
| 439 | + cast_to=cast(Type[ParsedChatCompletion[ResponseFormatT]], ChatCompletion), |
| 440 | + stream=False, |
365 | 441 | ) |
366 | 442 |
|
367 | 443 | def stream( |
@@ -461,3 +537,39 @@ def stream( |
461 | 537 | response_format=response_format, |
462 | 538 | input_tools=tools, |
463 | 539 | ) |
| 540 | + |
| 541 | + |
| 542 | +class CompletionsWithRawResponse: |
| 543 | + def __init__(self, completions: Completions) -> None: |
| 544 | + self._completions = completions |
| 545 | + |
| 546 | + self.parse = _legacy_response.to_raw_response_wrapper( |
| 547 | + completions.parse, |
| 548 | + ) |
| 549 | + |
| 550 | + |
| 551 | +class AsyncCompletionsWithRawResponse: |
| 552 | + def __init__(self, completions: AsyncCompletions) -> None: |
| 553 | + self._completions = completions |
| 554 | + |
| 555 | + self.parse = _legacy_response.async_to_raw_response_wrapper( |
| 556 | + completions.parse, |
| 557 | + ) |
| 558 | + |
| 559 | + |
| 560 | +class CompletionsWithStreamingResponse: |
| 561 | + def __init__(self, completions: Completions) -> None: |
| 562 | + self._completions = completions |
| 563 | + |
| 564 | + self.parse = to_streamed_response_wrapper( |
| 565 | + completions.parse, |
| 566 | + ) |
| 567 | + |
| 568 | + |
| 569 | +class AsyncCompletionsWithStreamingResponse: |
| 570 | + def __init__(self, completions: AsyncCompletions) -> None: |
| 571 | + self._completions = completions |
| 572 | + |
| 573 | + self.parse = async_to_streamed_response_wrapper( |
| 574 | + completions.parse, |
| 575 | + ) |
0 commit comments