_client.py 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272
  1. # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
  2. from __future__ import annotations
  3. import os
  4. from typing import TYPE_CHECKING, Any, Mapping, Callable, Awaitable
  5. from typing_extensions import Self, override
  6. import httpx
  7. from . import _exceptions
  8. from ._qs import Querystring
  9. from ._types import (
  10. Omit,
  11. Timeout,
  12. NotGiven,
  13. Transport,
  14. ProxiesTypes,
  15. RequestOptions,
  16. not_given,
  17. )
  18. from ._utils import (
  19. is_given,
  20. is_mapping,
  21. get_async_library,
  22. )
  23. from ._compat import cached_property
  24. from ._models import FinalRequestOptions
  25. from ._version import __version__
  26. from ._streaming import Stream as Stream, AsyncStream as AsyncStream
  27. from ._exceptions import OpenAIError, APIStatusError
  28. from ._base_client import (
  29. DEFAULT_MAX_RETRIES,
  30. SyncAPIClient,
  31. AsyncAPIClient,
  32. )
  33. if TYPE_CHECKING:
  34. from .resources import (
  35. beta,
  36. chat,
  37. audio,
  38. evals,
  39. files,
  40. images,
  41. models,
  42. videos,
  43. batches,
  44. uploads,
  45. realtime,
  46. responses,
  47. containers,
  48. embeddings,
  49. completions,
  50. fine_tuning,
  51. moderations,
  52. conversations,
  53. vector_stores,
  54. )
  55. from .resources.files import Files, AsyncFiles
  56. from .resources.images import Images, AsyncImages
  57. from .resources.models import Models, AsyncModels
  58. from .resources.videos import Videos, AsyncVideos
  59. from .resources.batches import Batches, AsyncBatches
  60. from .resources.webhooks import Webhooks, AsyncWebhooks
  61. from .resources.beta.beta import Beta, AsyncBeta
  62. from .resources.chat.chat import Chat, AsyncChat
  63. from .resources.embeddings import Embeddings, AsyncEmbeddings
  64. from .resources.audio.audio import Audio, AsyncAudio
  65. from .resources.completions import Completions, AsyncCompletions
  66. from .resources.evals.evals import Evals, AsyncEvals
  67. from .resources.moderations import Moderations, AsyncModerations
  68. from .resources.uploads.uploads import Uploads, AsyncUploads
  69. from .resources.realtime.realtime import Realtime, AsyncRealtime
  70. from .resources.responses.responses import Responses, AsyncResponses
  71. from .resources.containers.containers import Containers, AsyncContainers
  72. from .resources.fine_tuning.fine_tuning import FineTuning, AsyncFineTuning
  73. from .resources.conversations.conversations import Conversations, AsyncConversations
  74. from .resources.vector_stores.vector_stores import VectorStores, AsyncVectorStores
  75. __all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "OpenAI", "AsyncOpenAI", "Client", "AsyncClient"]
  76. class OpenAI(SyncAPIClient):
  77. # client options
  78. api_key: str
  79. organization: str | None
  80. project: str | None
  81. webhook_secret: str | None
  82. websocket_base_url: str | httpx.URL | None
  83. """Base URL for WebSocket connections.
  84. If not specified, the default base URL will be used, with 'wss://' replacing the
  85. 'http://' or 'https://' scheme. For example: 'http://example.com' becomes
  86. 'wss://example.com'
  87. """
  88. def __init__(
  89. self,
  90. *,
  91. api_key: str | None | Callable[[], str] = None,
  92. organization: str | None = None,
  93. project: str | None = None,
  94. webhook_secret: str | None = None,
  95. base_url: str | httpx.URL | None = None,
  96. websocket_base_url: str | httpx.URL | None = None,
  97. timeout: float | Timeout | None | NotGiven = not_given,
  98. max_retries: int = DEFAULT_MAX_RETRIES,
  99. default_headers: Mapping[str, str] | None = None,
  100. default_query: Mapping[str, object] | None = None,
  101. # Configure a custom httpx client.
  102. # We provide a `DefaultHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`.
  103. # See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details.
  104. http_client: httpx.Client | None = None,
  105. # Enable or disable schema validation for data returned by the API.
  106. # When enabled an error APIResponseValidationError is raised
  107. # if the API responds with invalid data for the expected schema.
  108. #
  109. # This parameter may be removed or changed in the future.
  110. # If you rely on this feature, please open a GitHub issue
  111. # outlining your use-case to help us decide if it should be
  112. # part of our public interface in the future.
  113. _strict_response_validation: bool = False,
  114. ) -> None:
  115. """Construct a new synchronous OpenAI client instance.
  116. This automatically infers the following arguments from their corresponding environment variables if they are not provided:
  117. - `api_key` from `OPENAI_API_KEY`
  118. - `organization` from `OPENAI_ORG_ID`
  119. - `project` from `OPENAI_PROJECT_ID`
  120. - `webhook_secret` from `OPENAI_WEBHOOK_SECRET`
  121. """
  122. if api_key is None:
  123. api_key = os.environ.get("OPENAI_API_KEY")
  124. if api_key is None:
  125. raise OpenAIError(
  126. "The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable"
  127. )
  128. if callable(api_key):
  129. self.api_key = ""
  130. self._api_key_provider: Callable[[], str] | None = api_key
  131. else:
  132. self.api_key = api_key
  133. self._api_key_provider = None
  134. if organization is None:
  135. organization = os.environ.get("OPENAI_ORG_ID")
  136. self.organization = organization
  137. if project is None:
  138. project = os.environ.get("OPENAI_PROJECT_ID")
  139. self.project = project
  140. if webhook_secret is None:
  141. webhook_secret = os.environ.get("OPENAI_WEBHOOK_SECRET")
  142. self.webhook_secret = webhook_secret
  143. self.websocket_base_url = websocket_base_url
  144. if base_url is None:
  145. base_url = os.environ.get("OPENAI_BASE_URL")
  146. if base_url is None:
  147. base_url = f"https://api.openai.com/v1"
  148. super().__init__(
  149. version=__version__,
  150. base_url=base_url,
  151. max_retries=max_retries,
  152. timeout=timeout,
  153. http_client=http_client,
  154. custom_headers=default_headers,
  155. custom_query=default_query,
  156. _strict_response_validation=_strict_response_validation,
  157. )
  158. self._default_stream_cls = Stream
  159. @cached_property
  160. def completions(self) -> Completions:
  161. from .resources.completions import Completions
  162. return Completions(self)
  163. @cached_property
  164. def chat(self) -> Chat:
  165. from .resources.chat import Chat
  166. return Chat(self)
  167. @cached_property
  168. def embeddings(self) -> Embeddings:
  169. from .resources.embeddings import Embeddings
  170. return Embeddings(self)
  171. @cached_property
  172. def files(self) -> Files:
  173. from .resources.files import Files
  174. return Files(self)
  175. @cached_property
  176. def images(self) -> Images:
  177. from .resources.images import Images
  178. return Images(self)
  179. @cached_property
  180. def audio(self) -> Audio:
  181. from .resources.audio import Audio
  182. return Audio(self)
  183. @cached_property
  184. def moderations(self) -> Moderations:
  185. from .resources.moderations import Moderations
  186. return Moderations(self)
  187. @cached_property
  188. def models(self) -> Models:
  189. from .resources.models import Models
  190. return Models(self)
  191. @cached_property
  192. def fine_tuning(self) -> FineTuning:
  193. from .resources.fine_tuning import FineTuning
  194. return FineTuning(self)
  195. @cached_property
  196. def vector_stores(self) -> VectorStores:
  197. from .resources.vector_stores import VectorStores
  198. return VectorStores(self)
  199. @cached_property
  200. def webhooks(self) -> Webhooks:
  201. from .resources.webhooks import Webhooks
  202. return Webhooks(self)
  203. @cached_property
  204. def beta(self) -> Beta:
  205. from .resources.beta import Beta
  206. return Beta(self)
  207. @cached_property
  208. def batches(self) -> Batches:
  209. from .resources.batches import Batches
  210. return Batches(self)
  211. @cached_property
  212. def uploads(self) -> Uploads:
  213. from .resources.uploads import Uploads
  214. return Uploads(self)
  215. @cached_property
  216. def responses(self) -> Responses:
  217. from .resources.responses import Responses
  218. return Responses(self)
  219. @cached_property
  220. def realtime(self) -> Realtime:
  221. from .resources.realtime import Realtime
  222. return Realtime(self)
  223. @cached_property
  224. def conversations(self) -> Conversations:
  225. from .resources.conversations import Conversations
  226. return Conversations(self)
  227. @cached_property
  228. def evals(self) -> Evals:
  229. from .resources.evals import Evals
  230. return Evals(self)
  231. @cached_property
  232. def containers(self) -> Containers:
  233. from .resources.containers import Containers
  234. return Containers(self)
  235. @cached_property
  236. def videos(self) -> Videos:
  237. from .resources.videos import Videos
  238. return Videos(self)
  239. @cached_property
  240. def with_raw_response(self) -> OpenAIWithRawResponse:
  241. return OpenAIWithRawResponse(self)
  242. @cached_property
  243. def with_streaming_response(self) -> OpenAIWithStreamedResponse:
  244. return OpenAIWithStreamedResponse(self)
  245. @property
  246. @override
  247. def qs(self) -> Querystring:
  248. return Querystring(array_format="brackets")
  249. def _refresh_api_key(self) -> None:
  250. if self._api_key_provider:
  251. self.api_key = self._api_key_provider()
  252. @override
  253. def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions:
  254. self._refresh_api_key()
  255. return super()._prepare_options(options)
  256. @property
  257. @override
  258. def auth_headers(self) -> dict[str, str]:
  259. api_key = self.api_key
  260. if not api_key:
  261. # if the api key is an empty string, encoding the header will fail
  262. return {}
  263. return {"Authorization": f"Bearer {api_key}"}
  264. @property
  265. @override
  266. def default_headers(self) -> dict[str, str | Omit]:
  267. return {
  268. **super().default_headers,
  269. "X-Stainless-Async": "false",
  270. "OpenAI-Organization": self.organization if self.organization is not None else Omit(),
  271. "OpenAI-Project": self.project if self.project is not None else Omit(),
  272. **self._custom_headers,
  273. }
  274. def copy(
  275. self,
  276. *,
  277. api_key: str | Callable[[], str] | None = None,
  278. organization: str | None = None,
  279. project: str | None = None,
  280. webhook_secret: str | None = None,
  281. websocket_base_url: str | httpx.URL | None = None,
  282. base_url: str | httpx.URL | None = None,
  283. timeout: float | Timeout | None | NotGiven = not_given,
  284. http_client: httpx.Client | None = None,
  285. max_retries: int | NotGiven = not_given,
  286. default_headers: Mapping[str, str] | None = None,
  287. set_default_headers: Mapping[str, str] | None = None,
  288. default_query: Mapping[str, object] | None = None,
  289. set_default_query: Mapping[str, object] | None = None,
  290. _extra_kwargs: Mapping[str, Any] = {},
  291. ) -> Self:
  292. """
  293. Create a new client instance re-using the same options given to the current client with optional overriding.
  294. """
  295. if default_headers is not None and set_default_headers is not None:
  296. raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive")
  297. if default_query is not None and set_default_query is not None:
  298. raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive")
  299. headers = self._custom_headers
  300. if default_headers is not None:
  301. headers = {**headers, **default_headers}
  302. elif set_default_headers is not None:
  303. headers = set_default_headers
  304. params = self._custom_query
  305. if default_query is not None:
  306. params = {**params, **default_query}
  307. elif set_default_query is not None:
  308. params = set_default_query
  309. http_client = http_client or self._client
  310. return self.__class__(
  311. api_key=api_key or self._api_key_provider or self.api_key,
  312. organization=organization or self.organization,
  313. project=project or self.project,
  314. webhook_secret=webhook_secret or self.webhook_secret,
  315. websocket_base_url=websocket_base_url or self.websocket_base_url,
  316. base_url=base_url or self.base_url,
  317. timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
  318. http_client=http_client,
  319. max_retries=max_retries if is_given(max_retries) else self.max_retries,
  320. default_headers=headers,
  321. default_query=params,
  322. **_extra_kwargs,
  323. )
  324. # Alias for `copy` for nicer inline usage, e.g.
  325. # client.with_options(timeout=10).foo.create(...)
  326. with_options = copy
  327. @override
  328. def _make_status_error(
  329. self,
  330. err_msg: str,
  331. *,
  332. body: object,
  333. response: httpx.Response,
  334. ) -> APIStatusError:
  335. data = body.get("error", body) if is_mapping(body) else body
  336. if response.status_code == 400:
  337. return _exceptions.BadRequestError(err_msg, response=response, body=data)
  338. if response.status_code == 401:
  339. return _exceptions.AuthenticationError(err_msg, response=response, body=data)
  340. if response.status_code == 403:
  341. return _exceptions.PermissionDeniedError(err_msg, response=response, body=data)
  342. if response.status_code == 404:
  343. return _exceptions.NotFoundError(err_msg, response=response, body=data)
  344. if response.status_code == 409:
  345. return _exceptions.ConflictError(err_msg, response=response, body=data)
  346. if response.status_code == 422:
  347. return _exceptions.UnprocessableEntityError(err_msg, response=response, body=data)
  348. if response.status_code == 429:
  349. return _exceptions.RateLimitError(err_msg, response=response, body=data)
  350. if response.status_code >= 500:
  351. return _exceptions.InternalServerError(err_msg, response=response, body=data)
  352. return APIStatusError(err_msg, response=response, body=data)
  353. class AsyncOpenAI(AsyncAPIClient):
  354. # client options
  355. api_key: str
  356. organization: str | None
  357. project: str | None
  358. webhook_secret: str | None
  359. websocket_base_url: str | httpx.URL | None
  360. """Base URL for WebSocket connections.
  361. If not specified, the default base URL will be used, with 'wss://' replacing the
  362. 'http://' or 'https://' scheme. For example: 'http://example.com' becomes
  363. 'wss://example.com'
  364. """
  365. def __init__(
  366. self,
  367. *,
  368. api_key: str | Callable[[], Awaitable[str]] | None = None,
  369. organization: str | None = None,
  370. project: str | None = None,
  371. webhook_secret: str | None = None,
  372. base_url: str | httpx.URL | None = None,
  373. websocket_base_url: str | httpx.URL | None = None,
  374. timeout: float | Timeout | None | NotGiven = not_given,
  375. max_retries: int = DEFAULT_MAX_RETRIES,
  376. default_headers: Mapping[str, str] | None = None,
  377. default_query: Mapping[str, object] | None = None,
  378. # Configure a custom httpx client.
  379. # We provide a `DefaultAsyncHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`.
  380. # See the [httpx documentation](https://www.python-httpx.org/api/#asyncclient) for more details.
  381. http_client: httpx.AsyncClient | None = None,
  382. # Enable or disable schema validation for data returned by the API.
  383. # When enabled an error APIResponseValidationError is raised
  384. # if the API responds with invalid data for the expected schema.
  385. #
  386. # This parameter may be removed or changed in the future.
  387. # If you rely on this feature, please open a GitHub issue
  388. # outlining your use-case to help us decide if it should be
  389. # part of our public interface in the future.
  390. _strict_response_validation: bool = False,
  391. ) -> None:
  392. """Construct a new async AsyncOpenAI client instance.
  393. This automatically infers the following arguments from their corresponding environment variables if they are not provided:
  394. - `api_key` from `OPENAI_API_KEY`
  395. - `organization` from `OPENAI_ORG_ID`
  396. - `project` from `OPENAI_PROJECT_ID`
  397. - `webhook_secret` from `OPENAI_WEBHOOK_SECRET`
  398. """
  399. if api_key is None:
  400. api_key = os.environ.get("OPENAI_API_KEY")
  401. if api_key is None:
  402. raise OpenAIError(
  403. "The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable"
  404. )
  405. if callable(api_key):
  406. self.api_key = ""
  407. self._api_key_provider: Callable[[], Awaitable[str]] | None = api_key
  408. else:
  409. self.api_key = api_key
  410. self._api_key_provider = None
  411. if organization is None:
  412. organization = os.environ.get("OPENAI_ORG_ID")
  413. self.organization = organization
  414. if project is None:
  415. project = os.environ.get("OPENAI_PROJECT_ID")
  416. self.project = project
  417. if webhook_secret is None:
  418. webhook_secret = os.environ.get("OPENAI_WEBHOOK_SECRET")
  419. self.webhook_secret = webhook_secret
  420. self.websocket_base_url = websocket_base_url
  421. if base_url is None:
  422. base_url = os.environ.get("OPENAI_BASE_URL")
  423. if base_url is None:
  424. base_url = f"https://api.openai.com/v1"
  425. super().__init__(
  426. version=__version__,
  427. base_url=base_url,
  428. max_retries=max_retries,
  429. timeout=timeout,
  430. http_client=http_client,
  431. custom_headers=default_headers,
  432. custom_query=default_query,
  433. _strict_response_validation=_strict_response_validation,
  434. )
  435. self._default_stream_cls = AsyncStream
  436. @cached_property
  437. def completions(self) -> AsyncCompletions:
  438. from .resources.completions import AsyncCompletions
  439. return AsyncCompletions(self)
  440. @cached_property
  441. def chat(self) -> AsyncChat:
  442. from .resources.chat import AsyncChat
  443. return AsyncChat(self)
  444. @cached_property
  445. def embeddings(self) -> AsyncEmbeddings:
  446. from .resources.embeddings import AsyncEmbeddings
  447. return AsyncEmbeddings(self)
  448. @cached_property
  449. def files(self) -> AsyncFiles:
  450. from .resources.files import AsyncFiles
  451. return AsyncFiles(self)
  452. @cached_property
  453. def images(self) -> AsyncImages:
  454. from .resources.images import AsyncImages
  455. return AsyncImages(self)
  456. @cached_property
  457. def audio(self) -> AsyncAudio:
  458. from .resources.audio import AsyncAudio
  459. return AsyncAudio(self)
  460. @cached_property
  461. def moderations(self) -> AsyncModerations:
  462. from .resources.moderations import AsyncModerations
  463. return AsyncModerations(self)
  464. @cached_property
  465. def models(self) -> AsyncModels:
  466. from .resources.models import AsyncModels
  467. return AsyncModels(self)
  468. @cached_property
  469. def fine_tuning(self) -> AsyncFineTuning:
  470. from .resources.fine_tuning import AsyncFineTuning
  471. return AsyncFineTuning(self)
  472. @cached_property
  473. def vector_stores(self) -> AsyncVectorStores:
  474. from .resources.vector_stores import AsyncVectorStores
  475. return AsyncVectorStores(self)
  476. @cached_property
  477. def webhooks(self) -> AsyncWebhooks:
  478. from .resources.webhooks import AsyncWebhooks
  479. return AsyncWebhooks(self)
  480. @cached_property
  481. def beta(self) -> AsyncBeta:
  482. from .resources.beta import AsyncBeta
  483. return AsyncBeta(self)
  484. @cached_property
  485. def batches(self) -> AsyncBatches:
  486. from .resources.batches import AsyncBatches
  487. return AsyncBatches(self)
  488. @cached_property
  489. def uploads(self) -> AsyncUploads:
  490. from .resources.uploads import AsyncUploads
  491. return AsyncUploads(self)
  492. @cached_property
  493. def responses(self) -> AsyncResponses:
  494. from .resources.responses import AsyncResponses
  495. return AsyncResponses(self)
  496. @cached_property
  497. def realtime(self) -> AsyncRealtime:
  498. from .resources.realtime import AsyncRealtime
  499. return AsyncRealtime(self)
  500. @cached_property
  501. def conversations(self) -> AsyncConversations:
  502. from .resources.conversations import AsyncConversations
  503. return AsyncConversations(self)
  504. @cached_property
  505. def evals(self) -> AsyncEvals:
  506. from .resources.evals import AsyncEvals
  507. return AsyncEvals(self)
  508. @cached_property
  509. def containers(self) -> AsyncContainers:
  510. from .resources.containers import AsyncContainers
  511. return AsyncContainers(self)
  512. @cached_property
  513. def videos(self) -> AsyncVideos:
  514. from .resources.videos import AsyncVideos
  515. return AsyncVideos(self)
  516. @cached_property
  517. def with_raw_response(self) -> AsyncOpenAIWithRawResponse:
  518. return AsyncOpenAIWithRawResponse(self)
  519. @cached_property
  520. def with_streaming_response(self) -> AsyncOpenAIWithStreamedResponse:
  521. return AsyncOpenAIWithStreamedResponse(self)
  522. @property
  523. @override
  524. def qs(self) -> Querystring:
  525. return Querystring(array_format="brackets")
  526. async def _refresh_api_key(self) -> None:
  527. if self._api_key_provider:
  528. self.api_key = await self._api_key_provider()
  529. @override
  530. async def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions:
  531. await self._refresh_api_key()
  532. return await super()._prepare_options(options)
  533. @property
  534. @override
  535. def auth_headers(self) -> dict[str, str]:
  536. api_key = self.api_key
  537. if not api_key:
  538. # if the api key is an empty string, encoding the header will fail
  539. return {}
  540. return {"Authorization": f"Bearer {api_key}"}
  541. @property
  542. @override
  543. def default_headers(self) -> dict[str, str | Omit]:
  544. return {
  545. **super().default_headers,
  546. "X-Stainless-Async": f"async:{get_async_library()}",
  547. "OpenAI-Organization": self.organization if self.organization is not None else Omit(),
  548. "OpenAI-Project": self.project if self.project is not None else Omit(),
  549. **self._custom_headers,
  550. }
  551. def copy(
  552. self,
  553. *,
  554. api_key: str | Callable[[], Awaitable[str]] | None = None,
  555. organization: str | None = None,
  556. project: str | None = None,
  557. webhook_secret: str | None = None,
  558. websocket_base_url: str | httpx.URL | None = None,
  559. base_url: str | httpx.URL | None = None,
  560. timeout: float | Timeout | None | NotGiven = not_given,
  561. http_client: httpx.AsyncClient | None = None,
  562. max_retries: int | NotGiven = not_given,
  563. default_headers: Mapping[str, str] | None = None,
  564. set_default_headers: Mapping[str, str] | None = None,
  565. default_query: Mapping[str, object] | None = None,
  566. set_default_query: Mapping[str, object] | None = None,
  567. _extra_kwargs: Mapping[str, Any] = {},
  568. ) -> Self:
  569. """
  570. Create a new client instance re-using the same options given to the current client with optional overriding.
  571. """
  572. if default_headers is not None and set_default_headers is not None:
  573. raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive")
  574. if default_query is not None and set_default_query is not None:
  575. raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive")
  576. headers = self._custom_headers
  577. if default_headers is not None:
  578. headers = {**headers, **default_headers}
  579. elif set_default_headers is not None:
  580. headers = set_default_headers
  581. params = self._custom_query
  582. if default_query is not None:
  583. params = {**params, **default_query}
  584. elif set_default_query is not None:
  585. params = set_default_query
  586. http_client = http_client or self._client
  587. return self.__class__(
  588. api_key=api_key or self._api_key_provider or self.api_key,
  589. organization=organization or self.organization,
  590. project=project or self.project,
  591. webhook_secret=webhook_secret or self.webhook_secret,
  592. websocket_base_url=websocket_base_url or self.websocket_base_url,
  593. base_url=base_url or self.base_url,
  594. timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
  595. http_client=http_client,
  596. max_retries=max_retries if is_given(max_retries) else self.max_retries,
  597. default_headers=headers,
  598. default_query=params,
  599. **_extra_kwargs,
  600. )
  601. # Alias for `copy` for nicer inline usage, e.g.
  602. # client.with_options(timeout=10).foo.create(...)
  603. with_options = copy
  604. @override
  605. def _make_status_error(
  606. self,
  607. err_msg: str,
  608. *,
  609. body: object,
  610. response: httpx.Response,
  611. ) -> APIStatusError:
  612. data = body.get("error", body) if is_mapping(body) else body
  613. if response.status_code == 400:
  614. return _exceptions.BadRequestError(err_msg, response=response, body=data)
  615. if response.status_code == 401:
  616. return _exceptions.AuthenticationError(err_msg, response=response, body=data)
  617. if response.status_code == 403:
  618. return _exceptions.PermissionDeniedError(err_msg, response=response, body=data)
  619. if response.status_code == 404:
  620. return _exceptions.NotFoundError(err_msg, response=response, body=data)
  621. if response.status_code == 409:
  622. return _exceptions.ConflictError(err_msg, response=response, body=data)
  623. if response.status_code == 422:
  624. return _exceptions.UnprocessableEntityError(err_msg, response=response, body=data)
  625. if response.status_code == 429:
  626. return _exceptions.RateLimitError(err_msg, response=response, body=data)
  627. if response.status_code >= 500:
  628. return _exceptions.InternalServerError(err_msg, response=response, body=data)
  629. return APIStatusError(err_msg, response=response, body=data)
  630. class OpenAIWithRawResponse:
  631. _client: OpenAI
  632. def __init__(self, client: OpenAI) -> None:
  633. self._client = client
  634. @cached_property
  635. def completions(self) -> completions.CompletionsWithRawResponse:
  636. from .resources.completions import CompletionsWithRawResponse
  637. return CompletionsWithRawResponse(self._client.completions)
  638. @cached_property
  639. def chat(self) -> chat.ChatWithRawResponse:
  640. from .resources.chat import ChatWithRawResponse
  641. return ChatWithRawResponse(self._client.chat)
  642. @cached_property
  643. def embeddings(self) -> embeddings.EmbeddingsWithRawResponse:
  644. from .resources.embeddings import EmbeddingsWithRawResponse
  645. return EmbeddingsWithRawResponse(self._client.embeddings)
  646. @cached_property
  647. def files(self) -> files.FilesWithRawResponse:
  648. from .resources.files import FilesWithRawResponse
  649. return FilesWithRawResponse(self._client.files)
  650. @cached_property
  651. def images(self) -> images.ImagesWithRawResponse:
  652. from .resources.images import ImagesWithRawResponse
  653. return ImagesWithRawResponse(self._client.images)
  654. @cached_property
  655. def audio(self) -> audio.AudioWithRawResponse:
  656. from .resources.audio import AudioWithRawResponse
  657. return AudioWithRawResponse(self._client.audio)
  658. @cached_property
  659. def moderations(self) -> moderations.ModerationsWithRawResponse:
  660. from .resources.moderations import ModerationsWithRawResponse
  661. return ModerationsWithRawResponse(self._client.moderations)
  662. @cached_property
  663. def models(self) -> models.ModelsWithRawResponse:
  664. from .resources.models import ModelsWithRawResponse
  665. return ModelsWithRawResponse(self._client.models)
  666. @cached_property
  667. def fine_tuning(self) -> fine_tuning.FineTuningWithRawResponse:
  668. from .resources.fine_tuning import FineTuningWithRawResponse
  669. return FineTuningWithRawResponse(self._client.fine_tuning)
  670. @cached_property
  671. def vector_stores(self) -> vector_stores.VectorStoresWithRawResponse:
  672. from .resources.vector_stores import VectorStoresWithRawResponse
  673. return VectorStoresWithRawResponse(self._client.vector_stores)
  674. @cached_property
  675. def beta(self) -> beta.BetaWithRawResponse:
  676. from .resources.beta import BetaWithRawResponse
  677. return BetaWithRawResponse(self._client.beta)
  678. @cached_property
  679. def batches(self) -> batches.BatchesWithRawResponse:
  680. from .resources.batches import BatchesWithRawResponse
  681. return BatchesWithRawResponse(self._client.batches)
  682. @cached_property
  683. def uploads(self) -> uploads.UploadsWithRawResponse:
  684. from .resources.uploads import UploadsWithRawResponse
  685. return UploadsWithRawResponse(self._client.uploads)
  686. @cached_property
  687. def responses(self) -> responses.ResponsesWithRawResponse:
  688. from .resources.responses import ResponsesWithRawResponse
  689. return ResponsesWithRawResponse(self._client.responses)
  690. @cached_property
  691. def realtime(self) -> realtime.RealtimeWithRawResponse:
  692. from .resources.realtime import RealtimeWithRawResponse
  693. return RealtimeWithRawResponse(self._client.realtime)
  694. @cached_property
  695. def conversations(self) -> conversations.ConversationsWithRawResponse:
  696. from .resources.conversations import ConversationsWithRawResponse
  697. return ConversationsWithRawResponse(self._client.conversations)
  698. @cached_property
  699. def evals(self) -> evals.EvalsWithRawResponse:
  700. from .resources.evals import EvalsWithRawResponse
  701. return EvalsWithRawResponse(self._client.evals)
  702. @cached_property
  703. def containers(self) -> containers.ContainersWithRawResponse:
  704. from .resources.containers import ContainersWithRawResponse
  705. return ContainersWithRawResponse(self._client.containers)
  706. @cached_property
  707. def videos(self) -> videos.VideosWithRawResponse:
  708. from .resources.videos import VideosWithRawResponse
  709. return VideosWithRawResponse(self._client.videos)
  710. class AsyncOpenAIWithRawResponse:
  711. _client: AsyncOpenAI
  712. def __init__(self, client: AsyncOpenAI) -> None:
  713. self._client = client
  714. @cached_property
  715. def completions(self) -> completions.AsyncCompletionsWithRawResponse:
  716. from .resources.completions import AsyncCompletionsWithRawResponse
  717. return AsyncCompletionsWithRawResponse(self._client.completions)
  718. @cached_property
  719. def chat(self) -> chat.AsyncChatWithRawResponse:
  720. from .resources.chat import AsyncChatWithRawResponse
  721. return AsyncChatWithRawResponse(self._client.chat)
  722. @cached_property
  723. def embeddings(self) -> embeddings.AsyncEmbeddingsWithRawResponse:
  724. from .resources.embeddings import AsyncEmbeddingsWithRawResponse
  725. return AsyncEmbeddingsWithRawResponse(self._client.embeddings)
  726. @cached_property
  727. def files(self) -> files.AsyncFilesWithRawResponse:
  728. from .resources.files import AsyncFilesWithRawResponse
  729. return AsyncFilesWithRawResponse(self._client.files)
  730. @cached_property
  731. def images(self) -> images.AsyncImagesWithRawResponse:
  732. from .resources.images import AsyncImagesWithRawResponse
  733. return AsyncImagesWithRawResponse(self._client.images)
  734. @cached_property
  735. def audio(self) -> audio.AsyncAudioWithRawResponse:
  736. from .resources.audio import AsyncAudioWithRawResponse
  737. return AsyncAudioWithRawResponse(self._client.audio)
  738. @cached_property
  739. def moderations(self) -> moderations.AsyncModerationsWithRawResponse:
  740. from .resources.moderations import AsyncModerationsWithRawResponse
  741. return AsyncModerationsWithRawResponse(self._client.moderations)
  742. @cached_property
  743. def models(self) -> models.AsyncModelsWithRawResponse:
  744. from .resources.models import AsyncModelsWithRawResponse
  745. return AsyncModelsWithRawResponse(self._client.models)
  746. @cached_property
  747. def fine_tuning(self) -> fine_tuning.AsyncFineTuningWithRawResponse:
  748. from .resources.fine_tuning import AsyncFineTuningWithRawResponse
  749. return AsyncFineTuningWithRawResponse(self._client.fine_tuning)
  750. @cached_property
  751. def vector_stores(self) -> vector_stores.AsyncVectorStoresWithRawResponse:
  752. from .resources.vector_stores import AsyncVectorStoresWithRawResponse
  753. return AsyncVectorStoresWithRawResponse(self._client.vector_stores)
  754. @cached_property
  755. def beta(self) -> beta.AsyncBetaWithRawResponse:
  756. from .resources.beta import AsyncBetaWithRawResponse
  757. return AsyncBetaWithRawResponse(self._client.beta)
  758. @cached_property
  759. def batches(self) -> batches.AsyncBatchesWithRawResponse:
  760. from .resources.batches import AsyncBatchesWithRawResponse
  761. return AsyncBatchesWithRawResponse(self._client.batches)
  762. @cached_property
  763. def uploads(self) -> uploads.AsyncUploadsWithRawResponse:
  764. from .resources.uploads import AsyncUploadsWithRawResponse
  765. return AsyncUploadsWithRawResponse(self._client.uploads)
  766. @cached_property
  767. def responses(self) -> responses.AsyncResponsesWithRawResponse:
  768. from .resources.responses import AsyncResponsesWithRawResponse
  769. return AsyncResponsesWithRawResponse(self._client.responses)
  770. @cached_property
  771. def realtime(self) -> realtime.AsyncRealtimeWithRawResponse:
  772. from .resources.realtime import AsyncRealtimeWithRawResponse
  773. return AsyncRealtimeWithRawResponse(self._client.realtime)
  774. @cached_property
  775. def conversations(self) -> conversations.AsyncConversationsWithRawResponse:
  776. from .resources.conversations import AsyncConversationsWithRawResponse
  777. return AsyncConversationsWithRawResponse(self._client.conversations)
  778. @cached_property
  779. def evals(self) -> evals.AsyncEvalsWithRawResponse:
  780. from .resources.evals import AsyncEvalsWithRawResponse
  781. return AsyncEvalsWithRawResponse(self._client.evals)
  782. @cached_property
  783. def containers(self) -> containers.AsyncContainersWithRawResponse:
  784. from .resources.containers import AsyncContainersWithRawResponse
  785. return AsyncContainersWithRawResponse(self._client.containers)
  786. @cached_property
  787. def videos(self) -> videos.AsyncVideosWithRawResponse:
  788. from .resources.videos import AsyncVideosWithRawResponse
  789. return AsyncVideosWithRawResponse(self._client.videos)
  790. class OpenAIWithStreamedResponse:
  791. _client: OpenAI
  792. def __init__(self, client: OpenAI) -> None:
  793. self._client = client
  794. @cached_property
  795. def completions(self) -> completions.CompletionsWithStreamingResponse:
  796. from .resources.completions import CompletionsWithStreamingResponse
  797. return CompletionsWithStreamingResponse(self._client.completions)
  798. @cached_property
  799. def chat(self) -> chat.ChatWithStreamingResponse:
  800. from .resources.chat import ChatWithStreamingResponse
  801. return ChatWithStreamingResponse(self._client.chat)
  802. @cached_property
  803. def embeddings(self) -> embeddings.EmbeddingsWithStreamingResponse:
  804. from .resources.embeddings import EmbeddingsWithStreamingResponse
  805. return EmbeddingsWithStreamingResponse(self._client.embeddings)
  806. @cached_property
  807. def files(self) -> files.FilesWithStreamingResponse:
  808. from .resources.files import FilesWithStreamingResponse
  809. return FilesWithStreamingResponse(self._client.files)
  810. @cached_property
  811. def images(self) -> images.ImagesWithStreamingResponse:
  812. from .resources.images import ImagesWithStreamingResponse
  813. return ImagesWithStreamingResponse(self._client.images)
  814. @cached_property
  815. def audio(self) -> audio.AudioWithStreamingResponse:
  816. from .resources.audio import AudioWithStreamingResponse
  817. return AudioWithStreamingResponse(self._client.audio)
  818. @cached_property
  819. def moderations(self) -> moderations.ModerationsWithStreamingResponse:
  820. from .resources.moderations import ModerationsWithStreamingResponse
  821. return ModerationsWithStreamingResponse(self._client.moderations)
  822. @cached_property
  823. def models(self) -> models.ModelsWithStreamingResponse:
  824. from .resources.models import ModelsWithStreamingResponse
  825. return ModelsWithStreamingResponse(self._client.models)
  826. @cached_property
  827. def fine_tuning(self) -> fine_tuning.FineTuningWithStreamingResponse:
  828. from .resources.fine_tuning import FineTuningWithStreamingResponse
  829. return FineTuningWithStreamingResponse(self._client.fine_tuning)
  830. @cached_property
  831. def vector_stores(self) -> vector_stores.VectorStoresWithStreamingResponse:
  832. from .resources.vector_stores import VectorStoresWithStreamingResponse
  833. return VectorStoresWithStreamingResponse(self._client.vector_stores)
  834. @cached_property
  835. def beta(self) -> beta.BetaWithStreamingResponse:
  836. from .resources.beta import BetaWithStreamingResponse
  837. return BetaWithStreamingResponse(self._client.beta)
  838. @cached_property
  839. def batches(self) -> batches.BatchesWithStreamingResponse:
  840. from .resources.batches import BatchesWithStreamingResponse
  841. return BatchesWithStreamingResponse(self._client.batches)
  842. @cached_property
  843. def uploads(self) -> uploads.UploadsWithStreamingResponse:
  844. from .resources.uploads import UploadsWithStreamingResponse
  845. return UploadsWithStreamingResponse(self._client.uploads)
  846. @cached_property
  847. def responses(self) -> responses.ResponsesWithStreamingResponse:
  848. from .resources.responses import ResponsesWithStreamingResponse
  849. return ResponsesWithStreamingResponse(self._client.responses)
  850. @cached_property
  851. def realtime(self) -> realtime.RealtimeWithStreamingResponse:
  852. from .resources.realtime import RealtimeWithStreamingResponse
  853. return RealtimeWithStreamingResponse(self._client.realtime)
  854. @cached_property
  855. def conversations(self) -> conversations.ConversationsWithStreamingResponse:
  856. from .resources.conversations import ConversationsWithStreamingResponse
  857. return ConversationsWithStreamingResponse(self._client.conversations)
  858. @cached_property
  859. def evals(self) -> evals.EvalsWithStreamingResponse:
  860. from .resources.evals import EvalsWithStreamingResponse
  861. return EvalsWithStreamingResponse(self._client.evals)
  862. @cached_property
  863. def containers(self) -> containers.ContainersWithStreamingResponse:
  864. from .resources.containers import ContainersWithStreamingResponse
  865. return ContainersWithStreamingResponse(self._client.containers)
  866. @cached_property
  867. def videos(self) -> videos.VideosWithStreamingResponse:
  868. from .resources.videos import VideosWithStreamingResponse
  869. return VideosWithStreamingResponse(self._client.videos)
  870. class AsyncOpenAIWithStreamedResponse:
  871. _client: AsyncOpenAI
  872. def __init__(self, client: AsyncOpenAI) -> None:
  873. self._client = client
  874. @cached_property
  875. def completions(self) -> completions.AsyncCompletionsWithStreamingResponse:
  876. from .resources.completions import AsyncCompletionsWithStreamingResponse
  877. return AsyncCompletionsWithStreamingResponse(self._client.completions)
  878. @cached_property
  879. def chat(self) -> chat.AsyncChatWithStreamingResponse:
  880. from .resources.chat import AsyncChatWithStreamingResponse
  881. return AsyncChatWithStreamingResponse(self._client.chat)
  882. @cached_property
  883. def embeddings(self) -> embeddings.AsyncEmbeddingsWithStreamingResponse:
  884. from .resources.embeddings import AsyncEmbeddingsWithStreamingResponse
  885. return AsyncEmbeddingsWithStreamingResponse(self._client.embeddings)
  886. @cached_property
  887. def files(self) -> files.AsyncFilesWithStreamingResponse:
  888. from .resources.files import AsyncFilesWithStreamingResponse
  889. return AsyncFilesWithStreamingResponse(self._client.files)
  890. @cached_property
  891. def images(self) -> images.AsyncImagesWithStreamingResponse:
  892. from .resources.images import AsyncImagesWithStreamingResponse
  893. return AsyncImagesWithStreamingResponse(self._client.images)
  894. @cached_property
  895. def audio(self) -> audio.AsyncAudioWithStreamingResponse:
  896. from .resources.audio import AsyncAudioWithStreamingResponse
  897. return AsyncAudioWithStreamingResponse(self._client.audio)
  898. @cached_property
  899. def moderations(self) -> moderations.AsyncModerationsWithStreamingResponse:
  900. from .resources.moderations import AsyncModerationsWithStreamingResponse
  901. return AsyncModerationsWithStreamingResponse(self._client.moderations)
  902. @cached_property
  903. def models(self) -> models.AsyncModelsWithStreamingResponse:
  904. from .resources.models import AsyncModelsWithStreamingResponse
  905. return AsyncModelsWithStreamingResponse(self._client.models)
  906. @cached_property
  907. def fine_tuning(self) -> fine_tuning.AsyncFineTuningWithStreamingResponse:
  908. from .resources.fine_tuning import AsyncFineTuningWithStreamingResponse
  909. return AsyncFineTuningWithStreamingResponse(self._client.fine_tuning)
  910. @cached_property
  911. def vector_stores(self) -> vector_stores.AsyncVectorStoresWithStreamingResponse:
  912. from .resources.vector_stores import AsyncVectorStoresWithStreamingResponse
  913. return AsyncVectorStoresWithStreamingResponse(self._client.vector_stores)
  914. @cached_property
  915. def beta(self) -> beta.AsyncBetaWithStreamingResponse:
  916. from .resources.beta import AsyncBetaWithStreamingResponse
  917. return AsyncBetaWithStreamingResponse(self._client.beta)
  918. @cached_property
  919. def batches(self) -> batches.AsyncBatchesWithStreamingResponse:
  920. from .resources.batches import AsyncBatchesWithStreamingResponse
  921. return AsyncBatchesWithStreamingResponse(self._client.batches)
  922. @cached_property
  923. def uploads(self) -> uploads.AsyncUploadsWithStreamingResponse:
  924. from .resources.uploads import AsyncUploadsWithStreamingResponse
  925. return AsyncUploadsWithStreamingResponse(self._client.uploads)
  926. @cached_property
  927. def responses(self) -> responses.AsyncResponsesWithStreamingResponse:
  928. from .resources.responses import AsyncResponsesWithStreamingResponse
  929. return AsyncResponsesWithStreamingResponse(self._client.responses)
  930. @cached_property
  931. def realtime(self) -> realtime.AsyncRealtimeWithStreamingResponse:
  932. from .resources.realtime import AsyncRealtimeWithStreamingResponse
  933. return AsyncRealtimeWithStreamingResponse(self._client.realtime)
  934. @cached_property
  935. def conversations(self) -> conversations.AsyncConversationsWithStreamingResponse:
  936. from .resources.conversations import AsyncConversationsWithStreamingResponse
  937. return AsyncConversationsWithStreamingResponse(self._client.conversations)
  938. @cached_property
  939. def evals(self) -> evals.AsyncEvalsWithStreamingResponse:
  940. from .resources.evals import AsyncEvalsWithStreamingResponse
  941. return AsyncEvalsWithStreamingResponse(self._client.evals)
  942. @cached_property
  943. def containers(self) -> containers.AsyncContainersWithStreamingResponse:
  944. from .resources.containers import AsyncContainersWithStreamingResponse
  945. return AsyncContainersWithStreamingResponse(self._client.containers)
  946. @cached_property
  947. def videos(self) -> videos.AsyncVideosWithStreamingResponse:
  948. from .resources.videos import AsyncVideosWithStreamingResponse
  949. return AsyncVideosWithStreamingResponse(self._client.videos)
  950. Client = OpenAI
  951. AsyncClient = AsyncOpenAI