Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release: 1.13.3 #1179

Merged
merged 7 commits into from
Feb 28, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
if: github.repository == 'openai/openai-python'

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install Rye
run: |
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.13.2"
".": "1.13.3"
}
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## 1.13.3 (2024-02-28)

Full Changelog: [v1.13.2...v1.13.3](https://github.com/openai/openai-python/compare/v1.13.2...v1.13.3)

### Features

* **api:** add wav and pcm to response_format ([#1189](https://github.com/openai/openai-python/issues/1189)) ([dbd20fc](https://github.com/openai/openai-python/commit/dbd20fc42e93358261f71b9aa0e5f955053c3825))


### Chores

* **client:** use anyio.sleep instead of asyncio.sleep ([#1198](https://github.com/openai/openai-python/issues/1198)) ([b6d025b](https://github.com/openai/openai-python/commit/b6d025b54f091e79f5d4a0a8923f29574fd66027))
* **internal:** bump pyright ([#1193](https://github.com/openai/openai-python/issues/1193)) ([9202e04](https://github.com/openai/openai-python/commit/9202e04d07a7c47232f39196346c734869b8f55a))
* **types:** extract run status to a named type ([#1178](https://github.com/openai/openai-python/issues/1178)) ([249ecbd](https://github.com/openai/openai-python/commit/249ecbdeb6566a385ec46dfd5000b4eaa03965f0))


### Documentation

* add note in azure_deployment docstring ([#1188](https://github.com/openai/openai-python/issues/1188)) ([96fa995](https://github.com/openai/openai-python/commit/96fa99572dd76ee708f2bae04d11b659cdd698b2))
* **examples:** add pyaudio streaming example ([#1194](https://github.com/openai/openai-python/issues/1194)) ([3683c5e](https://github.com/openai/openai-python/commit/3683c5e3c7f07e4b789a0c4cc417b2c59539cae2))

## 1.13.2 (2024-02-20)

Full Changelog: [v1.13.1...v1.13.2](https://github.com/openai/openai-python/compare/v1.13.1...v1.13.2)
Expand Down
2 changes: 1 addition & 1 deletion api.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ Methods:
Types:

```python
from openai.types.beta.threads import RequiredActionFunctionToolCall, Run
from openai.types.beta.threads import RequiredActionFunctionToolCall, Run, RunStatus
```

Methods:
Expand Down
28 changes: 27 additions & 1 deletion examples/audio.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python
#!/usr/bin/env rye run python

import time
from pathlib import Path

from openai import OpenAI
Expand All @@ -11,6 +12,8 @@


def main() -> None:
stream_to_speakers()

# Create text-to-speech audio file
with openai.audio.speech.with_streaming_response.create(
model="tts-1",
Expand All @@ -34,5 +37,28 @@ def main() -> None:
print(translation.text)


def stream_to_speakers() -> None:
import pyaudio

player_stream = pyaudio.PyAudio().open(format=pyaudio.paInt16, channels=1, rate=24000, output=True)

start_time = time.time()

with openai.audio.speech.with_streaming_response.create(
model="tts-1",
voice="alloy",
response_format="pcm", # similar to WAV, but without a header chunk at the start.
input="""I see skies of blue and clouds of white
The bright blessed days, the dark sacred nights
And I think to myself
What a wonderful world""",
) as response:
print(f"Time to first byte: {int((time.time() - start_time) * 1000)}ms")
for chunk in response.iter_bytes(chunk_size=1024):
player_stream.write(chunk)

print(f"Done in {int((time.time() - start_time) * 1000)}ms.")


if __name__ == "__main__":
main()
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "openai"
version = "1.13.2"
version = "1.13.3"
description = "The official Python library for the openai API"
readme = "README.md"
license = "Apache-2.0"
Expand Down Expand Up @@ -61,7 +61,8 @@ dev-dependencies = [
"dirty-equals>=0.6.0",
"importlib-metadata>=6.7.0",
"azure-identity >=1.14.1",
"types-tqdm > 4"
"types-tqdm > 4",
"types-pyaudio > 0"
]

[tool.rye.scripts]
Expand Down
7 changes: 4 additions & 3 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ charset-normalizer==3.3.2
# via requests
colorlog==6.7.0
# via nox
cryptography==42.0.3
cryptography==42.0.5
# via azure-identity
# via msal
# via pyjwt
Expand All @@ -57,7 +57,7 @@ idna==3.4
importlib-metadata==7.0.0
iniconfig==2.0.0
# via pytest
msal==1.26.0
msal==1.27.0
# via azure-identity
# via msal-extensions
msal-extensions==1.1.0
Expand Down Expand Up @@ -96,7 +96,7 @@ pydantic-core==2.10.1
# via pydantic
pyjwt==2.8.0
# via msal
pyright==1.1.332
pyright==1.1.351
pytest==7.1.1
# via pytest-asyncio
pytest-asyncio==0.21.1
Expand Down Expand Up @@ -126,6 +126,7 @@ tomli==2.0.1
# via pytest
tqdm==4.66.1
# via openai
types-pyaudio==0.2.16.20240106
types-pytz==2024.1.0.20240203
# via pandas-stubs
types-tqdm==4.66.0.2
Expand Down
2 changes: 1 addition & 1 deletion src/openai/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ def construct_type(*, value: object, type_: type) -> object:

if is_union(origin):
try:
return validate_type(type_=type_, value=value)
return validate_type(type_=cast("type[object]", type_), value=value)
except Exception:
pass

Expand Down
5 changes: 3 additions & 2 deletions src/openai/_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
from __future__ import annotations

import time
import asyncio
from typing import TYPE_CHECKING

import anyio

if TYPE_CHECKING:
from ._client import OpenAI, AsyncOpenAI

Expand Down Expand Up @@ -39,4 +40,4 @@ def __init__(self, client: AsyncOpenAI) -> None:
self._get_api_list = client.get_api_list

async def _sleep(self, seconds: float) -> None:
await asyncio.sleep(seconds)
await anyio.sleep(seconds)
2 changes: 1 addition & 1 deletion src/openai/_utils/_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def __dir__(self) -> Iterable[str]:

@property # type: ignore
@override
def __class__(self) -> type:
def __class__(self) -> type: # pyright: ignore
proxied = self.__get_proxied__()
if issubclass(type(proxied), LazyProxy):
return type(proxied)
Expand Down
2 changes: 1 addition & 1 deletion src/openai/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless.

__title__ = "openai"
__version__ = "1.13.2" # x-release-please-version
__version__ = "1.13.3" # x-release-please-version
2 changes: 1 addition & 1 deletion src/openai/cli/_tools/migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def install() -> Path:
unpacked_dir.mkdir(parents=True, exist_ok=True)

with tarfile.open(temp_file, "r:gz") as archive:
archive.extractall(unpacked_dir)
archive.extractall(unpacked_dir, filter="data")

for item in unpacked_dir.iterdir():
item.rename(target_dir / item.name)
Expand Down
4 changes: 2 additions & 2 deletions src/openai/lib/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def __init__(
azure_ad_token_provider: A function that returns an Azure Active Directory token, will be invoked on every request.

azure_deployment: A model deployment, if given sets the base client URL to include `/deployments/{azure_deployment}`.
Note: this means you won't be able to use non-deployment endpoints.
Note: this means you won't be able to use non-deployment endpoints. Not supported with Assistants APIs.
"""
if api_key is None:
api_key = os.environ.get("AZURE_OPENAI_API_KEY")
Expand Down Expand Up @@ -388,7 +388,7 @@ def __init__(
azure_ad_token_provider: A function that returns an Azure Active Directory token, will be invoked on every request.

azure_deployment: A model deployment, if given sets the base client URL to include `/deployments/{azure_deployment}`.
Note: this means you won't be able to use non-deployment endpoints.
Note: this means you won't be able to use non-deployment endpoints. Not supported with Assistants APIs.
"""
if api_key is None:
api_key = os.environ.get("AZURE_OPENAI_API_KEY")
Expand Down
16 changes: 12 additions & 4 deletions src/openai/resources/audio/speech.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def create(
input: str,
model: Union[str, Literal["tts-1", "tts-1-hd"]],
voice: Literal["alloy", "echo", "fable", "onyx", "nova", "shimmer"],
response_format: Literal["mp3", "opus", "aac", "flac"] | NotGiven = NOT_GIVEN,
response_format: Literal["mp3", "opus", "aac", "flac", "pcm", "wav"] | NotGiven = NOT_GIVEN,
speed: float | NotGiven = NOT_GIVEN,
# 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.
Expand All @@ -65,7 +65,11 @@ def create(
available in the
[Text to speech guide](https://platform.openai.com/docs/guides/text-to-speech/voice-options).

response_format: The format to audio in. Supported formats are `mp3`, `opus`, `aac`, and `flac`.
response_format: The format to return audio in. Supported formats are `mp3`, `opus`, `aac`,
`flac`, `pcm`, and `wav`.

The `pcm` audio format, similar to `wav` but without a header, utilizes a 24kHz
sample rate, mono channel, and 16-bit depth in signed little-endian format.

speed: The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is
the default.
Expand Down Expand Up @@ -113,7 +117,7 @@ async def create(
input: str,
model: Union[str, Literal["tts-1", "tts-1-hd"]],
voice: Literal["alloy", "echo", "fable", "onyx", "nova", "shimmer"],
response_format: Literal["mp3", "opus", "aac", "flac"] | NotGiven = NOT_GIVEN,
response_format: Literal["mp3", "opus", "aac", "flac", "pcm", "wav"] | NotGiven = NOT_GIVEN,
speed: float | NotGiven = NOT_GIVEN,
# 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.
Expand All @@ -137,7 +141,11 @@ async def create(
available in the
[Text to speech guide](https://platform.openai.com/docs/guides/text-to-speech/voice-options).

response_format: The format to audio in. Supported formats are `mp3`, `opus`, `aac`, and `flac`.
response_format: The format to return audio in. Supported formats are `mp3`, `opus`, `aac`,
`flac`, `pcm`, and `wav`.

The `pcm` audio format, similar to `wav` but without a header, utilizes a 24kHz
sample rate, mono channel, and 16-bit depth in signed little-endian format.

speed: The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is
the default.
Expand Down
10 changes: 8 additions & 2 deletions src/openai/types/audio/speech_create_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ class SpeechCreateParams(TypedDict, total=False):
[Text to speech guide](https://platform.openai.com/docs/guides/text-to-speech/voice-options).
"""

response_format: Literal["mp3", "opus", "aac", "flac"]
"""The format to audio in. Supported formats are `mp3`, `opus`, `aac`, and `flac`."""
response_format: Literal["mp3", "opus", "aac", "flac", "pcm", "wav"]
"""The format to return audio in.

Supported formats are `mp3`, `opus`, `aac`, `flac`, `pcm`, and `wav`.

The `pcm` audio format, similar to `wav` but without a header, utilizes a 24kHz
sample rate, mono channel, and 16-bit depth in signed little-endian format.
"""

speed: float
"""The speed of the generated audio.
Expand Down
1 change: 1 addition & 0 deletions src/openai/types/beta/threads/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

from .run import Run as Run
from .run_status import RunStatus as RunStatus
from .thread_message import ThreadMessage as ThreadMessage
from .run_list_params import RunListParams as RunListParams
from .run_create_params import RunCreateParams as RunCreateParams
Expand Down
5 changes: 2 additions & 3 deletions src/openai/types/beta/threads/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from ...shared import FunctionDefinition
from ...._models import BaseModel
from .run_status import RunStatus
from .required_action_function_tool_call import RequiredActionFunctionToolCall

__all__ = [
Expand Down Expand Up @@ -142,9 +143,7 @@ class Run(BaseModel):
started_at: Optional[int] = None
"""The Unix timestamp (in seconds) for when the run was started."""

status: Literal[
"queued", "in_progress", "requires_action", "cancelling", "cancelled", "failed", "completed", "expired"
]
status: RunStatus
"""
The status of the run, which can be either `queued`, `in_progress`,
`requires_action`, `cancelling`, `cancelled`, `failed`, `completed`, or
Expand Down
9 changes: 9 additions & 0 deletions src/openai/types/beta/threads/run_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# File generated from our OpenAPI spec by Stainless.

from typing_extensions import Literal

__all__ = ["RunStatus"]

RunStatus = Literal[
"queued", "in_progress", "requires_action", "cancelling", "cancelled", "failed", "completed", "expired"
]