main
1# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
3from __future__ import annotations
4
5import array
6import base64
7from typing import Union, Iterable, cast
8from typing_extensions import Literal
9
10import httpx
11
12from .. import _legacy_response
13from ..types import embedding_create_params
14from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
15from .._utils import is_given, maybe_transform
16from .._compat import cached_property
17from .._extras import numpy as np, has_numpy
18from .._resource import SyncAPIResource, AsyncAPIResource
19from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
20from .._base_client import make_request_options
21from ..types.embedding_model import EmbeddingModel
22from ..types.create_embedding_response import CreateEmbeddingResponse
23
24__all__ = ["Embeddings", "AsyncEmbeddings"]
25
26
27class Embeddings(SyncAPIResource):
28 @cached_property
29 def with_raw_response(self) -> EmbeddingsWithRawResponse:
30 """
31 This property can be used as a prefix for any HTTP method call to return
32 the raw response object instead of the parsed content.
33
34 For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
35 """
36 return EmbeddingsWithRawResponse(self)
37
38 @cached_property
39 def with_streaming_response(self) -> EmbeddingsWithStreamingResponse:
40 """
41 An alternative to `.with_raw_response` that doesn't eagerly read the response body.
42
43 For more information, see https://www.github.com/openai/openai-python#with_streaming_response
44 """
45 return EmbeddingsWithStreamingResponse(self)
46
47 def create(
48 self,
49 *,
50 input: Union[str, SequenceNotStr[str], Iterable[int], Iterable[Iterable[int]]],
51 model: Union[str, EmbeddingModel],
52 dimensions: int | Omit = omit,
53 encoding_format: Literal["float", "base64"] | Omit = omit,
54 user: str | Omit = omit,
55 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
56 # The extra values given here take precedence over values defined on the client or passed to this method.
57 extra_headers: Headers | None = None,
58 extra_query: Query | None = None,
59 extra_body: Body | None = None,
60 timeout: float | httpx.Timeout | None | NotGiven = not_given,
61 ) -> CreateEmbeddingResponse:
62 """
63 Creates an embedding vector representing the input text.
64
65 Args:
66 input: Input text to embed, encoded as a string or array of tokens. To embed multiple
67 inputs in a single request, pass an array of strings or array of token arrays.
68 The input must not exceed the max input tokens for the model (8192 tokens for
69 all embedding models), cannot be an empty string, and any array must be 2048
70 dimensions or less.
71 [Example Python code](https://cookbook.openai.com/examples/how_to_count_tokens_with_tiktoken)
72 for counting tokens. In addition to the per-input token limit, all embedding
73 models enforce a maximum of 300,000 tokens summed across all inputs in a single
74 request.
75
76 model: ID of the model to use. You can use the
77 [List models](https://platform.openai.com/docs/api-reference/models/list) API to
78 see all of your available models, or see our
79 [Model overview](https://platform.openai.com/docs/models) for descriptions of
80 them.
81
82 dimensions: The number of dimensions the resulting output embeddings should have. Only
83 supported in `text-embedding-3` and later models.
84
85 encoding_format: The format to return the embeddings in. Can be either `float` or
86 [`base64`](https://pypi.org/project/pybase64/).
87
88 user: A unique identifier representing your end-user, which can help OpenAI to monitor
89 and detect abuse.
90 [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids).
91
92 extra_headers: Send extra headers
93
94 extra_query: Add additional query parameters to the request
95
96 extra_body: Add additional JSON properties to the request
97
98 timeout: Override the client-level default timeout for this request, in seconds
99 """
100 params = {
101 "input": input,
102 "model": model,
103 "user": user,
104 "dimensions": dimensions,
105 "encoding_format": encoding_format,
106 }
107 if not is_given(encoding_format):
108 params["encoding_format"] = "base64"
109
110 def parser(obj: CreateEmbeddingResponse) -> CreateEmbeddingResponse:
111 if is_given(encoding_format):
112 # don't modify the response object if a user explicitly asked for a format
113 return obj
114
115 if not obj.data:
116 raise ValueError("No embedding data received")
117
118 for embedding in obj.data:
119 data = cast(object, embedding.embedding)
120 if not isinstance(data, str):
121 continue
122 if not has_numpy():
123 # use array for base64 optimisation
124 embedding.embedding = array.array("f", base64.b64decode(data)).tolist()
125 else:
126 embedding.embedding = np.frombuffer( # type: ignore[no-untyped-call]
127 base64.b64decode(data), dtype="float32"
128 ).tolist()
129
130 return obj
131
132 return self._post(
133 "/embeddings",
134 body=maybe_transform(params, embedding_create_params.EmbeddingCreateParams),
135 options=make_request_options(
136 extra_headers=extra_headers,
137 extra_query=extra_query,
138 extra_body=extra_body,
139 timeout=timeout,
140 post_parser=parser,
141 ),
142 cast_to=CreateEmbeddingResponse,
143 )
144
145
146class AsyncEmbeddings(AsyncAPIResource):
147 @cached_property
148 def with_raw_response(self) -> AsyncEmbeddingsWithRawResponse:
149 """
150 This property can be used as a prefix for any HTTP method call to return
151 the raw response object instead of the parsed content.
152
153 For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
154 """
155 return AsyncEmbeddingsWithRawResponse(self)
156
157 @cached_property
158 def with_streaming_response(self) -> AsyncEmbeddingsWithStreamingResponse:
159 """
160 An alternative to `.with_raw_response` that doesn't eagerly read the response body.
161
162 For more information, see https://www.github.com/openai/openai-python#with_streaming_response
163 """
164 return AsyncEmbeddingsWithStreamingResponse(self)
165
166 async def create(
167 self,
168 *,
169 input: Union[str, SequenceNotStr[str], Iterable[int], Iterable[Iterable[int]]],
170 model: Union[str, EmbeddingModel],
171 dimensions: int | Omit = omit,
172 encoding_format: Literal["float", "base64"] | Omit = omit,
173 user: str | Omit = omit,
174 # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
175 # The extra values given here take precedence over values defined on the client or passed to this method.
176 extra_headers: Headers | None = None,
177 extra_query: Query | None = None,
178 extra_body: Body | None = None,
179 timeout: float | httpx.Timeout | None | NotGiven = not_given,
180 ) -> CreateEmbeddingResponse:
181 """
182 Creates an embedding vector representing the input text.
183
184 Args:
185 input: Input text to embed, encoded as a string or array of tokens. To embed multiple
186 inputs in a single request, pass an array of strings or array of token arrays.
187 The input must not exceed the max input tokens for the model (8192 tokens for
188 all embedding models), cannot be an empty string, and any array must be 2048
189 dimensions or less.
190 [Example Python code](https://cookbook.openai.com/examples/how_to_count_tokens_with_tiktoken)
191 for counting tokens. In addition to the per-input token limit, all embedding
192 models enforce a maximum of 300,000 tokens summed across all inputs in a single
193 request.
194
195 model: ID of the model to use. You can use the
196 [List models](https://platform.openai.com/docs/api-reference/models/list) API to
197 see all of your available models, or see our
198 [Model overview](https://platform.openai.com/docs/models) for descriptions of
199 them.
200
201 dimensions: The number of dimensions the resulting output embeddings should have. Only
202 supported in `text-embedding-3` and later models.
203
204 encoding_format: The format to return the embeddings in. Can be either `float` or
205 [`base64`](https://pypi.org/project/pybase64/).
206
207 user: A unique identifier representing your end-user, which can help OpenAI to monitor
208 and detect abuse.
209 [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids).
210
211 extra_headers: Send extra headers
212
213 extra_query: Add additional query parameters to the request
214
215 extra_body: Add additional JSON properties to the request
216
217 timeout: Override the client-level default timeout for this request, in seconds
218 """
219 params = {
220 "input": input,
221 "model": model,
222 "user": user,
223 "dimensions": dimensions,
224 "encoding_format": encoding_format,
225 }
226 if not is_given(encoding_format):
227 params["encoding_format"] = "base64"
228
229 def parser(obj: CreateEmbeddingResponse) -> CreateEmbeddingResponse:
230 if is_given(encoding_format):
231 # don't modify the response object if a user explicitly asked for a format
232 return obj
233
234 if not obj.data:
235 raise ValueError("No embedding data received")
236
237 for embedding in obj.data:
238 data = cast(object, embedding.embedding)
239 if not isinstance(data, str):
240 continue
241 if not has_numpy():
242 # use array for base64 optimisation
243 embedding.embedding = array.array("f", base64.b64decode(data)).tolist()
244 else:
245 embedding.embedding = np.frombuffer( # type: ignore[no-untyped-call]
246 base64.b64decode(data), dtype="float32"
247 ).tolist()
248
249 return obj
250
251 return await self._post(
252 "/embeddings",
253 body=maybe_transform(params, embedding_create_params.EmbeddingCreateParams),
254 options=make_request_options(
255 extra_headers=extra_headers,
256 extra_query=extra_query,
257 extra_body=extra_body,
258 timeout=timeout,
259 post_parser=parser,
260 ),
261 cast_to=CreateEmbeddingResponse,
262 )
263
264
265class EmbeddingsWithRawResponse:
266 def __init__(self, embeddings: Embeddings) -> None:
267 self._embeddings = embeddings
268
269 self.create = _legacy_response.to_raw_response_wrapper(
270 embeddings.create,
271 )
272
273
274class AsyncEmbeddingsWithRawResponse:
275 def __init__(self, embeddings: AsyncEmbeddings) -> None:
276 self._embeddings = embeddings
277
278 self.create = _legacy_response.async_to_raw_response_wrapper(
279 embeddings.create,
280 )
281
282
283class EmbeddingsWithStreamingResponse:
284 def __init__(self, embeddings: Embeddings) -> None:
285 self._embeddings = embeddings
286
287 self.create = to_streamed_response_wrapper(
288 embeddings.create,
289 )
290
291
292class AsyncEmbeddingsWithStreamingResponse:
293 def __init__(self, embeddings: AsyncEmbeddings) -> None:
294 self._embeddings = embeddings
295
296 self.create = async_to_streamed_response_wrapper(
297 embeddings.create,
298 )