embeddings.py 12 KB

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