diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c373724d..46b9b6b2 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.8" + ".": "0.1.0-alpha.9" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d23361c..7f250f49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.1.0-alpha.9 (2025-01-29) + +Full Changelog: [v0.1.0-alpha.8...v0.1.0-alpha.9](https://github.com/cleanlab/codex-python/compare/v0.1.0-alpha.8...v0.1.0-alpha.9) + +### Features + +* **api:** remove bearer auth ([#46](https://github.com/cleanlab/codex-python/issues/46)) ([b3c11da](https://github.com/cleanlab/codex-python/commit/b3c11da891f4b648e334b591a468d2e3eadda6c1)) +* **api:** remove env var auth ([#50](https://github.com/cleanlab/codex-python/issues/50)) ([6cb50e1](https://github.com/cleanlab/codex-python/commit/6cb50e15363c386d103d49840134ed309042ef03)) + ## 0.1.0-alpha.8 (2025-01-28) Full Changelog: [v0.1.0-alpha.7...v0.1.0-alpha.8](https://github.com/cleanlab/codex-python/compare/v0.1.0-alpha.7...v0.1.0-alpha.8) diff --git a/README.md b/README.md index 42ef0af5..2695ffe2 100644 --- a/README.md +++ b/README.md @@ -39,11 +39,6 @@ project_return_schema = client.projects.create( print(project_return_schema.id) ``` -While you can provide a `bearer_token` keyword argument, -we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/) -to add `CODEX_BEARER_TOKEN="My Bearer Token"` to your `.env` file -so that your Bearer Token is not stored in source control. - ## Async usage Simply import `AsyncCodex` instead of `Codex` and use `await` with each API call: diff --git a/pyproject.toml b/pyproject.toml index 16ec8a7d..e4b23281 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "codex-sdk" -version = "0.1.0-alpha.8" +version = "0.1.0-alpha.9" description = "The official Python library for the Codex API" dynamic = ["readme"] license = "MIT" diff --git a/src/codex/_client.py b/src/codex/_client.py index fc0c27bf..09aaafd1 100644 --- a/src/codex/_client.py +++ b/src/codex/_client.py @@ -65,7 +65,6 @@ class Codex(SyncAPIClient): with_streaming_response: CodexWithStreamedResponse # client options - bearer_token: str | None api_key: str | None access_key: str | None @@ -74,7 +73,6 @@ class Codex(SyncAPIClient): def __init__( self, *, - bearer_token: str | None = None, api_key: str | None = None, access_key: str | None = None, environment: Literal["production", "staging", "local"] | NotGiven = NOT_GIVEN, @@ -97,23 +95,9 @@ def __init__( # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: - """Construct a new synchronous Codex client instance. - - This automatically infers the following arguments from their corresponding environment variables if they are not provided: - - `bearer_token` from `CODEX_BEARER_TOKEN` - - `api_key` from `CODEX_API_KEY` - - `access_key` from `CODEX_ACCESS_KEY` - """ - if bearer_token is None: - bearer_token = os.environ.get("CODEX_BEARER_TOKEN") - self.bearer_token = bearer_token - - if api_key is None: - api_key = os.environ.get("CODEX_API_KEY") + """Construct a new synchronous Codex client instance.""" self.api_key = api_key - if access_key is None: - access_key = os.environ.get("CODEX_ACCESS_KEY") self.access_key = access_key self._environment = environment @@ -168,21 +152,12 @@ def qs(self) -> Querystring: @property @override def auth_headers(self) -> dict[str, str]: - if self._http_bearer: - return self._http_bearer if self._authenticated_api_key: return self._authenticated_api_key if self._public_access_key: return self._public_access_key return {} - @property - def _http_bearer(self) -> dict[str, str]: - bearer_token = self.bearer_token - if bearer_token is None: - return {} - return {"Authorization": f"Bearer {bearer_token}"} - @property def _authenticated_api_key(self) -> dict[str, str]: api_key = self.api_key @@ -208,11 +183,6 @@ def default_headers(self) -> dict[str, str | Omit]: @override def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: - if self.bearer_token and headers.get("Authorization"): - return - if isinstance(custom_headers.get("Authorization"), Omit): - return - if self.api_key and headers.get("X-API-Key"): return if isinstance(custom_headers.get("X-API-Key"), Omit): @@ -224,13 +194,12 @@ def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: return raise TypeError( - '"Could not resolve authentication method. Expected one of bearer_token, api_key or access_key to be set. Or for one of the `Authorization`, `X-API-Key` or `X-Access-Key` headers to be explicitly omitted"' + '"Could not resolve authentication method. Expected either api_key or access_key to be set. Or for one of the `X-API-Key` or `X-Access-Key` headers to be explicitly omitted"' ) def copy( self, *, - bearer_token: str | None = None, api_key: str | None = None, access_key: str | None = None, environment: Literal["production", "staging", "local"] | None = None, @@ -267,7 +236,6 @@ def copy( http_client = http_client or self._client return self.__class__( - bearer_token=bearer_token or self.bearer_token, api_key=api_key or self.api_key, access_key=access_key or self.access_key, base_url=base_url or self.base_url, @@ -327,7 +295,6 @@ class AsyncCodex(AsyncAPIClient): with_streaming_response: AsyncCodexWithStreamedResponse # client options - bearer_token: str | None api_key: str | None access_key: str | None @@ -336,7 +303,6 @@ class AsyncCodex(AsyncAPIClient): def __init__( self, *, - bearer_token: str | None = None, api_key: str | None = None, access_key: str | None = None, environment: Literal["production", "staging", "local"] | NotGiven = NOT_GIVEN, @@ -359,23 +325,9 @@ def __init__( # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: - """Construct a new async Codex client instance. - - This automatically infers the following arguments from their corresponding environment variables if they are not provided: - - `bearer_token` from `CODEX_BEARER_TOKEN` - - `api_key` from `CODEX_API_KEY` - - `access_key` from `CODEX_ACCESS_KEY` - """ - if bearer_token is None: - bearer_token = os.environ.get("CODEX_BEARER_TOKEN") - self.bearer_token = bearer_token - - if api_key is None: - api_key = os.environ.get("CODEX_API_KEY") + """Construct a new async Codex client instance.""" self.api_key = api_key - if access_key is None: - access_key = os.environ.get("CODEX_ACCESS_KEY") self.access_key = access_key self._environment = environment @@ -430,21 +382,12 @@ def qs(self) -> Querystring: @property @override def auth_headers(self) -> dict[str, str]: - if self._http_bearer: - return self._http_bearer if self._authenticated_api_key: return self._authenticated_api_key if self._public_access_key: return self._public_access_key return {} - @property - def _http_bearer(self) -> dict[str, str]: - bearer_token = self.bearer_token - if bearer_token is None: - return {} - return {"Authorization": f"Bearer {bearer_token}"} - @property def _authenticated_api_key(self) -> dict[str, str]: api_key = self.api_key @@ -470,11 +413,6 @@ def default_headers(self) -> dict[str, str | Omit]: @override def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: - if self.bearer_token and headers.get("Authorization"): - return - if isinstance(custom_headers.get("Authorization"), Omit): - return - if self.api_key and headers.get("X-API-Key"): return if isinstance(custom_headers.get("X-API-Key"), Omit): @@ -486,13 +424,12 @@ def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: return raise TypeError( - '"Could not resolve authentication method. Expected one of bearer_token, api_key or access_key to be set. Or for one of the `Authorization`, `X-API-Key` or `X-Access-Key` headers to be explicitly omitted"' + '"Could not resolve authentication method. Expected either api_key or access_key to be set. Or for one of the `X-API-Key` or `X-Access-Key` headers to be explicitly omitted"' ) def copy( self, *, - bearer_token: str | None = None, api_key: str | None = None, access_key: str | None = None, environment: Literal["production", "staging", "local"] | None = None, @@ -529,7 +466,6 @@ def copy( http_client = http_client or self._client return self.__class__( - bearer_token=bearer_token or self.bearer_token, api_key=api_key or self.api_key, access_key=access_key or self.access_key, base_url=base_url or self.base_url, diff --git a/src/codex/_version.py b/src/codex/_version.py index 9cbcc56a..398bec65 100644 --- a/src/codex/_version.py +++ b/src/codex/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "codex" -__version__ = "0.1.0-alpha.8" # x-release-please-version +__version__ = "0.1.0-alpha.9" # x-release-please-version