Commit aa681899

Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
2023-11-10 02:46:43
release: 1.2.1 (#754) tag: v1.2.1
* refactor(client): deprecate files.retrieve_content in favour of files.content (#753) The latter supports binary response types more elegantly. * docs(readme): fix nested params example (#756) * release: 1.2.1
1 parent 8e4e5d4
src/openai/resources/files.py
@@ -3,6 +3,7 @@
 from __future__ import annotations
 
 import time
+import typing_extensions
 from typing import TYPE_CHECKING, Mapping, cast
 from typing_extensions import Literal
 
@@ -14,7 +15,11 @@ from .._utils import extract_files, maybe_transform, deepcopy_minimal
 from .._resource import SyncAPIResource, AsyncAPIResource
 from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ..pagination import SyncPage, AsyncPage
-from .._base_client import AsyncPaginator, make_request_options
+from .._base_client import (
+    AsyncPaginator,
+    HttpxBinaryResponseContent,
+    make_request_options,
+)
 
 if TYPE_CHECKING:
     from .._client import OpenAI, AsyncOpenAI
@@ -197,6 +202,38 @@ class Files(SyncAPIResource):
             cast_to=FileDeleted,
         )
 
+    def content(
+        self,
+        file_id: str,
+        *,
+        # 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,
+        extra_query: Query | None = None,
+        extra_body: Body | None = None,
+        timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+    ) -> HttpxBinaryResponseContent:
+        """
+        Returns the contents of the specified file.
+
+        Args:
+          extra_headers: Send extra headers
+
+          extra_query: Add additional query parameters to the request
+
+          extra_body: Add additional JSON properties to the request
+
+          timeout: Override the client-level default timeout for this request, in seconds
+        """
+        return self._get(
+            f"/files/{file_id}/content",
+            options=make_request_options(
+                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+            ),
+            cast_to=HttpxBinaryResponseContent,
+        )
+
+    @typing_extensions.deprecated("The `.content()` method should be used instead")
     def retrieve_content(
         self,
         file_id: str,
@@ -428,6 +465,38 @@ class AsyncFiles(AsyncAPIResource):
             cast_to=FileDeleted,
         )
 
+    async def content(
+        self,
+        file_id: str,
+        *,
+        # 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,
+        extra_query: Query | None = None,
+        extra_body: Body | None = None,
+        timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+    ) -> HttpxBinaryResponseContent:
+        """
+        Returns the contents of the specified file.
+
+        Args:
+          extra_headers: Send extra headers
+
+          extra_query: Add additional query parameters to the request
+
+          extra_body: Add additional JSON properties to the request
+
+          timeout: Override the client-level default timeout for this request, in seconds
+        """
+        return await self._get(
+            f"/files/{file_id}/content",
+            options=make_request_options(
+                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+            ),
+            cast_to=HttpxBinaryResponseContent,
+        )
+
+    @typing_extensions.deprecated("The `.content()` method should be used instead")
     async def retrieve_content(
         self,
         file_id: str,
@@ -498,8 +567,11 @@ class FilesWithRawResponse:
         self.delete = to_raw_response_wrapper(
             files.delete,
         )
-        self.retrieve_content = to_raw_response_wrapper(
-            files.retrieve_content,
+        self.content = to_raw_response_wrapper(
+            files.content,
+        )
+        self.retrieve_content = to_raw_response_wrapper(  # pyright: ignore[reportDeprecated]
+            files.retrieve_content  # pyright: ignore[reportDeprecated],
         )
 
 
@@ -517,6 +589,9 @@ class AsyncFilesWithRawResponse:
         self.delete = async_to_raw_response_wrapper(
             files.delete,
         )
-        self.retrieve_content = async_to_raw_response_wrapper(
-            files.retrieve_content,
+        self.content = async_to_raw_response_wrapper(
+            files.content,
+        )
+        self.retrieve_content = async_to_raw_response_wrapper(  # pyright: ignore[reportDeprecated]
+            files.retrieve_content  # pyright: ignore[reportDeprecated],
         )
src/openai/_version.py
@@ -1,4 +1,4 @@
 # File generated from our OpenAPI spec by Stainless.
 
 __title__ = "openai"
-__version__ = "1.2.0"  # x-release-please-version
+__version__ = "1.2.1"  # x-release-please-version
tests/api_resources/test_files.py
@@ -4,14 +4,19 @@ from __future__ import annotations
 
 import os
 
+import httpx
 import pytest
+from respx import MockRouter
 
 from openai import OpenAI, AsyncOpenAI
 from tests.utils import assert_matches_type
 from openai.types import FileObject, FileDeleted
+from openai._types import BinaryResponseContent
 from openai._client import OpenAI, AsyncOpenAI
 from openai.pagination import SyncPage, AsyncPage
 
+# pyright: reportDeprecated=false
+
 base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
 api_key = "My API Key"
 
@@ -91,19 +96,43 @@ class TestFiles:
         assert_matches_type(FileDeleted, file, path=["response"])
 
     @parametrize
-    def test_method_retrieve_content(self, client: OpenAI) -> None:
-        file = client.files.retrieve_content(
+    @pytest.mark.respx(base_url=base_url)
+    def test_method_content(self, client: OpenAI, respx_mock: MockRouter) -> None:
+        respx_mock.get("/files/{file_id}/content").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+        file = client.files.content(
             "string",
         )
-        assert_matches_type(str, file, path=["response"])
+        assert isinstance(file, BinaryResponseContent)
+        assert file.json() == {"foo": "bar"}
 
     @parametrize
-    def test_raw_response_retrieve_content(self, client: OpenAI) -> None:
-        response = client.files.with_raw_response.retrieve_content(
+    @pytest.mark.respx(base_url=base_url)
+    def test_raw_response_content(self, client: OpenAI, respx_mock: MockRouter) -> None:
+        respx_mock.get("/files/{file_id}/content").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+        response = client.files.with_raw_response.content(
             "string",
         )
         assert response.http_request.headers.get("X-Stainless-Lang") == "python"
         file = response.parse()
+        assert isinstance(file, BinaryResponseContent)
+        assert file.json() == {"foo": "bar"}
+
+    @parametrize
+    def test_method_retrieve_content(self, client: OpenAI) -> None:
+        with pytest.warns(DeprecationWarning):
+            file = client.files.retrieve_content(
+                "string",
+            )
+        assert_matches_type(str, file, path=["response"])
+
+    @parametrize
+    def test_raw_response_retrieve_content(self, client: OpenAI) -> None:
+        with pytest.warns(DeprecationWarning):
+            response = client.files.with_raw_response.retrieve_content(
+                "string",
+            )
+        assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+        file = response.parse()
         assert_matches_type(str, file, path=["response"])
 
 
@@ -182,17 +211,41 @@ class TestAsyncFiles:
         assert_matches_type(FileDeleted, file, path=["response"])
 
     @parametrize
-    async def test_method_retrieve_content(self, client: AsyncOpenAI) -> None:
-        file = await client.files.retrieve_content(
+    @pytest.mark.respx(base_url=base_url)
+    async def test_method_content(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None:
+        respx_mock.get("/files/{file_id}/content").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+        file = await client.files.content(
             "string",
         )
-        assert_matches_type(str, file, path=["response"])
+        assert isinstance(file, BinaryResponseContent)
+        assert file.json() == {"foo": "bar"}
 
     @parametrize
-    async def test_raw_response_retrieve_content(self, client: AsyncOpenAI) -> None:
-        response = await client.files.with_raw_response.retrieve_content(
+    @pytest.mark.respx(base_url=base_url)
+    async def test_raw_response_content(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None:
+        respx_mock.get("/files/{file_id}/content").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+        response = await client.files.with_raw_response.content(
             "string",
         )
         assert response.http_request.headers.get("X-Stainless-Lang") == "python"
         file = response.parse()
+        assert isinstance(file, BinaryResponseContent)
+        assert file.json() == {"foo": "bar"}
+
+    @parametrize
+    async def test_method_retrieve_content(self, client: AsyncOpenAI) -> None:
+        with pytest.warns(DeprecationWarning):
+            file = await client.files.retrieve_content(
+                "string",
+            )
+        assert_matches_type(str, file, path=["response"])
+
+    @parametrize
+    async def test_raw_response_retrieve_content(self, client: AsyncOpenAI) -> None:
+        with pytest.warns(DeprecationWarning):
+            response = await client.files.with_raw_response.retrieve_content(
+                "string",
+            )
+        assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+        file = response.parse()
         assert_matches_type(str, file, path=["response"])
.release-please-manifest.json
@@ -1,3 +1,3 @@
 {
-  ".": "1.2.0"
+  ".": "1.2.1"
 }
\ No newline at end of file
api.md
@@ -87,6 +87,7 @@ Methods:
 - <code title="get /files/{file_id}">client.files.<a href="./src/openai/resources/files.py">retrieve</a>(file_id) -> <a href="./src/openai/types/file_object.py">FileObject</a></code>
 - <code title="get /files">client.files.<a href="./src/openai/resources/files.py">list</a>(\*\*<a href="src/openai/types/file_list_params.py">params</a>) -> <a href="./src/openai/types/file_object.py">SyncPage[FileObject]</a></code>
 - <code title="delete /files/{file_id}">client.files.<a href="./src/openai/resources/files.py">delete</a>(file_id) -> <a href="./src/openai/types/file_deleted.py">FileDeleted</a></code>
+- <code title="get /files/{file_id}/content">client.files.<a href="./src/openai/resources/files.py">content</a>(file_id) -> HttpxBinaryResponseContent</code>
 - <code title="get /files/{file_id}/content">client.files.<a href="./src/openai/resources/files.py">retrieve_content</a>(file_id) -> str</code>
 - <code>client.files.<a href="./src/openai/resources/files.py">wait_for_processing</a>(\*args) -> FileObject</code>
 
CHANGELOG.md
@@ -1,5 +1,18 @@
 # Changelog
 
+## 1.2.1 (2023-11-09)
+
+Full Changelog: [v1.2.0...v1.2.1](https://github.com/openai/openai-python/compare/v1.2.0...v1.2.1)
+
+### Documentation
+
+* **readme:** fix nested params example ([#756](https://github.com/openai/openai-python/issues/756)) ([ffbe5ec](https://github.com/openai/openai-python/commit/ffbe5eca0f8790ebcdb27ffe845da178a3ef4c45))
+
+
+### Refactors
+
+* **client:** deprecate files.retrieve_content in favour of files.content ([#753](https://github.com/openai/openai-python/issues/753)) ([eea5bc1](https://github.com/openai/openai-python/commit/eea5bc173466f63a6e84bd2d741b4873ca056b4c))
+
 ## 1.2.0 (2023-11-08)
 
 Full Changelog: [v1.1.2...v1.2.0](https://github.com/openai/openai-python/compare/v1.1.2...v1.2.0)
pyproject.toml
@@ -1,6 +1,6 @@
 [project]
 name = "openai"
-version = "1.2.0"
+version = "1.2.1"
 description = "Client library for the openai API"
 readme = "README.md"
 license = "Apache-2.0"
README.md
@@ -237,7 +237,16 @@ from openai import OpenAI
 
 client = OpenAI()
 
-page = client.files.list()
+completion = client.chat.completions.create(
+    messages=[
+        {
+            "role": "user",
+            "content": "Can you generate an example json object describing a fruit?",
+        }
+    ],
+    model="gpt-3.5-turbo",
+    response_format={"type": "json_object"},
+)
 ```
 
 ## File Uploads