Skip to content

Commit f7c80c4

Browse files
fix(client): return binary content from get /containers/{container_id}/files/{file_id}/content
1 parent 88bcf3a commit f7c80c4

File tree

4 files changed

+67
-24
lines changed

4 files changed

+67
-24
lines changed

.stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 111
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-d4bcffecf0cdadf746faa6708ed1ec81fac451f9b857deabbab26f0a343b9314.yml
33
openapi_spec_hash: 7c54a18b4381248bda7cc34c52142615
4-
config_hash: 2102e4b25bbcab5d32d5ffa5d34daa0c
4+
config_hash: d23f847b9ebb3f427d0f198035bd3e9f

api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -894,4 +894,4 @@ Methods:
894894

895895
Methods:
896896

897-
- <code title="get /containers/{container_id}/files/{file_id}/content">client.containers.files.content.<a href="./src/openai/resources/containers/files/content.py">retrieve</a>(file_id, \*, container_id) -> None</code>
897+
- <code title="get /containers/{container_id}/files/{file_id}/content">client.containers.files.content.<a href="./src/openai/resources/containers/files/content.py">retrieve</a>(file_id, \*, container_id) -> HttpxBinaryResponseContent</code>

src/openai/resources/containers/files/content.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@
55
import httpx
66

77
from .... import _legacy_response
8-
from ...._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
8+
from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
99
from ...._compat import cached_property
1010
from ...._resource import SyncAPIResource, AsyncAPIResource
11-
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
11+
from ...._response import (
12+
StreamedBinaryAPIResponse,
13+
AsyncStreamedBinaryAPIResponse,
14+
to_custom_streamed_response_wrapper,
15+
async_to_custom_streamed_response_wrapper,
16+
)
1217
from ...._base_client import make_request_options
1318

