Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .castiron.stats.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
schema_version: 1
generation_id: 64f4392f-6816-485e-8210-b9a1c2ec7def
openapi_spec_hash: 92700e1a33a4f6174a01b46648c8186a
openapi_transformed_spec_hash: e37bbe0f04caa6093f1cb5d65d23ad03
config_hash: beab4f058e80bab30085bb6c8467b65f
codegen_sha: 23e8f705c06ddc2c2f80e8444b294793771e4f47
codegen_hash: 717da37491ba2e308f370daeb4883c974f792a4385c5cd411d46904796787997
public_codegen_sha: ffde304f4cfdd6d0ea6cd5ee855cc48efc89fc5d
generation_id: 894a0870-fe44-47b8-ae0e-d852e0a642a9
openapi_spec_hash: b2c62b342b04685226037c980f2b5a7a
openapi_transformed_spec_hash: ba44bf31326f01a1d886b7510dd9da8a
config_hash: 4fbbbcf377bcc17646cccb9fcfbac14a
codegen_sha: 29ea2f9fd4247a24ce57aec59ee2b9240745fcdf
codegen_hash: dcd47732b7809ce7566ec5162d689b5320158e41aebcce2b31eaa9cd97fc4da2
public_codegen_sha: eb1e776d29014be85225038a072a679387bda999
3 changes: 2 additions & 1 deletion api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,7 @@ Types:

