openai/openai-python

Public

mirrored from https://github.com/openai/openai-pythonAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
dev/rasmus/render_response_on_cancel

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/openai/__init__.py

372lines · modecode

1# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
3from __future__ import annotations
4
5import os as _os
6import typing as _t
7from typing_extensions import override
8
9from . import types
10from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes
11from ._utils import file_from_path
12from ._client import Client, OpenAI, Stream, Timeout, Transport, AsyncClient, AsyncOpenAI, AsyncStream, RequestOptions
13from ._models import BaseModel
14from ._version import __title__, __version__
15from ._response import APIResponse as APIResponse, AsyncAPIResponse as AsyncAPIResponse
16from ._constants import DEFAULT_TIMEOUT, DEFAULT_MAX_RETRIES, DEFAULT_CONNECTION_LIMITS
17from ._exceptions import (
18 APIError,
19 OpenAIError,
20 ConflictError,
21 NotFoundError,
22 APIStatusError,
23 RateLimitError,
24 APITimeoutError,
25 BadRequestError,
26 APIConnectionError,
27 AuthenticationError,
28 InternalServerError,
29 PermissionDeniedError,
30 LengthFinishReasonError,
31 UnprocessableEntityError,
32 APIResponseValidationError,
33 ContentFilterFinishReasonError,
34)
35from ._base_client import DefaultHttpxClient, DefaultAsyncHttpxClient
36from ._utils._logs import setup_logging as _setup_logging
37from ._legacy_response import HttpxBinaryResponseContent as HttpxBinaryResponseContent
38
39__all__ = [
40 "types",
41 "__version__",
42 "__title__",
43 "NoneType",
44 "Transport",
45 "ProxiesTypes",
46 "NotGiven",
47 "NOT_GIVEN",
48 "Omit",
49 "OpenAIError",
50 "APIError",
51 "APIStatusError",
52 "APITimeoutError",
53 "APIConnectionError",
54 "APIResponseValidationError",
55 "BadRequestError",
56 "AuthenticationError",
57 "PermissionDeniedError",
58 "NotFoundError",
59 "ConflictError",
60 "UnprocessableEntityError",
61 "RateLimitError",
62 "InternalServerError",
63 "LengthFinishReasonError",
64 "ContentFilterFinishReasonError",
65 "Timeout",
66 "RequestOptions",
67 "Client",
68 "AsyncClient",
69 "Stream",
70 "AsyncStream",
71 "OpenAI",
72 "AsyncOpenAI",
73 "file_from_path",
74 "BaseModel",
75 "DEFAULT_TIMEOUT",
76 "DEFAULT_MAX_RETRIES",
77 "DEFAULT_CONNECTION_LIMITS",
78 "DefaultHttpxClient",
79 "DefaultAsyncHttpxClient",
80]
81
82if not _t.TYPE_CHECKING:
83 from ._utils._resources_proxy import resources as resources
84
85from .lib import azure as _azure, pydantic_function_tool as pydantic_function_tool
86from .version import VERSION as VERSION
87from .lib.azure import AzureOpenAI as AzureOpenAI, AsyncAzureOpenAI as AsyncAzureOpenAI
88from .lib._old_api import *
89from .lib.streaming import (
90 AssistantEventHandler as AssistantEventHandler,
91 AsyncAssistantEventHandler as AsyncAssistantEventHandler,
92)
93
94_setup_logging()
95
96# Update the __module__ attribute for exported symbols so that
97# error messages point to this module instead of the module
98# it was originally defined in, e.g.
99# openai._exceptions.NotFoundError -> openai.NotFoundError
100__locals = locals()
101for __name in __all__:
102 if not __name.startswith("__"):
103 try:
104 __locals[__name].__module__ = "openai"
105 except (TypeError, AttributeError):
106 # Some of our exported symbols are builtins which we can't set attributes for.
107 pass
108
109# ------ Module level client ------
110import typing as _t
111import typing_extensions as _te
112
113import httpx as _httpx
114
115from ._base_client import DEFAULT_TIMEOUT, DEFAULT_MAX_RETRIES
116
117api_key: str | None = None
118
119organization: str | None = None
120
121project: str | None = None
122
123base_url: str | _httpx.URL | None = None
124
125timeout: float | Timeout | None = DEFAULT_TIMEOUT
126
127max_retries: int = DEFAULT_MAX_RETRIES
128
129default_headers: _t.Mapping[str, str] | None = None
130
131default_query: _t.Mapping[str, object] | None = None
132
133http_client: _httpx.Client | None = None
134
135_ApiType = _te.Literal["openai", "azure"]
136
137api_type: _ApiType | None = _t.cast(_ApiType, _os.environ.get("OPENAI_API_TYPE"))
138
139api_version: str | None = _os.environ.get("OPENAI_API_VERSION")
140
141azure_endpoint: str | None = _os.environ.get("AZURE_OPENAI_ENDPOINT")
142
143azure_ad_token: str | None = _os.environ.get("AZURE_OPENAI_AD_TOKEN")
144
145azure_ad_token_provider: _azure.AzureADTokenProvider | None = None
146
147
148class _ModuleClient(OpenAI):
149 # Note: we have to use type: ignores here as overriding class members
150 # with properties is technically unsafe but it is fine for our use case
151
152 @property # type: ignore
153 @override
154 def api_key(self) -> str | None:
155 return api_key
156
157 @api_key.setter # type: ignore
158 def api_key(self, value: str | None) -> None: # type: ignore
159 global api_key
160
161 api_key = value
162
163 @property # type: ignore
164 @override
165 def organization(self) -> str | None:
166 return organization
167
168 @organization.setter # type: ignore
169 def organization(self, value: str | None) -> None: # type: ignore
170 global organization
171
172 organization = value
173
174 @property # type: ignore
175 @override
176 def project(self) -> str | None:
177 return project
178
179 @project.setter # type: ignore
180 def project(self, value: str | None) -> None: # type: ignore
181 global project
182
183 project = value
184
185 @property
186 @override
187 def base_url(self) -> _httpx.URL:
188 if base_url is not None:
189 return _httpx.URL(base_url)
190
191 return super().base_url
192
193 @base_url.setter
194 def base_url(self, url: _httpx.URL | str) -> None:
195 super().base_url = url # type: ignore[misc]
196
197 @property # type: ignore
198 @override
199 def timeout(self) -> float | Timeout | None:
200 return timeout
201
202 @timeout.setter # type: ignore
203 def timeout(self, value: float | Timeout | None) -> None: # type: ignore
204 global timeout
205
206 timeout = value
207
208 @property # type: ignore
209 @override
210 def max_retries(self) -> int:
211 return max_retries
212
213 @max_retries.setter # type: ignore
214 def max_retries(self, value: int) -> None: # type: ignore
215 global max_retries
216
217 max_retries = value
218
219 @property # type: ignore
220 @override
221 def _custom_headers(self) -> _t.Mapping[str, str] | None:
222 return default_headers
223
224 @_custom_headers.setter # type: ignore
225 def _custom_headers(self, value: _t.Mapping[str, str] | None) -> None: # type: ignore
226 global default_headers
227
228 default_headers = value
229
230 @property # type: ignore
231 @override
232 def _custom_query(self) -> _t.Mapping[str, object] | None:
233 return default_query
234
235 @_custom_query.setter # type: ignore
236 def _custom_query(self, value: _t.Mapping[str, object] | None) -> None: # type: ignore
237 global default_query
238
239 default_query = value
240
241 @property # type: ignore
242 @override
243 def _client(self) -> _httpx.Client:
244 return http_client or super()._client
245
246 @_client.setter # type: ignore
247 def _client(self, value: _httpx.Client) -> None: # type: ignore
248 global http_client
249
250 http_client = value
251
252
253class _AzureModuleClient(_ModuleClient, AzureOpenAI): # type: ignore
254 ...
255
256
257class _AmbiguousModuleClientUsageError(OpenAIError):
258 def __init__(self) -> None:
259 super().__init__(
260 "Ambiguous use of module client; please set `openai.api_type` or the `OPENAI_API_TYPE` environment variable to `openai` or `azure`"
261 )
262
263
264def _has_openai_credentials() -> bool:
265 return _os.environ.get("OPENAI_API_KEY") is not None
266
267
268def _has_azure_credentials() -> bool:
269 return azure_endpoint is not None or _os.environ.get("AZURE_OPENAI_API_KEY") is not None
270
271
272def _has_azure_ad_credentials() -> bool:
273 return (
274 _os.environ.get("AZURE_OPENAI_AD_TOKEN") is not None
275 or azure_ad_token is not None
276 or azure_ad_token_provider is not None
277 )
278
279
280_client: OpenAI | None = None
281
282
283def _load_client() -> OpenAI: # type: ignore[reportUnusedFunction]
284 global _client
285
286 if _client is None:
287 global api_type, azure_endpoint, azure_ad_token, api_version
288
289 if azure_endpoint is None:
290 azure_endpoint = _os.environ.get("AZURE_OPENAI_ENDPOINT")
291
292 if azure_ad_token is None:
293 azure_ad_token = _os.environ.get("AZURE_OPENAI_AD_TOKEN")
294
295 if api_version is None:
296 api_version = _os.environ.get("OPENAI_API_VERSION")
297
298 if api_type is None:
299 has_openai = _has_openai_credentials()
300 has_azure = _has_azure_credentials()
301 has_azure_ad = _has_azure_ad_credentials()
302
303 if has_openai and (has_azure or has_azure_ad):
304 raise _AmbiguousModuleClientUsageError()
305
306 if (azure_ad_token is not None or azure_ad_token_provider is not None) and _os.environ.get(
307 "AZURE_OPENAI_API_KEY"
308 ) is not None:
309 raise _AmbiguousModuleClientUsageError()
310
311 if has_azure or has_azure_ad:
312 api_type = "azure"
313 else:
314 api_type = "openai"
315
316 if api_type == "azure":
317 _client = _AzureModuleClient( # type: ignore
318 api_version=api_version,
319 azure_endpoint=azure_endpoint,
320 api_key=api_key,
321 azure_ad_token=azure_ad_token,
322 azure_ad_token_provider=azure_ad_token_provider,
323 organization=organization,
324 base_url=base_url,
325 timeout=timeout,
326 max_retries=max_retries,
327 default_headers=default_headers,
328 default_query=default_query,
329 http_client=http_client,
330 )
331 return _client
332
333 _client = _ModuleClient(
334 api_key=api_key,
335 organization=organization,
336 project=project,
337 base_url=base_url,
338 timeout=timeout,
339 max_retries=max_retries,
340 default_headers=default_headers,
341 default_query=default_query,
342 http_client=http_client,
343 )
344 return _client
345
346 return _client
347
348
349def _reset_client() -> None: # type: ignore[reportUnusedFunction]
350 global _client
351
352 _client = None
353
354
355from ._module_client import (
356 beta as beta,
357 chat as chat,
358 audio as audio,
359 evals as evals,
360 files as files,
361 images as images,
362 models as models,
363 batches as batches,
364 uploads as uploads,
365 responses as responses,
366 containers as containers,
367 embeddings as embeddings,
368 completions as completions,
369 fine_tuning as fine_tuning,
370 moderations as moderations,
371 vector_stores as vector_stores,
372)
373