Commit 3408b5d2
Changed files (4)
src
openai
src/openai/lib/azure.py
@@ -130,6 +130,7 @@ class AzureOpenAI(BaseAzureClient[httpx.Client, Stream[Any]], OpenAI):
azure_ad_token: str | None = None,
azure_ad_token_provider: AzureADTokenProvider | None = None,
organization: str | None = None,
+ project: str | None = None,
base_url: str | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
@@ -143,6 +144,7 @@ class AzureOpenAI(BaseAzureClient[httpx.Client, Stream[Any]], OpenAI):
This automatically infers the following arguments from their corresponding environment variables if they are not provided:
- `api_key` from `AZURE_OPENAI_API_KEY`
- `organization` from `OPENAI_ORG_ID`
+ - `project` from `OPENAI_PROJECT_ID`
- `azure_ad_token` from `AZURE_OPENAI_AD_TOKEN`
- `api_version` from `OPENAI_API_VERSION`
- `azure_endpoint` from `AZURE_OPENAI_ENDPOINT`
@@ -205,6 +207,7 @@ class AzureOpenAI(BaseAzureClient[httpx.Client, Stream[Any]], OpenAI):
super().__init__(
api_key=api_key,
organization=organization,
+ project=project,
base_url=base_url,
timeout=timeout,
max_retries=max_retries,
@@ -223,6 +226,7 @@ class AzureOpenAI(BaseAzureClient[httpx.Client, Stream[Any]], OpenAI):
*,
api_key: str | None = None,
organization: str | None = None,
+ project: str | None = None,
api_version: str | None = None,
azure_ad_token: str | None = None,
azure_ad_token_provider: AzureADTokenProvider | None = None,
@@ -242,6 +246,7 @@ class AzureOpenAI(BaseAzureClient[httpx.Client, Stream[Any]], OpenAI):
return super().copy(
api_key=api_key,
organization=organization,
+ project=project,
base_url=base_url,
timeout=timeout,
http_client=http_client,
@@ -306,6 +311,7 @@ class AsyncAzureOpenAI(BaseAzureClient[httpx.AsyncClient, AsyncStream[Any]], Asy
azure_ad_token: str | None = None,
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
organization: str | None = None,
+ project: str | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
@@ -325,6 +331,7 @@ class AsyncAzureOpenAI(BaseAzureClient[httpx.AsyncClient, AsyncStream[Any]], Asy
azure_ad_token: str | None = None,
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
organization: str | None = None,
+ project: str | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
@@ -344,6 +351,7 @@ class AsyncAzureOpenAI(BaseAzureClient[httpx.AsyncClient, AsyncStream[Any]], Asy
azure_ad_token: str | None = None,
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
organization: str | None = None,
+ project: str | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
@@ -363,6 +371,7 @@ class AsyncAzureOpenAI(BaseAzureClient[httpx.AsyncClient, AsyncStream[Any]], Asy
azure_ad_token: str | None = None,
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
organization: str | None = None,
+ project: str | None = None,
base_url: str | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
@@ -376,6 +385,7 @@ class AsyncAzureOpenAI(BaseAzureClient[httpx.AsyncClient, AsyncStream[Any]], Asy
This automatically infers the following arguments from their corresponding environment variables if they are not provided:
- `api_key` from `AZURE_OPENAI_API_KEY`
- `organization` from `OPENAI_ORG_ID`
+ - `project` from `OPENAI_PROJECT_ID`
- `azure_ad_token` from `AZURE_OPENAI_AD_TOKEN`
- `api_version` from `OPENAI_API_VERSION`
- `azure_endpoint` from `AZURE_OPENAI_ENDPOINT`
@@ -438,6 +448,7 @@ class AsyncAzureOpenAI(BaseAzureClient[httpx.AsyncClient, AsyncStream[Any]], Asy
super().__init__(
api_key=api_key,
organization=organization,
+ project=project,
base_url=base_url,
timeout=timeout,
max_retries=max_retries,
@@ -456,6 +467,7 @@ class AsyncAzureOpenAI(BaseAzureClient[httpx.AsyncClient, AsyncStream[Any]], Asy
*,
api_key: str | None = None,
organization: str | None = None,
+ project: str | None = None,
api_version: str | None = None,
azure_ad_token: str | None = None,
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
@@ -475,6 +487,7 @@ class AsyncAzureOpenAI(BaseAzureClient[httpx.AsyncClient, AsyncStream[Any]], Asy
return super().copy(
api_key=api_key,
organization=organization,
+ project=project,
base_url=base_url,
timeout=timeout,
http_client=http_client,
src/openai/__init__.py
@@ -108,6 +108,8 @@ api_key: str | None = None
organization: str | None = None
+project: str | None = None
+
base_url: str | _httpx.URL | None = None
timeout: float | Timeout | None = DEFAULT_TIMEOUT
@@ -159,6 +161,17 @@ class _ModuleClient(OpenAI):
organization = value
+ @property # type: ignore
+ @override
+ def project(self) -> str | None:
+ return project
+
+ @project.setter # type: ignore
+ def project(self, value: str | None) -> None: # type: ignore
+ global project
+
+ project = value
+
@property
@override
def base_url(self) -> _httpx.URL:
@@ -310,6 +323,7 @@ def _load_client() -> OpenAI: # type: ignore[reportUnusedFunction]
_client = _ModuleClient(
api_key=api_key,
organization=organization,
+ project=project,
base_url=base_url,
timeout=timeout,
max_retries=max_retries,
src/openai/_client.py
@@ -64,12 +64,14 @@ class OpenAI(SyncAPIClient):
# client options
api_key: str
organization: str | None
+ project: str | None
def __init__(
self,
*,
api_key: str | None = None,
organization: str | None = None,
+ project: str | None = None,
base_url: str | httpx.URL | None = None,
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
@@ -94,6 +96,7 @@ class OpenAI(SyncAPIClient):
This automatically infers the following arguments from their corresponding environment variables if they are not provided:
- `api_key` from `OPENAI_API_KEY`
- `organization` from `OPENAI_ORG_ID`
+ - `project` from `OPENAI_PROJECT_ID`
"""
if api_key is None:
api_key = os.environ.get("OPENAI_API_KEY")
@@ -107,6 +110,10 @@ class OpenAI(SyncAPIClient):
organization = os.environ.get("OPENAI_ORG_ID")
self.organization = organization
+ if project is None:
+ project = os.environ.get("OPENAI_PROJECT_ID")
+ self.project = project
+
if base_url is None:
base_url = os.environ.get("OPENAI_BASE_URL")
if base_url is None:
@@ -157,6 +164,7 @@ class OpenAI(SyncAPIClient):
**super().default_headers,
"X-Stainless-Async": "false",
"OpenAI-Organization": self.organization if self.organization is not None else Omit(),
+ "OpenAI-Project": self.project if self.project is not None else Omit(),
**self._custom_headers,
}
@@ -165,6 +173,7 @@ class OpenAI(SyncAPIClient):
*,
api_key: str | None = None,
organization: str | None = None,
+ project: str | None = None,
base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
http_client: httpx.Client | None = None,
@@ -200,6 +209,7 @@ class OpenAI(SyncAPIClient):
return self.__class__(
api_key=api_key or self.api_key,
organization=organization or self.organization,
+ project=project or self.project,
base_url=base_url or self.base_url,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
@@ -266,12 +276,14 @@ class AsyncOpenAI(AsyncAPIClient):
# client options
api_key: str
organization: str | None
+ project: str | None
def __init__(
self,
*,
api_key: str | None = None,
organization: str | None = None,
+ project: str | None = None,
base_url: str | httpx.URL | None = None,
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
@@ -296,6 +308,7 @@ class AsyncOpenAI(AsyncAPIClient):
This automatically infers the following arguments from their corresponding environment variables if they are not provided:
- `api_key` from `OPENAI_API_KEY`
- `organization` from `OPENAI_ORG_ID`
+ - `project` from `OPENAI_PROJECT_ID`
"""
if api_key is None:
api_key = os.environ.get("OPENAI_API_KEY")
@@ -309,6 +322,10 @@ class AsyncOpenAI(AsyncAPIClient):
organization = os.environ.get("OPENAI_ORG_ID")
self.organization = organization
+ if project is None:
+ project = os.environ.get("OPENAI_PROJECT_ID")
+ self.project = project
+
if base_url is None:
base_url = os.environ.get("OPENAI_BASE_URL")
if base_url is None:
@@ -359,6 +376,7 @@ class AsyncOpenAI(AsyncAPIClient):
**super().default_headers,
"X-Stainless-Async": f"async:{get_async_library()}",
"OpenAI-Organization": self.organization if self.organization is not None else Omit(),
+ "OpenAI-Project": self.project if self.project is not None else Omit(),
**self._custom_headers,
}
@@ -367,6 +385,7 @@ class AsyncOpenAI(AsyncAPIClient):
*,
api_key: str | None = None,
organization: str | None = None,
+ project: str | None = None,
base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
http_client: httpx.AsyncClient | None = None,
@@ -402,6 +421,7 @@ class AsyncOpenAI(AsyncAPIClient):
return self.__class__(
api_key=api_key or self.api_key,
organization=organization or self.organization,
+ project=project or self.project,
base_url=base_url or self.base_url,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
tests/test_module_client.py
@@ -16,6 +16,7 @@ def reset_state() -> None:
openai._reset_client()
openai.api_key = None or "My API Key"
openai.organization = None
+ openai.project = None
openai.base_url = None
openai.timeout = DEFAULT_TIMEOUT
openai.max_retries = DEFAULT_MAX_RETRIES