Restore 0.1.5 version from stash
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from .beta import (
|
||||
Beta,
|
||||
AsyncBeta,
|
||||
BetaWithRawResponse,
|
||||
AsyncBetaWithRawResponse,
|
||||
BetaWithStreamingResponse,
|
||||
AsyncBetaWithStreamingResponse,
|
||||
)
|
||||
from .threads import (
|
||||
Threads,
|
||||
AsyncThreads,
|
||||
ThreadsWithRawResponse,
|
||||
AsyncThreadsWithRawResponse,
|
||||
ThreadsWithStreamingResponse,
|
||||
AsyncThreadsWithStreamingResponse,
|
||||
)
|
||||
from .assistants import (
|
||||
Assistants,
|
||||
AsyncAssistants,
|
||||
AssistantsWithRawResponse,
|
||||
AsyncAssistantsWithRawResponse,
|
||||
AssistantsWithStreamingResponse,
|
||||
AsyncAssistantsWithStreamingResponse,
|
||||
)
|
||||
from .vector_stores import (
|
||||
VectorStores,
|
||||
AsyncVectorStores,
|
||||
VectorStoresWithRawResponse,
|
||||
AsyncVectorStoresWithRawResponse,
|
||||
VectorStoresWithStreamingResponse,
|
||||
AsyncVectorStoresWithStreamingResponse,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"VectorStores",
|
||||
"AsyncVectorStores",
|
||||
"VectorStoresWithRawResponse",
|
||||
"AsyncVectorStoresWithRawResponse",
|
||||
"VectorStoresWithStreamingResponse",
|
||||
"AsyncVectorStoresWithStreamingResponse",
|
||||
"Assistants",
|
||||
"AsyncAssistants",
|
||||
"AssistantsWithRawResponse",
|
||||
"AsyncAssistantsWithRawResponse",
|
||||
"AssistantsWithStreamingResponse",
|
||||
"AsyncAssistantsWithStreamingResponse",
|
||||
"Threads",
|
||||
"AsyncThreads",
|
||||
"ThreadsWithRawResponse",
|
||||
"AsyncThreadsWithRawResponse",
|
||||
"ThreadsWithStreamingResponse",
|
||||
"AsyncThreadsWithStreamingResponse",
|
||||
"Beta",
|
||||
"AsyncBeta",
|
||||
"BetaWithRawResponse",
|
||||
"AsyncBetaWithRawResponse",
|
||||
"BetaWithStreamingResponse",
|
||||
"AsyncBetaWithStreamingResponse",
|
||||
]
|
||||
@@ -0,0 +1,888 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union, Iterable, Optional
|
||||
from typing_extensions import Literal
|
||||
|
||||
import httpx
|
||||
|
||||
from ... import _legacy_response
|
||||
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
||||
from ..._utils import (
|
||||
maybe_transform,
|
||||
async_maybe_transform,
|
||||
)
|
||||
from ..._compat import cached_property
|
||||
from ..._resource import SyncAPIResource, AsyncAPIResource
|
||||
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
|
||||
from ...pagination import SyncCursorPage, AsyncCursorPage
|
||||
from ...types.beta import (
|
||||
assistant_list_params,
|
||||
assistant_create_params,
|
||||
assistant_update_params,
|
||||
)
|
||||
from ..._base_client import AsyncPaginator, make_request_options
|
||||
from ...types.chat_model import ChatModel
|
||||
from ...types.beta.assistant import Assistant
|
||||
from ...types.beta.assistant_deleted import AssistantDeleted
|
||||
from ...types.beta.assistant_tool_param import AssistantToolParam
|
||||
from ...types.beta.assistant_response_format_option_param import AssistantResponseFormatOptionParam
|
||||
|
||||
__all__ = ["Assistants", "AsyncAssistants"]
|
||||
|
||||
|
||||
class Assistants(SyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AssistantsWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AssistantsWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AssistantsWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AssistantsWithStreamingResponse(self)
|
||||
|
||||
def create(
|
||||
self,
|
||||
*,
|
||||
model: Union[str, ChatModel],
|
||||
description: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
instructions: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
name: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
response_format: Optional[AssistantResponseFormatOptionParam] | NotGiven = NOT_GIVEN,
|
||||
temperature: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
tool_resources: Optional[assistant_create_params.ToolResources] | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[AssistantToolParam] | NotGiven = NOT_GIVEN,
|
||||
top_p: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Assistant:
|
||||
"""
|
||||
Create an assistant with a model and instructions.
|
||||
|
||||
Args:
|
||||
model: ID of the model to use. You can use the
|
||||
[List models](https://platform.openai.com/docs/api-reference/models/list) API to
|
||||
see all of your available models, or see our
|
||||
[Model overview](https://platform.openai.com/docs/models) for descriptions of
|
||||
them.
|
||||
|
||||
description: The description of the assistant. The maximum length is 512 characters.
|
||||
|
||||
instructions: The system instructions that the assistant uses. The maximum length is 256,000
|
||||
characters.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
name: The name of the assistant. The maximum length is 256 characters.
|
||||
|
||||
response_format: Specifies the format that the model must output. Compatible with
|
||||
[GPT-4o](https://platform.openai.com/docs/models#gpt-4o),
|
||||
[GPT-4 Turbo](https://platform.openai.com/docs/models#gpt-4-turbo-and-gpt-4),
|
||||
and all GPT-3.5 Turbo models since `gpt-3.5-turbo-1106`.
|
||||
|
||||
Setting to `{ "type": "json_schema", "json_schema": {...} }` enables Structured
|
||||
Outputs which ensures the model will match your supplied JSON schema. Learn more
|
||||
in the
|
||||
[Structured Outputs guide](https://platform.openai.com/docs/guides/structured-outputs).
|
||||
|
||||
Setting to `{ "type": "json_object" }` enables JSON mode, which ensures the
|
||||
message the model generates is valid JSON.
|
||||
|
||||
**Important:** when using JSON mode, you **must** also instruct the model to
|
||||
produce JSON yourself via a system or user message. Without this, the model may
|
||||
generate an unending stream of whitespace until the generation reaches the token
|
||||
limit, resulting in a long-running and seemingly "stuck" request. Also note that
|
||||
the message content may be partially cut off if `finish_reason="length"`, which
|
||||
indicates the generation exceeded `max_tokens` or the conversation exceeded the
|
||||
max context length.
|
||||
|
||||
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
|
||||
make the output more random, while lower values like 0.2 will make it more
|
||||
focused and deterministic.
|
||||
|
||||
tool_resources: A set of resources that are used by the assistant's tools. The resources are
|
||||
specific to the type of tool. For example, the `code_interpreter` tool requires
|
||||
a list of file IDs, while the `file_search` tool requires a list of vector store
|
||||
IDs.
|
||||
|
||||
tools: A list of tool enabled on the assistant. There can be a maximum of 128 tools per
|
||||
assistant. Tools can be of types `code_interpreter`, `file_search`, or
|
||||
`function`.
|
||||
|
||||
top_p: An alternative to sampling with temperature, called nucleus sampling, where the
|
||||
model considers the results of the tokens with top_p probability mass. So 0.1
|
||||
means only the tokens comprising the top 10% probability mass are considered.
|
||||
|
||||
We generally recommend altering this or temperature but not both.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
"/assistants",
|
||||
body=maybe_transform(
|
||||
{
|
||||
"model": model,
|
||||
"description": description,
|
||||
"instructions": instructions,
|
||||
"metadata": metadata,
|
||||
"name": name,
|
||||
"response_format": response_format,
|
||||
"temperature": temperature,
|
||||
"tool_resources": tool_resources,
|
||||
"tools": tools,
|
||||
"top_p": top_p,
|
||||
},
|
||||
assistant_create_params.AssistantCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Assistant,
|
||||
)
|
||||
|
||||
def retrieve(
|
||||
self,
|
||||
assistant_id: str,
|
||||
*,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Assistant:
|
||||
"""
|
||||
Retrieves an assistant.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not assistant_id:
|
||||
raise ValueError(f"Expected a non-empty value for `assistant_id` but received {assistant_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get(
|
||||
f"/assistants/{assistant_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Assistant,
|
||||
)
|
||||
|
||||
def update(
|
||||
self,
|
||||
assistant_id: str,
|
||||
*,
|
||||
description: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
instructions: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
model: str | NotGiven = NOT_GIVEN,
|
||||
name: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
response_format: Optional[AssistantResponseFormatOptionParam] | NotGiven = NOT_GIVEN,
|
||||
temperature: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
tool_resources: Optional[assistant_update_params.ToolResources] | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[AssistantToolParam] | NotGiven = NOT_GIVEN,
|
||||
top_p: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Assistant:
|
||||
"""Modifies an assistant.
|
||||
|
||||
Args:
|
||||
description: The description of the assistant.
|
||||
|
||||
The maximum length is 512 characters.
|
||||
|
||||
instructions: The system instructions that the assistant uses. The maximum length is 256,000
|
||||
characters.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
model: ID of the model to use. You can use the
|
||||
[List models](https://platform.openai.com/docs/api-reference/models/list) API to
|
||||
see all of your available models, or see our
|
||||
[Model overview](https://platform.openai.com/docs/models) for descriptions of
|
||||
them.
|
||||
|
||||
name: The name of the assistant. The maximum length is 256 characters.
|
||||
|
||||
response_format: Specifies the format that the model must output. Compatible with
|
||||
[GPT-4o](https://platform.openai.com/docs/models#gpt-4o),
|
||||
[GPT-4 Turbo](https://platform.openai.com/docs/models#gpt-4-turbo-and-gpt-4),
|
||||
and all GPT-3.5 Turbo models since `gpt-3.5-turbo-1106`.
|
||||
|
||||
Setting to `{ "type": "json_schema", "json_schema": {...} }` enables Structured
|
||||
Outputs which ensures the model will match your supplied JSON schema. Learn more
|
||||
in the
|
||||
[Structured Outputs guide](https://platform.openai.com/docs/guides/structured-outputs).
|
||||
|
||||
Setting to `{ "type": "json_object" }` enables JSON mode, which ensures the
|
||||
message the model generates is valid JSON.
|
||||
|
||||
**Important:** when using JSON mode, you **must** also instruct the model to
|
||||
produce JSON yourself via a system or user message. Without this, the model may
|
||||
generate an unending stream of whitespace until the generation reaches the token
|
||||
limit, resulting in a long-running and seemingly "stuck" request. Also note that
|
||||
the message content may be partially cut off if `finish_reason="length"`, which
|
||||
indicates the generation exceeded `max_tokens` or the conversation exceeded the
|
||||
max context length.
|
||||
|
||||
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
|
||||
make the output more random, while lower values like 0.2 will make it more
|
||||
focused and deterministic.
|
||||
|
||||
tool_resources: A set of resources that are used by the assistant's tools. The resources are
|
||||
specific to the type of tool. For example, the `code_interpreter` tool requires
|
||||
a list of file IDs, while the `file_search` tool requires a list of vector store
|
||||
IDs.
|
||||
|
||||
tools: A list of tool enabled on the assistant. There can be a maximum of 128 tools per
|
||||
assistant. Tools can be of types `code_interpreter`, `file_search`, or
|
||||
`function`.
|
||||
|
||||
top_p: An alternative to sampling with temperature, called nucleus sampling, where the
|
||||
model considers the results of the tokens with top_p probability mass. So 0.1
|
||||
means only the tokens comprising the top 10% probability mass are considered.
|
||||
|
||||
We generally recommend altering this or temperature but not both.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not assistant_id:
|
||||
raise ValueError(f"Expected a non-empty value for `assistant_id` but received {assistant_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
f"/assistants/{assistant_id}",
|
||||
body=maybe_transform(
|
||||
{
|
||||
"description": description,
|
||||
"instructions": instructions,
|
||||
"metadata": metadata,
|
||||
"model": model,
|
||||
"name": name,
|
||||
"response_format": response_format,
|
||||
"temperature": temperature,
|
||||
"tool_resources": tool_resources,
|
||||
"tools": tools,
|
||||
"top_p": top_p,
|
||||
},
|
||||
assistant_update_params.AssistantUpdateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Assistant,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
*,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> SyncCursorPage[Assistant]:
|
||||
"""Returns a list of assistants.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination.
|
||||
|
||||
`after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
"/assistants",
|
||||
page=SyncCursorPage[Assistant],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
assistant_list_params.AssistantListParams,
|
||||
),
|
||||
),
|
||||
model=Assistant,
|
||||
)
|
||||
|
||||
def delete(
|
||||
self,
|
||||
assistant_id: str,
|
||||
*,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> AssistantDeleted:
|
||||
"""
|
||||
Delete an assistant.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not assistant_id:
|
||||
raise ValueError(f"Expected a non-empty value for `assistant_id` but received {assistant_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._delete(
|
||||
f"/assistants/{assistant_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=AssistantDeleted,
|
||||
)
|
||||
|
||||
|
||||
class AsyncAssistants(AsyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncAssistantsWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncAssistantsWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncAssistantsWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncAssistantsWithStreamingResponse(self)
|
||||
|
||||
async def create(
|
||||
self,
|
||||
*,
|
||||
model: Union[str, ChatModel],
|
||||
description: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
instructions: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
name: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
response_format: Optional[AssistantResponseFormatOptionParam] | NotGiven = NOT_GIVEN,
|
||||
temperature: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
tool_resources: Optional[assistant_create_params.ToolResources] | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[AssistantToolParam] | NotGiven = NOT_GIVEN,
|
||||
top_p: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Assistant:
|
||||
"""
|
||||
Create an assistant with a model and instructions.
|
||||
|
||||
Args:
|
||||
model: ID of the model to use. You can use the
|
||||
[List models](https://platform.openai.com/docs/api-reference/models/list) API to
|
||||
see all of your available models, or see our
|
||||
[Model overview](https://platform.openai.com/docs/models) for descriptions of
|
||||
them.
|
||||
|
||||
description: The description of the assistant. The maximum length is 512 characters.
|
||||
|
||||
instructions: The system instructions that the assistant uses. The maximum length is 256,000
|
||||
characters.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
name: The name of the assistant. The maximum length is 256 characters.
|
||||
|
||||
response_format: Specifies the format that the model must output. Compatible with
|
||||
[GPT-4o](https://platform.openai.com/docs/models#gpt-4o),
|
||||
[GPT-4 Turbo](https://platform.openai.com/docs/models#gpt-4-turbo-and-gpt-4),
|
||||
and all GPT-3.5 Turbo models since `gpt-3.5-turbo-1106`.
|
||||
|
||||
Setting to `{ "type": "json_schema", "json_schema": {...} }` enables Structured
|
||||
Outputs which ensures the model will match your supplied JSON schema. Learn more
|
||||
in the
|
||||
[Structured Outputs guide](https://platform.openai.com/docs/guides/structured-outputs).
|
||||
|
||||
Setting to `{ "type": "json_object" }` enables JSON mode, which ensures the
|
||||
message the model generates is valid JSON.
|
||||
|
||||
**Important:** when using JSON mode, you **must** also instruct the model to
|
||||
produce JSON yourself via a system or user message. Without this, the model may
|
||||
generate an unending stream of whitespace until the generation reaches the token
|
||||
limit, resulting in a long-running and seemingly "stuck" request. Also note that
|
||||
the message content may be partially cut off if `finish_reason="length"`, which
|
||||
indicates the generation exceeded `max_tokens` or the conversation exceeded the
|
||||
max context length.
|
||||
|
||||
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
|
||||
make the output more random, while lower values like 0.2 will make it more
|
||||
focused and deterministic.
|
||||
|
||||
tool_resources: A set of resources that are used by the assistant's tools. The resources are
|
||||
specific to the type of tool. For example, the `code_interpreter` tool requires
|
||||
a list of file IDs, while the `file_search` tool requires a list of vector store
|
||||
IDs.
|
||||
|
||||
tools: A list of tool enabled on the assistant. There can be a maximum of 128 tools per
|
||||
assistant. Tools can be of types `code_interpreter`, `file_search`, or
|
||||
`function`.
|
||||
|
||||
top_p: An alternative to sampling with temperature, called nucleus sampling, where the
|
||||
model considers the results of the tokens with top_p probability mass. So 0.1
|
||||
means only the tokens comprising the top 10% probability mass are considered.
|
||||
|
||||
We generally recommend altering this or temperature but not both.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
"/assistants",
|
||||
body=await async_maybe_transform(
|
||||
{
|
||||
"model": model,
|
||||
"description": description,
|
||||
"instructions": instructions,
|
||||
"metadata": metadata,
|
||||
"name": name,
|
||||
"response_format": response_format,
|
||||
"temperature": temperature,
|
||||
"tool_resources": tool_resources,
|
||||
"tools": tools,
|
||||
"top_p": top_p,
|
||||
},
|
||||
assistant_create_params.AssistantCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Assistant,
|
||||
)
|
||||
|
||||
async def retrieve(
|
||||
self,
|
||||
assistant_id: str,
|
||||
*,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Assistant:
|
||||
"""
|
||||
Retrieves an assistant.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not assistant_id:
|
||||
raise ValueError(f"Expected a non-empty value for `assistant_id` but received {assistant_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._get(
|
||||
f"/assistants/{assistant_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Assistant,
|
||||
)
|
||||
|
||||
async def update(
|
||||
self,
|
||||
assistant_id: str,
|
||||
*,
|
||||
description: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
instructions: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
model: str | NotGiven = NOT_GIVEN,
|
||||
name: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
response_format: Optional[AssistantResponseFormatOptionParam] | NotGiven = NOT_GIVEN,
|
||||
temperature: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
tool_resources: Optional[assistant_update_params.ToolResources] | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[AssistantToolParam] | NotGiven = NOT_GIVEN,
|
||||
top_p: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Assistant:
|
||||
"""Modifies an assistant.
|
||||
|
||||
Args:
|
||||
description: The description of the assistant.
|
||||
|
||||
The maximum length is 512 characters.
|
||||
|
||||
instructions: The system instructions that the assistant uses. The maximum length is 256,000
|
||||
characters.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
model: ID of the model to use. You can use the
|
||||
[List models](https://platform.openai.com/docs/api-reference/models/list) API to
|
||||
see all of your available models, or see our
|
||||
[Model overview](https://platform.openai.com/docs/models) for descriptions of
|
||||
them.
|
||||
|
||||
name: The name of the assistant. The maximum length is 256 characters.
|
||||
|
||||
response_format: Specifies the format that the model must output. Compatible with
|
||||
[GPT-4o](https://platform.openai.com/docs/models#gpt-4o),
|
||||
[GPT-4 Turbo](https://platform.openai.com/docs/models#gpt-4-turbo-and-gpt-4),
|
||||
and all GPT-3.5 Turbo models since `gpt-3.5-turbo-1106`.
|
||||
|
||||
Setting to `{ "type": "json_schema", "json_schema": {...} }` enables Structured
|
||||
Outputs which ensures the model will match your supplied JSON schema. Learn more
|
||||
in the
|
||||
[Structured Outputs guide](https://platform.openai.com/docs/guides/structured-outputs).
|
||||
|
||||
Setting to `{ "type": "json_object" }` enables JSON mode, which ensures the
|
||||
message the model generates is valid JSON.
|
||||
|
||||
**Important:** when using JSON mode, you **must** also instruct the model to
|
||||
produce JSON yourself via a system or user message. Without this, the model may
|
||||
generate an unending stream of whitespace until the generation reaches the token
|
||||
limit, resulting in a long-running and seemingly "stuck" request. Also note that
|
||||
the message content may be partially cut off if `finish_reason="length"`, which
|
||||
indicates the generation exceeded `max_tokens` or the conversation exceeded the
|
||||
max context length.
|
||||
|
||||
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
|
||||
make the output more random, while lower values like 0.2 will make it more
|
||||
focused and deterministic.
|
||||
|
||||
tool_resources: A set of resources that are used by the assistant's tools. The resources are
|
||||
specific to the type of tool. For example, the `code_interpreter` tool requires
|
||||
a list of file IDs, while the `file_search` tool requires a list of vector store
|
||||
IDs.
|
||||
|
||||
tools: A list of tool enabled on the assistant. There can be a maximum of 128 tools per
|
||||
assistant. Tools can be of types `code_interpreter`, `file_search`, or
|
||||
`function`.
|
||||
|
||||
top_p: An alternative to sampling with temperature, called nucleus sampling, where the
|
||||
model considers the results of the tokens with top_p probability mass. So 0.1
|
||||
means only the tokens comprising the top 10% probability mass are considered.
|
||||
|
||||
We generally recommend altering this or temperature but not both.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not assistant_id:
|
||||
raise ValueError(f"Expected a non-empty value for `assistant_id` but received {assistant_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
f"/assistants/{assistant_id}",
|
||||
body=await async_maybe_transform(
|
||||
{
|
||||
"description": description,
|
||||
"instructions": instructions,
|
||||
"metadata": metadata,
|
||||
"model": model,
|
||||
"name": name,
|
||||
"response_format": response_format,
|
||||
"temperature": temperature,
|
||||
"tool_resources": tool_resources,
|
||||
"tools": tools,
|
||||
"top_p": top_p,
|
||||
},
|
||||
assistant_update_params.AssistantUpdateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Assistant,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
*,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> AsyncPaginator[Assistant, AsyncCursorPage[Assistant]]:
|
||||
"""Returns a list of assistants.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination.
|
||||
|
||||
`after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
"/assistants",
|
||||
page=AsyncCursorPage[Assistant],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
assistant_list_params.AssistantListParams,
|
||||
),
|
||||
),
|
||||
model=Assistant,
|
||||
)
|
||||
|
||||
async def delete(
|
||||
self,
|
||||
assistant_id: str,
|
||||
*,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> AssistantDeleted:
|
||||
"""
|
||||
Delete an assistant.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not assistant_id:
|
||||
raise ValueError(f"Expected a non-empty value for `assistant_id` but received {assistant_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._delete(
|
||||
f"/assistants/{assistant_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=AssistantDeleted,
|
||||
)
|
||||
|
||||
|
||||
class AssistantsWithRawResponse:
|
||||
def __init__(self, assistants: Assistants) -> None:
|
||||
self._assistants = assistants
|
||||
|
||||
self.create = _legacy_response.to_raw_response_wrapper(
|
||||
assistants.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.to_raw_response_wrapper(
|
||||
assistants.retrieve,
|
||||
)
|
||||
self.update = _legacy_response.to_raw_response_wrapper(
|
||||
assistants.update,
|
||||
)
|
||||
self.list = _legacy_response.to_raw_response_wrapper(
|
||||
assistants.list,
|
||||
)
|
||||
self.delete = _legacy_response.to_raw_response_wrapper(
|
||||
assistants.delete,
|
||||
)
|
||||
|
||||
|
||||
class AsyncAssistantsWithRawResponse:
|
||||
def __init__(self, assistants: AsyncAssistants) -> None:
|
||||
self._assistants = assistants
|
||||
|
||||
self.create = _legacy_response.async_to_raw_response_wrapper(
|
||||
assistants.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.async_to_raw_response_wrapper(
|
||||
assistants.retrieve,
|
||||
)
|
||||
self.update = _legacy_response.async_to_raw_response_wrapper(
|
||||
assistants.update,
|
||||
)
|
||||
self.list = _legacy_response.async_to_raw_response_wrapper(
|
||||
assistants.list,
|
||||
)
|
||||
self.delete = _legacy_response.async_to_raw_response_wrapper(
|
||||
assistants.delete,
|
||||
)
|
||||
|
||||
|
||||
class AssistantsWithStreamingResponse:
|
||||
def __init__(self, assistants: Assistants) -> None:
|
||||
self._assistants = assistants
|
||||
|
||||
self.create = to_streamed_response_wrapper(
|
||||
assistants.create,
|
||||
)
|
||||
self.retrieve = to_streamed_response_wrapper(
|
||||
assistants.retrieve,
|
||||
)
|
||||
self.update = to_streamed_response_wrapper(
|
||||
assistants.update,
|
||||
)
|
||||
self.list = to_streamed_response_wrapper(
|
||||
assistants.list,
|
||||
)
|
||||
self.delete = to_streamed_response_wrapper(
|
||||
assistants.delete,
|
||||
)
|
||||
|
||||
|
||||
class AsyncAssistantsWithStreamingResponse:
|
||||
def __init__(self, assistants: AsyncAssistants) -> None:
|
||||
self._assistants = assistants
|
||||
|
||||
self.create = async_to_streamed_response_wrapper(
|
||||
assistants.create,
|
||||
)
|
||||
self.retrieve = async_to_streamed_response_wrapper(
|
||||
assistants.retrieve,
|
||||
)
|
||||
self.update = async_to_streamed_response_wrapper(
|
||||
assistants.update,
|
||||
)
|
||||
self.list = async_to_streamed_response_wrapper(
|
||||
assistants.list,
|
||||
)
|
||||
self.delete = async_to_streamed_response_wrapper(
|
||||
assistants.delete,
|
||||
)
|
||||
@@ -0,0 +1,207 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from ..._compat import cached_property
|
||||
from .chat.chat import Chat, AsyncChat
|
||||
from .assistants import (
|
||||
Assistants,
|
||||
AsyncAssistants,
|
||||
AssistantsWithRawResponse,
|
||||
AsyncAssistantsWithRawResponse,
|
||||
AssistantsWithStreamingResponse,
|
||||
AsyncAssistantsWithStreamingResponse,
|
||||
)
|
||||
from ..._resource import SyncAPIResource, AsyncAPIResource
|
||||
from .threads.threads import (
|
||||
Threads,
|
||||
AsyncThreads,
|
||||
ThreadsWithRawResponse,
|
||||
AsyncThreadsWithRawResponse,
|
||||
ThreadsWithStreamingResponse,
|
||||
AsyncThreadsWithStreamingResponse,
|
||||
)
|
||||
from .realtime.realtime import (
|
||||
Realtime,
|
||||
AsyncRealtime,
|
||||
RealtimeWithRawResponse,
|
||||
AsyncRealtimeWithRawResponse,
|
||||
RealtimeWithStreamingResponse,
|
||||
AsyncRealtimeWithStreamingResponse,
|
||||
)
|
||||
from .vector_stores.vector_stores import (
|
||||
VectorStores,
|
||||
AsyncVectorStores,
|
||||
VectorStoresWithRawResponse,
|
||||
AsyncVectorStoresWithRawResponse,
|
||||
VectorStoresWithStreamingResponse,
|
||||
AsyncVectorStoresWithStreamingResponse,
|
||||
)
|
||||
|
||||
__all__ = ["Beta", "AsyncBeta"]
|
||||
|
||||
|
||||
class Beta(SyncAPIResource):
|
||||
@cached_property
|
||||
def chat(self) -> Chat:
|
||||
return Chat(self._client)
|
||||
|
||||
@cached_property
|
||||
def realtime(self) -> Realtime:
|
||||
return Realtime(self._client)
|
||||
|
||||
@cached_property
|
||||
def vector_stores(self) -> VectorStores:
|
||||
return VectorStores(self._client)
|
||||
|
||||
@cached_property
|
||||
def assistants(self) -> Assistants:
|
||||
return Assistants(self._client)
|
||||
|
||||
@cached_property
|
||||
def threads(self) -> Threads:
|
||||
return Threads(self._client)
|
||||
|
||||
@cached_property
|
||||
def with_raw_response(self) -> BetaWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return BetaWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> BetaWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return BetaWithStreamingResponse(self)
|
||||
|
||||
|
||||
class AsyncBeta(AsyncAPIResource):
|
||||
@cached_property
|
||||
def chat(self) -> AsyncChat:
|
||||
return AsyncChat(self._client)
|
||||
|
||||
@cached_property
|
||||
def realtime(self) -> AsyncRealtime:
|
||||
return AsyncRealtime(self._client)
|
||||
|
||||
@cached_property
|
||||
def vector_stores(self) -> AsyncVectorStores:
|
||||
return AsyncVectorStores(self._client)
|
||||
|
||||
@cached_property
|
||||
def assistants(self) -> AsyncAssistants:
|
||||
return AsyncAssistants(self._client)
|
||||
|
||||
@cached_property
|
||||
def threads(self) -> AsyncThreads:
|
||||
return AsyncThreads(self._client)
|
||||
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncBetaWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncBetaWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncBetaWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncBetaWithStreamingResponse(self)
|
||||
|
||||
|
||||
class BetaWithRawResponse:
|
||||
def __init__(self, beta: Beta) -> None:
|
||||
self._beta = beta
|
||||
|
||||
@cached_property
|
||||
def realtime(self) -> RealtimeWithRawResponse:
|
||||
return RealtimeWithRawResponse(self._beta.realtime)
|
||||
|
||||
@cached_property
|
||||
def vector_stores(self) -> VectorStoresWithRawResponse:
|
||||
return VectorStoresWithRawResponse(self._beta.vector_stores)
|
||||
|
||||
@cached_property
|
||||
def assistants(self) -> AssistantsWithRawResponse:
|
||||
return AssistantsWithRawResponse(self._beta.assistants)
|
||||
|
||||
@cached_property
|
||||
def threads(self) -> ThreadsWithRawResponse:
|
||||
return ThreadsWithRawResponse(self._beta.threads)
|
||||
|
||||
|
||||
class AsyncBetaWithRawResponse:
|
||||
def __init__(self, beta: AsyncBeta) -> None:
|
||||
self._beta = beta
|
||||
|
||||
@cached_property
|
||||
def realtime(self) -> AsyncRealtimeWithRawResponse:
|
||||
return AsyncRealtimeWithRawResponse(self._beta.realtime)
|
||||
|
||||
@cached_property
|
||||
def vector_stores(self) -> AsyncVectorStoresWithRawResponse:
|
||||
return AsyncVectorStoresWithRawResponse(self._beta.vector_stores)
|
||||
|
||||
@cached_property
|
||||
def assistants(self) -> AsyncAssistantsWithRawResponse:
|
||||
return AsyncAssistantsWithRawResponse(self._beta.assistants)
|
||||
|
||||
@cached_property
|
||||
def threads(self) -> AsyncThreadsWithRawResponse:
|
||||
return AsyncThreadsWithRawResponse(self._beta.threads)
|
||||
|
||||
|
||||
class BetaWithStreamingResponse:
|
||||
def __init__(self, beta: Beta) -> None:
|
||||
self._beta = beta
|
||||
|
||||
@cached_property
|
||||
def realtime(self) -> RealtimeWithStreamingResponse:
|
||||
return RealtimeWithStreamingResponse(self._beta.realtime)
|
||||
|
||||
@cached_property
|
||||
def vector_stores(self) -> VectorStoresWithStreamingResponse:
|
||||
return VectorStoresWithStreamingResponse(self._beta.vector_stores)
|
||||
|
||||
@cached_property
|
||||
def assistants(self) -> AssistantsWithStreamingResponse:
|
||||
return AssistantsWithStreamingResponse(self._beta.assistants)
|
||||
|
||||
@cached_property
|
||||
def threads(self) -> ThreadsWithStreamingResponse:
|
||||
return ThreadsWithStreamingResponse(self._beta.threads)
|
||||
|
||||
|
||||
class AsyncBetaWithStreamingResponse:
|
||||
def __init__(self, beta: AsyncBeta) -> None:
|
||||
self._beta = beta
|
||||
|
||||
@cached_property
|
||||
def realtime(self) -> AsyncRealtimeWithStreamingResponse:
|
||||
return AsyncRealtimeWithStreamingResponse(self._beta.realtime)
|
||||
|
||||
@cached_property
|
||||
def vector_stores(self) -> AsyncVectorStoresWithStreamingResponse:
|
||||
return AsyncVectorStoresWithStreamingResponse(self._beta.vector_stores)
|
||||
|
||||
@cached_property
|
||||
def assistants(self) -> AsyncAssistantsWithStreamingResponse:
|
||||
return AsyncAssistantsWithStreamingResponse(self._beta.assistants)
|
||||
|
||||
@cached_property
|
||||
def threads(self) -> AsyncThreadsWithStreamingResponse:
|
||||
return AsyncThreadsWithStreamingResponse(self._beta.threads)
|
||||
@@ -0,0 +1,11 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from .chat import Chat, AsyncChat
|
||||
from .completions import Completions, AsyncCompletions
|
||||
|
||||
__all__ = [
|
||||
"Completions",
|
||||
"AsyncCompletions",
|
||||
"Chat",
|
||||
"AsyncChat",
|
||||
]
|
||||
@@ -0,0 +1,21 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from ...._compat import cached_property
|
||||
from .completions import Completions, AsyncCompletions
|
||||
from ...._resource import SyncAPIResource, AsyncAPIResource
|
||||
|
||||
__all__ = ["Chat", "AsyncChat"]
|
||||
|
||||
|
||||
class Chat(SyncAPIResource):
|
||||
@cached_property
|
||||
def completions(self) -> Completions:
|
||||
return Completions(self._client)
|
||||
|
||||
|
||||
class AsyncChat(AsyncAPIResource):
|
||||
@cached_property
|
||||
def completions(self) -> AsyncCompletions:
|
||||
return AsyncCompletions(self._client)
|
||||
@@ -0,0 +1,629 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Dict, List, Type, Union, Iterable, Optional, cast
|
||||
from functools import partial
|
||||
from typing_extensions import Literal
|
||||
|
||||
import httpx
|
||||
|
||||
from .... import _legacy_response
|
||||
from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
||||
from ...._utils import maybe_transform, async_maybe_transform
|
||||
from ...._compat import cached_property
|
||||
from ...._resource import SyncAPIResource, AsyncAPIResource
|
||||
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
|
||||
from ...._streaming import Stream
|
||||
from ....types.chat import (
|
||||
ChatCompletionReasoningEffort,
|
||||
completion_create_params,
|
||||
)
|
||||
from ...._base_client import make_request_options
|
||||
from ....lib._parsing import (
|
||||
ResponseFormatT,
|
||||
validate_input_tools as _validate_input_tools,
|
||||
parse_chat_completion as _parse_chat_completion,
|
||||
type_to_response_format_param as _type_to_response_format,
|
||||
)
|
||||
from ....types.chat_model import ChatModel
|
||||
from ....lib.streaming.chat import ChatCompletionStreamManager, AsyncChatCompletionStreamManager
|
||||
from ....types.chat.chat_completion import ChatCompletion
|
||||
from ....types.chat.chat_completion_chunk import ChatCompletionChunk
|
||||
from ....types.chat.parsed_chat_completion import ParsedChatCompletion
|
||||
from ....types.chat.chat_completion_modality import ChatCompletionModality
|
||||
from ....types.chat.chat_completion_tool_param import ChatCompletionToolParam
|
||||
from ....types.chat.chat_completion_audio_param import ChatCompletionAudioParam
|
||||
from ....types.chat.chat_completion_message_param import ChatCompletionMessageParam
|
||||
from ....types.chat.chat_completion_stream_options_param import ChatCompletionStreamOptionsParam
|
||||
from ....types.chat.chat_completion_prediction_content_param import ChatCompletionPredictionContentParam
|
||||
from ....types.chat.chat_completion_tool_choice_option_param import ChatCompletionToolChoiceOptionParam
|
||||
|
||||
__all__ = ["Completions", "AsyncCompletions"]
|
||||
|
||||
|
||||
class Completions(SyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> CompletionsWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return CompletionsWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> CompletionsWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return CompletionsWithStreamingResponse(self)
|
||||
|
||||
def parse(
|
||||
self,
|
||||
*,
|
||||
messages: Iterable[ChatCompletionMessageParam],
|
||||
model: Union[str, ChatModel],
|
||||
audio: Optional[ChatCompletionAudioParam] | NotGiven = NOT_GIVEN,
|
||||
response_format: type[ResponseFormatT] | NotGiven = NOT_GIVEN,
|
||||
frequency_penalty: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
function_call: completion_create_params.FunctionCall | NotGiven = NOT_GIVEN,
|
||||
functions: Iterable[completion_create_params.Function] | NotGiven = NOT_GIVEN,
|
||||
logit_bias: Optional[Dict[str, int]] | NotGiven = NOT_GIVEN,
|
||||
logprobs: Optional[bool] | NotGiven = NOT_GIVEN,
|
||||
max_completion_tokens: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
max_tokens: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN,
|
||||
modalities: Optional[List[ChatCompletionModality]] | NotGiven = NOT_GIVEN,
|
||||
n: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
parallel_tool_calls: bool | NotGiven = NOT_GIVEN,
|
||||
prediction: Optional[ChatCompletionPredictionContentParam] | NotGiven = NOT_GIVEN,
|
||||
presence_penalty: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
reasoning_effort: ChatCompletionReasoningEffort | NotGiven = NOT_GIVEN,
|
||||
seed: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
service_tier: Optional[Literal["auto", "default"]] | NotGiven = NOT_GIVEN,
|
||||
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
|
||||
store: Optional[bool] | NotGiven = NOT_GIVEN,
|
||||
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
|
||||
temperature: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
|
||||
top_logprobs: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
top_p: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
user: str | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> ParsedChatCompletion[ResponseFormatT]:
|
||||
"""Wrapper over the `client.chat.completions.create()` method that provides richer integrations with Python specific types
|
||||
& returns a `ParsedChatCompletion` object, which is a subclass of the standard `ChatCompletion` class.
|
||||
|
||||
You can pass a pydantic model to this method and it will automatically convert the model
|
||||
into a JSON schema, send it to the API and parse the response content back into the given model.
|
||||
|
||||
This method will also automatically parse `function` tool calls if:
|
||||
- You use the `openai.pydantic_function_tool()` helper method
|
||||
- You mark your tool schema with `"strict": True`
|
||||
|
||||
Example usage:
|
||||
```py
|
||||
from pydantic import BaseModel
|
||||
from openai import OpenAI
|
||||
|
||||
|
||||
class Step(BaseModel):
|
||||
explanation: str
|
||||
output: str
|
||||
|
||||
|
||||
class MathResponse(BaseModel):
|
||||
steps: List[Step]
|
||||
final_answer: str
|
||||
|
||||
|
||||
client = OpenAI()
|
||||
completion = client.beta.chat.completions.parse(
|
||||
model="gpt-4o-2024-08-06",
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a helpful math tutor."},
|
||||
{"role": "user", "content": "solve 8x + 31 = 2"},
|
||||
],
|
||||
response_format=MathResponse,
|
||||
)
|
||||
|
||||
message = completion.choices[0].message
|
||||
if message.parsed:
|
||||
print(message.parsed.steps)
|
||||
print("answer: ", message.parsed.final_answer)
|
||||
```
|
||||
"""
|
||||
_validate_input_tools(tools)
|
||||
|
||||
extra_headers = {
|
||||
"X-Stainless-Helper-Method": "beta.chat.completions.parse",
|
||||
**(extra_headers or {}),
|
||||
}
|
||||
|
||||
def parser(raw_completion: ChatCompletion) -> ParsedChatCompletion[ResponseFormatT]:
|
||||
return _parse_chat_completion(
|
||||
response_format=response_format,
|
||||
chat_completion=raw_completion,
|
||||
input_tools=tools,
|
||||
)
|
||||
|
||||
return self._post(
|
||||
"/chat/completions",
|
||||
body=maybe_transform(
|
||||
{
|
||||
"messages": messages,
|
||||
"model": model,
|
||||
"audio": audio,
|
||||
"frequency_penalty": frequency_penalty,
|
||||
"function_call": function_call,
|
||||
"functions": functions,
|
||||
"logit_bias": logit_bias,
|
||||
"logprobs": logprobs,
|
||||
"max_completion_tokens": max_completion_tokens,
|
||||
"max_tokens": max_tokens,
|
||||
"metadata": metadata,
|
||||
"modalities": modalities,
|
||||
"n": n,
|
||||
"parallel_tool_calls": parallel_tool_calls,
|
||||
"prediction": prediction,
|
||||
"presence_penalty": presence_penalty,
|
||||
"reasoning_effort": reasoning_effort,
|
||||
"response_format": _type_to_response_format(response_format),
|
||||
"seed": seed,
|
||||
"service_tier": service_tier,
|
||||
"stop": stop,
|
||||
"store": store,
|
||||
"stream": False,
|
||||
"stream_options": stream_options,
|
||||
"temperature": temperature,
|
||||
"tool_choice": tool_choice,
|
||||
"tools": tools,
|
||||
"top_logprobs": top_logprobs,
|
||||
"top_p": top_p,
|
||||
"user": user,
|
||||
},
|
||||
completion_create_params.CompletionCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
post_parser=parser,
|
||||
),
|
||||
# we turn the `ChatCompletion` instance into a `ParsedChatCompletion`
|
||||
# in the `parser` function above
|
||||
cast_to=cast(Type[ParsedChatCompletion[ResponseFormatT]], ChatCompletion),
|
||||
stream=False,
|
||||
)
|
||||
|
||||
def stream(
|
||||
self,
|
||||
*,
|
||||
messages: Iterable[ChatCompletionMessageParam],
|
||||
model: Union[str, ChatModel],
|
||||
audio: Optional[ChatCompletionAudioParam] | NotGiven = NOT_GIVEN,
|
||||
response_format: completion_create_params.ResponseFormat | type[ResponseFormatT] | NotGiven = NOT_GIVEN,
|
||||
frequency_penalty: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
function_call: completion_create_params.FunctionCall | NotGiven = NOT_GIVEN,
|
||||
functions: Iterable[completion_create_params.Function] | NotGiven = NOT_GIVEN,
|
||||
logit_bias: Optional[Dict[str, int]] | NotGiven = NOT_GIVEN,
|
||||
logprobs: Optional[bool] | NotGiven = NOT_GIVEN,
|
||||
max_completion_tokens: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
max_tokens: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN,
|
||||
modalities: Optional[List[ChatCompletionModality]] | NotGiven = NOT_GIVEN,
|
||||
n: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
parallel_tool_calls: bool | NotGiven = NOT_GIVEN,
|
||||
prediction: Optional[ChatCompletionPredictionContentParam] | NotGiven = NOT_GIVEN,
|
||||
presence_penalty: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
reasoning_effort: ChatCompletionReasoningEffort | NotGiven = NOT_GIVEN,
|
||||
seed: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
service_tier: Optional[Literal["auto", "default"]] | NotGiven = NOT_GIVEN,
|
||||
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
|
||||
store: Optional[bool] | NotGiven = NOT_GIVEN,
|
||||
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
|
||||
temperature: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
|
||||
top_logprobs: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
top_p: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
user: str | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> ChatCompletionStreamManager[ResponseFormatT]:
|
||||
"""Wrapper over the `client.chat.completions.create(stream=True)` method that provides a more granular event API
|
||||
and automatic accumulation of each delta.
|
||||
|
||||
This also supports all of the parsing utilities that `.parse()` does.
|
||||
|
||||
Unlike `.create(stream=True)`, the `.stream()` method requires usage within a context manager to prevent accidental leakage of the response:
|
||||
|
||||
```py
|
||||
with client.beta.chat.completions.stream(
|
||||
model="gpt-4o-2024-08-06",
|
||||
messages=[...],
|
||||
) as stream:
|
||||
for event in stream:
|
||||
if event.type == "content.delta":
|
||||
print(event.delta, flush=True, end="")
|
||||
```
|
||||
|
||||
When the context manager is entered, a `ChatCompletionStream` instance is returned which, like `.create(stream=True)` is an iterator. The full list of events that are yielded by the iterator are outlined in [these docs](https://github.com/openai/openai-python/blob/main/helpers.md#chat-completions-events).
|
||||
|
||||
When the context manager exits, the response will be closed, however the `stream` instance is still available outside
|
||||
the context manager.
|
||||
"""
|
||||
extra_headers = {
|
||||
"X-Stainless-Helper-Method": "beta.chat.completions.stream",
|
||||
**(extra_headers or {}),
|
||||
}
|
||||
|
||||
api_request: partial[Stream[ChatCompletionChunk]] = partial(
|
||||
self._client.chat.completions.create,
|
||||
messages=messages,
|
||||
model=model,
|
||||
audio=audio,
|
||||
stream=True,
|
||||
response_format=_type_to_response_format(response_format),
|
||||
frequency_penalty=frequency_penalty,
|
||||
function_call=function_call,
|
||||
functions=functions,
|
||||
logit_bias=logit_bias,
|
||||
logprobs=logprobs,
|
||||
max_completion_tokens=max_completion_tokens,
|
||||
max_tokens=max_tokens,
|
||||
metadata=metadata,
|
||||
modalities=modalities,
|
||||
n=n,
|
||||
parallel_tool_calls=parallel_tool_calls,
|
||||
prediction=prediction,
|
||||
presence_penalty=presence_penalty,
|
||||
reasoning_effort=reasoning_effort,
|
||||
seed=seed,
|
||||
service_tier=service_tier,
|
||||
store=store,
|
||||
stop=stop,
|
||||
stream_options=stream_options,
|
||||
temperature=temperature,
|
||||
tool_choice=tool_choice,
|
||||
tools=tools,
|
||||
top_logprobs=top_logprobs,
|
||||
top_p=top_p,
|
||||
user=user,
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
)
|
||||
return ChatCompletionStreamManager(
|
||||
api_request,
|
||||
response_format=response_format,
|
||||
input_tools=tools,
|
||||
)
|
||||
|
||||
|
||||
class AsyncCompletions(AsyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncCompletionsWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncCompletionsWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncCompletionsWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncCompletionsWithStreamingResponse(self)
|
||||
|
||||
async def parse(
|
||||
self,
|
||||
*,
|
||||
messages: Iterable[ChatCompletionMessageParam],
|
||||
model: Union[str, ChatModel],
|
||||
audio: Optional[ChatCompletionAudioParam] | NotGiven = NOT_GIVEN,
|
||||
response_format: type[ResponseFormatT] | NotGiven = NOT_GIVEN,
|
||||
frequency_penalty: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
function_call: completion_create_params.FunctionCall | NotGiven = NOT_GIVEN,
|
||||
functions: Iterable[completion_create_params.Function] | NotGiven = NOT_GIVEN,
|
||||
logit_bias: Optional[Dict[str, int]] | NotGiven = NOT_GIVEN,
|
||||
logprobs: Optional[bool] | NotGiven = NOT_GIVEN,
|
||||
max_completion_tokens: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
max_tokens: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN,
|
||||
modalities: Optional[List[ChatCompletionModality]] | NotGiven = NOT_GIVEN,
|
||||
n: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
parallel_tool_calls: bool | NotGiven = NOT_GIVEN,
|
||||
prediction: Optional[ChatCompletionPredictionContentParam] | NotGiven = NOT_GIVEN,
|
||||
presence_penalty: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
reasoning_effort: ChatCompletionReasoningEffort | NotGiven = NOT_GIVEN,
|
||||
seed: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
service_tier: Optional[Literal["auto", "default"]] | NotGiven = NOT_GIVEN,
|
||||
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
|
||||
store: Optional[bool] | NotGiven = NOT_GIVEN,
|
||||
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
|
||||
temperature: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
|
||||
top_logprobs: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
top_p: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
user: str | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> ParsedChatCompletion[ResponseFormatT]:
|
||||
"""Wrapper over the `client.chat.completions.create()` method that provides richer integrations with Python specific types
|
||||
& returns a `ParsedChatCompletion` object, which is a subclass of the standard `ChatCompletion` class.
|
||||
|
||||
You can pass a pydantic model to this method and it will automatically convert the model
|
||||
into a JSON schema, send it to the API and parse the response content back into the given model.
|
||||
|
||||
This method will also automatically parse `function` tool calls if:
|
||||
- You use the `openai.pydantic_function_tool()` helper method
|
||||
- You mark your tool schema with `"strict": True`
|
||||
|
||||
Example usage:
|
||||
```py
|
||||
from pydantic import BaseModel
|
||||
from openai import AsyncOpenAI
|
||||
|
||||
|
||||
class Step(BaseModel):
|
||||
explanation: str
|
||||
output: str
|
||||
|
||||
|
||||
class MathResponse(BaseModel):
|
||||
steps: List[Step]
|
||||
final_answer: str
|
||||
|
||||
|
||||
client = AsyncOpenAI()
|
||||
completion = await client.beta.chat.completions.parse(
|
||||
model="gpt-4o-2024-08-06",
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a helpful math tutor."},
|
||||
{"role": "user", "content": "solve 8x + 31 = 2"},
|
||||
],
|
||||
response_format=MathResponse,
|
||||
)
|
||||
|
||||
message = completion.choices[0].message
|
||||
if message.parsed:
|
||||
print(message.parsed.steps)
|
||||
print("answer: ", message.parsed.final_answer)
|
||||
```
|
||||
"""
|
||||
_validate_input_tools(tools)
|
||||
|
||||
extra_headers = {
|
||||
"X-Stainless-Helper-Method": "beta.chat.completions.parse",
|
||||
**(extra_headers or {}),
|
||||
}
|
||||
|
||||
def parser(raw_completion: ChatCompletion) -> ParsedChatCompletion[ResponseFormatT]:
|
||||
return _parse_chat_completion(
|
||||
response_format=response_format,
|
||||
chat_completion=raw_completion,
|
||||
input_tools=tools,
|
||||
)
|
||||
|
||||
return await self._post(
|
||||
"/chat/completions",
|
||||
body=await async_maybe_transform(
|
||||
{
|
||||
"messages": messages,
|
||||
"model": model,
|
||||
"audio": audio,
|
||||
"frequency_penalty": frequency_penalty,
|
||||
"function_call": function_call,
|
||||
"functions": functions,
|
||||
"logit_bias": logit_bias,
|
||||
"logprobs": logprobs,
|
||||
"max_completion_tokens": max_completion_tokens,
|
||||
"max_tokens": max_tokens,
|
||||
"metadata": metadata,
|
||||
"modalities": modalities,
|
||||
"n": n,
|
||||
"parallel_tool_calls": parallel_tool_calls,
|
||||
"prediction": prediction,
|
||||
"presence_penalty": presence_penalty,
|
||||
"reasoning_effort": reasoning_effort,
|
||||
"response_format": _type_to_response_format(response_format),
|
||||
"seed": seed,
|
||||
"service_tier": service_tier,
|
||||
"store": store,
|
||||
"stop": stop,
|
||||
"stream": False,
|
||||
"stream_options": stream_options,
|
||||
"temperature": temperature,
|
||||
"tool_choice": tool_choice,
|
||||
"tools": tools,
|
||||
"top_logprobs": top_logprobs,
|
||||
"top_p": top_p,
|
||||
"user": user,
|
||||
},
|
||||
completion_create_params.CompletionCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
post_parser=parser,
|
||||
),
|
||||
# we turn the `ChatCompletion` instance into a `ParsedChatCompletion`
|
||||
# in the `parser` function above
|
||||
cast_to=cast(Type[ParsedChatCompletion[ResponseFormatT]], ChatCompletion),
|
||||
stream=False,
|
||||
)
|
||||
|
||||
def stream(
|
||||
self,
|
||||
*,
|
||||
messages: Iterable[ChatCompletionMessageParam],
|
||||
model: Union[str, ChatModel],
|
||||
audio: Optional[ChatCompletionAudioParam] | NotGiven = NOT_GIVEN,
|
||||
response_format: completion_create_params.ResponseFormat | type[ResponseFormatT] | NotGiven = NOT_GIVEN,
|
||||
frequency_penalty: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
function_call: completion_create_params.FunctionCall | NotGiven = NOT_GIVEN,
|
||||
functions: Iterable[completion_create_params.Function] | NotGiven = NOT_GIVEN,
|
||||
logit_bias: Optional[Dict[str, int]] | NotGiven = NOT_GIVEN,
|
||||
logprobs: Optional[bool] | NotGiven = NOT_GIVEN,
|
||||
max_completion_tokens: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
max_tokens: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN,
|
||||
modalities: Optional[List[ChatCompletionModality]] | NotGiven = NOT_GIVEN,
|
||||
n: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
parallel_tool_calls: bool | NotGiven = NOT_GIVEN,
|
||||
prediction: Optional[ChatCompletionPredictionContentParam] | NotGiven = NOT_GIVEN,
|
||||
presence_penalty: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
reasoning_effort: ChatCompletionReasoningEffort | NotGiven = NOT_GIVEN,
|
||||
seed: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
service_tier: Optional[Literal["auto", "default"]] | NotGiven = NOT_GIVEN,
|
||||
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
|
||||
store: Optional[bool] | NotGiven = NOT_GIVEN,
|
||||
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
|
||||
temperature: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
|
||||
top_logprobs: Optional[int] | NotGiven = NOT_GIVEN,
|
||||
top_p: Optional[float] | NotGiven = NOT_GIVEN,
|
||||
user: str | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> AsyncChatCompletionStreamManager[ResponseFormatT]:
|
||||
"""Wrapper over the `client.chat.completions.create(stream=True)` method that provides a more granular event API
|
||||
and automatic accumulation of each delta.
|
||||
|
||||
This also supports all of the parsing utilities that `.parse()` does.
|
||||
|
||||
Unlike `.create(stream=True)`, the `.stream()` method requires usage within a context manager to prevent accidental leakage of the response:
|
||||
|
||||
```py
|
||||
async with client.beta.chat.completions.stream(
|
||||
model="gpt-4o-2024-08-06",
|
||||
messages=[...],
|
||||
) as stream:
|
||||
async for event in stream:
|
||||
if event.type == "content.delta":
|
||||
print(event.delta, flush=True, end="")
|
||||
```
|
||||
|
||||
When the context manager is entered, an `AsyncChatCompletionStream` instance is returned which, like `.create(stream=True)` is an async iterator. The full list of events that are yielded by the iterator are outlined in [these docs](https://github.com/openai/openai-python/blob/main/helpers.md#chat-completions-events).
|
||||
|
||||
When the context manager exits, the response will be closed, however the `stream` instance is still available outside
|
||||
the context manager.
|
||||
"""
|
||||
_validate_input_tools(tools)
|
||||
|
||||
extra_headers = {
|
||||
"X-Stainless-Helper-Method": "beta.chat.completions.stream",
|
||||
**(extra_headers or {}),
|
||||
}
|
||||
|
||||
api_request = self._client.chat.completions.create(
|
||||
messages=messages,
|
||||
model=model,
|
||||
audio=audio,
|
||||
stream=True,
|
||||
response_format=_type_to_response_format(response_format),
|
||||
frequency_penalty=frequency_penalty,
|
||||
function_call=function_call,
|
||||
functions=functions,
|
||||
logit_bias=logit_bias,
|
||||
logprobs=logprobs,
|
||||
max_completion_tokens=max_completion_tokens,
|
||||
max_tokens=max_tokens,
|
||||
metadata=metadata,
|
||||
modalities=modalities,
|
||||
n=n,
|
||||
parallel_tool_calls=parallel_tool_calls,
|
||||
prediction=prediction,
|
||||
presence_penalty=presence_penalty,
|
||||
reasoning_effort=reasoning_effort,
|
||||
seed=seed,
|
||||
service_tier=service_tier,
|
||||
stop=stop,
|
||||
store=store,
|
||||
stream_options=stream_options,
|
||||
temperature=temperature,
|
||||
tool_choice=tool_choice,
|
||||
tools=tools,
|
||||
top_logprobs=top_logprobs,
|
||||
top_p=top_p,
|
||||
user=user,
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
)
|
||||
return AsyncChatCompletionStreamManager(
|
||||
api_request,
|
||||
response_format=response_format,
|
||||
input_tools=tools,
|
||||
)
|
||||
|
||||
|
||||
class CompletionsWithRawResponse:
|
||||
def __init__(self, completions: Completions) -> None:
|
||||
self._completions = completions
|
||||
|
||||
self.parse = _legacy_response.to_raw_response_wrapper(
|
||||
completions.parse,
|
||||
)
|
||||
|
||||
|
||||
class AsyncCompletionsWithRawResponse:
|
||||
def __init__(self, completions: AsyncCompletions) -> None:
|
||||
self._completions = completions
|
||||
|
||||
self.parse = _legacy_response.async_to_raw_response_wrapper(
|
||||
completions.parse,
|
||||
)
|
||||
|
||||
|
||||
class CompletionsWithStreamingResponse:
|
||||
def __init__(self, completions: Completions) -> None:
|
||||
self._completions = completions
|
||||
|
||||
self.parse = to_streamed_response_wrapper(
|
||||
completions.parse,
|
||||
)
|
||||
|
||||
|
||||
class AsyncCompletionsWithStreamingResponse:
|
||||
def __init__(self, completions: AsyncCompletions) -> None:
|
||||
self._completions = completions
|
||||
|
||||
self.parse = async_to_streamed_response_wrapper(
|
||||
completions.parse,
|
||||
)
|
||||
@@ -0,0 +1,33 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from .realtime import (
|
||||
Realtime,
|
||||
AsyncRealtime,
|
||||
RealtimeWithRawResponse,
|
||||
AsyncRealtimeWithRawResponse,
|
||||
RealtimeWithStreamingResponse,
|
||||
AsyncRealtimeWithStreamingResponse,
|
||||
)
|
||||
from .sessions import (
|
||||
Sessions,
|
||||
AsyncSessions,
|
||||
SessionsWithRawResponse,
|
||||
AsyncSessionsWithRawResponse,
|
||||
SessionsWithStreamingResponse,
|
||||
AsyncSessionsWithStreamingResponse,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"Sessions",
|
||||
"AsyncSessions",
|
||||
"SessionsWithRawResponse",
|
||||
"AsyncSessionsWithRawResponse",
|
||||
"SessionsWithStreamingResponse",
|
||||
"AsyncSessionsWithStreamingResponse",
|
||||
"Realtime",
|
||||
"AsyncRealtime",
|
||||
"RealtimeWithRawResponse",
|
||||
"AsyncRealtimeWithRawResponse",
|
||||
"RealtimeWithStreamingResponse",
|
||||
"AsyncRealtimeWithStreamingResponse",
|
||||
]
|
||||
@@ -0,0 +1,966 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from types import TracebackType
|
||||
from typing import TYPE_CHECKING, Any, Iterator, cast
|
||||
from typing_extensions import AsyncIterator
|
||||
|
||||
import httpx
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .sessions import (
|
||||
Sessions,
|
||||
AsyncSessions,
|
||||
SessionsWithRawResponse,
|
||||
AsyncSessionsWithRawResponse,
|
||||
SessionsWithStreamingResponse,
|
||||
AsyncSessionsWithStreamingResponse,
|
||||
)
|
||||
from ...._types import NOT_GIVEN, Query, Headers, NotGiven
|
||||
from ...._utils import (
|
||||
is_azure_client,
|
||||
maybe_transform,
|
||||
strip_not_given,
|
||||
async_maybe_transform,
|
||||
is_async_azure_client,
|
||||
)
|
||||
from ...._compat import cached_property
|
||||
from ...._models import construct_type_unchecked
|
||||
from ...._resource import SyncAPIResource, AsyncAPIResource
|
||||
from ...._exceptions import OpenAIError
|
||||
from ...._base_client import _merge_mappings
|
||||
from ....types.beta.realtime import session_update_event_param, response_create_event_param
|
||||
from ....types.websocket_connection_options import WebsocketConnectionOptions
|
||||
from ....types.beta.realtime.realtime_client_event import RealtimeClientEvent
|
||||
from ....types.beta.realtime.realtime_server_event import RealtimeServerEvent
|
||||
from ....types.beta.realtime.conversation_item_param import ConversationItemParam
|
||||
from ....types.beta.realtime.realtime_client_event_param import RealtimeClientEventParam
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from websockets.sync.client import ClientConnection as WebsocketConnection
|
||||
from websockets.asyncio.client import ClientConnection as AsyncWebsocketConnection
|
||||
|
||||
from ...._client import OpenAI, AsyncOpenAI
|
||||
|
||||
__all__ = ["Realtime", "AsyncRealtime"]
|
||||
|
||||
log: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Realtime(SyncAPIResource):
|
||||
@cached_property
|
||||
def sessions(self) -> Sessions:
|
||||
return Sessions(self._client)
|
||||
|
||||
@cached_property
|
||||
def with_raw_response(self) -> RealtimeWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return RealtimeWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> RealtimeWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return RealtimeWithStreamingResponse(self)
|
||||
|
||||
def connect(
|
||||
self,
|
||||
*,
|
||||
model: str,
|
||||
extra_query: Query = {},
|
||||
extra_headers: Headers = {},
|
||||
websocket_connection_options: WebsocketConnectionOptions = {},
|
||||
) -> RealtimeConnectionManager:
|
||||
"""
|
||||
The Realtime API enables you to build low-latency, multi-modal conversational experiences. It currently supports text and audio as both input and output, as well as function calling.
|
||||
|
||||
Some notable benefits of the API include:
|
||||
|
||||
- Native speech-to-speech: Skipping an intermediate text format means low latency and nuanced output.
|
||||
- Natural, steerable voices: The models have natural inflection and can laugh, whisper, and adhere to tone direction.
|
||||
- Simultaneous multimodal output: Text is useful for moderation; faster-than-realtime audio ensures stable playback.
|
||||
|
||||
The Realtime API is a stateful, event-based API that communicates over a WebSocket.
|
||||
"""
|
||||
return RealtimeConnectionManager(
|
||||
client=self._client,
|
||||
extra_query=extra_query,
|
||||
extra_headers=extra_headers,
|
||||
websocket_connection_options=websocket_connection_options,
|
||||
model=model,
|
||||
)
|
||||
|
||||
|
||||
class AsyncRealtime(AsyncAPIResource):
|
||||
@cached_property
|
||||
def sessions(self) -> AsyncSessions:
|
||||
return AsyncSessions(self._client)
|
||||
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncRealtimeWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncRealtimeWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncRealtimeWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncRealtimeWithStreamingResponse(self)
|
||||
|
||||
def connect(
|
||||
self,
|
||||
*,
|
||||
model: str,
|
||||
extra_query: Query = {},
|
||||
extra_headers: Headers = {},
|
||||
websocket_connection_options: WebsocketConnectionOptions = {},
|
||||
) -> AsyncRealtimeConnectionManager:
|
||||
"""
|
||||
The Realtime API enables you to build low-latency, multi-modal conversational experiences. It currently supports text and audio as both input and output, as well as function calling.
|
||||
|
||||
Some notable benefits of the API include:
|
||||
|
||||
- Native speech-to-speech: Skipping an intermediate text format means low latency and nuanced output.
|
||||
- Natural, steerable voices: The models have natural inflection and can laugh, whisper, and adhere to tone direction.
|
||||
- Simultaneous multimodal output: Text is useful for moderation; faster-than-realtime audio ensures stable playback.
|
||||
|
||||
The Realtime API is a stateful, event-based API that communicates over a WebSocket.
|
||||
"""
|
||||
return AsyncRealtimeConnectionManager(
|
||||
client=self._client,
|
||||
extra_query=extra_query,
|
||||
extra_headers=extra_headers,
|
||||
websocket_connection_options=websocket_connection_options,
|
||||
model=model,
|
||||
)
|
||||
|
||||
|
||||
class RealtimeWithRawResponse:
|
||||
def __init__(self, realtime: Realtime) -> None:
|
||||
self._realtime = realtime
|
||||
|
||||
@cached_property
|
||||
def sessions(self) -> SessionsWithRawResponse:
|
||||
return SessionsWithRawResponse(self._realtime.sessions)
|
||||
|
||||
|
||||
class AsyncRealtimeWithRawResponse:
|
||||
def __init__(self, realtime: AsyncRealtime) -> None:
|
||||
self._realtime = realtime
|
||||
|
||||
@cached_property
|
||||
def sessions(self) -> AsyncSessionsWithRawResponse:
|
||||
return AsyncSessionsWithRawResponse(self._realtime.sessions)
|
||||
|
||||
|
||||
class RealtimeWithStreamingResponse:
|
||||
def __init__(self, realtime: Realtime) -> None:
|
||||
self._realtime = realtime
|
||||
|
||||
@cached_property
|
||||
def sessions(self) -> SessionsWithStreamingResponse:
|
||||
return SessionsWithStreamingResponse(self._realtime.sessions)
|
||||
|
||||
|
||||
class AsyncRealtimeWithStreamingResponse:
|
||||
def __init__(self, realtime: AsyncRealtime) -> None:
|
||||
self._realtime = realtime
|
||||
|
||||
@cached_property
|
||||
def sessions(self) -> AsyncSessionsWithStreamingResponse:
|
||||
return AsyncSessionsWithStreamingResponse(self._realtime.sessions)
|
||||
|
||||
|
||||
class AsyncRealtimeConnection:
|
||||
"""Represents a live websocket connection to the Realtime API"""
|
||||
|
||||
session: AsyncRealtimeSessionResource
|
||||
response: AsyncRealtimeResponseResource
|
||||
conversation: AsyncRealtimeConversationResource
|
||||
input_audio_buffer: AsyncRealtimeInputAudioBufferResource
|
||||
|
||||
_connection: AsyncWebsocketConnection
|
||||
|
||||
def __init__(self, connection: AsyncWebsocketConnection) -> None:
|
||||
self._connection = connection
|
||||
|
||||
self.session = AsyncRealtimeSessionResource(self)
|
||||
self.response = AsyncRealtimeResponseResource(self)
|
||||
self.conversation = AsyncRealtimeConversationResource(self)
|
||||
self.input_audio_buffer = AsyncRealtimeInputAudioBufferResource(self)
|
||||
|
||||
async def __aiter__(self) -> AsyncIterator[RealtimeServerEvent]:
|
||||
"""
|
||||
An infinite-iterator that will continue to yield events until
|
||||
the connection is closed.
|
||||
"""
|
||||
from websockets.exceptions import ConnectionClosedOK
|
||||
|
||||
try:
|
||||
while True:
|
||||
yield await self.recv()
|
||||
except ConnectionClosedOK:
|
||||
return
|
||||
|
||||
async def recv(self) -> RealtimeServerEvent:
|
||||
"""
|
||||
Receive the next message from the connection and parses it into a `RealtimeServerEvent` object.
|
||||
|
||||
Canceling this method is safe. There's no risk of losing data.
|
||||
"""
|
||||
return self.parse_event(await self.recv_bytes())
|
||||
|
||||
async def recv_bytes(self) -> bytes:
|
||||
"""Receive the next message from the connection as raw bytes.
|
||||
|
||||
Canceling this method is safe. There's no risk of losing data.
|
||||
|
||||
If you want to parse the message into a `RealtimeServerEvent` object like `.recv()` does,
|
||||
then you can call `.parse_event(data)`.
|
||||
"""
|
||||
message = await self._connection.recv(decode=False)
|
||||
log.debug(f"Received websocket message: %s", message)
|
||||
if not isinstance(message, bytes):
|
||||
# passing `decode=False` should always result in us getting `bytes` back
|
||||
raise TypeError(f"Expected `.recv(decode=False)` to return `bytes` but got {type(message)}")
|
||||
|
||||
return message
|
||||
|
||||
async def send(self, event: RealtimeClientEvent | RealtimeClientEventParam) -> None:
|
||||
data = (
|
||||
event.to_json(use_api_names=True, exclude_defaults=True, exclude_unset=True)
|
||||
if isinstance(event, BaseModel)
|
||||
else json.dumps(await async_maybe_transform(event, RealtimeClientEventParam))
|
||||
)
|
||||
await self._connection.send(data)
|
||||
|
||||
async def close(self, *, code: int = 1000, reason: str = "") -> None:
|
||||
await self._connection.close(code=code, reason=reason)
|
||||
|
||||
def parse_event(self, data: str | bytes) -> RealtimeServerEvent:
|
||||
"""
|
||||
Converts a raw `str` or `bytes` message into a `RealtimeServerEvent` object.
|
||||
|
||||
This is helpful if you're using `.recv_bytes()`.
|
||||
"""
|
||||
return cast(
|
||||
RealtimeServerEvent, construct_type_unchecked(value=json.loads(data), type_=cast(Any, RealtimeServerEvent))
|
||||
)
|
||||
|
||||
|
||||
class AsyncRealtimeConnectionManager:
|
||||
"""
|
||||
Context manager over a `AsyncRealtimeConnection` that is returned by `beta.realtime.connect()`
|
||||
|
||||
This context manager ensures that the connection will be closed when it exits.
|
||||
|
||||
---
|
||||
|
||||
Note that if your application doesn't work well with the context manager approach then you
|
||||
can call the `.enter()` method directly to initiate a connection.
|
||||
|
||||
**Warning**: You must remember to close the connection with `.close()`.
|
||||
|
||||
```py
|
||||
connection = await client.beta.realtime.connect(...).enter()
|
||||
# ...
|
||||
await connection.close()
|
||||
```
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
client: AsyncOpenAI,
|
||||
model: str,
|
||||
extra_query: Query,
|
||||
extra_headers: Headers,
|
||||
websocket_connection_options: WebsocketConnectionOptions,
|
||||
) -> None:
|
||||
self.__client = client
|
||||
self.__model = model
|
||||
self.__connection: AsyncRealtimeConnection | None = None
|
||||
self.__extra_query = extra_query
|
||||
self.__extra_headers = extra_headers
|
||||
self.__websocket_connection_options = websocket_connection_options
|
||||
|
||||
async def __aenter__(self) -> AsyncRealtimeConnection:
|
||||
"""
|
||||
👋 If your application doesn't work well with the context manager approach then you
|
||||
can call this method directly to initiate a connection.
|
||||
|
||||
**Warning**: You must remember to close the connection with `.close()`.
|
||||
|
||||
```py
|
||||
connection = await client.beta.realtime.connect(...).enter()
|
||||
# ...
|
||||
await connection.close()
|
||||
```
|
||||
"""
|
||||
try:
|
||||
from websockets.asyncio.client import connect
|
||||
except ImportError as exc:
|
||||
raise OpenAIError("You need to install `openai[realtime]` to use this method") from exc
|
||||
|
||||
extra_query = self.__extra_query
|
||||
auth_headers = self.__client.auth_headers
|
||||
if is_async_azure_client(self.__client):
|
||||
extra_query, auth_headers = await self.__client._configure_realtime(self.__model, extra_query)
|
||||
|
||||
url = self._prepare_url().copy_with(
|
||||
params={
|
||||
**self.__client.base_url.params,
|
||||
"model": self.__model,
|
||||
**extra_query,
|
||||
},
|
||||
)
|
||||
log.debug("Connecting to %s", url)
|
||||
if self.__websocket_connection_options:
|
||||
log.debug("Connection options: %s", self.__websocket_connection_options)
|
||||
|
||||
self.__connection = AsyncRealtimeConnection(
|
||||
await connect(
|
||||
str(url),
|
||||
user_agent_header=self.__client.user_agent,
|
||||
additional_headers=_merge_mappings(
|
||||
{
|
||||
**auth_headers,
|
||||
"OpenAI-Beta": "realtime=v1",
|
||||
},
|
||||
self.__extra_headers,
|
||||
),
|
||||
**self.__websocket_connection_options,
|
||||
)
|
||||
)
|
||||
|
||||
return self.__connection
|
||||
|
||||
enter = __aenter__
|
||||
|
||||
def _prepare_url(self) -> httpx.URL:
|
||||
if self.__client.websocket_base_url is not None:
|
||||
base_url = httpx.URL(self.__client.websocket_base_url)
|
||||
else:
|
||||
base_url = self.__client._base_url.copy_with(scheme="wss")
|
||||
|
||||
merge_raw_path = base_url.raw_path.rstrip(b"/") + b"/realtime"
|
||||
return base_url.copy_with(raw_path=merge_raw_path)
|
||||
|
||||
async def __aexit__(
|
||||
self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None
|
||||
) -> None:
|
||||
if self.__connection is not None:
|
||||
await self.__connection.close()
|
||||
|
||||
|
||||
class RealtimeConnection:
|
||||
"""Represents a live websocket connection to the Realtime API"""
|
||||
|
||||
session: RealtimeSessionResource
|
||||
response: RealtimeResponseResource
|
||||
conversation: RealtimeConversationResource
|
||||
input_audio_buffer: RealtimeInputAudioBufferResource
|
||||
|
||||
_connection: WebsocketConnection
|
||||
|
||||
def __init__(self, connection: WebsocketConnection) -> None:
|
||||
self._connection = connection
|
||||
|
||||
self.session = RealtimeSessionResource(self)
|
||||
self.response = RealtimeResponseResource(self)
|
||||
self.conversation = RealtimeConversationResource(self)
|
||||
self.input_audio_buffer = RealtimeInputAudioBufferResource(self)
|
||||
|
||||
def __iter__(self) -> Iterator[RealtimeServerEvent]:
|
||||
"""
|
||||
An infinite-iterator that will continue to yield events until
|
||||
the connection is closed.
|
||||
"""
|
||||
from websockets.exceptions import ConnectionClosedOK
|
||||
|
||||
try:
|
||||
while True:
|
||||
yield self.recv()
|
||||
except ConnectionClosedOK:
|
||||
return
|
||||
|
||||
def recv(self) -> RealtimeServerEvent:
|
||||
"""
|
||||
Receive the next message from the connection and parses it into a `RealtimeServerEvent` object.
|
||||
|
||||
Canceling this method is safe. There's no risk of losing data.
|
||||
"""
|
||||
return self.parse_event(self.recv_bytes())
|
||||
|
||||
def recv_bytes(self) -> bytes:
|
||||
"""Receive the next message from the connection as raw bytes.
|
||||
|
||||
Canceling this method is safe. There's no risk of losing data.
|
||||
|
||||
If you want to parse the message into a `RealtimeServerEvent` object like `.recv()` does,
|
||||
then you can call `.parse_event(data)`.
|
||||
"""
|
||||
message = self._connection.recv(decode=False)
|
||||
log.debug(f"Received websocket message: %s", message)
|
||||
if not isinstance(message, bytes):
|
||||
# passing `decode=False` should always result in us getting `bytes` back
|
||||
raise TypeError(f"Expected `.recv(decode=False)` to return `bytes` but got {type(message)}")
|
||||
|
||||
return message
|
||||
|
||||
def send(self, event: RealtimeClientEvent | RealtimeClientEventParam) -> None:
|
||||
data = (
|
||||
event.to_json(use_api_names=True, exclude_defaults=True, exclude_unset=True)
|
||||
if isinstance(event, BaseModel)
|
||||
else json.dumps(maybe_transform(event, RealtimeClientEventParam))
|
||||
)
|
||||
self._connection.send(data)
|
||||
|
||||
def close(self, *, code: int = 1000, reason: str = "") -> None:
|
||||
self._connection.close(code=code, reason=reason)
|
||||
|
||||
def parse_event(self, data: str | bytes) -> RealtimeServerEvent:
|
||||
"""
|
||||
Converts a raw `str` or `bytes` message into a `RealtimeServerEvent` object.
|
||||
|
||||
This is helpful if you're using `.recv_bytes()`.
|
||||
"""
|
||||
return cast(
|
||||
RealtimeServerEvent, construct_type_unchecked(value=json.loads(data), type_=cast(Any, RealtimeServerEvent))
|
||||
)
|
||||
|
||||
|
||||
class RealtimeConnectionManager:
|
||||
"""
|
||||
Context manager over a `RealtimeConnection` that is returned by `beta.realtime.connect()`
|
||||
|
||||
This context manager ensures that the connection will be closed when it exits.
|
||||
|
||||
---
|
||||
|
||||
Note that if your application doesn't work well with the context manager approach then you
|
||||
can call the `.enter()` method directly to initiate a connection.
|
||||
|
||||
**Warning**: You must remember to close the connection with `.close()`.
|
||||
|
||||
```py
|
||||
connection = client.beta.realtime.connect(...).enter()
|
||||
# ...
|
||||
connection.close()
|
||||
```
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
client: OpenAI,
|
||||
model: str,
|
||||
extra_query: Query,
|
||||
extra_headers: Headers,
|
||||
websocket_connection_options: WebsocketConnectionOptions,
|
||||
) -> None:
|
||||
self.__client = client
|
||||
self.__model = model
|
||||
self.__connection: RealtimeConnection | None = None
|
||||
self.__extra_query = extra_query
|
||||
self.__extra_headers = extra_headers
|
||||
self.__websocket_connection_options = websocket_connection_options
|
||||
|
||||
def __enter__(self) -> RealtimeConnection:
|
||||
"""
|
||||
👋 If your application doesn't work well with the context manager approach then you
|
||||
can call this method directly to initiate a connection.
|
||||
|
||||
**Warning**: You must remember to close the connection with `.close()`.
|
||||
|
||||
```py
|
||||
connection = client.beta.realtime.connect(...).enter()
|
||||
# ...
|
||||
connection.close()
|
||||
```
|
||||
"""
|
||||
try:
|
||||
from websockets.sync.client import connect
|
||||
except ImportError as exc:
|
||||
raise OpenAIError("You need to install `openai[realtime]` to use this method") from exc
|
||||
|
||||
extra_query = self.__extra_query
|
||||
auth_headers = self.__client.auth_headers
|
||||
if is_azure_client(self.__client):
|
||||
extra_query, auth_headers = self.__client._configure_realtime(self.__model, extra_query)
|
||||
|
||||
url = self._prepare_url().copy_with(
|
||||
params={
|
||||
**self.__client.base_url.params,
|
||||
"model": self.__model,
|
||||
**extra_query,
|
||||
},
|
||||
)
|
||||
log.debug("Connecting to %s", url)
|
||||
if self.__websocket_connection_options:
|
||||
log.debug("Connection options: %s", self.__websocket_connection_options)
|
||||
|
||||
self.__connection = RealtimeConnection(
|
||||
connect(
|
||||
str(url),
|
||||
user_agent_header=self.__client.user_agent,
|
||||
additional_headers=_merge_mappings(
|
||||
{
|
||||
**auth_headers,
|
||||
"OpenAI-Beta": "realtime=v1",
|
||||
},
|
||||
self.__extra_headers,
|
||||
),
|
||||
**self.__websocket_connection_options,
|
||||
)
|
||||
)
|
||||
|
||||
return self.__connection
|
||||
|
||||
enter = __enter__
|
||||
|
||||
def _prepare_url(self) -> httpx.URL:
|
||||
if self.__client.websocket_base_url is not None:
|
||||
base_url = httpx.URL(self.__client.websocket_base_url)
|
||||
else:
|
||||
base_url = self.__client._base_url.copy_with(scheme="wss")
|
||||
|
||||
merge_raw_path = base_url.raw_path.rstrip(b"/") + b"/realtime"
|
||||
return base_url.copy_with(raw_path=merge_raw_path)
|
||||
|
||||
def __exit__(
|
||||
self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None
|
||||
) -> None:
|
||||
if self.__connection is not None:
|
||||
self.__connection.close()
|
||||
|
||||
|
||||
class BaseRealtimeConnectionResource:
|
||||
def __init__(self, connection: RealtimeConnection) -> None:
|
||||
self._connection = connection
|
||||
|
||||
|
||||
class RealtimeSessionResource(BaseRealtimeConnectionResource):
|
||||
def update(self, *, session: session_update_event_param.Session, event_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""Send this event to update the session’s default configuration.
|
||||
|
||||
The client may
|
||||
send this event at any time to update the session configuration, and any
|
||||
field may be updated at any time, except for "voice". The server will respond
|
||||
with a `session.updated` event that shows the full effective configuration.
|
||||
Only fields that are present are updated, thus the correct way to clear a
|
||||
field like "instructions" is to pass an empty string.
|
||||
"""
|
||||
self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "session.update", "session": session, "event_id": event_id}),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class RealtimeResponseResource(BaseRealtimeConnectionResource):
|
||||
def cancel(self, *, event_id: str | NotGiven = NOT_GIVEN, response_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""Send this event to cancel an in-progress response.
|
||||
|
||||
The server will respond
|
||||
with a `response.cancelled` event or an error if there is no response to
|
||||
cancel.
|
||||
"""
|
||||
self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "response.cancel", "event_id": event_id, "response_id": response_id}),
|
||||
)
|
||||
)
|
||||
|
||||
def create(
|
||||
self,
|
||||
*,
|
||||
event_id: str | NotGiven = NOT_GIVEN,
|
||||
response: response_create_event_param.Response | NotGiven = NOT_GIVEN,
|
||||
) -> None:
|
||||
"""
|
||||
This event instructs the server to create a Response, which means triggering
|
||||
model inference. When in Server VAD mode, the server will create Responses
|
||||
automatically.
|
||||
|
||||
A Response will include at least one Item, and may have two, in which case
|
||||
the second will be a function call. These Items will be appended to the
|
||||
conversation history.
|
||||
|
||||
The server will respond with a `response.created` event, events for Items
|
||||
and content created, and finally a `response.done` event to indicate the
|
||||
Response is complete.
|
||||
|
||||
The `response.create` event includes inference configuration like
|
||||
`instructions`, and `temperature`. These fields will override the Session's
|
||||
configuration for this Response only.
|
||||
"""
|
||||
self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "response.create", "event_id": event_id, "response": response}),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class RealtimeConversationResource(BaseRealtimeConnectionResource):
|
||||
@cached_property
|
||||
def item(self) -> RealtimeConversationItemResource:
|
||||
return RealtimeConversationItemResource(self._connection)
|
||||
|
||||
|
||||
class RealtimeConversationItemResource(BaseRealtimeConnectionResource):
|
||||
def delete(self, *, item_id: str, event_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""Send this event when you want to remove any item from the conversation
|
||||
history.
|
||||
|
||||
The server will respond with a `conversation.item.deleted` event,
|
||||
unless the item does not exist in the conversation history, in which case the
|
||||
server will respond with an error.
|
||||
"""
|
||||
self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "conversation.item.delete", "item_id": item_id, "event_id": event_id}),
|
||||
)
|
||||
)
|
||||
|
||||
def create(
|
||||
self,
|
||||
*,
|
||||
item: ConversationItemParam,
|
||||
event_id: str | NotGiven = NOT_GIVEN,
|
||||
previous_item_id: str | NotGiven = NOT_GIVEN,
|
||||
) -> None:
|
||||
"""
|
||||
Add a new Item to the Conversation's context, including messages, function
|
||||
calls, and function call responses. This event can be used both to populate a
|
||||
"history" of the conversation and to add new items mid-stream, but has the
|
||||
current limitation that it cannot populate assistant audio messages.
|
||||
|
||||
If successful, the server will respond with a `conversation.item.created`
|
||||
event, otherwise an `error` event will be sent.
|
||||
"""
|
||||
self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given(
|
||||
{
|
||||
"type": "conversation.item.create",
|
||||
"item": item,
|
||||
"event_id": event_id,
|
||||
"previous_item_id": previous_item_id,
|
||||
}
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
def truncate(
|
||||
self, *, audio_end_ms: int, content_index: int, item_id: str, event_id: str | NotGiven = NOT_GIVEN
|
||||
) -> None:
|
||||
"""Send this event to truncate a previous assistant message’s audio.
|
||||
|
||||
The server
|
||||
will produce audio faster than realtime, so this event is useful when the user
|
||||
interrupts to truncate audio that has already been sent to the client but not
|
||||
yet played. This will synchronize the server's understanding of the audio with
|
||||
the client's playback.
|
||||
|
||||
Truncating audio will delete the server-side text transcript to ensure there
|
||||
is not text in the context that hasn't been heard by the user.
|
||||
|
||||
If successful, the server will respond with a `conversation.item.truncated`
|
||||
event.
|
||||
"""
|
||||
self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given(
|
||||
{
|
||||
"type": "conversation.item.truncate",
|
||||
"audio_end_ms": audio_end_ms,
|
||||
"content_index": content_index,
|
||||
"item_id": item_id,
|
||||
"event_id": event_id,
|
||||
}
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class RealtimeInputAudioBufferResource(BaseRealtimeConnectionResource):
|
||||
def clear(self, *, event_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""Send this event to clear the audio bytes in the buffer.
|
||||
|
||||
The server will
|
||||
respond with an `input_audio_buffer.cleared` event.
|
||||
"""
|
||||
self._connection.send(
|
||||
cast(RealtimeClientEventParam, strip_not_given({"type": "input_audio_buffer.clear", "event_id": event_id}))
|
||||
)
|
||||
|
||||
def commit(self, *, event_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""
|
||||
Send this event to commit the user input audio buffer, which will create a
|
||||
new user message item in the conversation. This event will produce an error
|
||||
if the input audio buffer is empty. When in Server VAD mode, the client does
|
||||
not need to send this event, the server will commit the audio buffer
|
||||
automatically.
|
||||
|
||||
Committing the input audio buffer will trigger input audio transcription
|
||||
(if enabled in session configuration), but it will not create a response
|
||||
from the model. The server will respond with an `input_audio_buffer.committed`
|
||||
event.
|
||||
"""
|
||||
self._connection.send(
|
||||
cast(RealtimeClientEventParam, strip_not_given({"type": "input_audio_buffer.commit", "event_id": event_id}))
|
||||
)
|
||||
|
||||
def append(self, *, audio: str, event_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""Send this event to append audio bytes to the input audio buffer.
|
||||
|
||||
The audio
|
||||
buffer is temporary storage you can write to and later commit. In Server VAD
|
||||
mode, the audio buffer is used to detect speech and the server will decide
|
||||
when to commit. When Server VAD is disabled, you must commit the audio buffer
|
||||
manually.
|
||||
|
||||
The client may choose how much audio to place in each event up to a maximum
|
||||
of 15 MiB, for example streaming smaller chunks from the client may allow the
|
||||
VAD to be more responsive. Unlike made other client events, the server will
|
||||
not send a confirmation response to this event.
|
||||
"""
|
||||
self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "input_audio_buffer.append", "audio": audio, "event_id": event_id}),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class BaseAsyncRealtimeConnectionResource:
|
||||
def __init__(self, connection: AsyncRealtimeConnection) -> None:
|
||||
self._connection = connection
|
||||
|
||||
|
||||
class AsyncRealtimeSessionResource(BaseAsyncRealtimeConnectionResource):
|
||||
async def update(
|
||||
self, *, session: session_update_event_param.Session, event_id: str | NotGiven = NOT_GIVEN
|
||||
) -> None:
|
||||
"""Send this event to update the session’s default configuration.
|
||||
|
||||
The client may
|
||||
send this event at any time to update the session configuration, and any
|
||||
field may be updated at any time, except for "voice". The server will respond
|
||||
with a `session.updated` event that shows the full effective configuration.
|
||||
Only fields that are present are updated, thus the correct way to clear a
|
||||
field like "instructions" is to pass an empty string.
|
||||
"""
|
||||
await self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "session.update", "session": session, "event_id": event_id}),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class AsyncRealtimeResponseResource(BaseAsyncRealtimeConnectionResource):
|
||||
async def cancel(self, *, event_id: str | NotGiven = NOT_GIVEN, response_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""Send this event to cancel an in-progress response.
|
||||
|
||||
The server will respond
|
||||
with a `response.cancelled` event or an error if there is no response to
|
||||
cancel.
|
||||
"""
|
||||
await self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "response.cancel", "event_id": event_id, "response_id": response_id}),
|
||||
)
|
||||
)
|
||||
|
||||
async def create(
|
||||
self,
|
||||
*,
|
||||
event_id: str | NotGiven = NOT_GIVEN,
|
||||
response: response_create_event_param.Response | NotGiven = NOT_GIVEN,
|
||||
) -> None:
|
||||
"""
|
||||
This event instructs the server to create a Response, which means triggering
|
||||
model inference. When in Server VAD mode, the server will create Responses
|
||||
automatically.
|
||||
|
||||
A Response will include at least one Item, and may have two, in which case
|
||||
the second will be a function call. These Items will be appended to the
|
||||
conversation history.
|
||||
|
||||
The server will respond with a `response.created` event, events for Items
|
||||
and content created, and finally a `response.done` event to indicate the
|
||||
Response is complete.
|
||||
|
||||
The `response.create` event includes inference configuration like
|
||||
`instructions`, and `temperature`. These fields will override the Session's
|
||||
configuration for this Response only.
|
||||
"""
|
||||
await self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "response.create", "event_id": event_id, "response": response}),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class AsyncRealtimeConversationResource(BaseAsyncRealtimeConnectionResource):
|
||||
@cached_property
|
||||
def item(self) -> AsyncRealtimeConversationItemResource:
|
||||
return AsyncRealtimeConversationItemResource(self._connection)
|
||||
|
||||
|
||||
class AsyncRealtimeConversationItemResource(BaseAsyncRealtimeConnectionResource):
|
||||
async def delete(self, *, item_id: str, event_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""Send this event when you want to remove any item from the conversation
|
||||
history.
|
||||
|
||||
The server will respond with a `conversation.item.deleted` event,
|
||||
unless the item does not exist in the conversation history, in which case the
|
||||
server will respond with an error.
|
||||
"""
|
||||
await self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "conversation.item.delete", "item_id": item_id, "event_id": event_id}),
|
||||
)
|
||||
)
|
||||
|
||||
async def create(
|
||||
self,
|
||||
*,
|
||||
item: ConversationItemParam,
|
||||
event_id: str | NotGiven = NOT_GIVEN,
|
||||
previous_item_id: str | NotGiven = NOT_GIVEN,
|
||||
) -> None:
|
||||
"""
|
||||
Add a new Item to the Conversation's context, including messages, function
|
||||
calls, and function call responses. This event can be used both to populate a
|
||||
"history" of the conversation and to add new items mid-stream, but has the
|
||||
current limitation that it cannot populate assistant audio messages.
|
||||
|
||||
If successful, the server will respond with a `conversation.item.created`
|
||||
event, otherwise an `error` event will be sent.
|
||||
"""
|
||||
await self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given(
|
||||
{
|
||||
"type": "conversation.item.create",
|
||||
"item": item,
|
||||
"event_id": event_id,
|
||||
"previous_item_id": previous_item_id,
|
||||
}
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
async def truncate(
|
||||
self, *, audio_end_ms: int, content_index: int, item_id: str, event_id: str | NotGiven = NOT_GIVEN
|
||||
) -> None:
|
||||
"""Send this event to truncate a previous assistant message’s audio.
|
||||
|
||||
The server
|
||||
will produce audio faster than realtime, so this event is useful when the user
|
||||
interrupts to truncate audio that has already been sent to the client but not
|
||||
yet played. This will synchronize the server's understanding of the audio with
|
||||
the client's playback.
|
||||
|
||||
Truncating audio will delete the server-side text transcript to ensure there
|
||||
is not text in the context that hasn't been heard by the user.
|
||||
|
||||
If successful, the server will respond with a `conversation.item.truncated`
|
||||
event.
|
||||
"""
|
||||
await self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given(
|
||||
{
|
||||
"type": "conversation.item.truncate",
|
||||
"audio_end_ms": audio_end_ms,
|
||||
"content_index": content_index,
|
||||
"item_id": item_id,
|
||||
"event_id": event_id,
|
||||
}
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class AsyncRealtimeInputAudioBufferResource(BaseAsyncRealtimeConnectionResource):
|
||||
async def clear(self, *, event_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""Send this event to clear the audio bytes in the buffer.
|
||||
|
||||
The server will
|
||||
respond with an `input_audio_buffer.cleared` event.
|
||||
"""
|
||||
await self._connection.send(
|
||||
cast(RealtimeClientEventParam, strip_not_given({"type": "input_audio_buffer.clear", "event_id": event_id}))
|
||||
)
|
||||
|
||||
async def commit(self, *, event_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""
|
||||
Send this event to commit the user input audio buffer, which will create a
|
||||
new user message item in the conversation. This event will produce an error
|
||||
if the input audio buffer is empty. When in Server VAD mode, the client does
|
||||
not need to send this event, the server will commit the audio buffer
|
||||
automatically.
|
||||
|
||||
Committing the input audio buffer will trigger input audio transcription
|
||||
(if enabled in session configuration), but it will not create a response
|
||||
from the model. The server will respond with an `input_audio_buffer.committed`
|
||||
event.
|
||||
"""
|
||||
await self._connection.send(
|
||||
cast(RealtimeClientEventParam, strip_not_given({"type": "input_audio_buffer.commit", "event_id": event_id}))
|
||||
)
|
||||
|
||||
async def append(self, *, audio: str, event_id: str | NotGiven = NOT_GIVEN) -> None:
|
||||
"""Send this event to append audio bytes to the input audio buffer.
|
||||
|
||||
The audio
|
||||
buffer is temporary storage you can write to and later commit. In Server VAD
|
||||
mode, the audio buffer is used to detect speech and the server will decide
|
||||
when to commit. When Server VAD is disabled, you must commit the audio buffer
|
||||
manually.
|
||||
|
||||
The client may choose how much audio to place in each event up to a maximum
|
||||
of 15 MiB, for example streaming smaller chunks from the client may allow the
|
||||
VAD to be more responsive. Unlike made other client events, the server will
|
||||
not send a confirmation response to this event.
|
||||
"""
|
||||
await self._connection.send(
|
||||
cast(
|
||||
RealtimeClientEventParam,
|
||||
strip_not_given({"type": "input_audio_buffer.append", "audio": audio, "event_id": event_id}),
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,337 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union, Iterable
|
||||
from typing_extensions import Literal
|
||||
|
||||
import httpx
|
||||
|
||||
from .... import _legacy_response
|
||||
from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
||||
from ...._utils import (
|
||||
maybe_transform,
|
||||
async_maybe_transform,
|
||||
)
|
||||
from ...._compat import cached_property
|
||||
from ...._resource import SyncAPIResource, AsyncAPIResource
|
||||
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
|
||||
from ...._base_client import make_request_options
|
||||
from ....types.beta.realtime import session_create_params
|
||||
from ....types.beta.realtime.session_create_response import SessionCreateResponse
|
||||
|
||||
__all__ = ["Sessions", "AsyncSessions"]
|
||||
|
||||
|
||||
class Sessions(SyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> SessionsWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return SessionsWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> SessionsWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return SessionsWithStreamingResponse(self)
|
||||
|
||||
def create(
|
||||
self,
|
||||
*,
|
||||
model: Literal[
|
||||
"gpt-4o-realtime-preview",
|
||||
"gpt-4o-realtime-preview-2024-10-01",
|
||||
"gpt-4o-realtime-preview-2024-12-17",
|
||||
"gpt-4o-mini-realtime-preview",
|
||||
"gpt-4o-mini-realtime-preview-2024-12-17",
|
||||
],
|
||||
input_audio_format: Literal["pcm16", "g711_ulaw", "g711_alaw"] | NotGiven = NOT_GIVEN,
|
||||
input_audio_transcription: session_create_params.InputAudioTranscription | NotGiven = NOT_GIVEN,
|
||||
instructions: str | NotGiven = NOT_GIVEN,
|
||||
max_response_output_tokens: Union[int, Literal["inf"]] | NotGiven = NOT_GIVEN,
|
||||
modalities: List[Literal["text", "audio"]] | NotGiven = NOT_GIVEN,
|
||||
output_audio_format: Literal["pcm16", "g711_ulaw", "g711_alaw"] | NotGiven = NOT_GIVEN,
|
||||
temperature: float | NotGiven = NOT_GIVEN,
|
||||
tool_choice: str | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[session_create_params.Tool] | NotGiven = NOT_GIVEN,
|
||||
turn_detection: session_create_params.TurnDetection | NotGiven = NOT_GIVEN,
|
||||
voice: Literal["alloy", "ash", "ballad", "coral", "echo", "sage", "shimmer", "verse"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> SessionCreateResponse:
|
||||
"""
|
||||
Create an ephemeral API token for use in client-side applications with the
|
||||
Realtime API. Can be configured with the same session parameters as the
|
||||
`session.update` client event.
|
||||
|
||||
It responds with a session object, plus a `client_secret` key which contains a
|
||||
usable ephemeral API token that can be used to authenticate browser clients for
|
||||
the Realtime API.
|
||||
|
||||
Args:
|
||||
model: The Realtime model used for this session.
|
||||
|
||||
input_audio_format: The format of input audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`.
|
||||
|
||||
input_audio_transcription: Configuration for input audio transcription, defaults to off and can be set to
|
||||
`null` to turn off once on. Input audio transcription is not native to the
|
||||
model, since the model consumes audio directly. Transcription runs
|
||||
asynchronously through Whisper and should be treated as rough guidance rather
|
||||
than the representation understood by the model.
|
||||
|
||||
instructions: The default system instructions (i.e. system message) prepended to model calls.
|
||||
This field allows the client to guide the model on desired responses. The model
|
||||
can be instructed on response content and format, (e.g. "be extremely succinct",
|
||||
"act friendly", "here are examples of good responses") and on audio behavior
|
||||
(e.g. "talk quickly", "inject emotion into your voice", "laugh frequently"). The
|
||||
instructions are not guaranteed to be followed by the model, but they provide
|
||||
guidance to the model on the desired behavior.
|
||||
|
||||
Note that the server sets default instructions which will be used if this field
|
||||
is not set and are visible in the `session.created` event at the start of the
|
||||
session.
|
||||
|
||||
max_response_output_tokens: Maximum number of output tokens for a single assistant response, inclusive of
|
||||
tool calls. Provide an integer between 1 and 4096 to limit output tokens, or
|
||||
`inf` for the maximum available tokens for a given model. Defaults to `inf`.
|
||||
|
||||
modalities: The set of modalities the model can respond with. To disable audio, set this to
|
||||
["text"].
|
||||
|
||||
output_audio_format: The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`.
|
||||
|
||||
temperature: Sampling temperature for the model, limited to [0.6, 1.2]. Defaults to 0.8.
|
||||
|
||||
tool_choice: How the model chooses tools. Options are `auto`, `none`, `required`, or specify
|
||||
a function.
|
||||
|
||||
tools: Tools (functions) available to the model.
|
||||
|
||||
turn_detection: Configuration for turn detection. Can be set to `null` to turn off. Server VAD
|
||||
means that the model will detect the start and end of speech based on audio
|
||||
volume and respond at the end of user speech.
|
||||
|
||||
voice: The voice the model uses to respond. Voice cannot be changed during the session
|
||||
once the model has responded with audio at least once. Current voice options are
|
||||
`alloy`, `ash`, `ballad`, `coral`, `echo` `sage`, `shimmer` and `verse`.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
"/realtime/sessions",
|
||||
body=maybe_transform(
|
||||
{
|
||||
"model": model,
|
||||
"input_audio_format": input_audio_format,
|
||||
"input_audio_transcription": input_audio_transcription,
|
||||
"instructions": instructions,
|
||||
"max_response_output_tokens": max_response_output_tokens,
|
||||
"modalities": modalities,
|
||||
"output_audio_format": output_audio_format,
|
||||
"temperature": temperature,
|
||||
"tool_choice": tool_choice,
|
||||
"tools": tools,
|
||||
"turn_detection": turn_detection,
|
||||
"voice": voice,
|
||||
},
|
||||
session_create_params.SessionCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=SessionCreateResponse,
|
||||
)
|
||||
|
||||
|
||||
class AsyncSessions(AsyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncSessionsWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncSessionsWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncSessionsWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncSessionsWithStreamingResponse(self)
|
||||
|
||||
async def create(
|
||||
self,
|
||||
*,
|
||||
model: Literal[
|
||||
"gpt-4o-realtime-preview",
|
||||
"gpt-4o-realtime-preview-2024-10-01",
|
||||
"gpt-4o-realtime-preview-2024-12-17",
|
||||
"gpt-4o-mini-realtime-preview",
|
||||
"gpt-4o-mini-realtime-preview-2024-12-17",
|
||||
],
|
||||
input_audio_format: Literal["pcm16", "g711_ulaw", "g711_alaw"] | NotGiven = NOT_GIVEN,
|
||||
input_audio_transcription: session_create_params.InputAudioTranscription | NotGiven = NOT_GIVEN,
|
||||
instructions: str | NotGiven = NOT_GIVEN,
|
||||
max_response_output_tokens: Union[int, Literal["inf"]] | NotGiven = NOT_GIVEN,
|
||||
modalities: List[Literal["text", "audio"]] | NotGiven = NOT_GIVEN,
|
||||
output_audio_format: Literal["pcm16", "g711_ulaw", "g711_alaw"] | NotGiven = NOT_GIVEN,
|
||||
temperature: float | NotGiven = NOT_GIVEN,
|
||||
tool_choice: str | NotGiven = NOT_GIVEN,
|
||||
tools: Iterable[session_create_params.Tool] | NotGiven = NOT_GIVEN,
|
||||
turn_detection: session_create_params.TurnDetection | NotGiven = NOT_GIVEN,
|
||||
voice: Literal["alloy", "ash", "ballad", "coral", "echo", "sage", "shimmer", "verse"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> SessionCreateResponse:
|
||||
"""
|
||||
Create an ephemeral API token for use in client-side applications with the
|
||||
Realtime API. Can be configured with the same session parameters as the
|
||||
`session.update` client event.
|
||||
|
||||
It responds with a session object, plus a `client_secret` key which contains a
|
||||
usable ephemeral API token that can be used to authenticate browser clients for
|
||||
the Realtime API.
|
||||
|
||||
Args:
|
||||
model: The Realtime model used for this session.
|
||||
|
||||
input_audio_format: The format of input audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`.
|
||||
|
||||
input_audio_transcription: Configuration for input audio transcription, defaults to off and can be set to
|
||||
`null` to turn off once on. Input audio transcription is not native to the
|
||||
model, since the model consumes audio directly. Transcription runs
|
||||
asynchronously through Whisper and should be treated as rough guidance rather
|
||||
than the representation understood by the model.
|
||||
|
||||
instructions: The default system instructions (i.e. system message) prepended to model calls.
|
||||
This field allows the client to guide the model on desired responses. The model
|
||||
can be instructed on response content and format, (e.g. "be extremely succinct",
|
||||
"act friendly", "here are examples of good responses") and on audio behavior
|
||||
(e.g. "talk quickly", "inject emotion into your voice", "laugh frequently"). The
|
||||
instructions are not guaranteed to be followed by the model, but they provide
|
||||
guidance to the model on the desired behavior.
|
||||
|
||||
Note that the server sets default instructions which will be used if this field
|
||||
is not set and are visible in the `session.created` event at the start of the
|
||||
session.
|
||||
|
||||
max_response_output_tokens: Maximum number of output tokens for a single assistant response, inclusive of
|
||||
tool calls. Provide an integer between 1 and 4096 to limit output tokens, or
|
||||
`inf` for the maximum available tokens for a given model. Defaults to `inf`.
|
||||
|
||||
modalities: The set of modalities the model can respond with. To disable audio, set this to
|
||||
["text"].
|
||||
|
||||
output_audio_format: The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`.
|
||||
|
||||
temperature: Sampling temperature for the model, limited to [0.6, 1.2]. Defaults to 0.8.
|
||||
|
||||
tool_choice: How the model chooses tools. Options are `auto`, `none`, `required`, or specify
|
||||
a function.
|
||||
|
||||
tools: Tools (functions) available to the model.
|
||||
|
||||
turn_detection: Configuration for turn detection. Can be set to `null` to turn off. Server VAD
|
||||
means that the model will detect the start and end of speech based on audio
|
||||
volume and respond at the end of user speech.
|
||||
|
||||
voice: The voice the model uses to respond. Voice cannot be changed during the session
|
||||
once the model has responded with audio at least once. Current voice options are
|
||||
`alloy`, `ash`, `ballad`, `coral`, `echo` `sage`, `shimmer` and `verse`.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
"/realtime/sessions",
|
||||
body=await async_maybe_transform(
|
||||
{
|
||||
"model": model,
|
||||
"input_audio_format": input_audio_format,
|
||||
"input_audio_transcription": input_audio_transcription,
|
||||
"instructions": instructions,
|
||||
"max_response_output_tokens": max_response_output_tokens,
|
||||
"modalities": modalities,
|
||||
"output_audio_format": output_audio_format,
|
||||
"temperature": temperature,
|
||||
"tool_choice": tool_choice,
|
||||
"tools": tools,
|
||||
"turn_detection": turn_detection,
|
||||
"voice": voice,
|
||||
},
|
||||
session_create_params.SessionCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=SessionCreateResponse,
|
||||
)
|
||||
|
||||
|
||||
class SessionsWithRawResponse:
|
||||
def __init__(self, sessions: Sessions) -> None:
|
||||
self._sessions = sessions
|
||||
|
||||
self.create = _legacy_response.to_raw_response_wrapper(
|
||||
sessions.create,
|
||||
)
|
||||
|
||||
|
||||
class AsyncSessionsWithRawResponse:
|
||||
def __init__(self, sessions: AsyncSessions) -> None:
|
||||
self._sessions = sessions
|
||||
|
||||
self.create = _legacy_response.async_to_raw_response_wrapper(
|
||||
sessions.create,
|
||||
)
|
||||
|
||||
|
||||
class SessionsWithStreamingResponse:
|
||||
def __init__(self, sessions: Sessions) -> None:
|
||||
self._sessions = sessions
|
||||
|
||||
self.create = to_streamed_response_wrapper(
|
||||
sessions.create,
|
||||
)
|
||||
|
||||
|
||||
class AsyncSessionsWithStreamingResponse:
|
||||
def __init__(self, sessions: AsyncSessions) -> None:
|
||||
self._sessions = sessions
|
||||
|
||||
self.create = async_to_streamed_response_wrapper(
|
||||
sessions.create,
|
||||
)
|
||||
@@ -0,0 +1,47 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from .runs import (
|
||||
Runs,
|
||||
AsyncRuns,
|
||||
RunsWithRawResponse,
|
||||
AsyncRunsWithRawResponse,
|
||||
RunsWithStreamingResponse,
|
||||
AsyncRunsWithStreamingResponse,
|
||||
)
|
||||
from .threads import (
|
||||
Threads,
|
||||
AsyncThreads,
|
||||
ThreadsWithRawResponse,
|
||||
AsyncThreadsWithRawResponse,
|
||||
ThreadsWithStreamingResponse,
|
||||
AsyncThreadsWithStreamingResponse,
|
||||
)
|
||||
from .messages import (
|
||||
Messages,
|
||||
AsyncMessages,
|
||||
MessagesWithRawResponse,
|
||||
AsyncMessagesWithRawResponse,
|
||||
MessagesWithStreamingResponse,
|
||||
AsyncMessagesWithStreamingResponse,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"Runs",
|
||||
"AsyncRuns",
|
||||
"RunsWithRawResponse",
|
||||
"AsyncRunsWithRawResponse",
|
||||
"RunsWithStreamingResponse",
|
||||
"AsyncRunsWithStreamingResponse",
|
||||
"Messages",
|
||||
"AsyncMessages",
|
||||
"MessagesWithRawResponse",
|
||||
"AsyncMessagesWithRawResponse",
|
||||
"MessagesWithStreamingResponse",
|
||||
"AsyncMessagesWithStreamingResponse",
|
||||
"Threads",
|
||||
"AsyncThreads",
|
||||
"ThreadsWithRawResponse",
|
||||
"AsyncThreadsWithRawResponse",
|
||||
"ThreadsWithStreamingResponse",
|
||||
"AsyncThreadsWithStreamingResponse",
|
||||
]
|
||||
@@ -0,0 +1,661 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union, Iterable, Optional
|
||||
from typing_extensions import Literal
|
||||
|
||||
import httpx
|
||||
|
||||
from .... import _legacy_response
|
||||
from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
||||
from ...._utils import (
|
||||
maybe_transform,
|
||||
async_maybe_transform,
|
||||
)
|
||||
from ...._compat import cached_property
|
||||
from ...._resource import SyncAPIResource, AsyncAPIResource
|
||||
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
|
||||
from ....pagination import SyncCursorPage, AsyncCursorPage
|
||||
from ...._base_client import (
|
||||
AsyncPaginator,
|
||||
make_request_options,
|
||||
)
|
||||
from ....types.beta.threads import message_list_params, message_create_params, message_update_params
|
||||
from ....types.beta.threads.message import Message
|
||||
from ....types.beta.threads.message_deleted import MessageDeleted
|
||||
from ....types.beta.threads.message_content_part_param import MessageContentPartParam
|
||||
|
||||
__all__ = ["Messages", "AsyncMessages"]
|
||||
|
||||
|
||||
class Messages(SyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> MessagesWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return MessagesWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> MessagesWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return MessagesWithStreamingResponse(self)
|
||||
|
||||
def create(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
content: Union[str, Iterable[MessageContentPartParam]],
|
||||
role: Literal["user", "assistant"],
|
||||
attachments: Optional[Iterable[message_create_params.Attachment]] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Message:
|
||||
"""
|
||||
Create a message.
|
||||
|
||||
Args:
|
||||
content: The text contents of the message.
|
||||
|
||||
role:
|
||||
The role of the entity that is creating the message. Allowed values include:
|
||||
|
||||
- `user`: Indicates the message is sent by an actual user and should be used in
|
||||
most cases to represent user-generated messages.
|
||||
- `assistant`: Indicates the message is generated by the assistant. Use this
|
||||
value to insert messages from the assistant into the conversation.
|
||||
|
||||
attachments: A list of files attached to the message, and the tools they should be added to.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
f"/threads/{thread_id}/messages",
|
||||
body=maybe_transform(
|
||||
{
|
||||
"content": content,
|
||||
"role": role,
|
||||
"attachments": attachments,
|
||||
"metadata": metadata,
|
||||
},
|
||||
message_create_params.MessageCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Message,
|
||||
)
|
||||
|
||||
def retrieve(
|
||||
self,
|
||||
message_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Message:
|
||||
"""
|
||||
Retrieve a message.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not message_id:
|
||||
raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get(
|
||||
f"/threads/{thread_id}/messages/{message_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Message,
|
||||
)
|
||||
|
||||
def update(
|
||||
self,
|
||||
message_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Message:
|
||||
"""
|
||||
Modifies a message.
|
||||
|
||||
Args:
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not message_id:
|
||||
raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
f"/threads/{thread_id}/messages/{message_id}",
|
||||
body=maybe_transform({"metadata": metadata}, message_update_params.MessageUpdateParams),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Message,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
run_id: str | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> SyncCursorPage[Message]:
|
||||
"""
|
||||
Returns a list of messages for a given thread.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination. `after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
run_id: Filter messages by the run ID that generated them.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
f"/threads/{thread_id}/messages",
|
||||
page=SyncCursorPage[Message],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
"run_id": run_id,
|
||||
},
|
||||
message_list_params.MessageListParams,
|
||||
),
|
||||
),
|
||||
model=Message,
|
||||
)
|
||||
|
||||
def delete(
|
||||
self,
|
||||
message_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> MessageDeleted:
|
||||
"""
|
||||
Deletes a message.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not message_id:
|
||||
raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._delete(
|
||||
f"/threads/{thread_id}/messages/{message_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=MessageDeleted,
|
||||
)
|
||||
|
||||
|
||||
class AsyncMessages(AsyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncMessagesWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncMessagesWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncMessagesWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncMessagesWithStreamingResponse(self)
|
||||
|
||||
async def create(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
content: Union[str, Iterable[MessageContentPartParam]],
|
||||
role: Literal["user", "assistant"],
|
||||
attachments: Optional[Iterable[message_create_params.Attachment]] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Message:
|
||||
"""
|
||||
Create a message.
|
||||
|
||||
Args:
|
||||
content: The text contents of the message.
|
||||
|
||||
role:
|
||||
The role of the entity that is creating the message. Allowed values include:
|
||||
|
||||
- `user`: Indicates the message is sent by an actual user and should be used in
|
||||
most cases to represent user-generated messages.
|
||||
- `assistant`: Indicates the message is generated by the assistant. Use this
|
||||
value to insert messages from the assistant into the conversation.
|
||||
|
||||
attachments: A list of files attached to the message, and the tools they should be added to.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
f"/threads/{thread_id}/messages",
|
||||
body=await async_maybe_transform(
|
||||
{
|
||||
"content": content,
|
||||
"role": role,
|
||||
"attachments": attachments,
|
||||
"metadata": metadata,
|
||||
},
|
||||
message_create_params.MessageCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Message,
|
||||
)
|
||||
|
||||
async def retrieve(
|
||||
self,
|
||||
message_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Message:
|
||||
"""
|
||||
Retrieve a message.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not message_id:
|
||||
raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._get(
|
||||
f"/threads/{thread_id}/messages/{message_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Message,
|
||||
)
|
||||
|
||||
async def update(
|
||||
self,
|
||||
message_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> Message:
|
||||
"""
|
||||
Modifies a message.
|
||||
|
||||
Args:
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not message_id:
|
||||
raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
f"/threads/{thread_id}/messages/{message_id}",
|
||||
body=await async_maybe_transform({"metadata": metadata}, message_update_params.MessageUpdateParams),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=Message,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
run_id: str | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> AsyncPaginator[Message, AsyncCursorPage[Message]]:
|
||||
"""
|
||||
Returns a list of messages for a given thread.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination. `after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
run_id: Filter messages by the run ID that generated them.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
f"/threads/{thread_id}/messages",
|
||||
page=AsyncCursorPage[Message],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
"run_id": run_id,
|
||||
},
|
||||
message_list_params.MessageListParams,
|
||||
),
|
||||
),
|
||||
model=Message,
|
||||
)
|
||||
|
||||
async def delete(
|
||||
self,
|
||||
message_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> MessageDeleted:
|
||||
"""
|
||||
Deletes a message.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not message_id:
|
||||
raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._delete(
|
||||
f"/threads/{thread_id}/messages/{message_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=MessageDeleted,
|
||||
)
|
||||
|
||||
|
||||
class MessagesWithRawResponse:
|
||||
def __init__(self, messages: Messages) -> None:
|
||||
self._messages = messages
|
||||
|
||||
self.create = _legacy_response.to_raw_response_wrapper(
|
||||
messages.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.to_raw_response_wrapper(
|
||||
messages.retrieve,
|
||||
)
|
||||
self.update = _legacy_response.to_raw_response_wrapper(
|
||||
messages.update,
|
||||
)
|
||||
self.list = _legacy_response.to_raw_response_wrapper(
|
||||
messages.list,
|
||||
)
|
||||
self.delete = _legacy_response.to_raw_response_wrapper(
|
||||
messages.delete,
|
||||
)
|
||||
|
||||
|
||||
class AsyncMessagesWithRawResponse:
|
||||
def __init__(self, messages: AsyncMessages) -> None:
|
||||
self._messages = messages
|
||||
|
||||
self.create = _legacy_response.async_to_raw_response_wrapper(
|
||||
messages.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.async_to_raw_response_wrapper(
|
||||
messages.retrieve,
|
||||
)
|
||||
self.update = _legacy_response.async_to_raw_response_wrapper(
|
||||
messages.update,
|
||||
)
|
||||
self.list = _legacy_response.async_to_raw_response_wrapper(
|
||||
messages.list,
|
||||
)
|
||||
self.delete = _legacy_response.async_to_raw_response_wrapper(
|
||||
messages.delete,
|
||||
)
|
||||
|
||||
|
||||
class MessagesWithStreamingResponse:
|
||||
def __init__(self, messages: Messages) -> None:
|
||||
self._messages = messages
|
||||
|
||||
self.create = to_streamed_response_wrapper(
|
||||
messages.create,
|
||||
)
|
||||
self.retrieve = to_streamed_response_wrapper(
|
||||
messages.retrieve,
|
||||
)
|
||||
self.update = to_streamed_response_wrapper(
|
||||
messages.update,
|
||||
)
|
||||
self.list = to_streamed_response_wrapper(
|
||||
messages.list,
|
||||
)
|
||||
self.delete = to_streamed_response_wrapper(
|
||||
messages.delete,
|
||||
)
|
||||
|
||||
|
||||
class AsyncMessagesWithStreamingResponse:
|
||||
def __init__(self, messages: AsyncMessages) -> None:
|
||||
self._messages = messages
|
||||
|
||||
self.create = async_to_streamed_response_wrapper(
|
||||
messages.create,
|
||||
)
|
||||
self.retrieve = async_to_streamed_response_wrapper(
|
||||
messages.retrieve,
|
||||
)
|
||||
self.update = async_to_streamed_response_wrapper(
|
||||
messages.update,
|
||||
)
|
||||
self.list = async_to_streamed_response_wrapper(
|
||||
messages.list,
|
||||
)
|
||||
self.delete = async_to_streamed_response_wrapper(
|
||||
messages.delete,
|
||||
)
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from .runs import (
|
||||
Runs,
|
||||
AsyncRuns,
|
||||
RunsWithRawResponse,
|
||||
AsyncRunsWithRawResponse,
|
||||
RunsWithStreamingResponse,
|
||||
AsyncRunsWithStreamingResponse,
|
||||
)
|
||||
from .steps import (
|
||||
Steps,
|
||||
AsyncSteps,
|
||||
StepsWithRawResponse,
|
||||
AsyncStepsWithRawResponse,
|
||||
StepsWithStreamingResponse,
|
||||
AsyncStepsWithStreamingResponse,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"Steps",
|
||||
"AsyncSteps",
|
||||
"StepsWithRawResponse",
|
||||
"AsyncStepsWithRawResponse",
|
||||
"StepsWithStreamingResponse",
|
||||
"AsyncStepsWithStreamingResponse",
|
||||
"Runs",
|
||||
"AsyncRuns",
|
||||
"RunsWithRawResponse",
|
||||
"AsyncRunsWithRawResponse",
|
||||
"RunsWithStreamingResponse",
|
||||
"AsyncRunsWithStreamingResponse",
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,381 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List
|
||||
from typing_extensions import Literal
|
||||
|
||||
import httpx
|
||||
|
||||
from ..... import _legacy_response
|
||||
from ....._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
||||
from ....._utils import (
|
||||
maybe_transform,
|
||||
async_maybe_transform,
|
||||
)
|
||||
from ....._compat import cached_property
|
||||
from ....._resource import SyncAPIResource, AsyncAPIResource
|
||||
from ....._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
|
||||
from .....pagination import SyncCursorPage, AsyncCursorPage
|
||||
from ....._base_client import AsyncPaginator, make_request_options
|
||||
from .....types.beta.threads.runs import step_list_params, step_retrieve_params
|
||||
from .....types.beta.threads.runs.run_step import RunStep
|
||||
from .....types.beta.threads.runs.run_step_include import RunStepInclude
|
||||
|
||||
__all__ = ["Steps", "AsyncSteps"]
|
||||
|
||||
|
||||
class Steps(SyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> StepsWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return StepsWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> StepsWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return StepsWithStreamingResponse(self)
|
||||
|
||||
def retrieve(
|
||||
self,
|
||||
step_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
run_id: str,
|
||||
include: List[RunStepInclude] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> RunStep:
|
||||
"""
|
||||
Retrieves a run step.
|
||||
|
||||
Args:
|
||||
include: A list of additional fields to include in the response. Currently the only
|
||||
supported value is `step_details.tool_calls[*].file_search.results[*].content`
|
||||
to fetch the file search result content.
|
||||
|
||||
See the
|
||||
[file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings)
|
||||
for more information.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not run_id:
|
||||
raise ValueError(f"Expected a non-empty value for `run_id` but received {run_id!r}")
|
||||
if not step_id:
|
||||
raise ValueError(f"Expected a non-empty value for `step_id` but received {step_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get(
|
||||
f"/threads/{thread_id}/runs/{run_id}/steps/{step_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform({"include": include}, step_retrieve_params.StepRetrieveParams),
|
||||
),
|
||||
cast_to=RunStep,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
run_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
include: List[RunStepInclude] | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> SyncCursorPage[RunStep]:
|
||||
"""
|
||||
Returns a list of run steps belonging to a run.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination. `after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
include: A list of additional fields to include in the response. Currently the only
|
||||
supported value is `step_details.tool_calls[*].file_search.results[*].content`
|
||||
to fetch the file search result content.
|
||||
|
||||
See the
|
||||
[file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings)
|
||||
for more information.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not run_id:
|
||||
raise ValueError(f"Expected a non-empty value for `run_id` but received {run_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
f"/threads/{thread_id}/runs/{run_id}/steps",
|
||||
page=SyncCursorPage[RunStep],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"include": include,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
step_list_params.StepListParams,
|
||||
),
|
||||
),
|
||||
model=RunStep,
|
||||
)
|
||||
|
||||
|
||||
class AsyncSteps(AsyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncStepsWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncStepsWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncStepsWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncStepsWithStreamingResponse(self)
|
||||
|
||||
async def retrieve(
|
||||
self,
|
||||
step_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
run_id: str,
|
||||
include: List[RunStepInclude] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> RunStep:
|
||||
"""
|
||||
Retrieves a run step.
|
||||
|
||||
Args:
|
||||
include: A list of additional fields to include in the response. Currently the only
|
||||
supported value is `step_details.tool_calls[*].file_search.results[*].content`
|
||||
to fetch the file search result content.
|
||||
|
||||
See the
|
||||
[file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings)
|
||||
for more information.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not run_id:
|
||||
raise ValueError(f"Expected a non-empty value for `run_id` but received {run_id!r}")
|
||||
if not step_id:
|
||||
raise ValueError(f"Expected a non-empty value for `step_id` but received {step_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._get(
|
||||
f"/threads/{thread_id}/runs/{run_id}/steps/{step_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=await async_maybe_transform({"include": include}, step_retrieve_params.StepRetrieveParams),
|
||||
),
|
||||
cast_to=RunStep,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
run_id: str,
|
||||
*,
|
||||
thread_id: str,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
include: List[RunStepInclude] | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> AsyncPaginator[RunStep, AsyncCursorPage[RunStep]]:
|
||||
"""
|
||||
Returns a list of run steps belonging to a run.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination. `after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
include: A list of additional fields to include in the response. Currently the only
|
||||
supported value is `step_details.tool_calls[*].file_search.results[*].content`
|
||||
to fetch the file search result content.
|
||||
|
||||
See the
|
||||
[file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings)
|
||||
for more information.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not thread_id:
|
||||
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
|
||||
if not run_id:
|
||||
raise ValueError(f"Expected a non-empty value for `run_id` but received {run_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
f"/threads/{thread_id}/runs/{run_id}/steps",
|
||||
page=AsyncCursorPage[RunStep],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"include": include,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
step_list_params.StepListParams,
|
||||
),
|
||||
),
|
||||
model=RunStep,
|
||||
)
|
||||
|
||||
|
||||
class StepsWithRawResponse:
|
||||
def __init__(self, steps: Steps) -> None:
|
||||
self._steps = steps
|
||||
|
||||
self.retrieve = _legacy_response.to_raw_response_wrapper(
|
||||
steps.retrieve,
|
||||
)
|
||||
self.list = _legacy_response.to_raw_response_wrapper(
|
||||
steps.list,
|
||||
)
|
||||
|
||||
|
||||
class AsyncStepsWithRawResponse:
|
||||
def __init__(self, steps: AsyncSteps) -> None:
|
||||
self._steps = steps
|
||||
|
||||
self.retrieve = _legacy_response.async_to_raw_response_wrapper(
|
||||
steps.retrieve,
|
||||
)
|
||||
self.list = _legacy_response.async_to_raw_response_wrapper(
|
||||
steps.list,
|
||||
)
|
||||
|
||||
|
||||
class StepsWithStreamingResponse:
|
||||
def __init__(self, steps: Steps) -> None:
|
||||
self._steps = steps
|
||||
|
||||
self.retrieve = to_streamed_response_wrapper(
|
||||
steps.retrieve,
|
||||
)
|
||||
self.list = to_streamed_response_wrapper(
|
||||
steps.list,
|
||||
)
|
||||
|
||||
|
||||
class AsyncStepsWithStreamingResponse:
|
||||
def __init__(self, steps: AsyncSteps) -> None:
|
||||
self._steps = steps
|
||||
|
||||
self.retrieve = async_to_streamed_response_wrapper(
|
||||
steps.retrieve,
|
||||
)
|
||||
self.list = async_to_streamed_response_wrapper(
|
||||
steps.list,
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
+47
@@ -0,0 +1,47 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from .files import (
|
||||
Files,
|
||||
AsyncFiles,
|
||||
FilesWithRawResponse,
|
||||
AsyncFilesWithRawResponse,
|
||||
FilesWithStreamingResponse,
|
||||
AsyncFilesWithStreamingResponse,
|
||||
)
|
||||
from .file_batches import (
|
||||
FileBatches,
|
||||
AsyncFileBatches,
|
||||
FileBatchesWithRawResponse,
|
||||
AsyncFileBatchesWithRawResponse,
|
||||
FileBatchesWithStreamingResponse,
|
||||
AsyncFileBatchesWithStreamingResponse,
|
||||
)
|
||||
from .vector_stores import (
|
||||
VectorStores,
|
||||
AsyncVectorStores,
|
||||
VectorStoresWithRawResponse,
|
||||
AsyncVectorStoresWithRawResponse,
|
||||
VectorStoresWithStreamingResponse,
|
||||
AsyncVectorStoresWithStreamingResponse,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"Files",
|
||||
"AsyncFiles",
|
||||
"FilesWithRawResponse",
|
||||
"AsyncFilesWithRawResponse",
|
||||
"FilesWithStreamingResponse",
|
||||
"AsyncFilesWithStreamingResponse",
|
||||
"FileBatches",
|
||||
"AsyncFileBatches",
|
||||
"FileBatchesWithRawResponse",
|
||||
"AsyncFileBatchesWithRawResponse",
|
||||
"FileBatchesWithStreamingResponse",
|
||||
"AsyncFileBatchesWithStreamingResponse",
|
||||
"VectorStores",
|
||||
"AsyncVectorStores",
|
||||
"VectorStoresWithRawResponse",
|
||||
"AsyncVectorStoresWithRawResponse",
|
||||
"VectorStoresWithStreamingResponse",
|
||||
"AsyncVectorStoresWithStreamingResponse",
|
||||
]
|
||||
+785
@@ -0,0 +1,785 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from typing import List, Iterable
|
||||
from typing_extensions import Literal
|
||||
from concurrent.futures import Future, ThreadPoolExecutor, as_completed
|
||||
|
||||
import httpx
|
||||
import sniffio
|
||||
|
||||
from .... import _legacy_response
|
||||
from ....types import FileObject
|
||||
from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven, FileTypes
|
||||
from ...._utils import (
|
||||
is_given,
|
||||
maybe_transform,
|
||||
async_maybe_transform,
|
||||
)
|
||||
from ...._compat import cached_property
|
||||
from ...._resource import SyncAPIResource, AsyncAPIResource
|
||||
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
|
||||
from ....pagination import SyncCursorPage, AsyncCursorPage
|
||||
from ....types.beta import FileChunkingStrategyParam
|
||||
from ...._base_client import AsyncPaginator, make_request_options
|
||||
from ....types.beta.vector_stores import file_batch_create_params, file_batch_list_files_params
|
||||
from ....types.beta.file_chunking_strategy_param import FileChunkingStrategyParam
|
||||
from ....types.beta.vector_stores.vector_store_file import VectorStoreFile
|
||||
from ....types.beta.vector_stores.vector_store_file_batch import VectorStoreFileBatch
|
||||
|
||||
__all__ = ["FileBatches", "AsyncFileBatches"]
|
||||
|
||||
|
||||
class FileBatches(SyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> FileBatchesWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return FileBatchesWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> FileBatchesWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return FileBatchesWithStreamingResponse(self)
|
||||
|
||||
def create(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
file_ids: List[str],
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""
|
||||
Create a vector store file batch.
|
||||
|
||||
Args:
|
||||
file_ids: A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that
|
||||
the vector store should use. Useful for tools like `file_search` that can access
|
||||
files.
|
||||
|
||||
chunking_strategy: The chunking strategy used to chunk the file(s). If not set, will use the `auto`
|
||||
strategy. Only applicable if `file_ids` is non-empty.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
f"/vector_stores/{vector_store_id}/file_batches",
|
||||
body=maybe_transform(
|
||||
{
|
||||
"file_ids": file_ids,
|
||||
"chunking_strategy": chunking_strategy,
|
||||
},
|
||||
file_batch_create_params.FileBatchCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFileBatch,
|
||||
)
|
||||
|
||||
def retrieve(
|
||||
self,
|
||||
batch_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""
|
||||
Retrieves a vector store file batch.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not batch_id:
|
||||
raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get(
|
||||
f"/vector_stores/{vector_store_id}/file_batches/{batch_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFileBatch,
|
||||
)
|
||||
|
||||
def cancel(
|
||||
self,
|
||||
batch_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""Cancel a vector store file batch.
|
||||
|
||||
This attempts to cancel the processing of
|
||||
files in this batch as soon as possible.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not batch_id:
|
||||
raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
f"/vector_stores/{vector_store_id}/file_batches/{batch_id}/cancel",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFileBatch,
|
||||
)
|
||||
|
||||
def create_and_poll(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
file_ids: List[str],
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""Create a vector store batch and poll until all files have been processed."""
|
||||
batch = self.create(
|
||||
vector_store_id=vector_store_id,
|
||||
file_ids=file_ids,
|
||||
chunking_strategy=chunking_strategy,
|
||||
)
|
||||
# TODO: don't poll unless necessary??
|
||||
return self.poll(
|
||||
batch.id,
|
||||
vector_store_id=vector_store_id,
|
||||
poll_interval_ms=poll_interval_ms,
|
||||
)
|
||||
|
||||
def list_files(
|
||||
self,
|
||||
batch_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
filter: Literal["in_progress", "completed", "failed", "cancelled"] | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> SyncCursorPage[VectorStoreFile]:
|
||||
"""
|
||||
Returns a list of vector store files in a batch.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination. `after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
filter: Filter by file status. One of `in_progress`, `completed`, `failed`, `cancelled`.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not batch_id:
|
||||
raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
f"/vector_stores/{vector_store_id}/file_batches/{batch_id}/files",
|
||||
page=SyncCursorPage[VectorStoreFile],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"filter": filter,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
file_batch_list_files_params.FileBatchListFilesParams,
|
||||
),
|
||||
),
|
||||
model=VectorStoreFile,
|
||||
)
|
||||
|
||||
def poll(
|
||||
self,
|
||||
batch_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""Wait for the given file batch to be processed.
|
||||
|
||||
Note: this will return even if one of the files failed to process, you need to
|
||||
check batch.file_counts.failed_count to handle this case.
|
||||
"""
|
||||
headers: dict[str, str] = {"X-Stainless-Poll-Helper": "true"}
|
||||
if is_given(poll_interval_ms):
|
||||
headers["X-Stainless-Custom-Poll-Interval"] = str(poll_interval_ms)
|
||||
|
||||
while True:
|
||||
response = self.with_raw_response.retrieve(
|
||||
batch_id,
|
||||
vector_store_id=vector_store_id,
|
||||
extra_headers=headers,
|
||||
)
|
||||
|
||||
batch = response.parse()
|
||||
if batch.file_counts.in_progress > 0:
|
||||
if not is_given(poll_interval_ms):
|
||||
from_header = response.headers.get("openai-poll-after-ms")
|
||||
if from_header is not None:
|
||||
poll_interval_ms = int(from_header)
|
||||
else:
|
||||
poll_interval_ms = 1000
|
||||
|
||||
self._sleep(poll_interval_ms / 1000)
|
||||
continue
|
||||
|
||||
return batch
|
||||
|
||||
def upload_and_poll(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
files: Iterable[FileTypes],
|
||||
max_concurrency: int = 5,
|
||||
file_ids: List[str] = [],
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""Uploads the given files concurrently and then creates a vector store file batch.
|
||||
|
||||
If you've already uploaded certain files that you want to include in this batch
|
||||
then you can pass their IDs through the `file_ids` argument.
|
||||
|
||||
By default, if any file upload fails then an exception will be eagerly raised.
|
||||
|
||||
The number of concurrency uploads is configurable using the `max_concurrency`
|
||||
parameter.
|
||||
|
||||
Note: this method only supports `asyncio` or `trio` as the backing async
|
||||
runtime.
|
||||
"""
|
||||
results: list[FileObject] = []
|
||||
|
||||
with ThreadPoolExecutor(max_workers=max_concurrency) as executor:
|
||||
futures: list[Future[FileObject]] = [
|
||||
executor.submit(
|
||||
self._client.files.create,
|
||||
file=file,
|
||||
purpose="assistants",
|
||||
)
|
||||
for file in files
|
||||
]
|
||||
|
||||
for future in as_completed(futures):
|
||||
exc = future.exception()
|
||||
if exc:
|
||||
raise exc
|
||||
|
||||
results.append(future.result())
|
||||
|
||||
batch = self.create_and_poll(
|
||||
vector_store_id=vector_store_id,
|
||||
file_ids=[*file_ids, *(f.id for f in results)],
|
||||
poll_interval_ms=poll_interval_ms,
|
||||
chunking_strategy=chunking_strategy,
|
||||
)
|
||||
return batch
|
||||
|
||||
|
||||
class AsyncFileBatches(AsyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncFileBatchesWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncFileBatchesWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncFileBatchesWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncFileBatchesWithStreamingResponse(self)
|
||||
|
||||
async def create(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
file_ids: List[str],
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""
|
||||
Create a vector store file batch.
|
||||
|
||||
Args:
|
||||
file_ids: A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that
|
||||
the vector store should use. Useful for tools like `file_search` that can access
|
||||
files.
|
||||
|
||||
chunking_strategy: The chunking strategy used to chunk the file(s). If not set, will use the `auto`
|
||||
strategy. Only applicable if `file_ids` is non-empty.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
f"/vector_stores/{vector_store_id}/file_batches",
|
||||
body=await async_maybe_transform(
|
||||
{
|
||||
"file_ids": file_ids,
|
||||
"chunking_strategy": chunking_strategy,
|
||||
},
|
||||
file_batch_create_params.FileBatchCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFileBatch,
|
||||
)
|
||||
|
||||
async def retrieve(
|
||||
self,
|
||||
batch_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""
|
||||
Retrieves a vector store file batch.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not batch_id:
|
||||
raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._get(
|
||||
f"/vector_stores/{vector_store_id}/file_batches/{batch_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFileBatch,
|
||||
)
|
||||
|
||||
async def cancel(
|
||||
self,
|
||||
batch_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""Cancel a vector store file batch.
|
||||
|
||||
This attempts to cancel the processing of
|
||||
files in this batch as soon as possible.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not batch_id:
|
||||
raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
f"/vector_stores/{vector_store_id}/file_batches/{batch_id}/cancel",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFileBatch,
|
||||
)
|
||||
|
||||
async def create_and_poll(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
file_ids: List[str],
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""Create a vector store batch and poll until all files have been processed."""
|
||||
batch = await self.create(
|
||||
vector_store_id=vector_store_id,
|
||||
file_ids=file_ids,
|
||||
chunking_strategy=chunking_strategy,
|
||||
)
|
||||
# TODO: don't poll unless necessary??
|
||||
return await self.poll(
|
||||
batch.id,
|
||||
vector_store_id=vector_store_id,
|
||||
poll_interval_ms=poll_interval_ms,
|
||||
)
|
||||
|
||||
def list_files(
|
||||
self,
|
||||
batch_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
filter: Literal["in_progress", "completed", "failed", "cancelled"] | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> AsyncPaginator[VectorStoreFile, AsyncCursorPage[VectorStoreFile]]:
|
||||
"""
|
||||
Returns a list of vector store files in a batch.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination. `after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
filter: Filter by file status. One of `in_progress`, `completed`, `failed`, `cancelled`.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not batch_id:
|
||||
raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
f"/vector_stores/{vector_store_id}/file_batches/{batch_id}/files",
|
||||
page=AsyncCursorPage[VectorStoreFile],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"filter": filter,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
file_batch_list_files_params.FileBatchListFilesParams,
|
||||
),
|
||||
),
|
||||
model=VectorStoreFile,
|
||||
)
|
||||
|
||||
async def poll(
|
||||
self,
|
||||
batch_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""Wait for the given file batch to be processed.
|
||||
|
||||
Note: this will return even if one of the files failed to process, you need to
|
||||
check batch.file_counts.failed_count to handle this case.
|
||||
"""
|
||||
headers: dict[str, str] = {"X-Stainless-Poll-Helper": "true"}
|
||||
if is_given(poll_interval_ms):
|
||||
headers["X-Stainless-Custom-Poll-Interval"] = str(poll_interval_ms)
|
||||
|
||||
while True:
|
||||
response = await self.with_raw_response.retrieve(
|
||||
batch_id,
|
||||
vector_store_id=vector_store_id,
|
||||
extra_headers=headers,
|
||||
)
|
||||
|
||||
batch = response.parse()
|
||||
if batch.file_counts.in_progress > 0:
|
||||
if not is_given(poll_interval_ms):
|
||||
from_header = response.headers.get("openai-poll-after-ms")
|
||||
if from_header is not None:
|
||||
poll_interval_ms = int(from_header)
|
||||
else:
|
||||
poll_interval_ms = 1000
|
||||
|
||||
await self._sleep(poll_interval_ms / 1000)
|
||||
continue
|
||||
|
||||
return batch
|
||||
|
||||
async def upload_and_poll(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
files: Iterable[FileTypes],
|
||||
max_concurrency: int = 5,
|
||||
file_ids: List[str] = [],
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileBatch:
|
||||
"""Uploads the given files concurrently and then creates a vector store file batch.
|
||||
|
||||
If you've already uploaded certain files that you want to include in this batch
|
||||
then you can pass their IDs through the `file_ids` argument.
|
||||
|
||||
By default, if any file upload fails then an exception will be eagerly raised.
|
||||
|
||||
The number of concurrency uploads is configurable using the `max_concurrency`
|
||||
parameter.
|
||||
|
||||
Note: this method only supports `asyncio` or `trio` as the backing async
|
||||
runtime.
|
||||
"""
|
||||
uploaded_files: list[FileObject] = []
|
||||
|
||||
async_library = sniffio.current_async_library()
|
||||
|
||||
if async_library == "asyncio":
|
||||
|
||||
async def asyncio_upload_file(semaphore: asyncio.Semaphore, file: FileTypes) -> None:
|
||||
async with semaphore:
|
||||
file_obj = await self._client.files.create(
|
||||
file=file,
|
||||
purpose="assistants",
|
||||
)
|
||||
uploaded_files.append(file_obj)
|
||||
|
||||
semaphore = asyncio.Semaphore(max_concurrency)
|
||||
|
||||
tasks = [asyncio_upload_file(semaphore, file) for file in files]
|
||||
|
||||
await asyncio.gather(*tasks)
|
||||
elif async_library == "trio":
|
||||
# We only import if the library is being used.
|
||||
# We support Python 3.7 so are using an older version of trio that does not have type information
|
||||
import trio # type: ignore # pyright: ignore[reportMissingTypeStubs]
|
||||
|
||||
async def trio_upload_file(limiter: trio.CapacityLimiter, file: FileTypes) -> None:
|
||||
async with limiter:
|
||||
file_obj = await self._client.files.create(
|
||||
file=file,
|
||||
purpose="assistants",
|
||||
)
|
||||
uploaded_files.append(file_obj)
|
||||
|
||||
limiter = trio.CapacityLimiter(max_concurrency)
|
||||
|
||||
async with trio.open_nursery() as nursery:
|
||||
for file in files:
|
||||
nursery.start_soon(trio_upload_file, limiter, file) # pyright: ignore [reportUnknownMemberType]
|
||||
else:
|
||||
raise RuntimeError(
|
||||
f"Async runtime {async_library} is not supported yet. Only asyncio or trio is supported",
|
||||
)
|
||||
|
||||
batch = await self.create_and_poll(
|
||||
vector_store_id=vector_store_id,
|
||||
file_ids=[*file_ids, *(f.id for f in uploaded_files)],
|
||||
poll_interval_ms=poll_interval_ms,
|
||||
chunking_strategy=chunking_strategy,
|
||||
)
|
||||
return batch
|
||||
|
||||
|
||||
class FileBatchesWithRawResponse:
|
||||
def __init__(self, file_batches: FileBatches) -> None:
|
||||
self._file_batches = file_batches
|
||||
|
||||
self.create = _legacy_response.to_raw_response_wrapper(
|
||||
file_batches.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.to_raw_response_wrapper(
|
||||
file_batches.retrieve,
|
||||
)
|
||||
self.cancel = _legacy_response.to_raw_response_wrapper(
|
||||
file_batches.cancel,
|
||||
)
|
||||
self.list_files = _legacy_response.to_raw_response_wrapper(
|
||||
file_batches.list_files,
|
||||
)
|
||||
|
||||
|
||||
class AsyncFileBatchesWithRawResponse:
|
||||
def __init__(self, file_batches: AsyncFileBatches) -> None:
|
||||
self._file_batches = file_batches
|
||||
|
||||
self.create = _legacy_response.async_to_raw_response_wrapper(
|
||||
file_batches.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.async_to_raw_response_wrapper(
|
||||
file_batches.retrieve,
|
||||
)
|
||||
self.cancel = _legacy_response.async_to_raw_response_wrapper(
|
||||
file_batches.cancel,
|
||||
)
|
||||
self.list_files = _legacy_response.async_to_raw_response_wrapper(
|
||||
file_batches.list_files,
|
||||
)
|
||||
|
||||
|
||||
class FileBatchesWithStreamingResponse:
|
||||
def __init__(self, file_batches: FileBatches) -> None:
|
||||
self._file_batches = file_batches
|
||||
|
||||
self.create = to_streamed_response_wrapper(
|
||||
file_batches.create,
|
||||
)
|
||||
self.retrieve = to_streamed_response_wrapper(
|
||||
file_batches.retrieve,
|
||||
)
|
||||
self.cancel = to_streamed_response_wrapper(
|
||||
file_batches.cancel,
|
||||
)
|
||||
self.list_files = to_streamed_response_wrapper(
|
||||
file_batches.list_files,
|
||||
)
|
||||
|
||||
|
||||
class AsyncFileBatchesWithStreamingResponse:
|
||||
def __init__(self, file_batches: AsyncFileBatches) -> None:
|
||||
self._file_batches = file_batches
|
||||
|
||||
self.create = async_to_streamed_response_wrapper(
|
||||
file_batches.create,
|
||||
)
|
||||
self.retrieve = async_to_streamed_response_wrapper(
|
||||
file_batches.retrieve,
|
||||
)
|
||||
self.cancel = async_to_streamed_response_wrapper(
|
||||
file_batches.cancel,
|
||||
)
|
||||
self.list_files = async_to_streamed_response_wrapper(
|
||||
file_batches.list_files,
|
||||
)
|
||||
+726
@@ -0,0 +1,726 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing_extensions import Literal, assert_never
|
||||
|
||||
import httpx
|
||||
|
||||
from .... import _legacy_response
|
||||
from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven, FileTypes
|
||||
from ...._utils import (
|
||||
is_given,
|
||||
maybe_transform,
|
||||
async_maybe_transform,
|
||||
)
|
||||
from ...._compat import cached_property
|
||||
from ...._resource import SyncAPIResource, AsyncAPIResource
|
||||
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
|
||||
from ....pagination import SyncCursorPage, AsyncCursorPage
|
||||
from ....types.beta import FileChunkingStrategyParam
|
||||
from ...._base_client import AsyncPaginator, make_request_options
|
||||
from ....types.beta.vector_stores import file_list_params, file_create_params
|
||||
from ....types.beta.file_chunking_strategy_param import FileChunkingStrategyParam
|
||||
from ....types.beta.vector_stores.vector_store_file import VectorStoreFile
|
||||
from ....types.beta.vector_stores.vector_store_file_deleted import VectorStoreFileDeleted
|
||||
|
||||
__all__ = ["Files", "AsyncFiles"]
|
||||
|
||||
|
||||
class Files(SyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> FilesWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return FilesWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> FilesWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return FilesWithStreamingResponse(self)
|
||||
|
||||
def create(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
file_id: str,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""
|
||||
Create a vector store file by attaching a
|
||||
[File](https://platform.openai.com/docs/api-reference/files) to a
|
||||
[vector store](https://platform.openai.com/docs/api-reference/vector-stores/object).
|
||||
|
||||
Args:
|
||||
file_id: A [File](https://platform.openai.com/docs/api-reference/files) ID that the
|
||||
vector store should use. Useful for tools like `file_search` that can access
|
||||
files.
|
||||
|
||||
chunking_strategy: The chunking strategy used to chunk the file(s). If not set, will use the `auto`
|
||||
strategy. Only applicable if `file_ids` is non-empty.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
f"/vector_stores/{vector_store_id}/files",
|
||||
body=maybe_transform(
|
||||
{
|
||||
"file_id": file_id,
|
||||
"chunking_strategy": chunking_strategy,
|
||||
},
|
||||
file_create_params.FileCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFile,
|
||||
)
|
||||
|
||||
def retrieve(
|
||||
self,
|
||||
file_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""
|
||||
Retrieves a vector store file.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not file_id:
|
||||
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get(
|
||||
f"/vector_stores/{vector_store_id}/files/{file_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFile,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
filter: Literal["in_progress", "completed", "failed", "cancelled"] | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> SyncCursorPage[VectorStoreFile]:
|
||||
"""
|
||||
Returns a list of vector store files.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination. `after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
filter: Filter by file status. One of `in_progress`, `completed`, `failed`, `cancelled`.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
f"/vector_stores/{vector_store_id}/files",
|
||||
page=SyncCursorPage[VectorStoreFile],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"filter": filter,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
file_list_params.FileListParams,
|
||||
),
|
||||
),
|
||||
model=VectorStoreFile,
|
||||
)
|
||||
|
||||
def delete(
|
||||
self,
|
||||
file_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileDeleted:
|
||||
"""Delete a vector store file.
|
||||
|
||||
This will remove the file from the vector store but
|
||||
the file itself will not be deleted. To delete the file, use the
|
||||
[delete file](https://platform.openai.com/docs/api-reference/files/delete)
|
||||
endpoint.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not file_id:
|
||||
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._delete(
|
||||
f"/vector_stores/{vector_store_id}/files/{file_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFileDeleted,
|
||||
)
|
||||
|
||||
def create_and_poll(
|
||||
self,
|
||||
file_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""Attach a file to the given vector store and wait for it to be processed."""
|
||||
self.create(vector_store_id=vector_store_id, file_id=file_id, chunking_strategy=chunking_strategy)
|
||||
|
||||
return self.poll(
|
||||
file_id,
|
||||
vector_store_id=vector_store_id,
|
||||
poll_interval_ms=poll_interval_ms,
|
||||
)
|
||||
|
||||
def poll(
|
||||
self,
|
||||
file_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""Wait for the vector store file to finish processing.
|
||||
|
||||
Note: this will return even if the file failed to process, you need to check
|
||||
file.last_error and file.status to handle these cases
|
||||
"""
|
||||
headers: dict[str, str] = {"X-Stainless-Poll-Helper": "true"}
|
||||
if is_given(poll_interval_ms):
|
||||
headers["X-Stainless-Custom-Poll-Interval"] = str(poll_interval_ms)
|
||||
|
||||
while True:
|
||||
response = self.with_raw_response.retrieve(
|
||||
file_id,
|
||||
vector_store_id=vector_store_id,
|
||||
extra_headers=headers,
|
||||
)
|
||||
|
||||
file = response.parse()
|
||||
if file.status == "in_progress":
|
||||
if not is_given(poll_interval_ms):
|
||||
from_header = response.headers.get("openai-poll-after-ms")
|
||||
if from_header is not None:
|
||||
poll_interval_ms = int(from_header)
|
||||
else:
|
||||
poll_interval_ms = 1000
|
||||
|
||||
self._sleep(poll_interval_ms / 1000)
|
||||
elif file.status == "cancelled" or file.status == "completed" or file.status == "failed":
|
||||
return file
|
||||
else:
|
||||
if TYPE_CHECKING: # type: ignore[unreachable]
|
||||
assert_never(file.status)
|
||||
else:
|
||||
return file
|
||||
|
||||
def upload(
|
||||
self,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
file: FileTypes,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""Upload a file to the `files` API and then attach it to the given vector store.
|
||||
|
||||
Note the file will be asynchronously processed (you can use the alternative
|
||||
polling helper method to wait for processing to complete).
|
||||
"""
|
||||
file_obj = self._client.files.create(file=file, purpose="assistants")
|
||||
return self.create(vector_store_id=vector_store_id, file_id=file_obj.id, chunking_strategy=chunking_strategy)
|
||||
|
||||
def upload_and_poll(
|
||||
self,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
file: FileTypes,
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""Add a file to a vector store and poll until processing is complete."""
|
||||
file_obj = self._client.files.create(file=file, purpose="assistants")
|
||||
return self.create_and_poll(
|
||||
vector_store_id=vector_store_id,
|
||||
file_id=file_obj.id,
|
||||
chunking_strategy=chunking_strategy,
|
||||
poll_interval_ms=poll_interval_ms,
|
||||
)
|
||||
|
||||
|
||||
class AsyncFiles(AsyncAPIResource):
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncFilesWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncFilesWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncFilesWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncFilesWithStreamingResponse(self)
|
||||
|
||||
async def create(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
file_id: str,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""
|
||||
Create a vector store file by attaching a
|
||||
[File](https://platform.openai.com/docs/api-reference/files) to a
|
||||
[vector store](https://platform.openai.com/docs/api-reference/vector-stores/object).
|
||||
|
||||
Args:
|
||||
file_id: A [File](https://platform.openai.com/docs/api-reference/files) ID that the
|
||||
vector store should use. Useful for tools like `file_search` that can access
|
||||
files.
|
||||
|
||||
chunking_strategy: The chunking strategy used to chunk the file(s). If not set, will use the `auto`
|
||||
strategy. Only applicable if `file_ids` is non-empty.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
f"/vector_stores/{vector_store_id}/files",
|
||||
body=await async_maybe_transform(
|
||||
{
|
||||
"file_id": file_id,
|
||||
"chunking_strategy": chunking_strategy,
|
||||
},
|
||||
file_create_params.FileCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFile,
|
||||
)
|
||||
|
||||
async def retrieve(
|
||||
self,
|
||||
file_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""
|
||||
Retrieves a vector store file.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not file_id:
|
||||
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._get(
|
||||
f"/vector_stores/{vector_store_id}/files/{file_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFile,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
filter: Literal["in_progress", "completed", "failed", "cancelled"] | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> AsyncPaginator[VectorStoreFile, AsyncCursorPage[VectorStoreFile]]:
|
||||
"""
|
||||
Returns a list of vector store files.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination. `after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
filter: Filter by file status. One of `in_progress`, `completed`, `failed`, `cancelled`.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
f"/vector_stores/{vector_store_id}/files",
|
||||
page=AsyncCursorPage[VectorStoreFile],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"filter": filter,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
file_list_params.FileListParams,
|
||||
),
|
||||
),
|
||||
model=VectorStoreFile,
|
||||
)
|
||||
|
||||
async def delete(
|
||||
self,
|
||||
file_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFileDeleted:
|
||||
"""Delete a vector store file.
|
||||
|
||||
This will remove the file from the vector store but
|
||||
the file itself will not be deleted. To delete the file, use the
|
||||
[delete file](https://platform.openai.com/docs/api-reference/files/delete)
|
||||
endpoint.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
if not file_id:
|
||||
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._delete(
|
||||
f"/vector_stores/{vector_store_id}/files/{file_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreFileDeleted,
|
||||
)
|
||||
|
||||
async def create_and_poll(
|
||||
self,
|
||||
file_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""Attach a file to the given vector store and wait for it to be processed."""
|
||||
await self.create(vector_store_id=vector_store_id, file_id=file_id, chunking_strategy=chunking_strategy)
|
||||
|
||||
return await self.poll(
|
||||
file_id,
|
||||
vector_store_id=vector_store_id,
|
||||
poll_interval_ms=poll_interval_ms,
|
||||
)
|
||||
|
||||
async def poll(
|
||||
self,
|
||||
file_id: str,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""Wait for the vector store file to finish processing.
|
||||
|
||||
Note: this will return even if the file failed to process, you need to check
|
||||
file.last_error and file.status to handle these cases
|
||||
"""
|
||||
headers: dict[str, str] = {"X-Stainless-Poll-Helper": "true"}
|
||||
if is_given(poll_interval_ms):
|
||||
headers["X-Stainless-Custom-Poll-Interval"] = str(poll_interval_ms)
|
||||
|
||||
while True:
|
||||
response = await self.with_raw_response.retrieve(
|
||||
file_id,
|
||||
vector_store_id=vector_store_id,
|
||||
extra_headers=headers,
|
||||
)
|
||||
|
||||
file = response.parse()
|
||||
if file.status == "in_progress":
|
||||
if not is_given(poll_interval_ms):
|
||||
from_header = response.headers.get("openai-poll-after-ms")
|
||||
if from_header is not None:
|
||||
poll_interval_ms = int(from_header)
|
||||
else:
|
||||
poll_interval_ms = 1000
|
||||
|
||||
await self._sleep(poll_interval_ms / 1000)
|
||||
elif file.status == "cancelled" or file.status == "completed" or file.status == "failed":
|
||||
return file
|
||||
else:
|
||||
if TYPE_CHECKING: # type: ignore[unreachable]
|
||||
assert_never(file.status)
|
||||
else:
|
||||
return file
|
||||
|
||||
async def upload(
|
||||
self,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
file: FileTypes,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""Upload a file to the `files` API and then attach it to the given vector store.
|
||||
|
||||
Note the file will be asynchronously processed (you can use the alternative
|
||||
polling helper method to wait for processing to complete).
|
||||
"""
|
||||
file_obj = await self._client.files.create(file=file, purpose="assistants")
|
||||
return await self.create(
|
||||
vector_store_id=vector_store_id, file_id=file_obj.id, chunking_strategy=chunking_strategy
|
||||
)
|
||||
|
||||
async def upload_and_poll(
|
||||
self,
|
||||
*,
|
||||
vector_store_id: str,
|
||||
file: FileTypes,
|
||||
poll_interval_ms: int | NotGiven = NOT_GIVEN,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreFile:
|
||||
"""Add a file to a vector store and poll until processing is complete."""
|
||||
file_obj = await self._client.files.create(file=file, purpose="assistants")
|
||||
return await self.create_and_poll(
|
||||
vector_store_id=vector_store_id,
|
||||
file_id=file_obj.id,
|
||||
poll_interval_ms=poll_interval_ms,
|
||||
chunking_strategy=chunking_strategy,
|
||||
)
|
||||
|
||||
|
||||
class FilesWithRawResponse:
|
||||
def __init__(self, files: Files) -> None:
|
||||
self._files = files
|
||||
|
||||
self.create = _legacy_response.to_raw_response_wrapper(
|
||||
files.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.to_raw_response_wrapper(
|
||||
files.retrieve,
|
||||
)
|
||||
self.list = _legacy_response.to_raw_response_wrapper(
|
||||
files.list,
|
||||
)
|
||||
self.delete = _legacy_response.to_raw_response_wrapper(
|
||||
files.delete,
|
||||
)
|
||||
|
||||
|
||||
class AsyncFilesWithRawResponse:
|
||||
def __init__(self, files: AsyncFiles) -> None:
|
||||
self._files = files
|
||||
|
||||
self.create = _legacy_response.async_to_raw_response_wrapper(
|
||||
files.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.async_to_raw_response_wrapper(
|
||||
files.retrieve,
|
||||
)
|
||||
self.list = _legacy_response.async_to_raw_response_wrapper(
|
||||
files.list,
|
||||
)
|
||||
self.delete = _legacy_response.async_to_raw_response_wrapper(
|
||||
files.delete,
|
||||
)
|
||||
|
||||
|
||||
class FilesWithStreamingResponse:
|
||||
def __init__(self, files: Files) -> None:
|
||||
self._files = files
|
||||
|
||||
self.create = to_streamed_response_wrapper(
|
||||
files.create,
|
||||
)
|
||||
self.retrieve = to_streamed_response_wrapper(
|
||||
files.retrieve,
|
||||
)
|
||||
self.list = to_streamed_response_wrapper(
|
||||
files.list,
|
||||
)
|
||||
self.delete = to_streamed_response_wrapper(
|
||||
files.delete,
|
||||
)
|
||||
|
||||
|
||||
class AsyncFilesWithStreamingResponse:
|
||||
def __init__(self, files: AsyncFiles) -> None:
|
||||
self._files = files
|
||||
|
||||
self.create = async_to_streamed_response_wrapper(
|
||||
files.create,
|
||||
)
|
||||
self.retrieve = async_to_streamed_response_wrapper(
|
||||
files.retrieve,
|
||||
)
|
||||
self.list = async_to_streamed_response_wrapper(
|
||||
files.list,
|
||||
)
|
||||
self.delete = async_to_streamed_response_wrapper(
|
||||
files.delete,
|
||||
)
|
||||
+719
@@ -0,0 +1,719 @@
|
||||
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Optional
|
||||
from typing_extensions import Literal
|
||||
|
||||
import httpx
|
||||
|
||||
from .... import _legacy_response
|
||||
from .files import (
|
||||
Files,
|
||||
AsyncFiles,
|
||||
FilesWithRawResponse,
|
||||
AsyncFilesWithRawResponse,
|
||||
FilesWithStreamingResponse,
|
||||
AsyncFilesWithStreamingResponse,
|
||||
)
|
||||
from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
||||
from ...._utils import (
|
||||
maybe_transform,
|
||||
async_maybe_transform,
|
||||
)
|
||||
from ...._compat import cached_property
|
||||
from ...._resource import SyncAPIResource, AsyncAPIResource
|
||||
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
|
||||
from .file_batches import (
|
||||
FileBatches,
|
||||
AsyncFileBatches,
|
||||
FileBatchesWithRawResponse,
|
||||
AsyncFileBatchesWithRawResponse,
|
||||
FileBatchesWithStreamingResponse,
|
||||
AsyncFileBatchesWithStreamingResponse,
|
||||
)
|
||||
from ....pagination import SyncCursorPage, AsyncCursorPage
|
||||
from ....types.beta import (
|
||||
FileChunkingStrategyParam,
|
||||
vector_store_list_params,
|
||||
vector_store_create_params,
|
||||
vector_store_update_params,
|
||||
)
|
||||
from ...._base_client import AsyncPaginator, make_request_options
|
||||
from ....types.beta.vector_store import VectorStore
|
||||
from ....types.beta.vector_store_deleted import VectorStoreDeleted
|
||||
from ....types.beta.file_chunking_strategy_param import FileChunkingStrategyParam
|
||||
|
||||
__all__ = ["VectorStores", "AsyncVectorStores"]
|
||||
|
||||
|
||||
class VectorStores(SyncAPIResource):
|
||||
@cached_property
|
||||
def files(self) -> Files:
|
||||
return Files(self._client)
|
||||
|
||||
@cached_property
|
||||
def file_batches(self) -> FileBatches:
|
||||
return FileBatches(self._client)
|
||||
|
||||
@cached_property
|
||||
def with_raw_response(self) -> VectorStoresWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return VectorStoresWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> VectorStoresWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return VectorStoresWithStreamingResponse(self)
|
||||
|
||||
def create(
|
||||
self,
|
||||
*,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
expires_after: vector_store_create_params.ExpiresAfter | NotGiven = NOT_GIVEN,
|
||||
file_ids: List[str] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
name: str | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStore:
|
||||
"""
|
||||
Create a vector store.
|
||||
|
||||
Args:
|
||||
chunking_strategy: The chunking strategy used to chunk the file(s). If not set, will use the `auto`
|
||||
strategy. Only applicable if `file_ids` is non-empty.
|
||||
|
||||
expires_after: The expiration policy for a vector store.
|
||||
|
||||
file_ids: A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that
|
||||
the vector store should use. Useful for tools like `file_search` that can access
|
||||
files.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
name: The name of the vector store.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
"/vector_stores",
|
||||
body=maybe_transform(
|
||||
{
|
||||
"chunking_strategy": chunking_strategy,
|
||||
"expires_after": expires_after,
|
||||
"file_ids": file_ids,
|
||||
"metadata": metadata,
|
||||
"name": name,
|
||||
},
|
||||
vector_store_create_params.VectorStoreCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStore,
|
||||
)
|
||||
|
||||
def retrieve(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStore:
|
||||
"""
|
||||
Retrieves a vector store.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get(
|
||||
f"/vector_stores/{vector_store_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStore,
|
||||
)
|
||||
|
||||
def update(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
expires_after: Optional[vector_store_update_params.ExpiresAfter] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
name: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStore:
|
||||
"""
|
||||
Modifies a vector store.
|
||||
|
||||
Args:
|
||||
expires_after: The expiration policy for a vector store.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
name: The name of the vector store.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._post(
|
||||
f"/vector_stores/{vector_store_id}",
|
||||
body=maybe_transform(
|
||||
{
|
||||
"expires_after": expires_after,
|
||||
"metadata": metadata,
|
||||
"name": name,
|
||||
},
|
||||
vector_store_update_params.VectorStoreUpdateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStore,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
*,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> SyncCursorPage[VectorStore]:
|
||||
"""Returns a list of vector stores.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination.
|
||||
|
||||
`after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
"/vector_stores",
|
||||
page=SyncCursorPage[VectorStore],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
vector_store_list_params.VectorStoreListParams,
|
||||
),
|
||||
),
|
||||
model=VectorStore,
|
||||
)
|
||||
|
||||
def delete(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreDeleted:
|
||||
"""
|
||||
Delete a vector store.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._delete(
|
||||
f"/vector_stores/{vector_store_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreDeleted,
|
||||
)
|
||||
|
||||
|
||||
class AsyncVectorStores(AsyncAPIResource):
|
||||
@cached_property
|
||||
def files(self) -> AsyncFiles:
|
||||
return AsyncFiles(self._client)
|
||||
|
||||
@cached_property
|
||||
def file_batches(self) -> AsyncFileBatches:
|
||||
return AsyncFileBatches(self._client)
|
||||
|
||||
@cached_property
|
||||
def with_raw_response(self) -> AsyncVectorStoresWithRawResponse:
|
||||
"""
|
||||
This property can be used as a prefix for any HTTP method call to return the
|
||||
the raw response object instead of the parsed content.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
|
||||
"""
|
||||
return AsyncVectorStoresWithRawResponse(self)
|
||||
|
||||
@cached_property
|
||||
def with_streaming_response(self) -> AsyncVectorStoresWithStreamingResponse:
|
||||
"""
|
||||
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
||||
|
||||
For more information, see https://www.github.com/openai/openai-python#with_streaming_response
|
||||
"""
|
||||
return AsyncVectorStoresWithStreamingResponse(self)
|
||||
|
||||
async def create(
|
||||
self,
|
||||
*,
|
||||
chunking_strategy: FileChunkingStrategyParam | NotGiven = NOT_GIVEN,
|
||||
expires_after: vector_store_create_params.ExpiresAfter | NotGiven = NOT_GIVEN,
|
||||
file_ids: List[str] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
name: str | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStore:
|
||||
"""
|
||||
Create a vector store.
|
||||
|
||||
Args:
|
||||
chunking_strategy: The chunking strategy used to chunk the file(s). If not set, will use the `auto`
|
||||
strategy. Only applicable if `file_ids` is non-empty.
|
||||
|
||||
expires_after: The expiration policy for a vector store.
|
||||
|
||||
file_ids: A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that
|
||||
the vector store should use. Useful for tools like `file_search` that can access
|
||||
files.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
name: The name of the vector store.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
"/vector_stores",
|
||||
body=await async_maybe_transform(
|
||||
{
|
||||
"chunking_strategy": chunking_strategy,
|
||||
"expires_after": expires_after,
|
||||
"file_ids": file_ids,
|
||||
"metadata": metadata,
|
||||
"name": name,
|
||||
},
|
||||
vector_store_create_params.VectorStoreCreateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStore,
|
||||
)
|
||||
|
||||
async def retrieve(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStore:
|
||||
"""
|
||||
Retrieves a vector store.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._get(
|
||||
f"/vector_stores/{vector_store_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStore,
|
||||
)
|
||||
|
||||
async def update(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
expires_after: Optional[vector_store_update_params.ExpiresAfter] | NotGiven = NOT_GIVEN,
|
||||
metadata: Optional[object] | NotGiven = NOT_GIVEN,
|
||||
name: Optional[str] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStore:
|
||||
"""
|
||||
Modifies a vector store.
|
||||
|
||||
Args:
|
||||
expires_after: The expiration policy for a vector store.
|
||||
|
||||
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
|
||||
for storing additional information about the object in a structured format. Keys
|
||||
can be a maximum of 64 characters long and values can be a maximum of 512
|
||||
characters long.
|
||||
|
||||
name: The name of the vector store.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._post(
|
||||
f"/vector_stores/{vector_store_id}",
|
||||
body=await async_maybe_transform(
|
||||
{
|
||||
"expires_after": expires_after,
|
||||
"metadata": metadata,
|
||||
"name": name,
|
||||
},
|
||||
vector_store_update_params.VectorStoreUpdateParams,
|
||||
),
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStore,
|
||||
)
|
||||
|
||||
def list(
|
||||
self,
|
||||
*,
|
||||
after: str | NotGiven = NOT_GIVEN,
|
||||
before: str | NotGiven = NOT_GIVEN,
|
||||
limit: int | NotGiven = NOT_GIVEN,
|
||||
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> AsyncPaginator[VectorStore, AsyncCursorPage[VectorStore]]:
|
||||
"""Returns a list of vector stores.
|
||||
|
||||
Args:
|
||||
after: A cursor for use in pagination.
|
||||
|
||||
`after` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
||||
fetch the next page of the list.
|
||||
|
||||
before: A cursor for use in pagination. `before` is an object ID that defines your place
|
||||
in the list. For instance, if you make a list request and receive 100 objects,
|
||||
starting with obj_foo, your subsequent call can include before=obj_foo in order
|
||||
to fetch the previous page of the list.
|
||||
|
||||
limit: A limit on the number of objects to be returned. Limit can range between 1 and
|
||||
100, and the default is 20.
|
||||
|
||||
order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending
|
||||
order and `desc` for descending order.
|
||||
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return self._get_api_list(
|
||||
"/vector_stores",
|
||||
page=AsyncCursorPage[VectorStore],
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers,
|
||||
extra_query=extra_query,
|
||||
extra_body=extra_body,
|
||||
timeout=timeout,
|
||||
query=maybe_transform(
|
||||
{
|
||||
"after": after,
|
||||
"before": before,
|
||||
"limit": limit,
|
||||
"order": order,
|
||||
},
|
||||
vector_store_list_params.VectorStoreListParams,
|
||||
),
|
||||
),
|
||||
model=VectorStore,
|
||||
)
|
||||
|
||||
async def delete(
|
||||
self,
|
||||
vector_store_id: str,
|
||||
*,
|
||||
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
||||
# The extra values given here take precedence over values defined on the client or passed to this method.
|
||||
extra_headers: Headers | None = None,
|
||||
extra_query: Query | None = None,
|
||||
extra_body: Body | None = None,
|
||||
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
||||
) -> VectorStoreDeleted:
|
||||
"""
|
||||
Delete a vector store.
|
||||
|
||||
Args:
|
||||
extra_headers: Send extra headers
|
||||
|
||||
extra_query: Add additional query parameters to the request
|
||||
|
||||
extra_body: Add additional JSON properties to the request
|
||||
|
||||
timeout: Override the client-level default timeout for this request, in seconds
|
||||
"""
|
||||
if not vector_store_id:
|
||||
raise ValueError(f"Expected a non-empty value for `vector_store_id` but received {vector_store_id!r}")
|
||||
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
|
||||
return await self._delete(
|
||||
f"/vector_stores/{vector_store_id}",
|
||||
options=make_request_options(
|
||||
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
||||
),
|
||||
cast_to=VectorStoreDeleted,
|
||||
)
|
||||
|
||||
|
||||
class VectorStoresWithRawResponse:
|
||||
def __init__(self, vector_stores: VectorStores) -> None:
|
||||
self._vector_stores = vector_stores
|
||||
|
||||
self.create = _legacy_response.to_raw_response_wrapper(
|
||||
vector_stores.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.to_raw_response_wrapper(
|
||||
vector_stores.retrieve,
|
||||
)
|
||||
self.update = _legacy_response.to_raw_response_wrapper(
|
||||
vector_stores.update,
|
||||
)
|
||||
self.list = _legacy_response.to_raw_response_wrapper(
|
||||
vector_stores.list,
|
||||
)
|
||||
self.delete = _legacy_response.to_raw_response_wrapper(
|
||||
vector_stores.delete,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def files(self) -> FilesWithRawResponse:
|
||||
return FilesWithRawResponse(self._vector_stores.files)
|
||||
|
||||
@cached_property
|
||||
def file_batches(self) -> FileBatchesWithRawResponse:
|
||||
return FileBatchesWithRawResponse(self._vector_stores.file_batches)
|
||||
|
||||
|
||||
class AsyncVectorStoresWithRawResponse:
|
||||
def __init__(self, vector_stores: AsyncVectorStores) -> None:
|
||||
self._vector_stores = vector_stores
|
||||
|
||||
self.create = _legacy_response.async_to_raw_response_wrapper(
|
||||
vector_stores.create,
|
||||
)
|
||||
self.retrieve = _legacy_response.async_to_raw_response_wrapper(
|
||||
vector_stores.retrieve,
|
||||
)
|
||||
self.update = _legacy_response.async_to_raw_response_wrapper(
|
||||
vector_stores.update,
|
||||
)
|
||||
self.list = _legacy_response.async_to_raw_response_wrapper(
|
||||
vector_stores.list,
|
||||
)
|
||||
self.delete = _legacy_response.async_to_raw_response_wrapper(
|
||||
vector_stores.delete,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def files(self) -> AsyncFilesWithRawResponse:
|
||||
return AsyncFilesWithRawResponse(self._vector_stores.files)
|
||||
|
||||
@cached_property
|
||||
def file_batches(self) -> AsyncFileBatchesWithRawResponse:
|
||||
return AsyncFileBatchesWithRawResponse(self._vector_stores.file_batches)
|
||||
|
||||
|
||||
class VectorStoresWithStreamingResponse:
|
||||
def __init__(self, vector_stores: VectorStores) -> None:
|
||||
self._vector_stores = vector_stores
|
||||
|
||||
self.create = to_streamed_response_wrapper(
|
||||
vector_stores.create,
|
||||
)
|
||||
self.retrieve = to_streamed_response_wrapper(
|
||||
vector_stores.retrieve,
|
||||
)
|
||||
self.update = to_streamed_response_wrapper(
|
||||
vector_stores.update,
|
||||
)
|
||||
self.list = to_streamed_response_wrapper(
|
||||
vector_stores.list,
|
||||
)
|
||||
self.delete = to_streamed_response_wrapper(
|
||||
vector_stores.delete,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def files(self) -> FilesWithStreamingResponse:
|
||||
return FilesWithStreamingResponse(self._vector_stores.files)
|
||||
|
||||
@cached_property
|
||||
def file_batches(self) -> FileBatchesWithStreamingResponse:
|
||||
return FileBatchesWithStreamingResponse(self._vector_stores.file_batches)
|
||||
|
||||
|
||||
class AsyncVectorStoresWithStreamingResponse:
|
||||
def __init__(self, vector_stores: AsyncVectorStores) -> None:
|
||||
self._vector_stores = vector_stores
|
||||
|
||||
self.create = async_to_streamed_response_wrapper(
|
||||
vector_stores.create,
|
||||
)
|
||||
self.retrieve = async_to_streamed_response_wrapper(
|
||||
vector_stores.retrieve,
|
||||
)
|
||||
self.update = async_to_streamed_response_wrapper(
|
||||
vector_stores.update,
|
||||
)
|
||||
self.list = async_to_streamed_response_wrapper(
|
||||
vector_stores.list,
|
||||
)
|
||||
self.delete = async_to_streamed_response_wrapper(
|
||||
vector_stores.delete,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def files(self) -> AsyncFilesWithStreamingResponse:
|
||||
return AsyncFilesWithStreamingResponse(self._vector_stores.files)
|
||||
|
||||
@cached_property
|
||||
def file_batches(self) -> AsyncFileBatchesWithStreamingResponse:
|
||||
return AsyncFileBatchesWithStreamingResponse(self._vector_stores.file_batches)
|
||||
Reference in New Issue
Block a user