Skip to content

fix(client): correct types for transcriptions / translations #1757

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

Merged
merged 1 commit into from
Sep 27, 2024
Merged
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 .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
configured_endpoints: 68
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-17ddd746c775ca4d4fbe64e5621ac30756ef09c061ff6313190b6ec162222d4c.yml
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-71e58a77027c67e003fdd1b1ac8ac11557d8bfabc7666d1a827c6b1ca8ab98b5.yml
14 changes: 10 additions & 4 deletions api.md
Original file line number Diff line number Diff line change
@@ -121,24 +121,30 @@ from openai.types import AudioModel, AudioResponseFormat
Types:

```python
from openai.types.audio import Transcription
from openai.types.audio import (
Transcription,
TranscriptionSegment,
TranscriptionVerbose,
TranscriptionWord,
TranscriptionCreateResponse,
)
```

Methods:

- <code title="post /audio/transcriptions">client.audio.transcriptions.<a href="./src/openai/resources/audio/transcriptions.py">create</a>(\*\*<a href="src/openai/types/audio/transcription_create_params.py">params</a>) -> <a href="./src/openai/types/audio/transcription.py">Transcription</a></code>
- <code title="post /audio/transcriptions">client.audio.transcriptions.<a href="./src/openai/resources/audio/transcriptions.py">create</a>(\*\*<a href="src/openai/types/audio/transcription_create_params.py">params</a>) -> <a href="./src/openai/types/audio/transcription_create_response.py">TranscriptionCreateResponse</a></code>

## Translations

Types:

```python
from openai.types.audio import Translation
from openai.types.audio import Translation, TranslationVerbose, TranslationCreateResponse
```

Methods:

- <code title="post /audio/translations">client.audio.translations.<a href="./src/openai/resources/audio/translations.py">create</a>(\*\*<a href="src/openai/types/audio/translation_create_params.py">params</a>) -> <a href="./src/openai/types/audio/translation.py">Translation</a></code>
- <code title="post /audio/translations">client.audio.translations.<a href="./src/openai/resources/audio/translations.py">create</a>(\*\*<a href="src/openai/types/audio/translation_create_params.py">params</a>) -> <a href="./src/openai/types/audio/translation_create_response.py">TranslationCreateResponse</a></code>

## Speech

46 changes: 28 additions & 18 deletions src/openai/resources/audio/transcriptions.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

from __future__ import annotations

from typing import List, Union, Mapping, cast
from typing import Any, List, Union, Mapping, cast
from typing_extensions import Literal

import httpx
@@ -22,8 +22,8 @@
from ...types.audio import transcription_create_params
from ..._base_client import make_request_options
from ...types.audio_model import AudioModel
from ...types.audio.transcription import Transcription
from ...types.audio_response_format import AudioResponseFormat
from ...types.audio.transcription_create_response import TranscriptionCreateResponse

__all__ = ["Transcriptions", "AsyncTranscriptions"]

