Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
hoonman authored Jan 27, 2025
2 parents 6c1b185 + b95be16 commit cc45f94
Show file tree
Hide file tree
Showing 69 changed files with 668 additions and 256 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:

- name: Run lints
run: ./scripts/lint

test:
name: test
runs-on: ubuntu-latest
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.59.7"
".": "1.60.1"
}
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
configured_endpoints: 69
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-b5b0e2c794b012919701c3fd43286af10fa25d33ceb8a881bec2636028f446e0.yml
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-3904ef6b29a89c98f93a9b7da19879695f3c440564be6384db7af1b734611ede.yml
75 changes: 75 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,80 @@
# Changelog

## 1.60.1 (2025-01-24)

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

### Chores

* **internal:** minor formatting changes ([#2050](https://github.com/openai/openai-python/issues/2050)) ([9c44192](https://github.com/openai/openai-python/commit/9c44192be5776d9252d36dc027a33c60b33d81b2))


### Documentation

* **examples/azure:** add async snippet ([#1787](https://github.com/openai/openai-python/issues/1787)) ([f60eda1](https://github.com/openai/openai-python/commit/f60eda1c1e8caf0ec2274b18b3fb2252304196db))

## 1.60.0 (2025-01-22)

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

### Features

* **api:** update enum values, comments, and examples ([#2045](https://github.com/openai/openai-python/issues/2045)) ([e8205fd](https://github.com/openai/openai-python/commit/e8205fd58f0d677f476c577a8d9afb90f5710506))


### Chores

* **internal:** minor style changes ([#2043](https://github.com/openai/openai-python/issues/2043)) ([89a9dd8](https://github.com/openai/openai-python/commit/89a9dd821eaf5300ad11b0270b61fdfa4fd6e9b6))


### Documentation

* **readme:** mention failed requests in request IDs ([5f7c30b](https://github.com/openai/openai-python/commit/5f7c30bc006ffb666c324011a68aae357cb33e35))

## 1.59.9 (2025-01-20)

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

### Bug Fixes

* **tests:** make test_get_platform less flaky ([#2040](https://github.com/openai/openai-python/issues/2040)) ([72ea05c](https://github.com/openai/openai-python/commit/72ea05cf18caaa7a5e6fe7e2251ab93fa0ba3140))


### Chores

* **internal:** avoid pytest-asyncio deprecation warning ([#2041](https://github.com/openai/openai-python/issues/2041)) ([b901046](https://github.com/openai/openai-python/commit/b901046ddda9c79b7f019e2263c02d126a3b2ee2))
* **internal:** update websockets dep ([#2036](https://github.com/openai/openai-python/issues/2036)) ([642cd11](https://github.com/openai/openai-python/commit/642cd119482c6fbca925ba702ad2579f9dc47bf9))


### Documentation

* fix typo ([#2031](https://github.com/openai/openai-python/issues/2031)) ([02fcf15](https://github.com/openai/openai-python/commit/02fcf15611953089826a74725cb96201d94658bb))
* **raw responses:** fix duplicate `the` ([#2039](https://github.com/openai/openai-python/issues/2039)) ([9b8eab9](https://github.com/openai/openai-python/commit/9b8eab99fdc6a581a1f5cc421c6f74b0e2b30415))

## 1.59.8 (2025-01-17)

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

### Bug Fixes

* streaming ([c16f58e](https://github.com/openai/openai-python/commit/c16f58ead0bc85055b164182689ba74b7e939dfa))
* **structured outputs:** avoid parsing empty empty content ([#2023](https://github.com/openai/openai-python/issues/2023)) ([6d3513c](https://github.com/openai/openai-python/commit/6d3513c86f6e5800f8f73a45e089b7a205327121))
* **structured outputs:** correct schema coercion for inline ref expansion ([#2025](https://github.com/openai/openai-python/issues/2025)) ([2f4f0b3](https://github.com/openai/openai-python/commit/2f4f0b374207f162060c328b71ec995049dc42e8))
* **types:** correct type for vector store chunking strategy ([#2017](https://github.com/openai/openai-python/issues/2017)) ([e389279](https://github.com/openai/openai-python/commit/e38927950a5cdad99065853fe7b72aad6bb322e9))


### Chores

* **examples:** update realtime model ([f26746c](https://github.com/openai/openai-python/commit/f26746cbcd893d66cf8a3fd68a7c3779dc8c833c)), closes [#2020](https://github.com/openai/openai-python/issues/2020)
* **internal:** bump pyright dependency ([#2021](https://github.com/openai/openai-python/issues/2021)) ([0a9a0f5](https://github.com/openai/openai-python/commit/0a9a0f5d8b9d5457643798287f893305006dd518))
* **internal:** streaming refactors ([#2012](https://github.com/openai/openai-python/issues/2012)) ([d76a748](https://github.com/openai/openai-python/commit/d76a748f606743407f94dfc26758095560e2082a))
* **internal:** update deps ([#2015](https://github.com/openai/openai-python/issues/2015)) ([514e0e4](https://github.com/openai/openai-python/commit/514e0e415f87ab4510262d29ed6125384e017b84))


### Documentation

* **examples/azure:** example script with realtime API ([#1967](https://github.com/openai/openai-python/issues/1967)) ([84f2f9c](https://github.com/openai/openai-python/commit/84f2f9c0439229a7db7136fe78419292d34d1f81))

## 1.59.7 (2025-01-13)

Full Changelog: [v1.59.6...v1.59.7](https://github.com/openai/openai-python/compare/v1.59.6...v1.59.7)
Expand Down
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ from openai import AsyncOpenAI
async def main():
client = AsyncOpenAI()

async with client.beta.realtime.connect(model="gpt-4o-realtime-preview-2024-10-01") as connection:
async with client.beta.realtime.connect(model="gpt-4o-realtime-preview") as connection:
await connection.session.update(session={'modalities': ['text']})

await connection.conversation.item.create(
Expand Down Expand Up @@ -309,7 +309,7 @@ Whenever an error occurs, the Realtime API will send an [`error` event](https://
```py
client = AsyncOpenAI()

async with client.beta.realtime.connect(model="gpt-4o-realtime-preview-2024-10-01") as connection:
async with client.beta.realtime.connect(model="gpt-4o-realtime-preview") as connection:
...
async for event in connection:
if event.type == 'error':
Expand Down Expand Up @@ -499,6 +499,21 @@ Note that unlike other properties that use an `_` prefix, the `_request_id` prop
*is* public. Unless documented otherwise, *all* other `_` prefix properties,
methods and modules are *private*.

> [!IMPORTANT]
> If you need to access request IDs for failed requests you must catch the `APIStatusError` exception

```python
import openai

try:
completion = await client.chat.completions.create(
messages=[{"role": "user", "content": "Say this is a test"}], model="gpt-4"
)
except openai.APIStatusError as exc:
print(exc.request_id) # req_123
raise exc
```


### Retries

Expand Down
2 changes: 1 addition & 1 deletion api.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ from openai.types.beta import (
OtherFileChunkingStrategyObject,
StaticFileChunkingStrategy,
StaticFileChunkingStrategyObject,
StaticFileChunkingStrategyParam,
StaticFileChunkingStrategyObjectParam,
VectorStore,
VectorStoreDeleted,
)
Expand Down
79 changes: 58 additions & 21 deletions examples/azure_ad.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,67 @@
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
import asyncio

from openai import AzureOpenAI
from openai.lib.azure import AzureOpenAI, AsyncAzureOpenAI, AzureADTokenProvider, AsyncAzureADTokenProvider

token_provider = get_bearer_token_provider(DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default")
scopes = "https://cognitiveservices.azure.com/.default"


# may change in the future
# May change in the future
# https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#rest-api-versioning
api_version = "2023-07-01-preview"

# https://learn.microsoft.com/en-us/azure/cognitive-services/openai/how-to/create-resource?pivots=web-portal#create-a-resource
endpoint = "https://my-resource.openai.azure.com"

client = AzureOpenAI(
api_version=api_version,
azure_endpoint=endpoint,
azure_ad_token_provider=token_provider,
)

completion = client.chat.completions.create(
model="deployment-name", # e.g. gpt-35-instant
messages=[
{
"role": "user",
"content": "How do I output all files in a directory using Python?",
},
],
)
print(completion.to_json())
deployment_name = "deployment-name" # e.g. gpt-35-instant


def sync_main() -> None:
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider: AzureADTokenProvider = get_bearer_token_provider(DefaultAzureCredential(), scopes)

client = AzureOpenAI(
api_version=api_version,
azure_endpoint=endpoint,
azure_ad_token_provider=token_provider,
)

completion = client.chat.completions.create(
model=deployment_name,
messages=[
{
"role": "user",
"content": "How do I output all files in a directory using Python?",
}
],
)

print(completion.to_json())


async def async_main() -> None:
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider

token_provider: AsyncAzureADTokenProvider = get_bearer_token_provider(DefaultAzureCredential(), scopes)

client = AsyncAzureOpenAI(
api_version=api_version,
azure_endpoint=endpoint,
azure_ad_token_provider=token_provider,
)

completion = await client.chat.completions.create(
model=deployment_name,
messages=[
{
"role": "user",
"content": "How do I output all files in a directory using Python?",
}
],
)

print(completion.to_json())


sync_main()

asyncio.run(async_main())
57 changes: 57 additions & 0 deletions examples/realtime/azure_realtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import os
import asyncio

from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider

from openai import AsyncAzureOpenAI

# Azure OpenAI Realtime Docs

# How-to: https://learn.microsoft.com/azure/ai-services/openai/how-to/realtime-audio
# Supported models and API versions: https://learn.microsoft.com/azure/ai-services/openai/how-to/realtime-audio#supported-models
# Entra ID auth: https://learn.microsoft.com/azure/ai-services/openai/how-to/managed-identity


async def main() -> None:
"""The following example demonstrates how to configure Azure OpenAI to use the Realtime API.
For an audio example, see push_to_talk_app.py and update the client and model parameter accordingly.

When prompted for user input, type a message and hit enter to send it to the model.
Enter "q" to quit the conversation.
"""

credential = DefaultAzureCredential()
client = AsyncAzureOpenAI(
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
azure_ad_token_provider=get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default"),
api_version="2024-10-01-preview",
)
async with client.beta.realtime.connect(
model="gpt-4o-realtime-preview", # deployment name for your model
) as connection:
await connection.session.update(session={"modalities": ["text"]}) # type: ignore
while True:
user_input = input("Enter a message: ")
if user_input == "q":
break

await connection.conversation.item.create(
item={
"type": "message",
"role": "user",
"content": [{"type": "input_text", "text": user_input}],
}
)
await connection.response.create()
async for event in connection:
if event.type == "response.text.delta":
print(event.delta, flush=True, end="")
elif event.type == "response.text.done":
print()
elif event.type == "response.done":
break

await credential.close()


asyncio.run(main())
2 changes: 1 addition & 1 deletion examples/realtime/push_to_talk_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ async def on_mount(self) -> None:
self.run_worker(self.send_mic_audio())

async def handle_realtime_connection(self) -> None:
async with self.client.beta.realtime.connect(model="gpt-4o-realtime-preview-2024-10-01") as conn:
async with self.client.beta.realtime.connect(model="gpt-4o-realtime-preview") as conn:
self.connection = conn
self.connected.set()

Expand Down
2 changes: 1 addition & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ cache_fine_grained = True
# ```
# Changing this codegen to make mypy happy would increase complexity
# and would not be worth it.
disable_error_code = func-returns-value
disable_error_code = func-returns-value,overload-cannot-match

# https://github.com/python/mypy/issues/12162
[mypy.overrides]
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "openai"
version = "1.59.7"
version = "1.60.1"
description = "The official Python library for the openai API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down Expand Up @@ -142,6 +142,7 @@ testpaths = ["tests"]
addopts = "--tb=short"
xfail_strict = true
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "session"
filterwarnings = [
"error"
]
Expand Down
6 changes: 3 additions & 3 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ msal==1.31.0
# via msal-extensions
msal-extensions==1.2.0
# via azure-identity
mypy==1.13.0
mypy==1.14.1
mypy-extensions==1.0.0
# via black
# via mypy
Expand Down Expand Up @@ -124,7 +124,7 @@ pygments==2.18.0
# via rich
pyjwt==2.8.0
# via msal
pyright==1.1.390
pyright==1.1.392.post0
pytest==8.3.3
# via pytest-asyncio
pytest-asyncio==0.24.0
Expand Down Expand Up @@ -184,7 +184,7 @@ urllib3==2.2.1
# via requests
virtualenv==20.24.5
# via nox
websockets==14.1
websockets==14.2
# via openai
zipp==3.17.0
# via importlib-metadata
2 changes: 1 addition & 1 deletion requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,5 @@ typing-extensions==4.12.2
# via pydantic-core
tzdata==2024.1
# via pandas
websockets==14.1
websockets==14.2
# via openai
2 changes: 1 addition & 1 deletion scripts/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -e

cd "$(dirname "$0")/.."

if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then
if ! command -v rye >/dev/null 2>&1 && [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then
brew bundle check >/dev/null 2>&1 || {
echo "==> Installing Homebrew dependencies…"
brew bundle
Expand Down
1 change: 0 additions & 1 deletion scripts/lint
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ rye run lint

echo "==> Making sure it imports"
rye run python -c 'import openai'

Loading

0 comments on commit cc45f94

Please sign in to comment.