```python
from openai.types.admin.organization import (
CostQuantityUnit,
UsageAudioSpeechesResponse,
UsageAudioTranscriptionsResponse,
UsageCodeInterpreterSessionsResponse,
Expand Down Expand Up @@ -1232,7 +1233,7 @@ Methods:
Types:

```python
from openai.types.admin.organization import Project
from openai.types.admin.organization import Project, ProjectResidency
```

Methods:
Expand Down
56 changes: 51 additions & 5 deletions api_reference/openapi.transformed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9552,7 +9552,8 @@ paths:
"line_item": null,
"project_id": null,
"api_key_id": null,
"quantity": null
"quantity": null,
"quantity_unit": null
}
]
}
Expand Down Expand Up @@ -31011,6 +31012,21 @@ components:
- type: number
description: When `group_by=line_item`, this field provides the quantity of the grouped costs result.
- type: 'null'
quantity_unit:
description: The unit of the `quantity` value. If no single supported unit applies to the result, this field is `null`.
anyOf:
- type: string
- type: string
enum:
- tokens
- 1000_tokens
- duration_seconds
- duration_minutes
- duration_hours
- gibibyte_hours
- images
- characters
- type: 'null'
required:
- object
x-oaiMeta:
Expand All @@ -31022,9 +31038,10 @@ components:
"value": 0.06,
"currency": "usd"
},
"line_item": "Image models",
"line_item": "input_tokens",
"project_id": "proj_abc",
"quantity": 10000
"quantity": 10000,
"quantity_unit": "tokens"
}
CreateAssistantRequest:
type: object
Expand Down Expand Up @@ -42278,6 +42295,9 @@ components:
- type: string
- type: 'null'
description: The external key associated with the project.
residency:
$ref: '#/components/schemas/PublicProjectResidency'
description: The residency configuration for the project.
required:
- id
- object
Expand Down Expand Up @@ -42473,7 +42493,15 @@ components:
anyOf:
- type: string
- type: 'null'
description: Create the project with the specified data residency region. Your organization must have access to Data residency functionality in order to use. See [data residency controls](https://platform.openai.com/docs/guides/your-data#data-residency-controls) to review the functionality and limitations of setting this field.
deprecated: true
description: |-
Create the project with the specified data residency region. Your organization must have access to Data residency functionality in order to use. See [data residency controls](https://platform.openai.com/docs/guides/your-data#data-residency-controls) to review the functionality and limitations of setting this field.
Deprecated: use `residency` instead. Do not provide both `geography` and `residency`.
residency:
anyOf:
- $ref: '#/components/schemas/PublicProjectResidency'
- type: 'null'
description: Create the project with the specified residency configuration. Your organization must have access to the requested residency configuration in order to use it. See [data residency controls](https://platform.openai.com/docs/guides/your-data#data-residency-controls) to review the functionality and limitations of setting this field.
external_key_id:
anyOf:
- type: string
Expand Down Expand Up @@ -43170,7 +43198,10 @@ components:
anyOf:
- type: string
- type: 'null'
description: Geography for the project.
deprecated: true
description: |-
Geography for the project.
Deprecated: use `residency` when creating a project to configure data residency. This field is retained for backward compatibility.
ProjectUser:
type: object
description: Represents an individual user in a project.
Expand Down Expand Up @@ -64729,6 +64760,21 @@ components:
- input_tokens_details
title: Image generation usage
description: For `gpt-image-1` only, the token usage information for the image generation.
PublicProjectResidency:
type: string
enum:
- GLOBAL
- US_STORAGE_PROCESSING
- EU_STORAGE_PROCESSING
- JP_STORAGE
- KR_STORAGE
- CA_STORAGE
- SG_STORAGE
- IN_STORAGE
- AU_STORAGE
- GB_STORAGE
- AE_STORAGE
- AE_STORAGE_PROCESSING
SpecificProgrammaticToolCallingParam:
properties:
type:
Expand Down
48 changes: 48 additions & 0 deletions src/openai/_multipart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details.

from __future__ import annotations

from typing import Mapping, cast

from ._types import Body, Omit, NotGiven, FileTypes, RequestFiles
from ._utils._json import openapi_dumps


def encode_multipart(
body: object,
extra_body: Body | None,
encodings: Mapping[str, tuple[str, bool]],
raw_body_field: str | None = None,
existing_files: RequestFiles | None = None,
) -> tuple[dict[str, object] | None, RequestFiles | None, bytes | None, str]:
"""Prepare explicitly encoded form fields without flattening their JSON contents."""
if not isinstance(body, Mapping):
raise TypeError("Multipart request body must be a mapping")
if extra_body is not None and not isinstance(extra_body, Mapping):
raise TypeError("Multipart extra_body must be a mapping")
original = cast(Mapping[str, object], body)
overrides = cast(Mapping[str, object], extra_body or {})
merged = {key: value for key, value in {**original, **overrides}.items() if not isinstance(value, (Omit, NotGiven))}
# A raw request alternative is safe only when there is no other payload to lose.
# Explicit null remains a JSON part; only an omitted field selects the raw body.
if not existing_files and raw_body_field is not None and set(merged) == {raw_body_field}:
value = merged[raw_body_field]
if not isinstance(value, str):
raise TypeError("Raw multipart alternative must be a string")
return None, None, value.encode("utf-8"), encodings[raw_body_field][0]

files: list[tuple[str, FileTypes]] = list(
existing_files.items() if isinstance(existing_files, Mapping) else (existing_files or [])
)
for name, (content_type, as_json) in encodings.items():
if name not in merged:
continue
value = merged.pop(name)
if as_json:
data = openapi_dumps(value)
else:
if not isinstance(value, str):
raise TypeError(f"Multipart field {name!r} must be a string")
data = value.encode("utf-8")
files.append((name, (None, data, content_type)))
return merged or None, files, None, "multipart/form-data"
91 changes: 3 additions & 88 deletions src/openai/lib/_realtime.py
Original file line number Diff line number Diff line change
@@ -1,92 +1,7 @@
from __future__ import annotations

import json
from typing_extensions import override

import httpx2

from openai import _legacy_response
from openai._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from openai._utils import maybe_transform, async_maybe_transform
from openai._base_client import make_request_options
from openai.resources.realtime.calls import Calls, AsyncCalls
from openai.types.realtime.realtime_session_create_request_param import RealtimeSessionCreateRequestParam
# Compatibility aliases for the former handwritten call-creation implementation.
# Multipart and raw SDP serialization now come from the generated resources.
from openai.resources.realtime.calls import Calls as _Calls, AsyncCalls as _AsyncCalls

__all__ = ["_Calls", "_AsyncCalls"]


# Custom code to override the `create` method to have correct behavior with
# application/sdp and multipart/form-data.
# Ideally we can cutover to the generated code this overrides eventually and remove this.
class _Calls(Calls):
@override
def create(
self,
*,
sdp: str,
session: RealtimeSessionCreateRequestParam | Omit = omit,
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx2.Timeout | None | NotGiven = not_given,
) -> _legacy_response.HttpxBinaryResponseContent:
if session is omit:
extra_headers = {"Accept": "application/sdp", "Content-Type": "application/sdp", **(extra_headers or {})}
return self._post(
"/realtime/calls",
content=sdp.encode("utf-8"),
options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, timeout=timeout),
cast_to=_legacy_response.HttpxBinaryResponseContent,
)

extra_headers = {"Accept": "application/sdp", "Content-Type": "multipart/form-data", **(extra_headers or {})}
session_payload = maybe_transform(session, RealtimeSessionCreateRequestParam)
files = [
("sdp", (None, sdp.encode("utf-8"), "application/sdp")),
("session", (None, json.dumps(session_payload).encode("utf-8"), "application/json")),
]
return self._post(
"/realtime/calls",
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=_legacy_response.HttpxBinaryResponseContent,
)


class _AsyncCalls(AsyncCalls):
@override
async def create(
self,
*,
sdp: str,
session: RealtimeSessionCreateRequestParam | Omit = omit,
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx2.Timeout | None | NotGiven = not_given,
) -> _legacy_response.HttpxBinaryResponseContent:
if session is omit:
extra_headers = {"Accept": "application/sdp", "Content-Type": "application/sdp", **(extra_headers or {})}
return await self._post(
"/realtime/calls",
content=sdp.encode("utf-8"),
options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, timeout=timeout),
cast_to=_legacy_response.HttpxBinaryResponseContent,
)

extra_headers = {"Accept": "application/sdp", "Content-Type": "multipart/form-data", **(extra_headers or {})}
session_payload = await async_maybe_transform(session, RealtimeSessionCreateRequestParam)
files = [
("sdp", (None, sdp.encode("utf-8"), "application/sdp")),
("session", (None, json.dumps(session_payload).encode("utf-8"), "application/json")),
]
return await self._post(
"/realtime/calls",
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=_legacy_response.HttpxBinaryResponseContent,
)
32 changes: 29 additions & 3 deletions src/openai/resources/admin/organization/projects/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,12 @@
HostedToolPermissionsWithStreamingResponse,
AsyncHostedToolPermissionsWithStreamingResponse,
)
from .....types.admin.organization import project_list_params, project_create_params, project_update_params
from .....types.admin.organization import (
ProjectResidency,
project_list_params,
project_create_params,
project_update_params,
)
from .service_accounts.service_accounts import (
ServiceAccounts,
AsyncServiceAccounts,
Expand All @@ -112,6 +117,7 @@
AsyncServiceAccountsWithStreamingResponse,
)
from .....types.admin.organization.project import Project
from .....types.admin.organization.project_residency import ProjectResidency

__all__ = ["Projects", "AsyncProjects"]

Expand Down Expand Up @@ -190,6 +196,7 @@ def create(
name: str,
external_key_id: Optional[str] | Omit = omit,
geography: Optional[str] | Omit = omit,
residency: Optional[ProjectResidency] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
Expand All @@ -210,6 +217,13 @@ def create(
geography: Create the project with the specified data residency region. Your organization
must have access to Data residency functionality in order to use. See
[data residency controls](https://platform.openai.com/docs/guides/your-data#data-residency-controls)
to review the functionality and limitations of setting this field. Deprecated:
use `residency` instead. Do not provide both `geography` and `residency`.

residency: Create the project with the specified residency configuration. Your organization
must have access to the requested residency configuration in order to use it.
See
[data residency controls](https://platform.openai.com/docs/guides/your-data#data-residency-controls)
to review the functionality and limitations of setting this field.

extra_headers: Send extra headers
Expand All @@ -227,6 +241,7 @@ def create(
"name": name,
"external_key_id": external_key_id,
"geography": geography,
"residency": residency,
},
project_create_params.ProjectCreateParams,
),
Expand Down Expand Up @@ -297,7 +312,8 @@ def update(
Args:
external_key_id: External key ID to associate with the project.

geography: Geography for the project.
geography: Geography for the project. Deprecated: use `residency` when creating a project
to configure data residency. This field is retained for backward compatibility.

name: The updated name of the project, this name appears in reports.

Expand Down Expand Up @@ -503,6 +519,7 @@ async def create(
name: str,
external_key_id: Optional[str] | Omit = omit,
geography: Optional[str] | Omit = omit,
residency: Optional[ProjectResidency] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
Expand All @@ -523,6 +540,13 @@ async def create(
geography: Create the project with the specified data residency region. Your organization
must have access to Data residency functionality in order to use. See
[data residency controls](https://platform.openai.com/docs/guides/your-data#data-residency-controls)
to review the functionality and limitations of setting this field. Deprecated:
use `residency` instead. Do not provide both `geography` and `residency`.

residency: Create the project with the specified residency configuration. Your organization
must have access to the requested residency configuration in order to use it.
See
[data residency controls](https://platform.openai.com/docs/guides/your-data#data-residency-controls)
to review the functionality and limitations of setting this field.

extra_headers: Send extra headers
Expand All @@ -540,6 +564,7 @@ async def create(
"name": name,
"external_key_id": external_key_id,
"geography": geography,
"residency": residency,
},
project_create_params.ProjectCreateParams,
),
Expand Down Expand Up @@ -610,7 +635,8 @@ async def update(
Args:
external_key_id: External key ID to associate with the project.

geography: Geography for the project.
geography: Geography for the project. Deprecated: use `residency` when creating a project
to configure data residency. This field is retained for backward compatibility.

name: The updated name of the project, this name appears in reports.

Expand Down
Loading
Loading