@@ -64,7 +64,7 @@ def create(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Transcription:
) -> TranscriptionCreateResponse:
"""
Transcribes audio into the input language.
@@ -124,14 +124,19 @@ def create(
# sent to the server will contain a `boundary` parameter, e.g.
# multipart/form-data; boundary=---abc--
extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
return self._post(
"/audio/transcriptions",
body=maybe_transform(body, transcription_create_params.TranscriptionCreateParams),
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
return cast(
TranscriptionCreateResponse,
self._post(
"/audio/transcriptions",
body=maybe_transform(body, transcription_create_params.TranscriptionCreateParams),
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=cast(
Any, TranscriptionCreateResponse
), # Union types cannot be passed in as arguments in the type system
),
cast_to=Transcription,
)


@@ -171,7 +176,7 @@ async def create(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Transcription:
) -> TranscriptionCreateResponse:
"""
Transcribes audio into the input language.
@@ -231,14 +236,19 @@ async def create(
# sent to the server will contain a `boundary` parameter, e.g.
# multipart/form-data; boundary=---abc--
extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
return await self._post(
"/audio/transcriptions",
body=await async_maybe_transform(body, transcription_create_params.TranscriptionCreateParams),
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
return cast(
TranscriptionCreateResponse,
await self._post(
"/audio/transcriptions",
body=await async_maybe_transform(body, transcription_create_params.TranscriptionCreateParams),
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=cast(
Any, TranscriptionCreateResponse
), # Union types cannot be passed in as arguments in the type system
),
cast_to=Transcription,
)


46 changes: 28 additions & 18 deletions src/openai/resources/audio/translations.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

from __future__ import annotations

from typing import Union, Mapping, cast
from typing import Any, Union, Mapping, cast

import httpx

@@ -21,8 +21,8 @@
from ...types.audio import translation_create_params
from ..._base_client import make_request_options
from ...types.audio_model import AudioModel
from ...types.audio.translation import Translation
from ...types.audio_response_format import AudioResponseFormat
from ...types.audio.translation_create_response import TranslationCreateResponse

__all__ = ["Translations", "AsyncTranslations"]

@@ -61,7 +61,7 @@ def create(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Translation:
) -> TranslationCreateResponse:
"""
Translates audio into English.
@@ -108,14 +108,19 @@ def create(
# sent to the server will contain a `boundary` parameter, e.g.
# multipart/form-data; boundary=---abc--
extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
return self._post(
"/audio/translations",
body=maybe_transform(body, translation_create_params.TranslationCreateParams),
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
return cast(
TranslationCreateResponse,
self._post(
"/audio/translations",
body=maybe_transform(body, translation_create_params.TranslationCreateParams),
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=cast(
Any, TranslationCreateResponse
), # Union types cannot be passed in as arguments in the type system
),
cast_to=Translation,
)


@@ -153,7 +158,7 @@ async def create(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Translation:
) -> TranslationCreateResponse:
"""
Translates audio into English.
@@ -200,14 +205,19 @@ async def create(
# sent to the server will contain a `boundary` parameter, e.g.
# multipart/form-data; boundary=---abc--
extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
return await self._post(
"/audio/translations",
body=await async_maybe_transform(body, translation_create_params.TranslationCreateParams),
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
return cast(
TranslationCreateResponse,
await self._post(
"/audio/translations",
body=await async_maybe_transform(body, translation_create_params.TranslationCreateParams),
files=files,
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=cast(
Any, TranslationCreateResponse
), # Union types cannot be passed in as arguments in the type system
),
cast_to=Translation,
)


6 changes: 6 additions & 0 deletions src/openai/types/audio/__init__.py
Original file line number Diff line number Diff line change
@@ -5,6 +5,12 @@
from .translation import Translation as Translation
from .speech_model import SpeechModel as SpeechModel
from .transcription import Transcription as Transcription
from .transcription_word import TranscriptionWord as TranscriptionWord
from .translation_verbose import TranslationVerbose as TranslationVerbose
from .speech_create_params import SpeechCreateParams as SpeechCreateParams
from .transcription_segment import TranscriptionSegment as TranscriptionSegment
from .transcription_verbose import TranscriptionVerbose as TranscriptionVerbose
from .translation_create_params import TranslationCreateParams as TranslationCreateParams
from .transcription_create_params import TranscriptionCreateParams as TranscriptionCreateParams
from .translation_create_response import TranslationCreateResponse as TranslationCreateResponse
from .transcription_create_response import TranscriptionCreateResponse as TranscriptionCreateResponse
11 changes: 11 additions & 0 deletions src/openai/types/audio/transcription_create_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Union
from typing_extensions import TypeAlias

from .transcription import Transcription
from .transcription_verbose import TranscriptionVerbose

__all__ = ["TranscriptionCreateResponse"]

TranscriptionCreateResponse: TypeAlias = Union[Transcription, TranscriptionVerbose]
49 changes: 49 additions & 0 deletions src/openai/types/audio/transcription_segment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import List

from ..._models import BaseModel

__all__ = ["TranscriptionSegment"]


class TranscriptionSegment(BaseModel):
id: int
"""Unique identifier of the segment."""

avg_logprob: float
"""Average logprob of the segment.
If the value is lower than -1, consider the logprobs failed.
"""

compression_ratio: float
"""Compression ratio of the segment.
If the value is greater than 2.4, consider the compression failed.
"""

end: float
"""End time of the segment in seconds."""

no_speech_prob: float
"""Probability of no speech in the segment.
If the value is higher than 1.0 and the `avg_logprob` is below -1, consider this
segment silent.
"""

seek: int
"""Seek offset of the segment."""

start: float
"""Start time of the segment in seconds."""

temperature: float
"""Temperature parameter used for generating the segment."""

text: str
"""Text content of the segment."""

tokens: List[int]
"""Array of token IDs for the text content."""
26 changes: 26 additions & 0 deletions src/openai/types/audio/transcription_verbose.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import List, Optional

from ..._models import BaseModel
from .transcription_word import TranscriptionWord
from .transcription_segment import TranscriptionSegment

__all__ = ["TranscriptionVerbose"]


class TranscriptionVerbose(BaseModel):
duration: str
"""The duration of the input audio."""

language: str
"""The language of the input audio."""

text: str
"""The transcribed text."""

segments: Optional[List[TranscriptionSegment]] = None
"""Segments of the transcribed text and their corresponding details."""

words: Optional[List[TranscriptionWord]] = None
"""Extracted words and their corresponding timestamps."""
18 changes: 18 additions & 0 deletions src/openai/types/audio/transcription_word.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.



from ..._models import BaseModel

__all__ = ["TranscriptionWord"]


class TranscriptionWord(BaseModel):
end: float
"""End time of the word in seconds."""

start: float
"""Start time of the word in seconds."""

word: str
"""The text content of the word."""
11 changes: 11 additions & 0 deletions src/openai/types/audio/translation_create_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Union
from typing_extensions import TypeAlias

from .translation import Translation
from .translation_verbose import TranslationVerbose

__all__ = ["TranslationCreateResponse"]

TranslationCreateResponse: TypeAlias = Union[Translation, TranslationVerbose]
22 changes: 22 additions & 0 deletions src/openai/types/audio/translation_verbose.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import List, Optional

from ..._models import BaseModel
from .transcription_segment import TranscriptionSegment

__all__ = ["TranslationVerbose"]


class TranslationVerbose(BaseModel):
duration: str
"""The duration of the input audio."""

language: str
"""The language of the output translation (always `english`)."""

text: str
"""The translated text."""

segments: Optional[List[TranscriptionSegment]] = None
"""Segments of the translated text and their corresponding details."""
18 changes: 9 additions & 9 deletions tests/api_resources/audio/test_transcriptions.py
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@

from openai import OpenAI, AsyncOpenAI
from tests.utils import assert_matches_type
from openai.types.audio import Transcription
from openai.types.audio import TranscriptionCreateResponse

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

@@ -23,7 +23,7 @@ def test_method_create(self, client: OpenAI) -> None:
file=b"raw file contents",
model="whisper-1",
)
assert_matches_type(Transcription, transcription, path=["response"])
assert_matches_type(TranscriptionCreateResponse, transcription, path=["response"])

@parametrize
def test_method_create_with_all_params(self, client: OpenAI) -> None:
@@ -36,7 +36,7 @@ def test_method_create_with_all_params(self, client: OpenAI) -> None:
temperature=0,
timestamp_granularities=["word", "segment"],
)
assert_matches_type(Transcription, transcription, path=["response"])
assert_matches_type(TranscriptionCreateResponse, transcription, path=["response"])

@parametrize
def test_raw_response_create(self, client: OpenAI) -> None:
@@ -48,7 +48,7 @@ def test_raw_response_create(self, client: OpenAI) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transcription = response.parse()
assert_matches_type(Transcription, transcription, path=["response"])
assert_matches_type(TranscriptionCreateResponse, transcription, path=["response"])

@parametrize
def test_streaming_response_create(self, client: OpenAI) -> None:
@@ -60,7 +60,7 @@ def test_streaming_response_create(self, client: OpenAI) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

transcription = response.parse()
assert_matches_type(Transcription, transcription, path=["response"])
assert_matches_type(TranscriptionCreateResponse, transcription, path=["response"])

assert cast(Any, response.is_closed) is True

@@ -74,7 +74,7 @@ async def test_method_create(self, async_client: AsyncOpenAI) -> None:
file=b"raw file contents",
model="whisper-1",
)
assert_matches_type(Transcription, transcription, path=["response"])
assert_matches_type(TranscriptionCreateResponse, transcription, path=["response"])

@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None:
@@ -87,7 +87,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) ->
temperature=0,
timestamp_granularities=["word", "segment"],
)
assert_matches_type(Transcription, transcription, path=["response"])
assert_matches_type(TranscriptionCreateResponse, transcription, path=["response"])

