From 05dcaaeb6b617cc0e87ac0c984c1c325c2def30f Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Thu, 9 Nov 2023 18:46:43 +0000
Subject: [PATCH] release: 1.2.1 (#754)
* 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
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 13 +++++
README.md | 11 +++-
api.md | 1 +
pyproject.toml | 2 +-
src/openai/_version.py | 2 +-
src/openai/resources/files.py | 85 +++++++++++++++++++++++++++++--
tests/api_resources/test_files.py | 73 ++++++++++++++++++++++----
8 files changed, 170 insertions(+), 19 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index d0ab6645f5..d43a621a8e 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "1.2.0"
+ ".": "1.2.1"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b58f41340..1911aef970 100644
--- a/CHANGELOG.md
+++ b/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)
diff --git a/README.md b/README.md
index cedbc72337..11a1236b5a 100644
--- a/README.md
+++ b/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
diff --git a/api.md b/api.md
index e0237803de..a7ee177411 100644
--- a/api.md
+++ b/api.md
@@ -87,6 +87,7 @@ Methods:
- client.files.retrieve(file_id) -> FileObject
- client.files.list(\*\*params) -> SyncPage[FileObject]
- client.files.delete(file_id) -> FileDeleted
+- client.files.content(file_id) -> HttpxBinaryResponseContent
- client.files.retrieve_content(file_id) -> str
- client.files.wait_for_processing(\*args) -> FileObject
diff --git a/pyproject.toml b/pyproject.toml
index 1900794dfc..844f501c45 100644
--- a/pyproject.toml
+++ b/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"
diff --git a/src/openai/_version.py b/src/openai/_version.py
index 9d7e588fcf..46c55958e6 100644
--- a/src/openai/_version.py
+++ b/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
diff --git a/src/openai/resources/files.py b/src/openai/resources/files.py
index b317845c3a..a6f75e5a4c 100644
--- a/src/openai/resources/files.py
+++ b/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 .._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 @@ def delete(
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 @@ async def delete(
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 @@ def __init__(self, files: Files) -> None:
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 @@ def __init__(self, files: AsyncFiles) -> None:
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],
)
diff --git a/tests/api_resources/test_files.py b/tests/api_resources/test_files.py
index d668c2d0c7..a2c9d07314 100644
--- a/tests/api_resources/test_files.py
+++ b/tests/api_resources/test_files.py
@@ -4,14 +4,19 @@
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 @@ def test_raw_response_delete(self, client: OpenAI) -> None:
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 @@ async def test_raw_response_delete(self, client: AsyncOpenAI) -> None:
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"])