From 7863fba58838380e273caf8e320d26b25b261f77 Mon Sep 17 00:00:00 2001 From: jbeckwith-oai <269036200+jbeckwith-oai@users.noreply.github.com> Date: Fri, 4 Sep 2026 17:40:05 -0700 Subject: [PATCH 1/2] feat(api): add service-account API key expiration fields Castiron-Internal-PR: https://github.com/openai/openai-python-internal/pull/84 Castiron-Source-SHA: 6eefcc34b79ca8c3087a3f6ee6fbbaf5b8ac7510 Castiron-Public-Base-SHA: 2a98f6a1dee448c6410531c89c2de0af4383c6a7 --- .castiron.stats.yml | 12 ++--- api_reference/openapi.transformed.yml | 17 +++++++ .../projects/service_accounts/api_keys.py | 10 ++++ .../resources/beta/responses/responses.py | 50 +++++++++++++++++-- src/openai/resources/realtime/realtime.py | 32 ++++++++++-- src/openai/resources/responses/responses.py | 50 +++++++++++++++++-- .../service_accounts/api_key_create_params.py | 4 ++ .../api_key_create_response.py | 7 +++ .../types/beta/beta_responses_client_event.py | 7 ++- .../beta/beta_responses_client_event_param.py | 7 ++- .../types/beta/response_create_params.py | 7 ++- .../types/responses/response_create_params.py | 7 ++- .../types/responses/responses_client_event.py | 7 ++- .../responses/responses_client_event_param.py | 7 ++- .../service_accounts/test_api_keys.py | 2 + tests/test_send_queue_reconnect.py | 4 +- 16 files changed, 204 insertions(+), 26 deletions(-) diff --git a/.castiron.stats.yml b/.castiron.stats.yml index fa277b5818..a97c970823 100644 --- a/.castiron.stats.yml +++ b/.castiron.stats.yml @@ -1,8 +1,8 @@ schema_version: 1 -generation_id: c8545f55-7807-4037-9c86-3784b96f3960 -openapi_spec_hash: 0f07f47154153d68e717ae594b07dc4c -openapi_transformed_spec_hash: a1a351d4356d65a15a857d0aca5f7b09 +generation_id: 7c85e3b8-1fd9-4422-9e62-0b845e4d0dd6 +openapi_spec_hash: 4e1ab2560f0c0f65641ea0a2d769a0d5 +openapi_transformed_spec_hash: fd14e90569d03122e5fdcc35e52153b4 config_hash: dfe8a20c64cc5d852e69c441cbd28ae7 -codegen_sha: 1d8024b3eb37e3e329104029ed81fd2085ff1218 -codegen_hash: e1ee819da91a6c8ae8c8af8c4e3054f52eaec918912e9be3b2bd6bc692608d5e -public_codegen_sha: 67cbc9398ec6c0feb5bad24421b648b42bbc405f +codegen_sha: 1a2564e113780db175aecce7b826099172da9171 +codegen_hash: aee79621a90e3602ea790e7bc34cfc58368c4217f4d77921bc8960d65b4a8845 +public_codegen_sha: 5d5101490afb27fea944f63bc21b52140409bf4a diff --git a/api_reference/openapi.transformed.yml b/api_reference/openapi.transformed.yml index 1ba6aca36e..4990382d1d 100644 --- a/api_reference/openapi.transformed.yml +++ b/api_reference/openapi.transformed.yml @@ -34039,6 +34039,8 @@ components: description: | Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. + If set to true, response data will be stored for at least 30 days, subject to the [data retention exceptions](/api/docs/guides/your-data#v1responses). default: true - type: 'null' instructions: @@ -66300,6 +66302,13 @@ components: description: API key scope. type: array description: API key scopes. + expires_in_seconds: + anyOf: + - type: integer + maximum: 31536000 + minimum: 1 + description: Number of seconds until the API key expires. + - type: 'null' type: object required: [] description: The service account API key create request payload. @@ -66322,6 +66331,12 @@ components: type: integer format: unixtime description: The Unix timestamp (in seconds) when the API key was created. + expires_at: + anyOf: + - type: integer + format: unixtime + description: The Unix timestamp (in seconds) when the API key expires, or null if it does not expire. + - type: 'null' id: type: string description: The identifier of the API key. @@ -80449,6 +80464,8 @@ components: description: | Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. + If set to true, response data will be stored for at least 30 days, subject to the [data retention exceptions](/api/docs/guides/your-data#v1responses). default: true - type: 'null' instructions: diff --git a/src/openai/resources/admin/organization/projects/service_accounts/api_keys.py b/src/openai/resources/admin/organization/projects/service_accounts/api_keys.py index 96f38b544d..cedd32e001 100644 --- a/src/openai/resources/admin/organization/projects/service_accounts/api_keys.py +++ b/src/openai/resources/admin/organization/projects/service_accounts/api_keys.py @@ -2,6 +2,8 @@ from __future__ import annotations +from typing import Optional + import httpx2 from ...... import _legacy_response @@ -42,6 +44,7 @@ def create( service_account_id: str, *, project_id: str, + expires_in_seconds: Optional[int] | Omit = omit, name: str | Omit = omit, scopes: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -59,6 +62,8 @@ def create( service_account_id: The ID of the service account. + expires_in_seconds: Number of seconds until the API key expires. + name: API key name. scopes: API key scopes. @@ -83,6 +88,7 @@ def create( ), body=maybe_transform( { + "expires_in_seconds": expires_in_seconds, "name": name, "scopes": scopes, }, @@ -124,6 +130,7 @@ async def create( service_account_id: str, *, project_id: str, + expires_in_seconds: Optional[int] | Omit = omit, name: str | Omit = omit, scopes: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -141,6 +148,8 @@ async def create( service_account_id: The ID of the service account. + expires_in_seconds: Number of seconds until the API key expires. + name: API key name. scopes: API key scopes. @@ -165,6 +174,7 @@ async def create( ), body=await async_maybe_transform( { + "expires_in_seconds": expires_in_seconds, "name": name, "scopes": scopes, }, diff --git a/src/openai/resources/beta/responses/responses.py b/src/openai/resources/beta/responses/responses.py index 6c515d457f..e3c73c6be1 100644 --- a/src/openai/resources/beta/responses/responses.py +++ b/src/openai/resources/beta/responses/responses.py @@ -420,6 +420,9 @@ def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream: If set to true, the model response data will be streamed to the client as it is generated using @@ -822,6 +825,9 @@ def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream_options: Options for streaming responses. Only set this when you set `stream: true`. @@ -1217,6 +1223,9 @@ def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream_options: Options for streaming responses. Only set this when you set `stream: true`. @@ -2375,6 +2384,9 @@ async def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream: If set to true, the model response data will be streamed to the client as it is generated using @@ -2777,6 +2789,9 @@ async def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream_options: Options for streaming responses. Only set this when you set `stream: true`. @@ -3172,6 +3187,9 @@ async def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream_options: Options for streaming responses. Only set this when you set `stream: true`. @@ -4126,6 +4144,7 @@ def __init__( self._make_ws = make_ws self._on_reconnecting = on_reconnecting self._max_retries = max_retries + self._reconnect_attempt = 0 self._initial_delay = initial_delay self._max_delay = max_delay self._extra_query = extra_query @@ -4165,7 +4184,17 @@ async def recv(self) -> BetaResponsesServerEvent: Canceling this method is safe. There's no risk of losing data. """ - return self.parse_event(await self.recv_bytes()) + event = self.parse_event(await self.recv_bytes()) + event_type = ( + cast("dict[str, object]", event).get("type") + if isinstance(cast(object, event), dict) + else getattr(event, "type", None) + ) + # A successful upgrade can still be followed by an admission error. + # Reset the budget only after receiving a non-error application event. + if isinstance(event_type, str) and event_type and event_type != "error": + self._reconnect_attempt = 0 + return event async def recv_bytes(self) -> bytes: """Receive the next message from the connection as raw bytes. @@ -4238,7 +4267,8 @@ async def _reconnect(self, exc: Exception) -> bool: self._is_reconnecting = True - for attempt in range(1, self._max_retries + 1): + for attempt in range(self._reconnect_attempt + 1, self._max_retries + 1): + self._reconnect_attempt = attempt base_delay = min(self._initial_delay * (2 ** (attempt - 1)), self._max_delay) jitter = 0.75 + random.random() * 0.25 delay = base_delay * jitter @@ -4583,6 +4613,7 @@ def __init__( self._make_ws = make_ws self._on_reconnecting = on_reconnecting self._max_retries = max_retries + self._reconnect_attempt = 0 self._initial_delay = initial_delay self._max_delay = max_delay self._extra_query = extra_query @@ -4622,7 +4653,17 @@ def recv(self) -> BetaResponsesServerEvent: Canceling this method is safe. There's no risk of losing data. """ - return self.parse_event(self.recv_bytes()) + event = self.parse_event(self.recv_bytes()) + event_type = ( + cast("dict[str, object]", event).get("type") + if isinstance(cast(object, event), dict) + else getattr(event, "type", None) + ) + # A successful upgrade can still be followed by an admission error. + # Reset the budget only after receiving a non-error application event. + if isinstance(event_type, str) and event_type and event_type != "error": + self._reconnect_attempt = 0 + return event def recv_bytes(self) -> bytes: """Receive the next message from the connection as raw bytes. @@ -4693,7 +4734,8 @@ def _reconnect(self, exc: Exception) -> bool: self._is_reconnecting = True - for attempt in range(1, self._max_retries + 1): + for attempt in range(self._reconnect_attempt + 1, self._max_retries + 1): + self._reconnect_attempt = attempt base_delay = min(self._initial_delay * (2 ** (attempt - 1)), self._max_delay) jitter = 0.75 + random.random() * 0.25 delay = base_delay * jitter diff --git a/src/openai/resources/realtime/realtime.py b/src/openai/resources/realtime/realtime.py index 3cb815bddf..9b96fb546e 100644 --- a/src/openai/resources/realtime/realtime.py +++ b/src/openai/resources/realtime/realtime.py @@ -286,6 +286,7 @@ def __init__( self._make_ws = make_ws self._on_reconnecting = on_reconnecting self._max_retries = max_retries + self._reconnect_attempt = 0 self._initial_delay = initial_delay self._max_delay = max_delay self._extra_query = extra_query @@ -329,7 +330,17 @@ async def recv(self) -> RealtimeServerEvent: Canceling this method is safe. There's no risk of losing data. """ - return self.parse_event(await self.recv_bytes()) + event = self.parse_event(await self.recv_bytes()) + event_type = ( + cast("dict[str, object]", event).get("type") + if isinstance(cast(object, event), dict) + else getattr(event, "type", None) + ) + # A successful upgrade can still be followed by an admission error. + # Reset the budget only after receiving a non-error application event. + if isinstance(event_type, str) and event_type and event_type != "error": + self._reconnect_attempt = 0 + return event async def recv_bytes(self) -> bytes: """Receive the next message from the connection as raw bytes. @@ -401,7 +412,8 @@ async def _reconnect(self, exc: Exception) -> bool: self._is_reconnecting = True - for attempt in range(1, self._max_retries + 1): + for attempt in range(self._reconnect_attempt + 1, self._max_retries + 1): + self._reconnect_attempt = attempt base_delay = min(self._initial_delay * (2 ** (attempt - 1)), self._max_delay) jitter = 0.75 + random.random() * 0.25 delay = base_delay * jitter @@ -768,6 +780,7 @@ def __init__( self._make_ws = make_ws self._on_reconnecting = on_reconnecting self._max_retries = max_retries + self._reconnect_attempt = 0 self._initial_delay = initial_delay self._max_delay = max_delay self._extra_query = extra_query @@ -811,7 +824,17 @@ def recv(self) -> RealtimeServerEvent: Canceling this method is safe. There's no risk of losing data. """ - return self.parse_event(self.recv_bytes()) + event = self.parse_event(self.recv_bytes()) + event_type = ( + cast("dict[str, object]", event).get("type") + if isinstance(cast(object, event), dict) + else getattr(event, "type", None) + ) + # A successful upgrade can still be followed by an admission error. + # Reset the budget only after receiving a non-error application event. + if isinstance(event_type, str) and event_type and event_type != "error": + self._reconnect_attempt = 0 + return event def recv_bytes(self) -> bytes: """Receive the next message from the connection as raw bytes. @@ -881,7 +904,8 @@ def _reconnect(self, exc: Exception) -> bool: self._is_reconnecting = True - for attempt in range(1, self._max_retries + 1): + for attempt in range(self._reconnect_attempt + 1, self._max_retries + 1): + self._reconnect_attempt = attempt base_delay = min(self._initial_delay * (2 ** (attempt - 1)), self._max_delay) jitter = 0.75 + random.random() * 0.25 delay = base_delay * jitter diff --git a/src/openai/resources/responses/responses.py b/src/openai/resources/responses/responses.py index 1618c34b42..4db05d4443 100644 --- a/src/openai/resources/responses/responses.py +++ b/src/openai/resources/responses/responses.py @@ -334,6 +334,9 @@ def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream: If set to true, the model response data will be streamed to the client as it is generated using @@ -624,6 +627,9 @@ def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream_options: Options for streaming responses. Only set this when you set `stream: true`. @@ -907,6 +913,9 @@ def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream_options: Options for streaming responses. Only set this when you set `stream: true`. @@ -2198,6 +2207,9 @@ async def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream: If set to true, the model response data will be streamed to the client as it is generated using @@ -2488,6 +2500,9 @@ async def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream_options: Options for streaming responses. Only set this when you set `stream: true`. @@ -2771,6 +2786,9 @@ async def create( parameter. store: Whether to store the generated model response for later retrieval via API. + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). stream_options: Options for streaming responses. Only set this when you set `stream: true`. @@ -4013,6 +4031,7 @@ def __init__( self._make_ws = make_ws self._on_reconnecting = on_reconnecting self._max_retries = max_retries + self._reconnect_attempt = 0 self._initial_delay = initial_delay self._max_delay = max_delay self._extra_query = extra_query @@ -4052,7 +4071,17 @@ async def recv(self) -> ResponsesServerEvent: Canceling this method is safe. There's no risk of losing data. """ - return self.parse_event(await self.recv_bytes()) + event = self.parse_event(await self.recv_bytes()) + event_type = ( + cast("dict[str, object]", event).get("type") + if isinstance(cast(object, event), dict) + else getattr(event, "type", None) + ) + # A successful upgrade can still be followed by an admission error. + # Reset the budget only after receiving a non-error application event. + if isinstance(event_type, str) and event_type and event_type != "error": + self._reconnect_attempt = 0 + return event async def recv_bytes(self) -> bytes: """Receive the next message from the connection as raw bytes. @@ -4125,7 +4154,8 @@ async def _reconnect(self, exc: Exception) -> bool: self._is_reconnecting = True - for attempt in range(1, self._max_retries + 1): + for attempt in range(self._reconnect_attempt + 1, self._max_retries + 1): + self._reconnect_attempt = attempt base_delay = min(self._initial_delay * (2 ** (attempt - 1)), self._max_delay) jitter = 0.75 + random.random() * 0.25 delay = base_delay * jitter @@ -4470,6 +4500,7 @@ def __init__( self._make_ws = make_ws self._on_reconnecting = on_reconnecting self._max_retries = max_retries + self._reconnect_attempt = 0 self._initial_delay = initial_delay self._max_delay = max_delay self._extra_query = extra_query @@ -4509,7 +4540,17 @@ def recv(self) -> ResponsesServerEvent: Canceling this method is safe. There's no risk of losing data. """ - return self.parse_event(self.recv_bytes()) + event = self.parse_event(self.recv_bytes()) + event_type = ( + cast("dict[str, object]", event).get("type") + if isinstance(cast(object, event), dict) + else getattr(event, "type", None) + ) + # A successful upgrade can still be followed by an admission error. + # Reset the budget only after receiving a non-error application event. + if isinstance(event_type, str) and event_type and event_type != "error": + self._reconnect_attempt = 0 + return event def recv_bytes(self) -> bytes: """Receive the next message from the connection as raw bytes. @@ -4580,7 +4621,8 @@ def _reconnect(self, exc: Exception) -> bool: self._is_reconnecting = True - for attempt in range(1, self._max_retries + 1): + for attempt in range(self._reconnect_attempt + 1, self._max_retries + 1): + self._reconnect_attempt = attempt base_delay = min(self._initial_delay * (2 ** (attempt - 1)), self._max_delay) jitter = 0.75 + random.random() * 0.25 delay = base_delay * jitter diff --git a/src/openai/types/admin/organization/projects/service_accounts/api_key_create_params.py b/src/openai/types/admin/organization/projects/service_accounts/api_key_create_params.py index adeaf17ee5..4964231317 100644 --- a/src/openai/types/admin/organization/projects/service_accounts/api_key_create_params.py +++ b/src/openai/types/admin/organization/projects/service_accounts/api_key_create_params.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Optional from typing_extensions import Required, TypedDict from ......_types import SequenceNotStr @@ -13,6 +14,9 @@ class APIKeyCreateParams(TypedDict, total=False): project_id: Required[str] """The ID of the project.""" + expires_in_seconds: Optional[int] + """Number of seconds until the API key expires.""" + name: str """API key name.""" diff --git a/src/openai/types/admin/organization/projects/service_accounts/api_key_create_response.py b/src/openai/types/admin/organization/projects/service_accounts/api_key_create_response.py index b7463b0c23..cefcf98a4c 100644 --- a/src/openai/types/admin/organization/projects/service_accounts/api_key_create_response.py +++ b/src/openai/types/admin/organization/projects/service_accounts/api_key_create_response.py @@ -1,5 +1,6 @@ # File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. +from typing import Optional from typing_extensions import Literal from ......_models import BaseModel @@ -22,3 +23,9 @@ class APIKeyCreateResponse(BaseModel): value: str """The unredacted API key value.""" + + expires_at: Optional[int] = None + """ + The Unix timestamp (in seconds) when the API key expires, or null if it does not + expire. + """ diff --git a/src/openai/types/beta/beta_responses_client_event.py b/src/openai/types/beta/beta_responses_client_event.py index 94709417cd..091bd015c3 100644 --- a/src/openai/types/beta/beta_responses_client_event.py +++ b/src/openai/types/beta/beta_responses_client_event.py @@ -544,7 +544,12 @@ class ResponseCreate(BaseModel): """ store: Optional[bool] = None - """Whether to store the generated model response for later retrieval via API.""" + """Whether to store the generated model response for later retrieval via API. + + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). + """ stream: Optional[bool] = None """ diff --git a/src/openai/types/beta/beta_responses_client_event_param.py b/src/openai/types/beta/beta_responses_client_event_param.py index 2ff8d6ad39..576ca59bb8 100644 --- a/src/openai/types/beta/beta_responses_client_event_param.py +++ b/src/openai/types/beta/beta_responses_client_event_param.py @@ -543,7 +543,12 @@ class ResponseCreate(TypedDict, total=False): """ store: Optional[bool] - """Whether to store the generated model response for later retrieval via API.""" + """Whether to store the generated model response for later retrieval via API. + + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). + """ stream: Optional[bool] """ diff --git a/src/openai/types/beta/response_create_params.py b/src/openai/types/beta/response_create_params.py index 587c68656c..cddb7cd966 100644 --- a/src/openai/types/beta/response_create_params.py +++ b/src/openai/types/beta/response_create_params.py @@ -350,7 +350,12 @@ class ResponseCreateParamsBase(TypedDict, total=False): """ store: Optional[bool] - """Whether to store the generated model response for later retrieval via API.""" + """Whether to store the generated model response for later retrieval via API. + + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). + """ stream_options: Optional[StreamOptions] """Options for streaming responses. Only set this when you set `stream: true`.""" diff --git a/src/openai/types/responses/response_create_params.py b/src/openai/types/responses/response_create_params.py index 7d08e9b03e..11669bef05 100644 --- a/src/openai/types/responses/response_create_params.py +++ b/src/openai/types/responses/response_create_params.py @@ -240,7 +240,12 @@ class ResponseCreateParamsBase(TypedDict, total=False): """ store: Optional[bool] - """Whether to store the generated model response for later retrieval via API.""" + """Whether to store the generated model response for later retrieval via API. + + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). + """ stream_options: Optional[StreamOptions] """Options for streaming responses. Only set this when you set `stream: true`.""" diff --git a/src/openai/types/responses/responses_client_event.py b/src/openai/types/responses/responses_client_event.py index 4df5625f5e..2ba335a523 100644 --- a/src/openai/types/responses/responses_client_event.py +++ b/src/openai/types/responses/responses_client_event.py @@ -379,7 +379,12 @@ class ResponseCreate(BaseModel): """ store: Optional[bool] = None - """Whether to store the generated model response for later retrieval via API.""" + """Whether to store the generated model response for later retrieval via API. + + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). + """ stream: Optional[bool] = None """ diff --git a/src/openai/types/responses/responses_client_event_param.py b/src/openai/types/responses/responses_client_event_param.py index 79a6a8fd00..b0b68c50e5 100644 --- a/src/openai/types/responses/responses_client_event_param.py +++ b/src/openai/types/responses/responses_client_event_param.py @@ -379,7 +379,12 @@ class ResponseCreate(TypedDict, total=False): """ store: Optional[bool] - """Whether to store the generated model response for later retrieval via API.""" + """Whether to store the generated model response for later retrieval via API. + + Defaults to true when omitted. If set to true, response data will be stored for + at least 30 days, subject to the + [data retention exceptions](/api/docs/guides/your-data#v1responses). + """ stream: Optional[bool] """ diff --git a/tests/api_resources/admin/organization/projects/service_accounts/test_api_keys.py b/tests/api_resources/admin/organization/projects/service_accounts/test_api_keys.py index 465c192140..8e45430f96 100644 --- a/tests/api_resources/admin/organization/projects/service_accounts/test_api_keys.py +++ b/tests/api_resources/admin/organization/projects/service_accounts/test_api_keys.py @@ -30,6 +30,7 @@ def test_method_create_with_all_params(self, client: OpenAI) -> None: api_key = client.admin.organization.projects.service_accounts.api_keys.create( service_account_id="service_account_id", project_id="project_id", + expires_in_seconds=1, name="name", scopes=["string"], ) @@ -94,6 +95,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> api_key = await async_client.admin.organization.projects.service_accounts.api_keys.create( service_account_id="service_account_id", project_id="project_id", + expires_in_seconds=1, name="name", scopes=["string"], ) diff --git a/tests/test_send_queue_reconnect.py b/tests/test_send_queue_reconnect.py index 008af801d4..9314b6a415 100644 --- a/tests/test_send_queue_reconnect.py +++ b/tests/test_send_queue_reconnect.py @@ -40,7 +40,7 @@ def failing_send(data: str) -> None: make_ws=MagicMock(return_value=ws), on_reconnecting=lambda _event: None, initial_delay=0, - max_retries=1, + max_retries=4, ) for _ in range(3): assert connection._reconnect(RuntimeError("fake disconnect")) @@ -85,7 +85,7 @@ async def failing_send(data: str) -> None: make_ws=AsyncMock(return_value=ws), on_reconnecting=lambda _event: None, initial_delay=0, - max_retries=1, + max_retries=4, ) for _ in range(3): assert await connection._reconnect(RuntimeError("fake disconnect")) From 2bdf7d7a1d3781b5281d5517efb5883f5a7d07cc Mon Sep 17 00:00:00 2001 From: Marcus Wood Date: Tue, 8 Sep 2026 12:59:50 -0700 Subject: [PATCH 2/2] fix: refresh mock spec checksum after merging main --- .castiron.stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.castiron.stats.yml b/.castiron.stats.yml index a97c970823..9e8258a3d3 100644 --- a/.castiron.stats.yml +++ b/.castiron.stats.yml @@ -1,7 +1,7 @@ schema_version: 1 generation_id: 7c85e3b8-1fd9-4422-9e62-0b845e4d0dd6 openapi_spec_hash: 4e1ab2560f0c0f65641ea0a2d769a0d5 -openapi_transformed_spec_hash: fd14e90569d03122e5fdcc35e52153b4 +openapi_transformed_spec_hash: 55e7b75c47c80e83f6e3c2970444e5ba config_hash: dfe8a20c64cc5d852e69c441cbd28ae7 codegen_sha: 1a2564e113780db175aecce7b826099172da9171 codegen_hash: aee79621a90e3602ea790e7bc34cfc58368c4217f4d77921bc8960d65b4a8845