1419
__all__ = ["Content", "AsyncContent"]
@@ -45,7 +50,7 @@ def retrieve(
4550
extra_query: Query | None = None,
4651
extra_body: Body | None = None,
4752
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
48-
) -> None:
53+
) -> _legacy_response.HttpxBinaryResponseContent:
4954
"""
5055
Retrieve Container File Content
5156
@@ -62,13 +67,13 @@ def retrieve(
6267
raise ValueError(f"Expected a non-empty value for `container_id` but received {container_id!r}")
6368
if not file_id:
6469
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
65-
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
70+
extra_headers = {"Accept": "application/binary", **(extra_headers or {})}
6671
return self._get(
6772
f"/containers/{container_id}/files/{file_id}/content",
6873
options=make_request_options(
6974
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
7075
),
71-
cast_to=NoneType,
76+
cast_to=_legacy_response.HttpxBinaryResponseContent,
7277
)
7378

7479

@@ -103,7 +108,7 @@ async def retrieve(
103108
extra_query: Query | None = None,
104109
extra_body: Body | None = None,
105110
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
106-
) -> None:
111+
) -> _legacy_response.HttpxBinaryResponseContent:
107112
"""
108113
Retrieve Container File Content
109114
@@ -120,13 +125,13 @@ async def retrieve(
120125
raise ValueError(f"Expected a non-empty value for `container_id` but received {container_id!r}")
121126
if not file_id:
122127
raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
123-
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
128+
extra_headers = {"Accept": "application/binary", **(extra_headers or {})}
124129
return await self._get(
125130
f"/containers/{container_id}/files/{file_id}/content",
126131
options=make_request_options(
127132
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
128133
),
129-
cast_to=NoneType,
134+
cast_to=_legacy_response.HttpxBinaryResponseContent,
130135
)
131136

132137

@@ -152,15 +157,17 @@ class ContentWithStreamingResponse:
152157
def __init__(self, content: Content) -> None:
153158
self._content = content
154159

155-
self.retrieve = to_streamed_response_wrapper(
160+
self.retrieve = to_custom_streamed_response_wrapper(
156161
content.retrieve,
162+
StreamedBinaryAPIResponse,
157163
)
158164

159165

160166
class AsyncContentWithStreamingResponse:
161167
def __init__(self, content: AsyncContent) -> None:
162168
self._content = content
163169

164-
self.retrieve = async_to_streamed_response_wrapper(
170+
self.retrieve = async_to_custom_streamed_response_wrapper(
165171
content.retrieve,
172+
AsyncStreamedBinaryAPIResponse,
166173
)

tests/api_resources/containers/files/test_content.py

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55
import os
66
from typing import Any, cast
77

8+
import httpx
89
import pytest
10+
from respx import MockRouter
911

12+
import openai._legacy_response as _legacy_response
1013
from openai import OpenAI, AsyncOpenAI
14+
from tests.utils import assert_matches_type
15+
16+
# pyright: reportDeprecated=false
1117

1218
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
1319

@@ -16,15 +22,25 @@ class TestContent:
1622
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
1723

1824
@parametrize
19-
def test_method_retrieve(self, client: OpenAI) -> None:
25+
@pytest.mark.respx(base_url=base_url)
26+
def test_method_retrieve(self, client: OpenAI, respx_mock: MockRouter) -> None:
27+
respx_mock.get("/containers/container_id/files/file_id/content").mock(
28+
return_value=httpx.Response(200, json={"foo": "bar"})
29+
)
2030
content = client.containers.files.content.retrieve(
2131
file_id="file_id",
2232
container_id="container_id",
2333
)
24-
assert content is None
34+
assert isinstance(content, _legacy_response.HttpxBinaryResponseContent)
35+
assert content.json() == {"foo": "bar"}
2536

2637
@parametrize
27-
def test_raw_response_retrieve(self, client: OpenAI) -> None:
38+
@pytest.mark.respx(base_url=base_url)
39+
def test_raw_response_retrieve(self, client: OpenAI, respx_mock: MockRouter) -> None:
40+
respx_mock.get("/containers/container_id/files/file_id/content").mock(
41+
return_value=httpx.Response(200, json={"foo": "bar"})
42+
)
43+
2844
response = client.containers.files.content.with_raw_response.retrieve(
2945
file_id="file_id",
3046
container_id="container_id",
@@ -33,10 +49,14 @@ def test_raw_response_retrieve(self, client: OpenAI) -> None:
3349
assert response.is_closed is True
3450
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
3551
content = response.parse()
36-
assert content is None
52+
assert_matches_type(_legacy_response.HttpxBinaryResponseContent, content, path=["response"])
3753

3854
@parametrize
39-
def test_streaming_response_retrieve(self, client: OpenAI) -> None:
55+
@pytest.mark.respx(base_url=base_url)
56+
def test_streaming_response_retrieve(self, client: OpenAI, respx_mock: MockRouter) -> None:
57+
respx_mock.get("/containers/container_id/files/file_id/content").mock(
58+
return_value=httpx.Response(200, json={"foo": "bar"})
59+
)
4060
with client.containers.files.content.with_streaming_response.retrieve(
4161
file_id="file_id",
4262
container_id="container_id",
@@ -45,11 +65,12 @@ def test_streaming_response_retrieve(self, client: OpenAI) -> None:
4565
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
4666

4767
content = response.parse()
48-
assert content is None
68+
assert_matches_type(bytes, content, path=["response"])
4969

5070
assert cast(Any, response.is_closed) is True
5171

5272
@parametrize
73+
@pytest.mark.respx(base_url=base_url)
5374
def test_path_params_retrieve(self, client: OpenAI) -> None:
5475
with pytest.raises(ValueError, match=r"Expected a non-empty value for `container_id` but received ''"):
5576
client.containers.files.content.with_raw_response.retrieve(
@@ -68,15 +89,25 @@ class TestAsyncContent:
6889
parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
6990

7091
@parametrize
71-
async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None:
92+
@pytest.mark.respx(base_url=base_url)
93+
async def test_method_retrieve(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None:
94+
respx_mock.get("/containers/container_id/files/file_id/content").mock(
95+
return_value=httpx.Response(200, json={"foo": "bar"})
96+
)
7297
content = await async_client.containers.files.content.retrieve(
7398
file_id="file_id",
7499
container_id="container_id",
75100
)
76-
assert content is None
101+
assert isinstance(content, _legacy_response.HttpxBinaryResponseContent)
102+
assert content.json() == {"foo": "bar"}
77103

78104
@parametrize
79-
async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None:
105+
@pytest.mark.respx(base_url=base_url)
106+
async def test_raw_response_retrieve(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None:
107+
respx_mock.get("/containers/container_id/files/file_id/content").mock(
108+
return_value=httpx.Response(200, json={"foo": "bar"})
109+
)
110+
80111
response = await async_client.containers.files.content.with_raw_response.retrieve(
81112
file_id="file_id",
82113
container_id="container_id",
@@ -85,10 +116,14 @@ async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None:
85116
assert response.is_closed is True
86117
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
87118
content = response.parse()
88-
assert content is None
119+
assert_matches_type(_legacy_response.HttpxBinaryResponseContent, content, path=["response"])
89120

90121
@parametrize
91-
async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None:
122+
@pytest.mark.respx(base_url=base_url)
123+
async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None:
124+
respx_mock.get("/containers/container_id/files/file_id/content").mock(
125+
return_value=httpx.Response(200, json={"foo": "bar"})
126+
)
92127
async with async_client.containers.files.content.with_streaming_response.retrieve(
93128
file_id="file_id",
94129
container_id="container_id",
@@ -97,11 +132,12 @@ async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> N
97132
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
98133

99134
content = await response.parse()
100-
assert content is None
135+
assert_matches_type(bytes, content, path=["response"])
101136

102137
assert cast(Any, response.is_closed) is True
103138

104139
@parametrize
140+
@pytest.mark.respx(base_url=base_url)
105141
async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None:
106142
with pytest.raises(ValueError, match=r"Expected a non-empty value for `container_id` but received ''"):
107143
await async_client.containers.files.content.with_raw_response.retrieve(

0 commit comments

Comments
 (0)