@parametrize
async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None:
@@ -99,7 +99,7 @@ async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transcription = response.parse()
assert_matches_type(Transcription, transcription, path=["response"])
assert_matches_type(TranscriptionCreateResponse, transcription, path=["response"])

@parametrize
async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None:
@@ -111,6 +111,6 @@ async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> Non
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

transcription = await response.parse()
assert_matches_type(Transcription, transcription, path=["response"])
assert_matches_type(TranscriptionCreateResponse, transcription, path=["response"])

assert cast(Any, response.is_closed) is True
18 changes: 9 additions & 9 deletions tests/api_resources/audio/test_translations.py
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@

from openai import OpenAI, AsyncOpenAI
from tests.utils import assert_matches_type
from openai.types.audio import Translation
from openai.types.audio import TranslationCreateResponse

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

@@ -23,7 +23,7 @@ def test_method_create(self, client: OpenAI) -> None:
file=b"raw file contents",
model="whisper-1",
)
assert_matches_type(Translation, translation, path=["response"])
assert_matches_type(TranslationCreateResponse, translation, path=["response"])

@parametrize
def test_method_create_with_all_params(self, client: OpenAI) -> None:
@@ -34,7 +34,7 @@ def test_method_create_with_all_params(self, client: OpenAI) -> None:
response_format="json",
temperature=0,
)
assert_matches_type(Translation, translation, path=["response"])
assert_matches_type(TranslationCreateResponse, translation, path=["response"])

