Skip to content

Commit 86aaa1d

Browse files
feat(api): add support for realtime calls
1 parent 75a3aa4 commit 86aaa1d

File tree

13 files changed

+1770
-14
lines changed

13 files changed

+1770
-14
lines changed

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 118
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-e205b1f2da6a1f2caa229efa9ede63f2d3d2fedeeb2dd6ed3d880bafdcb0ab88.yml
3-
openapi_spec_hash: c8aee2469a749f6a838b40c57e4b7b06
4-
config_hash: 45dcba51451ba532959c020a0ddbf23c
1+
configured_endpoints: 123
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-fadefdc7c7e30df47c09df323669b242ff90ee08e51f304175ace5274e0aab49.yml
3+
openapi_spec_hash: 6d20f639d9ff8a097a34962da6218231
4+
config_hash: 902654e60f5d659f2bfcfd903e17c46d

api.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,16 @@ Methods:
989989

990990
- <code title="post /realtime/client_secrets">client.realtime.client_secrets.<a href="./src/openai/resources/realtime/client_secrets.py">create</a>(\*\*<a href="src/openai/types/realtime/client_secret_create_params.py">params</a>) -> <a href="./src/openai/types/realtime/client_secret_create_response.py">ClientSecretCreateResponse</a></code>
991991

992+
## Calls
993+
994+
Methods:
995+
996+
- <code title="post /realtime/calls">client.realtime.calls.<a href="./src/openai/resources/realtime/calls.py">create</a>(\*\*<a href="src/openai/types/realtime/call_create_params.py">params</a>) -> HttpxBinaryResponseContent</code>
997+
- <code title="post /realtime/calls/{call_id}/accept">client.realtime.calls.<a href="./src/openai/resources/realtime/calls.py">accept</a>(call_id, \*\*<a href="src/openai/types/realtime/call_accept_params.py">params</a>) -> None</code>
998+
- <code title="post /realtime/calls/{call_id}/hangup">client.realtime.calls.<a href="./src/openai/resources/realtime/calls.py">hangup</a>(call_id) -> None</code>
999+
- <code title="post /realtime/calls/{call_id}/refer">client.realtime.calls.<a href="./src/openai/resources/realtime/calls.py">refer</a>(call_id, \*\*<a href="src/openai/types/realtime/call_refer_params.py">params</a>) -> None</code>
1000+
- <code title="post /realtime/calls/{call_id}/reject">client.realtime.calls.<a href="./src/openai/resources/realtime/calls.py">reject</a>(call_id, \*\*<a href="src/openai/types/realtime/call_reject_params.py">params</a>) -> None</code>
1001+
9921002
# Conversations
9931003

9941004
Types:

src/openai/lib/_realtime.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from __future__ import annotations
2+
3+
import json
4+
from typing_extensions import override
5+
6+
import httpx
7+
8+
from openai import _legacy_response
9+
from openai._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
10+
from openai._utils import maybe_transform, async_maybe_transform
11+
from openai._base_client import make_request_options
12+
from openai.resources.realtime.calls import Calls, AsyncCalls
13+
from openai.types.realtime.realtime_session_create_request_param import RealtimeSessionCreateRequestParam
14+
15+
__all__ = ["_Calls", "_AsyncCalls"]
16+
17+
18+
# Custom code to override the `create` method to have correct behavior with
19+
# application/sdp and multipart/form-data.
20+
# Ideally we can cutover to the generated code this overrides eventually and remove this.
21+
class _Calls(Calls):
22+
@override
23+
def create(
24+
self,
25+
*,
26+
sdp: str,
27+
session: RealtimeSessionCreateRequestParam | Omit = omit,
28+
extra_headers: Headers | None = None,
29+
extra_query: Query | None = None,
30+
extra_body: Body | None = None,
31+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
32+
) -> _legacy_response.HttpxBinaryResponseContent:
33+
if session is omit:
34+
extra_headers = {"Accept": "application/sdp", "Content-Type": "application/sdp", **(extra_headers or {})}
35+
return self._post(
36+
"/realtime/calls",
37+
body=sdp.encode("utf-8"),
38+
options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, timeout=timeout),
39+
cast_to=_legacy_response.HttpxBinaryResponseContent,
40+
)
41+
42+
extra_headers = {"Accept": "application/sdp", "Content-Type": "multipart/form-data", **(extra_headers or {})}
43+
session_payload = maybe_transform(session, RealtimeSessionCreateRequestParam)
44+
files = [
45+
("sdp", (None, sdp.encode("utf-8"), "application/sdp")),
46+
("session", (None, json.dumps(session_payload).encode("utf-8"), "application/json")),
47+
]
48+
return self._post(
49+
"/realtime/calls",
50+
files=files,
51+
options=make_request_options(
52+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
53+
),
54+
cast_to=_legacy_response.HttpxBinaryResponseContent,
55+
)
56+
57+
58+
class _AsyncCalls(AsyncCalls):
59+
@override
60+
async def create(
61+
self,
62+
*,
63+
sdp: str,
64+
session: RealtimeSessionCreateRequestParam | Omit = omit,
65+
extra_headers: Headers | None = None,
66+
extra_query: Query | None = None,
67+
extra_body: Body | None = None,
68+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
69+
) -> _legacy_response.HttpxBinaryResponseContent:
70+
if session is omit:
71+
extra_headers = {"Accept": "application/sdp", "Content-Type": "application/sdp", **(extra_headers or {})}
72+
return await self._post(
73+
"/realtime/calls",
74+
body=sdp.encode("utf-8"),
75+
options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, timeout=timeout),
76+
cast_to=_legacy_response.HttpxBinaryResponseContent,
77+
)
78+
79+
extra_headers = {"Accept": "application/sdp", "Content-Type": "multipart/form-data", **(extra_headers or {})}
80+
session_payload = await async_maybe_transform(session, RealtimeSessionCreateRequestParam)
81+
files = [
82+
("sdp", (None, sdp.encode("utf-8"), "application/sdp")),
83+
("session", (None, json.dumps(session_payload).encode("utf-8"), "application/json")),
84+
]
85+
return await self._post(
86+
"/realtime/calls",
87+
files=files,
88+
options=make_request_options(
89+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
90+
),
91+
cast_to=_legacy_response.HttpxBinaryResponseContent,
92+
)

src/openai/resources/realtime/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

3+
from .calls import (
4+
Calls,
5+
AsyncCalls,
6+
CallsWithRawResponse,
7+
AsyncCallsWithRawResponse,
8+
CallsWithStreamingResponse,
9+
AsyncCallsWithStreamingResponse,
10+
)
311
from .realtime import (
412
Realtime,
513
AsyncRealtime,
@@ -24,6 +32,12 @@
2432
"AsyncClientSecretsWithRawResponse",
2533
"ClientSecretsWithStreamingResponse",
2634
"AsyncClientSecretsWithStreamingResponse",
35+
"Calls",
36+
"AsyncCalls",
37+
"CallsWithRawResponse",
38+
"AsyncCallsWithRawResponse",
39+
"CallsWithStreamingResponse",
40+
"AsyncCallsWithStreamingResponse",
2741
"Realtime",
2842
"AsyncRealtime",
2943
"RealtimeWithRawResponse",

0 commit comments

Comments
 (0)