@parametrize
def test_raw_response_create(self, client: OpenAI) -> None:
@@ -46,7 +46,7 @@ def test_raw_response_create(self, client: OpenAI) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
translation = response.parse()
assert_matches_type(Translation, translation, path=["response"])
assert_matches_type(TranslationCreateResponse, translation, path=["response"])

@parametrize
def test_streaming_response_create(self, client: OpenAI) -> None:
@@ -58,7 +58,7 @@ def test_streaming_response_create(self, client: OpenAI) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

translation = response.parse()
assert_matches_type(Translation, translation, path=["response"])
assert_matches_type(TranslationCreateResponse, translation, path=["response"])

assert cast(Any, response.is_closed) is True

@@ -72,7 +72,7 @@ async def test_method_create(self, async_client: AsyncOpenAI) -> None:
file=b"raw file contents",
model="whisper-1",
)
assert_matches_type(Translation, translation, path=["response"])
assert_matches_type(TranslationCreateResponse, translation, path=["response"])

@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None:
@@ -83,7 +83,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) ->
response_format="json",
temperature=0,
)
assert_matches_type(Translation, translation, path=["response"])
assert_matches_type(TranslationCreateResponse, translation, path=["response"])

@parametrize
async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None:
@@ -95,7 +95,7 @@ async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
translation = response.parse()
assert_matches_type(Translation, translation, path=["response"])
assert_matches_type(TranslationCreateResponse, translation, path=["response"])

@parametrize
async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None:
@@ -107,6 +107,6 @@ async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> Non
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

translation = await response.parse()
assert_matches_type(Translation, translation, path=["response"])
assert_matches_type(TranslationCreateResponse, translation, path=["response"])

assert cast(Any, response.is_closed) is True