diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c523ce19f0..c3c95522a6 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.8.0" + ".": "1.9.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index c2ac83cdeb..14771f603b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 1.9.0 (2024-01-21) + +Full Changelog: [v1.8.0...v1.9.0](https://github.com/openai/openai-python/compare/v1.8.0...v1.9.0) + +### Features + +* **api:** add usage to runs and run steps ([#1090](https://github.com/openai/openai-python/issues/1090)) ([6c116df](https://github.com/openai/openai-python/commit/6c116dfbb0065d15050450df70e0e98fc8c80349)) + + +### Chores + +* **internal:** fix typing util function ([#1083](https://github.com/openai/openai-python/issues/1083)) ([3e60db6](https://github.com/openai/openai-python/commit/3e60db69f5d9187c4eb38451967259f534a36a82)) +* **internal:** remove redundant client test ([#1085](https://github.com/openai/openai-python/issues/1085)) ([947974f](https://github.com/openai/openai-python/commit/947974f5af726e252b7b12c863743e50f41b79d3)) +* **internal:** share client instances between all tests ([#1088](https://github.com/openai/openai-python/issues/1088)) ([05cd753](https://github.com/openai/openai-python/commit/05cd7531d40774d05c52b14dee54d137ac1452a3)) +* **internal:** speculative retry-after-ms support ([#1086](https://github.com/openai/openai-python/issues/1086)) ([36a7576](https://github.com/openai/openai-python/commit/36a7576a913be8509a3cf6f262543083b485136e)) +* lazy load raw resource class properties ([#1087](https://github.com/openai/openai-python/issues/1087)) ([d307127](https://github.com/openai/openai-python/commit/d30712744be07461e86763705c03c3495eadfc35)) + ## 1.8.0 (2024-01-16) Full Changelog: [v1.7.2...v1.8.0](https://github.com/openai/openai-python/compare/v1.7.2...v1.8.0) diff --git a/pyproject.toml b/pyproject.toml index 5019e6cf7e..82f4c7e068 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openai" -version = "1.8.0" +version = "1.9.0" description = "The official Python library for the openai API" readme = "README.md" license = "Apache-2.0" diff --git a/src/openai/_base_client.py b/src/openai/_base_client.py index 1dfbd7dfb3..43fad0603d 100644 --- a/src/openai/_base_client.py +++ b/src/openai/_base_client.py @@ -73,7 +73,9 @@ from ._constants import ( DEFAULT_LIMITS, DEFAULT_TIMEOUT, + MAX_RETRY_DELAY, DEFAULT_MAX_RETRIES, + INITIAL_RETRY_DELAY, RAW_RESPONSE_HEADER, OVERRIDE_CAST_TO_HEADER, ) @@ -590,6 +592,40 @@ def base_url(self, url: URL | str) -> None: def platform_headers(self) -> Dict[str, str]: return platform_headers(self._version) + def _parse_retry_after_header(self, response_headers: Optional[httpx.Headers] = None) -> float | None: + """Returns a float of the number of seconds (not milliseconds) to wait after retrying, or None if unspecified. + + About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After + See also https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After#syntax + """ + if response_headers is None: + return None + + # First, try the non-standard `retry-after-ms` header for milliseconds, + # which is more precise than integer-seconds `retry-after` + try: + retry_ms_header = response_headers.get("retry-after-ms", None) + return float(retry_ms_header) / 1000 + except (TypeError, ValueError): + pass + + # Next, try parsing `retry-after` header as seconds (allowing nonstandard floats). + retry_header = response_headers.get("retry-after") + try: + # note: the spec indicates that this should only ever be an integer + # but if someone sends a float there's no reason for us to not respect it + return float(retry_header) + except (TypeError, ValueError): + pass + + # Last, try parsing `retry-after` as a date. + retry_date_tuple = email.utils.parsedate_tz(retry_header) + if retry_date_tuple is None: + return None + + retry_date = email.utils.mktime_tz(retry_date_tuple) + return float(retry_date - time.time()) + def _calculate_retry_timeout( self, remaining_retries: int, @@ -597,40 +633,16 @@ def _calculate_retry_timeout( response_headers: Optional[httpx.Headers] = None, ) -> float: max_retries = options.get_max_retries(self.max_retries) - try: - # About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After - # - # ". See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After#syntax for - # details. - if response_headers is not None: - retry_header = response_headers.get("retry-after") - try: - # note: the spec indicates that this should only ever be an integer - # but if someone sends a float there's no reason for us to not respect it - retry_after = float(retry_header) - except Exception: - retry_date_tuple = email.utils.parsedate_tz(retry_header) - if retry_date_tuple is None: - retry_after = -1 - else: - retry_date = email.utils.mktime_tz(retry_date_tuple) - retry_after = int(retry_date - time.time()) - else: - retry_after = -1 - - except Exception: - retry_after = -1 # If the API asks us to wait a certain amount of time (and it's a reasonable amount), just do what it says. - if 0 < retry_after <= 60: + retry_after = self._parse_retry_after_header(response_headers) + if retry_after is not None and 0 < retry_after <= 60: return retry_after - initial_retry_delay = 0.5 - max_retry_delay = 8.0 nb_retries = max_retries - remaining_retries # Apply exponential backoff, but not more than the max. - sleep_seconds = min(initial_retry_delay * pow(2.0, nb_retries), max_retry_delay) + sleep_seconds = min(INITIAL_RETRY_DELAY * pow(2.0, nb_retries), MAX_RETRY_DELAY) # Apply some jitter, plus-or-minus half a second. jitter = 1 - 0.25 * random() diff --git a/src/openai/_constants.py b/src/openai/_constants.py index af9a04b80c..dffb8ecfb6 100644 --- a/src/openai/_constants.py +++ b/src/openai/_constants.py @@ -9,3 +9,6 @@ DEFAULT_TIMEOUT = httpx.Timeout(timeout=600.0, connect=5.0) DEFAULT_MAX_RETRIES = 2 DEFAULT_LIMITS = httpx.Limits(max_connections=100, max_keepalive_connections=20) + +INITIAL_RETRY_DELAY = 0.5 +MAX_RETRY_DELAY = 8.0 diff --git a/src/openai/_utils/_typing.py b/src/openai/_utils/_typing.py index b5e2c2e397..a020822bc0 100644 --- a/src/openai/_utils/_typing.py +++ b/src/openai/_utils/_typing.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, cast +from typing import Any, TypeVar, cast from typing_extensions import Required, Annotated, get_args, get_origin from .._types import InheritsGeneric @@ -23,6 +23,12 @@ def is_required_type(typ: type) -> bool: return get_origin(typ) == Required +def is_typevar(typ: type) -> bool: + # type ignore is required because type checkers + # think this expression will always return False + return type(typ) == TypeVar # type: ignore + + # Extracts T from Annotated[T, ...] or from Required[Annotated[T, ...]] def strip_annotated_type(typ: type) -> type: if is_required_type(typ) or is_annotated_type(typ): @@ -49,6 +55,15 @@ class MyResponse(Foo[bytes]): extract_type_var(MyResponse, bases=(Foo,), index=0) -> bytes ``` + + And where a generic subclass is given: + ```py + _T = TypeVar('_T') + class MyResponse(Foo[_T]): + ... + + extract_type_var(MyResponse[bytes], bases=(Foo,), index=0) -> bytes + ``` """ cls = cast(object, get_origin(typ) or typ) if cls in generic_bases: @@ -75,6 +90,18 @@ class MyResponse(Foo[bytes]): f"Does {cls} inherit from one of {generic_bases} ?" ) - return extract_type_arg(target_base_class, index) + extracted = extract_type_arg(target_base_class, index) + if is_typevar(extracted): + # If the extracted type argument is itself a type variable + # then that means the subclass itself is generic, so we have + # to resolve the type argument from the class itself, not + # the base class. + # + # Note: if there is more than 1 type argument, the subclass could + # change the ordering of the type arguments, this is not currently + # supported. + return extract_type_arg(typ, index) + + return extracted raise RuntimeError(f"Could not resolve inner type variable at index {index} for {typ}") diff --git a/src/openai/_version.py b/src/openai/_version.py index 311cab2540..b4e6d226ea 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.8.0" # x-release-please-version +__version__ = "1.9.0" # x-release-please-version diff --git a/src/openai/resources/audio/audio.py b/src/openai/resources/audio/audio.py index b14e64cff6..bafacf4422 100644 --- a/src/openai/resources/audio/audio.py +++ b/src/openai/resources/audio/audio.py @@ -78,27 +78,67 @@ def with_streaming_response(self) -> AsyncAudioWithStreamingResponse: class AudioWithRawResponse: def __init__(self, audio: Audio) -> None: - self.transcriptions = TranscriptionsWithRawResponse(audio.transcriptions) - self.translations = TranslationsWithRawResponse(audio.translations) - self.speech = SpeechWithRawResponse(audio.speech) + self._audio = audio + + @cached_property + def transcriptions(self) -> TranscriptionsWithRawResponse: + return TranscriptionsWithRawResponse(self._audio.transcriptions) + + @cached_property + def translations(self) -> TranslationsWithRawResponse: + return TranslationsWithRawResponse(self._audio.translations) + + @cached_property + def speech(self) -> SpeechWithRawResponse: + return SpeechWithRawResponse(self._audio.speech) class AsyncAudioWithRawResponse: def __init__(self, audio: AsyncAudio) -> None: - self.transcriptions = AsyncTranscriptionsWithRawResponse(audio.transcriptions) - self.translations = AsyncTranslationsWithRawResponse(audio.translations) - self.speech = AsyncSpeechWithRawResponse(audio.speech) + self._audio = audio + + @cached_property + def transcriptions(self) -> AsyncTranscriptionsWithRawResponse: + return AsyncTranscriptionsWithRawResponse(self._audio.transcriptions) + + @cached_property + def translations(self) -> AsyncTranslationsWithRawResponse: + return AsyncTranslationsWithRawResponse(self._audio.translations) + + @cached_property + def speech(self) -> AsyncSpeechWithRawResponse: + return AsyncSpeechWithRawResponse(self._audio.speech) class AudioWithStreamingResponse: def __init__(self, audio: Audio) -> None: - self.transcriptions = TranscriptionsWithStreamingResponse(audio.transcriptions) - self.translations = TranslationsWithStreamingResponse(audio.translations) - self.speech = SpeechWithStreamingResponse(audio.speech) + self._audio = audio + + @cached_property + def transcriptions(self) -> TranscriptionsWithStreamingResponse: + return TranscriptionsWithStreamingResponse(self._audio.transcriptions) + + @cached_property + def translations(self) -> TranslationsWithStreamingResponse: + return TranslationsWithStreamingResponse(self._audio.translations) + + @cached_property + def speech(self) -> SpeechWithStreamingResponse: + return SpeechWithStreamingResponse(self._audio.speech) class AsyncAudioWithStreamingResponse: def __init__(self, audio: AsyncAudio) -> None: - self.transcriptions = AsyncTranscriptionsWithStreamingResponse(audio.transcriptions) - self.translations = AsyncTranslationsWithStreamingResponse(audio.translations) - self.speech = AsyncSpeechWithStreamingResponse(audio.speech) + self._audio = audio + + @cached_property + def transcriptions(self) -> AsyncTranscriptionsWithStreamingResponse: + return AsyncTranscriptionsWithStreamingResponse(self._audio.transcriptions) + + @cached_property + def translations(self) -> AsyncTranslationsWithStreamingResponse: + return AsyncTranslationsWithStreamingResponse(self._audio.translations) + + @cached_property + def speech(self) -> AsyncSpeechWithStreamingResponse: + return AsyncSpeechWithStreamingResponse(self._audio.speech) diff --git a/src/openai/resources/audio/speech.py b/src/openai/resources/audio/speech.py index 9c051624d5..4e94d4aaef 100644 --- a/src/openai/resources/audio/speech.py +++ b/src/openai/resources/audio/speech.py @@ -170,6 +170,8 @@ async def create( class SpeechWithRawResponse: def __init__(self, speech: Speech) -> None: + self._speech = speech + self.create = _legacy_response.to_raw_response_wrapper( speech.create, ) @@ -177,6 +179,8 @@ def __init__(self, speech: Speech) -> None: class AsyncSpeechWithRawResponse: def __init__(self, speech: AsyncSpeech) -> None: + self._speech = speech + self.create = _legacy_response.async_to_raw_response_wrapper( speech.create, ) @@ -184,6 +188,8 @@ def __init__(self, speech: AsyncSpeech) -> None: class SpeechWithStreamingResponse: def __init__(self, speech: Speech) -> None: + self._speech = speech + self.create = to_custom_streamed_response_wrapper( speech.create, StreamedBinaryAPIResponse, @@ -192,6 +198,8 @@ def __init__(self, speech: Speech) -> None: class AsyncSpeechWithStreamingResponse: def __init__(self, speech: AsyncSpeech) -> None: + self._speech = speech + self.create = async_to_custom_streamed_response_wrapper( speech.create, AsyncStreamedBinaryAPIResponse, diff --git a/src/openai/resources/audio/transcriptions.py b/src/openai/resources/audio/transcriptions.py index 868ce7725f..2c167be395 100644 --- a/src/openai/resources/audio/transcriptions.py +++ b/src/openai/resources/audio/transcriptions.py @@ -199,6 +199,8 @@ async def create( class TranscriptionsWithRawResponse: def __init__(self, transcriptions: Transcriptions) -> None: + self._transcriptions = transcriptions + self.create = _legacy_response.to_raw_response_wrapper( transcriptions.create, ) @@ -206,6 +208,8 @@ def __init__(self, transcriptions: Transcriptions) -> None: class AsyncTranscriptionsWithRawResponse: def __init__(self, transcriptions: AsyncTranscriptions) -> None: + self._transcriptions = transcriptions + self.create = _legacy_response.async_to_raw_response_wrapper( transcriptions.create, ) @@ -213,6 +217,8 @@ def __init__(self, transcriptions: AsyncTranscriptions) -> None: class TranscriptionsWithStreamingResponse: def __init__(self, transcriptions: Transcriptions) -> None: + self._transcriptions = transcriptions + self.create = to_streamed_response_wrapper( transcriptions.create, ) @@ -220,6 +226,8 @@ def __init__(self, transcriptions: Transcriptions) -> None: class AsyncTranscriptionsWithStreamingResponse: def __init__(self, transcriptions: AsyncTranscriptions) -> None: + self._transcriptions = transcriptions + self.create = async_to_streamed_response_wrapper( transcriptions.create, ) diff --git a/src/openai/resources/audio/translations.py b/src/openai/resources/audio/translations.py index 333abfb4cf..d6cbc75886 100644 --- a/src/openai/resources/audio/translations.py +++ b/src/openai/resources/audio/translations.py @@ -185,6 +185,8 @@ async def create( class TranslationsWithRawResponse: def __init__(self, translations: Translations) -> None: + self._translations = translations + self.create = _legacy_response.to_raw_response_wrapper( translations.create, ) @@ -192,6 +194,8 @@ def __init__(self, translations: Translations) -> None: class AsyncTranslationsWithRawResponse: def __init__(self, translations: AsyncTranslations) -> None: + self._translations = translations + self.create = _legacy_response.async_to_raw_response_wrapper( translations.create, ) @@ -199,6 +203,8 @@ def __init__(self, translations: AsyncTranslations) -> None: class TranslationsWithStreamingResponse: def __init__(self, translations: Translations) -> None: + self._translations = translations + self.create = to_streamed_response_wrapper( translations.create, ) @@ -206,6 +212,8 @@ def __init__(self, translations: Translations) -> None: class AsyncTranslationsWithStreamingResponse: def __init__(self, translations: AsyncTranslations) -> None: + self._translations = translations + self.create = async_to_streamed_response_wrapper( translations.create, ) diff --git a/src/openai/resources/beta/assistants/assistants.py b/src/openai/resources/beta/assistants/assistants.py index a40acfb323..3a2418ad90 100644 --- a/src/openai/resources/beta/assistants/assistants.py +++ b/src/openai/resources/beta/assistants/assistants.py @@ -645,7 +645,7 @@ async def delete( class AssistantsWithRawResponse: def __init__(self, assistants: Assistants) -> None: - self.files = FilesWithRawResponse(assistants.files) + self._assistants = assistants self.create = _legacy_response.to_raw_response_wrapper( assistants.create, @@ -663,10 +663,14 @@ def __init__(self, assistants: Assistants) -> None: assistants.delete, ) + @cached_property + def files(self) -> FilesWithRawResponse: + return FilesWithRawResponse(self._assistants.files) + class AsyncAssistantsWithRawResponse: def __init__(self, assistants: AsyncAssistants) -> None: - self.files = AsyncFilesWithRawResponse(assistants.files) + self._assistants = assistants self.create = _legacy_response.async_to_raw_response_wrapper( assistants.create, @@ -684,10 +688,14 @@ def __init__(self, assistants: AsyncAssistants) -> None: assistants.delete, ) + @cached_property + def files(self) -> AsyncFilesWithRawResponse: + return AsyncFilesWithRawResponse(self._assistants.files) + class AssistantsWithStreamingResponse: def __init__(self, assistants: Assistants) -> None: - self.files = FilesWithStreamingResponse(assistants.files) + self._assistants = assistants self.create = to_streamed_response_wrapper( assistants.create, @@ -705,10 +713,14 @@ def __init__(self, assistants: Assistants) -> None: assistants.delete, ) + @cached_property + def files(self) -> FilesWithStreamingResponse: + return FilesWithStreamingResponse(self._assistants.files) + class AsyncAssistantsWithStreamingResponse: def __init__(self, assistants: AsyncAssistants) -> None: - self.files = AsyncFilesWithStreamingResponse(assistants.files) + self._assistants = assistants self.create = async_to_streamed_response_wrapper( assistants.create, @@ -725,3 +737,7 @@ def __init__(self, assistants: AsyncAssistants) -> None: self.delete = async_to_streamed_response_wrapper( assistants.delete, ) + + @cached_property + def files(self) -> AsyncFilesWithStreamingResponse: + return AsyncFilesWithStreamingResponse(self._assistants.files) diff --git a/src/openai/resources/beta/assistants/files.py b/src/openai/resources/beta/assistants/files.py index 12247044c4..c21465036a 100644 --- a/src/openai/resources/beta/assistants/files.py +++ b/src/openai/resources/beta/assistants/files.py @@ -410,6 +410,8 @@ async def delete( class FilesWithRawResponse: def __init__(self, files: Files) -> None: + self._files = files + self.create = _legacy_response.to_raw_response_wrapper( files.create, ) @@ -426,6 +428,8 @@ def __init__(self, files: Files) -> None: class AsyncFilesWithRawResponse: def __init__(self, files: AsyncFiles) -> None: + self._files = files + self.create = _legacy_response.async_to_raw_response_wrapper( files.create, ) @@ -442,6 +446,8 @@ def __init__(self, files: AsyncFiles) -> None: class FilesWithStreamingResponse: def __init__(self, files: Files) -> None: + self._files = files + self.create = to_streamed_response_wrapper( files.create, ) @@ -458,6 +464,8 @@ def __init__(self, files: Files) -> None: class AsyncFilesWithStreamingResponse: def __init__(self, files: AsyncFiles) -> None: + self._files = files + self.create = async_to_streamed_response_wrapper( files.create, ) diff --git a/src/openai/resources/beta/beta.py b/src/openai/resources/beta/beta.py index b11a706d5d..7081cff305 100644 --- a/src/openai/resources/beta/beta.py +++ b/src/openai/resources/beta/beta.py @@ -64,23 +64,51 @@ def with_streaming_response(self) -> AsyncBetaWithStreamingResponse: class BetaWithRawResponse: def __init__(self, beta: Beta) -> None: - self.assistants = AssistantsWithRawResponse(beta.assistants) - self.threads = ThreadsWithRawResponse(beta.threads) + self._beta = beta + + @cached_property + def assistants(self) -> AssistantsWithRawResponse: + return AssistantsWithRawResponse(self._beta.assistants) + + @cached_property + def threads(self) -> ThreadsWithRawResponse: + return ThreadsWithRawResponse(self._beta.threads) class AsyncBetaWithRawResponse: def __init__(self, beta: AsyncBeta) -> None: - self.assistants = AsyncAssistantsWithRawResponse(beta.assistants) - self.threads = AsyncThreadsWithRawResponse(beta.threads) + self._beta = beta + + @cached_property + def assistants(self) -> AsyncAssistantsWithRawResponse: + return AsyncAssistantsWithRawResponse(self._beta.assistants) + + @cached_property + def threads(self) -> AsyncThreadsWithRawResponse: + return AsyncThreadsWithRawResponse(self._beta.threads) class BetaWithStreamingResponse: def __init__(self, beta: Beta) -> None: - self.assistants = AssistantsWithStreamingResponse(beta.assistants) - self.threads = ThreadsWithStreamingResponse(beta.threads) + self._beta = beta + + @cached_property + def assistants(self) -> AssistantsWithStreamingResponse: + return AssistantsWithStreamingResponse(self._beta.assistants) + + @cached_property + def threads(self) -> ThreadsWithStreamingResponse: + return ThreadsWithStreamingResponse(self._beta.threads) class AsyncBetaWithStreamingResponse: def __init__(self, beta: AsyncBeta) -> None: - self.assistants = AsyncAssistantsWithStreamingResponse(beta.assistants) - self.threads = AsyncThreadsWithStreamingResponse(beta.threads) + self._beta = beta + + @cached_property + def assistants(self) -> AsyncAssistantsWithStreamingResponse: + return AsyncAssistantsWithStreamingResponse(self._beta.assistants) + + @cached_property + def threads(self) -> AsyncThreadsWithStreamingResponse: + return AsyncThreadsWithStreamingResponse(self._beta.threads) diff --git a/src/openai/resources/beta/threads/messages/files.py b/src/openai/resources/beta/threads/messages/files.py index 8b6c4581d0..fc8b894d72 100644 --- a/src/openai/resources/beta/threads/messages/files.py +++ b/src/openai/resources/beta/threads/messages/files.py @@ -266,6 +266,8 @@ def list( class FilesWithRawResponse: def __init__(self, files: Files) -> None: + self._files = files + self.retrieve = _legacy_response.to_raw_response_wrapper( files.retrieve, ) @@ -276,6 +278,8 @@ def __init__(self, files: Files) -> None: class AsyncFilesWithRawResponse: def __init__(self, files: AsyncFiles) -> None: + self._files = files + self.retrieve = _legacy_response.async_to_raw_response_wrapper( files.retrieve, ) @@ -286,6 +290,8 @@ def __init__(self, files: AsyncFiles) -> None: class FilesWithStreamingResponse: def __init__(self, files: Files) -> None: + self._files = files + self.retrieve = to_streamed_response_wrapper( files.retrieve, ) @@ -296,6 +302,8 @@ def __init__(self, files: Files) -> None: class AsyncFilesWithStreamingResponse: def __init__(self, files: AsyncFiles) -> None: + self._files = files + self.retrieve = async_to_streamed_response_wrapper( files.retrieve, ) diff --git a/src/openai/resources/beta/threads/messages/messages.py b/src/openai/resources/beta/threads/messages/messages.py index f5a17f902f..c95cdd5d00 100644 --- a/src/openai/resources/beta/threads/messages/messages.py +++ b/src/openai/resources/beta/threads/messages/messages.py @@ -481,7 +481,7 @@ def list( class MessagesWithRawResponse: def __init__(self, messages: Messages) -> None: - self.files = FilesWithRawResponse(messages.files) + self._messages = messages self.create = _legacy_response.to_raw_response_wrapper( messages.create, @@ -496,10 +496,14 @@ def __init__(self, messages: Messages) -> None: messages.list, ) + @cached_property + def files(self) -> FilesWithRawResponse: + return FilesWithRawResponse(self._messages.files) + class AsyncMessagesWithRawResponse: def __init__(self, messages: AsyncMessages) -> None: - self.files = AsyncFilesWithRawResponse(messages.files) + self._messages = messages self.create = _legacy_response.async_to_raw_response_wrapper( messages.create, @@ -514,10 +518,14 @@ def __init__(self, messages: AsyncMessages) -> None: messages.list, ) + @cached_property + def files(self) -> AsyncFilesWithRawResponse: + return AsyncFilesWithRawResponse(self._messages.files) + class MessagesWithStreamingResponse: def __init__(self, messages: Messages) -> None: - self.files = FilesWithStreamingResponse(messages.files) + self._messages = messages self.create = to_streamed_response_wrapper( messages.create, @@ -532,10 +540,14 @@ def __init__(self, messages: Messages) -> None: messages.list, ) + @cached_property + def files(self) -> FilesWithStreamingResponse: + return FilesWithStreamingResponse(self._messages.files) + class AsyncMessagesWithStreamingResponse: def __init__(self, messages: AsyncMessages) -> None: - self.files = AsyncFilesWithStreamingResponse(messages.files) + self._messages = messages self.create = async_to_streamed_response_wrapper( messages.create, @@ -549,3 +561,7 @@ def __init__(self, messages: AsyncMessages) -> None: self.list = async_to_streamed_response_wrapper( messages.list, ) + + @cached_property + def files(self) -> AsyncFilesWithStreamingResponse: + return AsyncFilesWithStreamingResponse(self._messages.files) diff --git a/src/openai/resources/beta/threads/runs/runs.py b/src/openai/resources/beta/threads/runs/runs.py index ac7a1b3330..0ed48b4792 100644 --- a/src/openai/resources/beta/threads/runs/runs.py +++ b/src/openai/resources/beta/threads/runs/runs.py @@ -681,7 +681,7 @@ async def submit_tool_outputs( class RunsWithRawResponse: def __init__(self, runs: Runs) -> None: - self.steps = StepsWithRawResponse(runs.steps) + self._runs = runs self.create = _legacy_response.to_raw_response_wrapper( runs.create, @@ -702,10 +702,14 @@ def __init__(self, runs: Runs) -> None: runs.submit_tool_outputs, ) + @cached_property + def steps(self) -> StepsWithRawResponse: + return StepsWithRawResponse(self._runs.steps) + class AsyncRunsWithRawResponse: def __init__(self, runs: AsyncRuns) -> None: - self.steps = AsyncStepsWithRawResponse(runs.steps) + self._runs = runs self.create = _legacy_response.async_to_raw_response_wrapper( runs.create, @@ -726,10 +730,14 @@ def __init__(self, runs: AsyncRuns) -> None: runs.submit_tool_outputs, ) + @cached_property + def steps(self) -> AsyncStepsWithRawResponse: + return AsyncStepsWithRawResponse(self._runs.steps) + class RunsWithStreamingResponse: def __init__(self, runs: Runs) -> None: - self.steps = StepsWithStreamingResponse(runs.steps) + self._runs = runs self.create = to_streamed_response_wrapper( runs.create, @@ -750,10 +758,14 @@ def __init__(self, runs: Runs) -> None: runs.submit_tool_outputs, ) + @cached_property + def steps(self) -> StepsWithStreamingResponse: + return StepsWithStreamingResponse(self._runs.steps) + class AsyncRunsWithStreamingResponse: def __init__(self, runs: AsyncRuns) -> None: - self.steps = AsyncStepsWithStreamingResponse(runs.steps) + self._runs = runs self.create = async_to_streamed_response_wrapper( runs.create, @@ -773,3 +785,7 @@ def __init__(self, runs: AsyncRuns) -> None: self.submit_tool_outputs = async_to_streamed_response_wrapper( runs.submit_tool_outputs, ) + + @cached_property + def steps(self) -> AsyncStepsWithStreamingResponse: + return AsyncStepsWithStreamingResponse(self._runs.steps) diff --git a/src/openai/resources/beta/threads/runs/steps.py b/src/openai/resources/beta/threads/runs/steps.py index 9b1df10652..539745a594 100644 --- a/src/openai/resources/beta/threads/runs/steps.py +++ b/src/openai/resources/beta/threads/runs/steps.py @@ -264,6 +264,8 @@ def list( class StepsWithRawResponse: def __init__(self, steps: Steps) -> None: + self._steps = steps + self.retrieve = _legacy_response.to_raw_response_wrapper( steps.retrieve, ) @@ -274,6 +276,8 @@ def __init__(self, steps: Steps) -> None: class AsyncStepsWithRawResponse: def __init__(self, steps: AsyncSteps) -> None: + self._steps = steps + self.retrieve = _legacy_response.async_to_raw_response_wrapper( steps.retrieve, ) @@ -284,6 +288,8 @@ def __init__(self, steps: AsyncSteps) -> None: class StepsWithStreamingResponse: def __init__(self, steps: Steps) -> None: + self._steps = steps + self.retrieve = to_streamed_response_wrapper( steps.retrieve, ) @@ -294,6 +300,8 @@ def __init__(self, steps: Steps) -> None: class AsyncStepsWithStreamingResponse: def __init__(self, steps: AsyncSteps) -> None: + self._steps = steps + self.retrieve = async_to_streamed_response_wrapper( steps.retrieve, ) diff --git a/src/openai/resources/beta/threads/threads.py b/src/openai/resources/beta/threads/threads.py index d885404f59..0372ae2f66 100644 --- a/src/openai/resources/beta/threads/threads.py +++ b/src/openai/resources/beta/threads/threads.py @@ -537,8 +537,7 @@ async def create_and_run( class ThreadsWithRawResponse: def __init__(self, threads: Threads) -> None: - self.runs = RunsWithRawResponse(threads.runs) - self.messages = MessagesWithRawResponse(threads.messages) + self._threads = threads self.create = _legacy_response.to_raw_response_wrapper( threads.create, @@ -556,11 +555,18 @@ def __init__(self, threads: Threads) -> None: threads.create_and_run, ) + @cached_property + def runs(self) -> RunsWithRawResponse: + return RunsWithRawResponse(self._threads.runs) + + @cached_property + def messages(self) -> MessagesWithRawResponse: + return MessagesWithRawResponse(self._threads.messages) + class AsyncThreadsWithRawResponse: def __init__(self, threads: AsyncThreads) -> None: - self.runs = AsyncRunsWithRawResponse(threads.runs) - self.messages = AsyncMessagesWithRawResponse(threads.messages) + self._threads = threads self.create = _legacy_response.async_to_raw_response_wrapper( threads.create, @@ -578,11 +584,18 @@ def __init__(self, threads: AsyncThreads) -> None: threads.create_and_run, ) + @cached_property + def runs(self) -> AsyncRunsWithRawResponse: + return AsyncRunsWithRawResponse(self._threads.runs) + + @cached_property + def messages(self) -> AsyncMessagesWithRawResponse: + return AsyncMessagesWithRawResponse(self._threads.messages) + class ThreadsWithStreamingResponse: def __init__(self, threads: Threads) -> None: - self.runs = RunsWithStreamingResponse(threads.runs) - self.messages = MessagesWithStreamingResponse(threads.messages) + self._threads = threads self.create = to_streamed_response_wrapper( threads.create, @@ -600,11 +613,18 @@ def __init__(self, threads: Threads) -> None: threads.create_and_run, ) + @cached_property + def runs(self) -> RunsWithStreamingResponse: + return RunsWithStreamingResponse(self._threads.runs) + + @cached_property + def messages(self) -> MessagesWithStreamingResponse: + return MessagesWithStreamingResponse(self._threads.messages) + class AsyncThreadsWithStreamingResponse: def __init__(self, threads: AsyncThreads) -> None: - self.runs = AsyncRunsWithStreamingResponse(threads.runs) - self.messages = AsyncMessagesWithStreamingResponse(threads.messages) + self._threads = threads self.create = async_to_streamed_response_wrapper( threads.create, @@ -621,3 +641,11 @@ def __init__(self, threads: AsyncThreads) -> None: self.create_and_run = async_to_streamed_response_wrapper( threads.create_and_run, ) + + @cached_property + def runs(self) -> AsyncRunsWithStreamingResponse: + return AsyncRunsWithStreamingResponse(self._threads.runs) + + @cached_property + def messages(self) -> AsyncMessagesWithStreamingResponse: + return AsyncMessagesWithStreamingResponse(self._threads.messages) diff --git a/src/openai/resources/chat/chat.py b/src/openai/resources/chat/chat.py index 467a5e401b..b6effa4e63 100644 --- a/src/openai/resources/chat/chat.py +++ b/src/openai/resources/chat/chat.py @@ -46,19 +46,35 @@ def with_streaming_response(self) -> AsyncChatWithStreamingResponse: class ChatWithRawResponse: def __init__(self, chat: Chat) -> None: - self.completions = CompletionsWithRawResponse(chat.completions) + self._chat = chat + + @cached_property + def completions(self) -> CompletionsWithRawResponse: + return CompletionsWithRawResponse(self._chat.completions) class AsyncChatWithRawResponse: def __init__(self, chat: AsyncChat) -> None: - self.completions = AsyncCompletionsWithRawResponse(chat.completions) + self._chat = chat + + @cached_property + def completions(self) -> AsyncCompletionsWithRawResponse: + return AsyncCompletionsWithRawResponse(self._chat.completions) class ChatWithStreamingResponse: def __init__(self, chat: Chat) -> None: - self.completions = CompletionsWithStreamingResponse(chat.completions) + self._chat = chat + + @cached_property + def completions(self) -> CompletionsWithStreamingResponse: + return CompletionsWithStreamingResponse(self._chat.completions) class AsyncChatWithStreamingResponse: def __init__(self, chat: AsyncChat) -> None: - self.completions = AsyncCompletionsWithStreamingResponse(chat.completions) + self._chat = chat + + @cached_property + def completions(self) -> AsyncCompletionsWithStreamingResponse: + return AsyncCompletionsWithStreamingResponse(self._chat.completions) diff --git a/src/openai/resources/chat/completions.py b/src/openai/resources/chat/completions.py index 53645a9eb9..f461161ab7 100644 --- a/src/openai/resources/chat/completions.py +++ b/src/openai/resources/chat/completions.py @@ -1335,6 +1335,8 @@ async def create( class CompletionsWithRawResponse: def __init__(self, completions: Completions) -> None: + self._completions = completions + self.create = _legacy_response.to_raw_response_wrapper( completions.create, ) @@ -1342,6 +1344,8 @@ def __init__(self, completions: Completions) -> None: class AsyncCompletionsWithRawResponse: def __init__(self, completions: AsyncCompletions) -> None: + self._completions = completions + self.create = _legacy_response.async_to_raw_response_wrapper( completions.create, ) @@ -1349,6 +1353,8 @@ def __init__(self, completions: AsyncCompletions) -> None: class CompletionsWithStreamingResponse: def __init__(self, completions: Completions) -> None: + self._completions = completions + self.create = to_streamed_response_wrapper( completions.create, ) @@ -1356,6 +1362,8 @@ def __init__(self, completions: Completions) -> None: class AsyncCompletionsWithStreamingResponse: def __init__(self, completions: AsyncCompletions) -> None: + self._completions = completions + self.create = async_to_streamed_response_wrapper( completions.create, ) diff --git a/src/openai/resources/completions.py b/src/openai/resources/completions.py index 43a9947524..3d2e10230a 100644 --- a/src/openai/resources/completions.py +++ b/src/openai/resources/completions.py @@ -1052,6 +1052,8 @@ async def create( class CompletionsWithRawResponse: def __init__(self, completions: Completions) -> None: + self._completions = completions + self.create = _legacy_response.to_raw_response_wrapper( completions.create, ) @@ -1059,6 +1061,8 @@ def __init__(self, completions: Completions) -> None: class AsyncCompletionsWithRawResponse: def __init__(self, completions: AsyncCompletions) -> None: + self._completions = completions + self.create = _legacy_response.async_to_raw_response_wrapper( completions.create, ) @@ -1066,6 +1070,8 @@ def __init__(self, completions: AsyncCompletions) -> None: class CompletionsWithStreamingResponse: def __init__(self, completions: Completions) -> None: + self._completions = completions + self.create = to_streamed_response_wrapper( completions.create, ) @@ -1073,6 +1079,8 @@ def __init__(self, completions: Completions) -> None: class AsyncCompletionsWithStreamingResponse: def __init__(self, completions: AsyncCompletions) -> None: + self._completions = completions + self.create = async_to_streamed_response_wrapper( completions.create, ) diff --git a/src/openai/resources/embeddings.py b/src/openai/resources/embeddings.py index 49ce0f2fc8..5bc7ed855e 100644 --- a/src/openai/resources/embeddings.py +++ b/src/openai/resources/embeddings.py @@ -217,6 +217,8 @@ def parser(obj: CreateEmbeddingResponse) -> CreateEmbeddingResponse: class EmbeddingsWithRawResponse: def __init__(self, embeddings: Embeddings) -> None: + self._embeddings = embeddings + self.create = _legacy_response.to_raw_response_wrapper( embeddings.create, ) @@ -224,6 +226,8 @@ def __init__(self, embeddings: Embeddings) -> None: class AsyncEmbeddingsWithRawResponse: def __init__(self, embeddings: AsyncEmbeddings) -> None: + self._embeddings = embeddings + self.create = _legacy_response.async_to_raw_response_wrapper( embeddings.create, ) @@ -231,6 +235,8 @@ def __init__(self, embeddings: AsyncEmbeddings) -> None: class EmbeddingsWithStreamingResponse: def __init__(self, embeddings: Embeddings) -> None: + self._embeddings = embeddings + self.create = to_streamed_response_wrapper( embeddings.create, ) @@ -238,6 +244,8 @@ def __init__(self, embeddings: Embeddings) -> None: class AsyncEmbeddingsWithStreamingResponse: def __init__(self, embeddings: AsyncEmbeddings) -> None: + self._embeddings = embeddings + self.create = async_to_streamed_response_wrapper( embeddings.create, ) diff --git a/src/openai/resources/files.py b/src/openai/resources/files.py index ff924340ac..58a2a217c7 100644 --- a/src/openai/resources/files.py +++ b/src/openai/resources/files.py @@ -580,6 +580,8 @@ async def wait_for_processing( class FilesWithRawResponse: def __init__(self, files: Files) -> None: + self._files = files + self.create = _legacy_response.to_raw_response_wrapper( files.create, ) @@ -604,6 +606,8 @@ def __init__(self, files: Files) -> None: class AsyncFilesWithRawResponse: def __init__(self, files: AsyncFiles) -> None: + self._files = files + self.create = _legacy_response.async_to_raw_response_wrapper( files.create, ) @@ -628,6 +632,8 @@ def __init__(self, files: AsyncFiles) -> None: class FilesWithStreamingResponse: def __init__(self, files: Files) -> None: + self._files = files + self.create = to_streamed_response_wrapper( files.create, ) @@ -653,6 +659,8 @@ def __init__(self, files: Files) -> None: class AsyncFilesWithStreamingResponse: def __init__(self, files: AsyncFiles) -> None: + self._files = files + self.create = async_to_streamed_response_wrapper( files.create, ) diff --git a/src/openai/resources/fine_tuning/fine_tuning.py b/src/openai/resources/fine_tuning/fine_tuning.py index 197d46fb83..33b25baec9 100644 --- a/src/openai/resources/fine_tuning/fine_tuning.py +++ b/src/openai/resources/fine_tuning/fine_tuning.py @@ -46,19 +46,35 @@ def with_streaming_response(self) -> AsyncFineTuningWithStreamingResponse: class FineTuningWithRawResponse: def __init__(self, fine_tuning: FineTuning) -> None: - self.jobs = JobsWithRawResponse(fine_tuning.jobs) + self._fine_tuning = fine_tuning + + @cached_property + def jobs(self) -> JobsWithRawResponse: + return JobsWithRawResponse(self._fine_tuning.jobs) class AsyncFineTuningWithRawResponse: def __init__(self, fine_tuning: AsyncFineTuning) -> None: - self.jobs = AsyncJobsWithRawResponse(fine_tuning.jobs) + self._fine_tuning = fine_tuning + + @cached_property + def jobs(self) -> AsyncJobsWithRawResponse: + return AsyncJobsWithRawResponse(self._fine_tuning.jobs) class FineTuningWithStreamingResponse: def __init__(self, fine_tuning: FineTuning) -> None: - self.jobs = JobsWithStreamingResponse(fine_tuning.jobs) + self._fine_tuning = fine_tuning + + @cached_property + def jobs(self) -> JobsWithStreamingResponse: + return JobsWithStreamingResponse(self._fine_tuning.jobs) class AsyncFineTuningWithStreamingResponse: def __init__(self, fine_tuning: AsyncFineTuning) -> None: - self.jobs = AsyncJobsWithStreamingResponse(fine_tuning.jobs) + self._fine_tuning = fine_tuning + + @cached_property + def jobs(self) -> AsyncJobsWithStreamingResponse: + return AsyncJobsWithStreamingResponse(self._fine_tuning.jobs) diff --git a/src/openai/resources/fine_tuning/jobs.py b/src/openai/resources/fine_tuning/jobs.py index 208591fa47..6b59932982 100644 --- a/src/openai/resources/fine_tuning/jobs.py +++ b/src/openai/resources/fine_tuning/jobs.py @@ -553,6 +553,8 @@ def list_events( class JobsWithRawResponse: def __init__(self, jobs: Jobs) -> None: + self._jobs = jobs + self.create = _legacy_response.to_raw_response_wrapper( jobs.create, ) @@ -572,6 +574,8 @@ def __init__(self, jobs: Jobs) -> None: class AsyncJobsWithRawResponse: def __init__(self, jobs: AsyncJobs) -> None: + self._jobs = jobs + self.create = _legacy_response.async_to_raw_response_wrapper( jobs.create, ) @@ -591,6 +595,8 @@ def __init__(self, jobs: AsyncJobs) -> None: class JobsWithStreamingResponse: def __init__(self, jobs: Jobs) -> None: + self._jobs = jobs + self.create = to_streamed_response_wrapper( jobs.create, ) @@ -610,6 +616,8 @@ def __init__(self, jobs: Jobs) -> None: class AsyncJobsWithStreamingResponse: def __init__(self, jobs: AsyncJobs) -> None: + self._jobs = jobs + self.create = async_to_streamed_response_wrapper( jobs.create, ) diff --git a/src/openai/resources/images.py b/src/openai/resources/images.py index a3eb98574e..91530e47ca 100644 --- a/src/openai/resources/images.py +++ b/src/openai/resources/images.py @@ -518,6 +518,8 @@ async def generate( class ImagesWithRawResponse: def __init__(self, images: Images) -> None: + self._images = images + self.create_variation = _legacy_response.to_raw_response_wrapper( images.create_variation, ) @@ -531,6 +533,8 @@ def __init__(self, images: Images) -> None: class AsyncImagesWithRawResponse: def __init__(self, images: AsyncImages) -> None: + self._images = images + self.create_variation = _legacy_response.async_to_raw_response_wrapper( images.create_variation, ) @@ -544,6 +548,8 @@ def __init__(self, images: AsyncImages) -> None: class ImagesWithStreamingResponse: def __init__(self, images: Images) -> None: + self._images = images + self.create_variation = to_streamed_response_wrapper( images.create_variation, ) @@ -557,6 +563,8 @@ def __init__(self, images: Images) -> None: class AsyncImagesWithStreamingResponse: def __init__(self, images: AsyncImages) -> None: + self._images = images + self.create_variation = async_to_streamed_response_wrapper( images.create_variation, ) diff --git a/src/openai/resources/models.py b/src/openai/resources/models.py index e4a0d84810..3536f083d2 100644 --- a/src/openai/resources/models.py +++ b/src/openai/resources/models.py @@ -225,6 +225,8 @@ async def delete( class ModelsWithRawResponse: def __init__(self, models: Models) -> None: + self._models = models + self.retrieve = _legacy_response.to_raw_response_wrapper( models.retrieve, ) @@ -238,6 +240,8 @@ def __init__(self, models: Models) -> None: class AsyncModelsWithRawResponse: def __init__(self, models: AsyncModels) -> None: + self._models = models + self.retrieve = _legacy_response.async_to_raw_response_wrapper( models.retrieve, ) @@ -251,6 +255,8 @@ def __init__(self, models: AsyncModels) -> None: class ModelsWithStreamingResponse: def __init__(self, models: Models) -> None: + self._models = models + self.retrieve = to_streamed_response_wrapper( models.retrieve, ) @@ -264,6 +270,8 @@ def __init__(self, models: Models) -> None: class AsyncModelsWithStreamingResponse: def __init__(self, models: AsyncModels) -> None: + self._models = models + self.retrieve = async_to_streamed_response_wrapper( models.retrieve, ) diff --git a/src/openai/resources/moderations.py b/src/openai/resources/moderations.py index e7681f6263..540d089071 100644 --- a/src/openai/resources/moderations.py +++ b/src/openai/resources/moderations.py @@ -143,6 +143,8 @@ async def create( class ModerationsWithRawResponse: def __init__(self, moderations: Moderations) -> None: + self._moderations = moderations + self.create = _legacy_response.to_raw_response_wrapper( moderations.create, ) @@ -150,6 +152,8 @@ def __init__(self, moderations: Moderations) -> None: class AsyncModerationsWithRawResponse: def __init__(self, moderations: AsyncModerations) -> None: + self._moderations = moderations + self.create = _legacy_response.async_to_raw_response_wrapper( moderations.create, ) @@ -157,6 +161,8 @@ def __init__(self, moderations: AsyncModerations) -> None: class ModerationsWithStreamingResponse: def __init__(self, moderations: Moderations) -> None: + self._moderations = moderations + self.create = to_streamed_response_wrapper( moderations.create, ) @@ -164,6 +170,8 @@ def __init__(self, moderations: Moderations) -> None: class AsyncModerationsWithStreamingResponse: def __init__(self, moderations: AsyncModerations) -> None: + self._moderations = moderations + self.create = async_to_streamed_response_wrapper( moderations.create, ) diff --git a/src/openai/types/beta/threads/run.py b/src/openai/types/beta/threads/run.py index b6d66bd8dd..db4bc0e07d 100644 --- a/src/openai/types/beta/threads/run.py +++ b/src/openai/types/beta/threads/run.py @@ -17,6 +17,7 @@ "ToolAssistantToolsCode", "ToolAssistantToolsRetrieval", "ToolAssistantToolsFunction", + "Usage", ] @@ -61,6 +62,17 @@ class ToolAssistantToolsFunction(BaseModel): Tool = Union[ToolAssistantToolsCode, ToolAssistantToolsRetrieval, ToolAssistantToolsFunction] +class Usage(BaseModel): + completion_tokens: int + """Number of completion tokens used over the course of the run.""" + + prompt_tokens: int + """Number of prompt tokens used over the course of the run.""" + + total_tokens: int + """Total number of tokens used (prompt + completion).""" + + class Run(BaseModel): id: str """The identifier, which can be referenced in API endpoints.""" @@ -152,3 +164,10 @@ class Run(BaseModel): [assistant](https://platform.openai.com/docs/api-reference/assistants) used for this run. """ + + usage: Optional[Usage] = None + """Usage statistics related to the run. + + This value will be `null` if the run is not in a terminal state (i.e. + `in_progress`, `queued`, etc.). + """ diff --git a/src/openai/types/beta/threads/runs/run_step.py b/src/openai/types/beta/threads/runs/run_step.py index 1d95e9d6eb..5f3e29a312 100644 --- a/src/openai/types/beta/threads/runs/run_step.py +++ b/src/openai/types/beta/threads/runs/run_step.py @@ -8,7 +8,7 @@ from .tool_calls_step_details import ToolCallsStepDetails from .message_creation_step_details import MessageCreationStepDetails -__all__ = ["RunStep", "LastError", "StepDetails"] +__all__ = ["RunStep", "LastError", "StepDetails", "Usage"] class LastError(BaseModel): @@ -22,6 +22,17 @@ class LastError(BaseModel): StepDetails = Union[MessageCreationStepDetails, ToolCallsStepDetails] +class Usage(BaseModel): + completion_tokens: int + """Number of completion tokens used over the course of the run step.""" + + prompt_tokens: int + """Number of prompt tokens used over the course of the run step.""" + + total_tokens: int + """Total number of tokens used (prompt + completion).""" + + class RunStep(BaseModel): id: str """The identifier of the run step, which can be referenced in API endpoints.""" @@ -91,3 +102,9 @@ class RunStep(BaseModel): type: Literal["message_creation", "tool_calls"] """The type of run step, which can be either `message_creation` or `tool_calls`.""" + + usage: Optional[Usage] = None + """Usage statistics related to the run step. + + This value will be `null` while the run step's status is `in_progress`. + """ diff --git a/tests/api_resources/audio/test_speech.py b/tests/api_resources/audio/test_speech.py index a689c0d220..b1c7f79b1e 100644 --- a/tests/api_resources/audio/test_speech.py +++ b/tests/api_resources/audio/test_speech.py @@ -12,18 +12,14 @@ import openai._legacy_response as _legacy_response from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI # pyright: reportDeprecated=false base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestSpeech: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize @pytest.mark.respx(base_url=base_url) @@ -86,15 +82,13 @@ def test_streaming_response_create(self, client: OpenAI, respx_mock: MockRouter) class TestAsyncSpeech: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize @pytest.mark.respx(base_url=base_url) - async def test_method_create(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + async def test_method_create(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None: respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) - speech = await client.audio.speech.create( + speech = await async_client.audio.speech.create( input="string", model="string", voice="alloy", @@ -104,9 +98,9 @@ async def test_method_create(self, client: AsyncOpenAI, respx_mock: MockRouter) @parametrize @pytest.mark.respx(base_url=base_url) - async def test_method_create_with_all_params(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None: respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) - speech = await client.audio.speech.create( + speech = await async_client.audio.speech.create( input="string", model="string", voice="alloy", @@ -118,10 +112,10 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI, respx_mo @parametrize @pytest.mark.respx(base_url=base_url) - async def test_raw_response_create(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + async def test_raw_response_create(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None: respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) - response = await client.audio.speech.with_raw_response.create( + response = await async_client.audio.speech.with_raw_response.create( input="string", model="string", voice="alloy", @@ -134,9 +128,9 @@ async def test_raw_response_create(self, client: AsyncOpenAI, respx_mock: MockRo @parametrize @pytest.mark.respx(base_url=base_url) - async def test_streaming_response_create(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + async def test_streaming_response_create(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None: respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) - async with client.audio.speech.with_streaming_response.create( + async with async_client.audio.speech.with_streaming_response.create( input="string", model="string", voice="alloy", diff --git a/tests/api_resources/audio/test_transcriptions.py b/tests/api_resources/audio/test_transcriptions.py index 992adbabd9..d957871abc 100644 --- a/tests/api_resources/audio/test_transcriptions.py +++ b/tests/api_resources/audio/test_transcriptions.py @@ -9,17 +9,13 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.types.audio import Transcription base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestTranscriptions: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -69,21 +65,19 @@ def test_streaming_response_create(self, client: OpenAI) -> None: class TestAsyncTranscriptions: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - transcription = await client.audio.transcriptions.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + transcription = await async_client.audio.transcriptions.create( file=b"raw file contents", model="whisper-1", ) assert_matches_type(Transcription, transcription, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: - transcription = await client.audio.transcriptions.create( + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None: + transcription = await async_client.audio.transcriptions.create( file=b"raw file contents", model="whisper-1", language="string", @@ -94,8 +88,8 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(Transcription, transcription, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.audio.transcriptions.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.audio.transcriptions.with_raw_response.create( file=b"raw file contents", model="whisper-1", ) @@ -106,8 +100,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(Transcription, transcription, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.audio.transcriptions.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.audio.transcriptions.with_streaming_response.create( file=b"raw file contents", model="whisper-1", ) as response: diff --git a/tests/api_resources/audio/test_translations.py b/tests/api_resources/audio/test_translations.py index 913c443a79..72960c3249 100644 --- a/tests/api_resources/audio/test_translations.py +++ b/tests/api_resources/audio/test_translations.py @@ -9,17 +9,13 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.types.audio import Translation base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestTranslations: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -68,21 +64,19 @@ def test_streaming_response_create(self, client: OpenAI) -> None: class TestAsyncTranslations: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - translation = await client.audio.translations.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + translation = await async_client.audio.translations.create( file=b"raw file contents", model="whisper-1", ) assert_matches_type(Translation, translation, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: - translation = await client.audio.translations.create( + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None: + translation = await async_client.audio.translations.create( file=b"raw file contents", model="whisper-1", prompt="string", @@ -92,8 +86,8 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(Translation, translation, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.audio.translations.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.audio.translations.with_raw_response.create( file=b"raw file contents", model="whisper-1", ) @@ -104,8 +98,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(Translation, translation, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.audio.translations.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.audio.translations.with_streaming_response.create( file=b"raw file contents", model="whisper-1", ) as response: diff --git a/tests/api_resources/beta/assistants/test_files.py b/tests/api_resources/beta/assistants/test_files.py index 7db1368ccb..66e3e2efe6 100644 --- a/tests/api_resources/beta/assistants/test_files.py +++ b/tests/api_resources/beta/assistants/test_files.py @@ -9,18 +9,14 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.pagination import SyncCursorPage, AsyncCursorPage from openai.types.beta.assistants import AssistantFile, FileDeleteResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestFiles: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -211,21 +207,19 @@ def test_path_params_delete(self, client: OpenAI) -> None: class TestAsyncFiles: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - file = await client.beta.assistants.files.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + file = await async_client.beta.assistants.files.create( "file-abc123", file_id="string", ) assert_matches_type(AssistantFile, file, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.beta.assistants.files.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.assistants.files.with_raw_response.create( "file-abc123", file_id="string", ) @@ -236,8 +230,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(AssistantFile, file, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.beta.assistants.files.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.assistants.files.with_streaming_response.create( "file-abc123", file_id="string", ) as response: @@ -250,24 +244,24 @@ async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_create(self, client: AsyncOpenAI) -> None: + async def test_path_params_create(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `assistant_id` but received ''"): - await client.beta.assistants.files.with_raw_response.create( + await async_client.beta.assistants.files.with_raw_response.create( "", file_id="string", ) @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - file = await client.beta.assistants.files.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + file = await async_client.beta.assistants.files.retrieve( "string", assistant_id="string", ) assert_matches_type(AssistantFile, file, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.beta.assistants.files.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.assistants.files.with_raw_response.retrieve( "string", assistant_id="string", ) @@ -278,8 +272,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(AssistantFile, file, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.beta.assistants.files.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.assistants.files.with_streaming_response.retrieve( "string", assistant_id="string", ) as response: @@ -292,29 +286,29 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `assistant_id` but received ''"): - await client.beta.assistants.files.with_raw_response.retrieve( + await async_client.beta.assistants.files.with_raw_response.retrieve( "string", assistant_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): - await client.beta.assistants.files.with_raw_response.retrieve( + await async_client.beta.assistants.files.with_raw_response.retrieve( "", assistant_id="string", ) @parametrize - async def test_method_list(self, client: AsyncOpenAI) -> None: - file = await client.beta.assistants.files.list( + async def test_method_list(self, async_client: AsyncOpenAI) -> None: + file = await async_client.beta.assistants.files.list( "string", ) assert_matches_type(AsyncCursorPage[AssistantFile], file, path=["response"]) @parametrize - async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: - file = await client.beta.assistants.files.list( + async def test_method_list_with_all_params(self, async_client: AsyncOpenAI) -> None: + file = await async_client.beta.assistants.files.list( "string", after="string", before="string", @@ -324,8 +318,8 @@ async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[AssistantFile], file, path=["response"]) @parametrize - async def test_raw_response_list(self, client: AsyncOpenAI) -> None: - response = await client.beta.assistants.files.with_raw_response.list( + async def test_raw_response_list(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.assistants.files.with_raw_response.list( "string", ) @@ -335,8 +329,8 @@ async def test_raw_response_list(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[AssistantFile], file, path=["response"]) @parametrize - async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: - async with client.beta.assistants.files.with_streaming_response.list( + async def test_streaming_response_list(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.assistants.files.with_streaming_response.list( "string", ) as response: assert not response.is_closed @@ -348,23 +342,23 @@ async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_list(self, client: AsyncOpenAI) -> None: + async def test_path_params_list(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `assistant_id` but received ''"): - await client.beta.assistants.files.with_raw_response.list( + await async_client.beta.assistants.files.with_raw_response.list( "", ) @parametrize - async def test_method_delete(self, client: AsyncOpenAI) -> None: - file = await client.beta.assistants.files.delete( + async def test_method_delete(self, async_client: AsyncOpenAI) -> None: + file = await async_client.beta.assistants.files.delete( "string", assistant_id="string", ) assert_matches_type(FileDeleteResponse, file, path=["response"]) @parametrize - async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: - response = await client.beta.assistants.files.with_raw_response.delete( + async def test_raw_response_delete(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.assistants.files.with_raw_response.delete( "string", assistant_id="string", ) @@ -375,8 +369,8 @@ async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: assert_matches_type(FileDeleteResponse, file, path=["response"]) @parametrize - async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: - async with client.beta.assistants.files.with_streaming_response.delete( + async def test_streaming_response_delete(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.assistants.files.with_streaming_response.delete( "string", assistant_id="string", ) as response: @@ -389,15 +383,15 @@ async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_delete(self, client: AsyncOpenAI) -> None: + async def test_path_params_delete(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `assistant_id` but received ''"): - await client.beta.assistants.files.with_raw_response.delete( + await async_client.beta.assistants.files.with_raw_response.delete( "string", assistant_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): - await client.beta.assistants.files.with_raw_response.delete( + await async_client.beta.assistants.files.with_raw_response.delete( "", assistant_id="string", ) diff --git a/tests/api_resources/beta/test_assistants.py b/tests/api_resources/beta/test_assistants.py index fa09769622..8db40bde93 100644 --- a/tests/api_resources/beta/test_assistants.py +++ b/tests/api_resources/beta/test_assistants.py @@ -9,7 +9,6 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.pagination import SyncCursorPage, AsyncCursorPage from openai.types.beta import ( Assistant, @@ -17,13 +16,10 @@ ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestAssistants: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -234,20 +230,18 @@ def test_path_params_delete(self, client: OpenAI) -> None: class TestAsyncAssistants: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - assistant = await client.beta.assistants.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + assistant = await async_client.beta.assistants.create( model="string", ) assert_matches_type(Assistant, assistant, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: - assistant = await client.beta.assistants.create( + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None: + assistant = await async_client.beta.assistants.create( model="string", description="string", file_ids=["string", "string", "string"], @@ -259,8 +253,8 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(Assistant, assistant, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.beta.assistants.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.assistants.with_raw_response.create( model="string", ) @@ -270,8 +264,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(Assistant, assistant, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.beta.assistants.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.assistants.with_streaming_response.create( model="string", ) as response: assert not response.is_closed @@ -283,15 +277,15 @@ async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - assistant = await client.beta.assistants.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + assistant = await async_client.beta.assistants.retrieve( "string", ) assert_matches_type(Assistant, assistant, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.beta.assistants.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.assistants.with_raw_response.retrieve( "string", ) @@ -301,8 +295,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(Assistant, assistant, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.beta.assistants.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.assistants.with_streaming_response.retrieve( "string", ) as response: assert not response.is_closed @@ -314,22 +308,22 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `assistant_id` but received ''"): - await client.beta.assistants.with_raw_response.retrieve( + await async_client.beta.assistants.with_raw_response.retrieve( "", ) @parametrize - async def test_method_update(self, client: AsyncOpenAI) -> None: - assistant = await client.beta.assistants.update( + async def test_method_update(self, async_client: AsyncOpenAI) -> None: + assistant = await async_client.beta.assistants.update( "string", ) assert_matches_type(Assistant, assistant, path=["response"]) @parametrize - async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: - assistant = await client.beta.assistants.update( + async def test_method_update_with_all_params(self, async_client: AsyncOpenAI) -> None: + assistant = await async_client.beta.assistants.update( "string", description="string", file_ids=["string", "string", "string"], @@ -342,8 +336,8 @@ async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(Assistant, assistant, path=["response"]) @parametrize - async def test_raw_response_update(self, client: AsyncOpenAI) -> None: - response = await client.beta.assistants.with_raw_response.update( + async def test_raw_response_update(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.assistants.with_raw_response.update( "string", ) @@ -353,8 +347,8 @@ async def test_raw_response_update(self, client: AsyncOpenAI) -> None: assert_matches_type(Assistant, assistant, path=["response"]) @parametrize - async def test_streaming_response_update(self, client: AsyncOpenAI) -> None: - async with client.beta.assistants.with_streaming_response.update( + async def test_streaming_response_update(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.assistants.with_streaming_response.update( "string", ) as response: assert not response.is_closed @@ -366,20 +360,20 @@ async def test_streaming_response_update(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_update(self, client: AsyncOpenAI) -> None: + async def test_path_params_update(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `assistant_id` but received ''"): - await client.beta.assistants.with_raw_response.update( + await async_client.beta.assistants.with_raw_response.update( "", ) @parametrize - async def test_method_list(self, client: AsyncOpenAI) -> None: - assistant = await client.beta.assistants.list() + async def test_method_list(self, async_client: AsyncOpenAI) -> None: + assistant = await async_client.beta.assistants.list() assert_matches_type(AsyncCursorPage[Assistant], assistant, path=["response"]) @parametrize - async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: - assistant = await client.beta.assistants.list( + async def test_method_list_with_all_params(self, async_client: AsyncOpenAI) -> None: + assistant = await async_client.beta.assistants.list( after="string", before="string", limit=0, @@ -388,8 +382,8 @@ async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[Assistant], assistant, path=["response"]) @parametrize - async def test_raw_response_list(self, client: AsyncOpenAI) -> None: - response = await client.beta.assistants.with_raw_response.list() + async def test_raw_response_list(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.assistants.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -397,8 +391,8 @@ async def test_raw_response_list(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[Assistant], assistant, path=["response"]) @parametrize - async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: - async with client.beta.assistants.with_streaming_response.list() as response: + async def test_streaming_response_list(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.assistants.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -408,15 +402,15 @@ async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_method_delete(self, client: AsyncOpenAI) -> None: - assistant = await client.beta.assistants.delete( + async def test_method_delete(self, async_client: AsyncOpenAI) -> None: + assistant = await async_client.beta.assistants.delete( "string", ) assert_matches_type(AssistantDeleted, assistant, path=["response"]) @parametrize - async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: - response = await client.beta.assistants.with_raw_response.delete( + async def test_raw_response_delete(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.assistants.with_raw_response.delete( "string", ) @@ -426,8 +420,8 @@ async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: assert_matches_type(AssistantDeleted, assistant, path=["response"]) @parametrize - async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: - async with client.beta.assistants.with_streaming_response.delete( + async def test_streaming_response_delete(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.assistants.with_streaming_response.delete( "string", ) as response: assert not response.is_closed @@ -439,8 +433,8 @@ async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_delete(self, client: AsyncOpenAI) -> None: + async def test_path_params_delete(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `assistant_id` but received ''"): - await client.beta.assistants.with_raw_response.delete( + await async_client.beta.assistants.with_raw_response.delete( "", ) diff --git a/tests/api_resources/beta/test_threads.py b/tests/api_resources/beta/test_threads.py index ba55cc85da..5b347de1f0 100644 --- a/tests/api_resources/beta/test_threads.py +++ b/tests/api_resources/beta/test_threads.py @@ -9,7 +9,6 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.types.beta import ( Thread, ThreadDeleted, @@ -17,13 +16,10 @@ from openai.types.beta.threads import Run base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestThreads: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -266,18 +262,16 @@ def test_streaming_response_create_and_run(self, client: OpenAI) -> None: class TestAsyncThreads: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - thread = await client.beta.threads.create() + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + thread = await async_client.beta.threads.create() assert_matches_type(Thread, thread, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: - thread = await client.beta.threads.create( + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None: + thread = await async_client.beta.threads.create( messages=[ { "role": "user", @@ -303,8 +297,8 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(Thread, thread, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.with_raw_response.create() + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.with_raw_response.create() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -312,8 +306,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(Thread, thread, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.with_streaming_response.create() as response: + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.with_streaming_response.create() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -323,15 +317,15 @@ async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - thread = await client.beta.threads.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + thread = await async_client.beta.threads.retrieve( "string", ) assert_matches_type(Thread, thread, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.with_raw_response.retrieve( "string", ) @@ -341,8 +335,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(Thread, thread, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.with_streaming_response.retrieve( "string", ) as response: assert not response.is_closed @@ -354,30 +348,30 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.with_raw_response.retrieve( + await async_client.beta.threads.with_raw_response.retrieve( "", ) @parametrize - async def test_method_update(self, client: AsyncOpenAI) -> None: - thread = await client.beta.threads.update( + async def test_method_update(self, async_client: AsyncOpenAI) -> None: + thread = await async_client.beta.threads.update( "string", ) assert_matches_type(Thread, thread, path=["response"]) @parametrize - async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: - thread = await client.beta.threads.update( + async def test_method_update_with_all_params(self, async_client: AsyncOpenAI) -> None: + thread = await async_client.beta.threads.update( "string", metadata={}, ) assert_matches_type(Thread, thread, path=["response"]) @parametrize - async def test_raw_response_update(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.with_raw_response.update( + async def test_raw_response_update(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.with_raw_response.update( "string", ) @@ -387,8 +381,8 @@ async def test_raw_response_update(self, client: AsyncOpenAI) -> None: assert_matches_type(Thread, thread, path=["response"]) @parametrize - async def test_streaming_response_update(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.with_streaming_response.update( + async def test_streaming_response_update(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.with_streaming_response.update( "string", ) as response: assert not response.is_closed @@ -400,22 +394,22 @@ async def test_streaming_response_update(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_update(self, client: AsyncOpenAI) -> None: + async def test_path_params_update(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.with_raw_response.update( + await async_client.beta.threads.with_raw_response.update( "", ) @parametrize - async def test_method_delete(self, client: AsyncOpenAI) -> None: - thread = await client.beta.threads.delete( + async def test_method_delete(self, async_client: AsyncOpenAI) -> None: + thread = await async_client.beta.threads.delete( "string", ) assert_matches_type(ThreadDeleted, thread, path=["response"]) @parametrize - async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.with_raw_response.delete( + async def test_raw_response_delete(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.with_raw_response.delete( "string", ) @@ -425,8 +419,8 @@ async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: assert_matches_type(ThreadDeleted, thread, path=["response"]) @parametrize - async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.with_streaming_response.delete( + async def test_streaming_response_delete(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.with_streaming_response.delete( "string", ) as response: assert not response.is_closed @@ -438,22 +432,22 @@ async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_delete(self, client: AsyncOpenAI) -> None: + async def test_path_params_delete(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.with_raw_response.delete( + await async_client.beta.threads.with_raw_response.delete( "", ) @parametrize - async def test_method_create_and_run(self, client: AsyncOpenAI) -> None: - thread = await client.beta.threads.create_and_run( + async def test_method_create_and_run(self, async_client: AsyncOpenAI) -> None: + thread = await async_client.beta.threads.create_and_run( assistant_id="string", ) assert_matches_type(Run, thread, path=["response"]) @parametrize - async def test_method_create_and_run_with_all_params(self, client: AsyncOpenAI) -> None: - thread = await client.beta.threads.create_and_run( + async def test_method_create_and_run_with_all_params(self, async_client: AsyncOpenAI) -> None: + thread = await async_client.beta.threads.create_and_run( assistant_id="string", instructions="string", metadata={}, @@ -486,8 +480,8 @@ async def test_method_create_and_run_with_all_params(self, client: AsyncOpenAI) assert_matches_type(Run, thread, path=["response"]) @parametrize - async def test_raw_response_create_and_run(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.with_raw_response.create_and_run( + async def test_raw_response_create_and_run(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.with_raw_response.create_and_run( assistant_id="string", ) @@ -497,8 +491,8 @@ async def test_raw_response_create_and_run(self, client: AsyncOpenAI) -> None: assert_matches_type(Run, thread, path=["response"]) @parametrize - async def test_streaming_response_create_and_run(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.with_streaming_response.create_and_run( + async def test_streaming_response_create_and_run(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.with_streaming_response.create_and_run( assistant_id="string", ) as response: assert not response.is_closed diff --git a/tests/api_resources/beta/threads/messages/test_files.py b/tests/api_resources/beta/threads/messages/test_files.py index 2d248642e9..4d0613fd2f 100644 --- a/tests/api_resources/beta/threads/messages/test_files.py +++ b/tests/api_resources/beta/threads/messages/test_files.py @@ -9,18 +9,14 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.pagination import SyncCursorPage, AsyncCursorPage from openai.types.beta.threads.messages import MessageFile base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestFiles: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_retrieve(self, client: OpenAI) -> None: @@ -144,13 +140,11 @@ def test_path_params_list(self, client: OpenAI) -> None: class TestAsyncFiles: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - file = await client.beta.threads.messages.files.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + file = await async_client.beta.threads.messages.files.retrieve( "file-abc123", thread_id="thread_abc123", message_id="msg_abc123", @@ -158,8 +152,8 @@ async def test_method_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(MessageFile, file, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.messages.files.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.messages.files.with_raw_response.retrieve( "file-abc123", thread_id="thread_abc123", message_id="msg_abc123", @@ -171,8 +165,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(MessageFile, file, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.messages.files.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.messages.files.with_streaming_response.retrieve( "file-abc123", thread_id="thread_abc123", message_id="msg_abc123", @@ -186,39 +180,39 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.messages.files.with_raw_response.retrieve( + await async_client.beta.threads.messages.files.with_raw_response.retrieve( "file-abc123", thread_id="", message_id="msg_abc123", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"): - await client.beta.threads.messages.files.with_raw_response.retrieve( + await async_client.beta.threads.messages.files.with_raw_response.retrieve( "file-abc123", thread_id="thread_abc123", message_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): - await client.beta.threads.messages.files.with_raw_response.retrieve( + await async_client.beta.threads.messages.files.with_raw_response.retrieve( "", thread_id="thread_abc123", message_id="msg_abc123", ) @parametrize - async def test_method_list(self, client: AsyncOpenAI) -> None: - file = await client.beta.threads.messages.files.list( + async def test_method_list(self, async_client: AsyncOpenAI) -> None: + file = await async_client.beta.threads.messages.files.list( "string", thread_id="string", ) assert_matches_type(AsyncCursorPage[MessageFile], file, path=["response"]) @parametrize - async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: - file = await client.beta.threads.messages.files.list( + async def test_method_list_with_all_params(self, async_client: AsyncOpenAI) -> None: + file = await async_client.beta.threads.messages.files.list( "string", thread_id="string", after="string", @@ -229,8 +223,8 @@ async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[MessageFile], file, path=["response"]) @parametrize - async def test_raw_response_list(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.messages.files.with_raw_response.list( + async def test_raw_response_list(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.messages.files.with_raw_response.list( "string", thread_id="string", ) @@ -241,8 +235,8 @@ async def test_raw_response_list(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[MessageFile], file, path=["response"]) @parametrize - async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.messages.files.with_streaming_response.list( + async def test_streaming_response_list(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.messages.files.with_streaming_response.list( "string", thread_id="string", ) as response: @@ -255,15 +249,15 @@ async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_list(self, client: AsyncOpenAI) -> None: + async def test_path_params_list(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.messages.files.with_raw_response.list( + await async_client.beta.threads.messages.files.with_raw_response.list( "string", thread_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"): - await client.beta.threads.messages.files.with_raw_response.list( + await async_client.beta.threads.messages.files.with_raw_response.list( "", thread_id="string", ) diff --git a/tests/api_resources/beta/threads/runs/test_steps.py b/tests/api_resources/beta/threads/runs/test_steps.py index 2ec164a535..c15848cd70 100644 --- a/tests/api_resources/beta/threads/runs/test_steps.py +++ b/tests/api_resources/beta/threads/runs/test_steps.py @@ -9,18 +9,14 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.pagination import SyncCursorPage, AsyncCursorPage from openai.types.beta.threads.runs import RunStep base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestSteps: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_retrieve(self, client: OpenAI) -> None: @@ -144,13 +140,11 @@ def test_path_params_list(self, client: OpenAI) -> None: class TestAsyncSteps: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - step = await client.beta.threads.runs.steps.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + step = await async_client.beta.threads.runs.steps.retrieve( "string", thread_id="string", run_id="string", @@ -158,8 +152,8 @@ async def test_method_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(RunStep, step, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.runs.steps.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.runs.steps.with_raw_response.retrieve( "string", thread_id="string", run_id="string", @@ -171,8 +165,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(RunStep, step, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.runs.steps.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.runs.steps.with_streaming_response.retrieve( "string", thread_id="string", run_id="string", @@ -186,39 +180,39 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.runs.steps.with_raw_response.retrieve( + await async_client.beta.threads.runs.steps.with_raw_response.retrieve( "string", thread_id="", run_id="string", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `run_id` but received ''"): - await client.beta.threads.runs.steps.with_raw_response.retrieve( + await async_client.beta.threads.runs.steps.with_raw_response.retrieve( "string", thread_id="string", run_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `step_id` but received ''"): - await client.beta.threads.runs.steps.with_raw_response.retrieve( + await async_client.beta.threads.runs.steps.with_raw_response.retrieve( "", thread_id="string", run_id="string", ) @parametrize - async def test_method_list(self, client: AsyncOpenAI) -> None: - step = await client.beta.threads.runs.steps.list( + async def test_method_list(self, async_client: AsyncOpenAI) -> None: + step = await async_client.beta.threads.runs.steps.list( "string", thread_id="string", ) assert_matches_type(AsyncCursorPage[RunStep], step, path=["response"]) @parametrize - async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: - step = await client.beta.threads.runs.steps.list( + async def test_method_list_with_all_params(self, async_client: AsyncOpenAI) -> None: + step = await async_client.beta.threads.runs.steps.list( "string", thread_id="string", after="string", @@ -229,8 +223,8 @@ async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[RunStep], step, path=["response"]) @parametrize - async def test_raw_response_list(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.runs.steps.with_raw_response.list( + async def test_raw_response_list(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.runs.steps.with_raw_response.list( "string", thread_id="string", ) @@ -241,8 +235,8 @@ async def test_raw_response_list(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[RunStep], step, path=["response"]) @parametrize - async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.runs.steps.with_streaming_response.list( + async def test_streaming_response_list(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.runs.steps.with_streaming_response.list( "string", thread_id="string", ) as response: @@ -255,15 +249,15 @@ async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_list(self, client: AsyncOpenAI) -> None: + async def test_path_params_list(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.runs.steps.with_raw_response.list( + await async_client.beta.threads.runs.steps.with_raw_response.list( "string", thread_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `run_id` but received ''"): - await client.beta.threads.runs.steps.with_raw_response.list( + await async_client.beta.threads.runs.steps.with_raw_response.list( "", thread_id="string", ) diff --git a/tests/api_resources/beta/threads/test_messages.py b/tests/api_resources/beta/threads/test_messages.py index 508e9b96c9..538d2f4c2a 100644 --- a/tests/api_resources/beta/threads/test_messages.py +++ b/tests/api_resources/beta/threads/test_messages.py @@ -9,18 +9,14 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.pagination import SyncCursorPage, AsyncCursorPage from openai.types.beta.threads import ThreadMessage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestMessages: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -235,13 +231,11 @@ def test_path_params_list(self, client: OpenAI) -> None: class TestAsyncMessages: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - message = await client.beta.threads.messages.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + message = await async_client.beta.threads.messages.create( "string", content="x", role="user", @@ -249,8 +243,8 @@ async def test_method_create(self, client: AsyncOpenAI) -> None: assert_matches_type(ThreadMessage, message, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: - message = await client.beta.threads.messages.create( + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None: + message = await async_client.beta.threads.messages.create( "string", content="x", role="user", @@ -260,8 +254,8 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(ThreadMessage, message, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.messages.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.messages.with_raw_response.create( "string", content="x", role="user", @@ -273,8 +267,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(ThreadMessage, message, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.messages.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.messages.with_streaming_response.create( "string", content="x", role="user", @@ -288,25 +282,25 @@ async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_create(self, client: AsyncOpenAI) -> None: + async def test_path_params_create(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.messages.with_raw_response.create( + await async_client.beta.threads.messages.with_raw_response.create( "", content="x", role="user", ) @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - message = await client.beta.threads.messages.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + message = await async_client.beta.threads.messages.retrieve( "string", thread_id="string", ) assert_matches_type(ThreadMessage, message, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.messages.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.messages.with_raw_response.retrieve( "string", thread_id="string", ) @@ -317,8 +311,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(ThreadMessage, message, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.messages.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.messages.with_streaming_response.retrieve( "string", thread_id="string", ) as response: @@ -331,30 +325,30 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.messages.with_raw_response.retrieve( + await async_client.beta.threads.messages.with_raw_response.retrieve( "string", thread_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"): - await client.beta.threads.messages.with_raw_response.retrieve( + await async_client.beta.threads.messages.with_raw_response.retrieve( "", thread_id="string", ) @parametrize - async def test_method_update(self, client: AsyncOpenAI) -> None: - message = await client.beta.threads.messages.update( + async def test_method_update(self, async_client: AsyncOpenAI) -> None: + message = await async_client.beta.threads.messages.update( "string", thread_id="string", ) assert_matches_type(ThreadMessage, message, path=["response"]) @parametrize - async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: - message = await client.beta.threads.messages.update( + async def test_method_update_with_all_params(self, async_client: AsyncOpenAI) -> None: + message = await async_client.beta.threads.messages.update( "string", thread_id="string", metadata={}, @@ -362,8 +356,8 @@ async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(ThreadMessage, message, path=["response"]) @parametrize - async def test_raw_response_update(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.messages.with_raw_response.update( + async def test_raw_response_update(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.messages.with_raw_response.update( "string", thread_id="string", ) @@ -374,8 +368,8 @@ async def test_raw_response_update(self, client: AsyncOpenAI) -> None: assert_matches_type(ThreadMessage, message, path=["response"]) @parametrize - async def test_streaming_response_update(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.messages.with_streaming_response.update( + async def test_streaming_response_update(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.messages.with_streaming_response.update( "string", thread_id="string", ) as response: @@ -388,29 +382,29 @@ async def test_streaming_response_update(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_update(self, client: AsyncOpenAI) -> None: + async def test_path_params_update(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.messages.with_raw_response.update( + await async_client.beta.threads.messages.with_raw_response.update( "string", thread_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"): - await client.beta.threads.messages.with_raw_response.update( + await async_client.beta.threads.messages.with_raw_response.update( "", thread_id="string", ) @parametrize - async def test_method_list(self, client: AsyncOpenAI) -> None: - message = await client.beta.threads.messages.list( + async def test_method_list(self, async_client: AsyncOpenAI) -> None: + message = await async_client.beta.threads.messages.list( "string", ) assert_matches_type(AsyncCursorPage[ThreadMessage], message, path=["response"]) @parametrize - async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: - message = await client.beta.threads.messages.list( + async def test_method_list_with_all_params(self, async_client: AsyncOpenAI) -> None: + message = await async_client.beta.threads.messages.list( "string", after="string", before="string", @@ -420,8 +414,8 @@ async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[ThreadMessage], message, path=["response"]) @parametrize - async def test_raw_response_list(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.messages.with_raw_response.list( + async def test_raw_response_list(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.messages.with_raw_response.list( "string", ) @@ -431,8 +425,8 @@ async def test_raw_response_list(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[ThreadMessage], message, path=["response"]) @parametrize - async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.messages.with_streaming_response.list( + async def test_streaming_response_list(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.messages.with_streaming_response.list( "string", ) as response: assert not response.is_closed @@ -444,8 +438,8 @@ async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_list(self, client: AsyncOpenAI) -> None: + async def test_path_params_list(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.messages.with_raw_response.list( + await async_client.beta.threads.messages.with_raw_response.list( "", ) diff --git a/tests/api_resources/beta/threads/test_runs.py b/tests/api_resources/beta/threads/test_runs.py index 66a9edd5c0..9e88d65eaf 100644 --- a/tests/api_resources/beta/threads/test_runs.py +++ b/tests/api_resources/beta/threads/test_runs.py @@ -9,20 +9,16 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.pagination import SyncCursorPage, AsyncCursorPage from openai.types.beta.threads import ( Run, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestRuns: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -336,21 +332,19 @@ def test_path_params_submit_tool_outputs(self, client: OpenAI) -> None: class TestAsyncRuns: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - run = await client.beta.threads.runs.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + run = await async_client.beta.threads.runs.create( "string", assistant_id="string", ) assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: - run = await client.beta.threads.runs.create( + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None: + run = await async_client.beta.threads.runs.create( "string", assistant_id="string", additional_instructions="string", @@ -362,8 +356,8 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.runs.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.runs.with_raw_response.create( "string", assistant_id="string", ) @@ -374,8 +368,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.runs.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.runs.with_streaming_response.create( "string", assistant_id="string", ) as response: @@ -388,24 +382,24 @@ async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_create(self, client: AsyncOpenAI) -> None: + async def test_path_params_create(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.runs.with_raw_response.create( + await async_client.beta.threads.runs.with_raw_response.create( "", assistant_id="string", ) @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - run = await client.beta.threads.runs.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + run = await async_client.beta.threads.runs.retrieve( "string", thread_id="string", ) assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.runs.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.runs.with_raw_response.retrieve( "string", thread_id="string", ) @@ -416,8 +410,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.runs.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.runs.with_streaming_response.retrieve( "string", thread_id="string", ) as response: @@ -430,30 +424,30 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.runs.with_raw_response.retrieve( + await async_client.beta.threads.runs.with_raw_response.retrieve( "string", thread_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `run_id` but received ''"): - await client.beta.threads.runs.with_raw_response.retrieve( + await async_client.beta.threads.runs.with_raw_response.retrieve( "", thread_id="string", ) @parametrize - async def test_method_update(self, client: AsyncOpenAI) -> None: - run = await client.beta.threads.runs.update( + async def test_method_update(self, async_client: AsyncOpenAI) -> None: + run = await async_client.beta.threads.runs.update( "string", thread_id="string", ) assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: - run = await client.beta.threads.runs.update( + async def test_method_update_with_all_params(self, async_client: AsyncOpenAI) -> None: + run = await async_client.beta.threads.runs.update( "string", thread_id="string", metadata={}, @@ -461,8 +455,8 @@ async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_raw_response_update(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.runs.with_raw_response.update( + async def test_raw_response_update(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.runs.with_raw_response.update( "string", thread_id="string", ) @@ -473,8 +467,8 @@ async def test_raw_response_update(self, client: AsyncOpenAI) -> None: assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_streaming_response_update(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.runs.with_streaming_response.update( + async def test_streaming_response_update(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.runs.with_streaming_response.update( "string", thread_id="string", ) as response: @@ -487,29 +481,29 @@ async def test_streaming_response_update(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_update(self, client: AsyncOpenAI) -> None: + async def test_path_params_update(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.runs.with_raw_response.update( + await async_client.beta.threads.runs.with_raw_response.update( "string", thread_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `run_id` but received ''"): - await client.beta.threads.runs.with_raw_response.update( + await async_client.beta.threads.runs.with_raw_response.update( "", thread_id="string", ) @parametrize - async def test_method_list(self, client: AsyncOpenAI) -> None: - run = await client.beta.threads.runs.list( + async def test_method_list(self, async_client: AsyncOpenAI) -> None: + run = await async_client.beta.threads.runs.list( "string", ) assert_matches_type(AsyncCursorPage[Run], run, path=["response"]) @parametrize - async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: - run = await client.beta.threads.runs.list( + async def test_method_list_with_all_params(self, async_client: AsyncOpenAI) -> None: + run = await async_client.beta.threads.runs.list( "string", after="string", before="string", @@ -519,8 +513,8 @@ async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[Run], run, path=["response"]) @parametrize - async def test_raw_response_list(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.runs.with_raw_response.list( + async def test_raw_response_list(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.runs.with_raw_response.list( "string", ) @@ -530,8 +524,8 @@ async def test_raw_response_list(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[Run], run, path=["response"]) @parametrize - async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.runs.with_streaming_response.list( + async def test_streaming_response_list(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.runs.with_streaming_response.list( "string", ) as response: assert not response.is_closed @@ -543,23 +537,23 @@ async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_list(self, client: AsyncOpenAI) -> None: + async def test_path_params_list(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.runs.with_raw_response.list( + await async_client.beta.threads.runs.with_raw_response.list( "", ) @parametrize - async def test_method_cancel(self, client: AsyncOpenAI) -> None: - run = await client.beta.threads.runs.cancel( + async def test_method_cancel(self, async_client: AsyncOpenAI) -> None: + run = await async_client.beta.threads.runs.cancel( "string", thread_id="string", ) assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_raw_response_cancel(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.runs.with_raw_response.cancel( + async def test_raw_response_cancel(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.runs.with_raw_response.cancel( "string", thread_id="string", ) @@ -570,8 +564,8 @@ async def test_raw_response_cancel(self, client: AsyncOpenAI) -> None: assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_streaming_response_cancel(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.runs.with_streaming_response.cancel( + async def test_streaming_response_cancel(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.runs.with_streaming_response.cancel( "string", thread_id="string", ) as response: @@ -584,22 +578,22 @@ async def test_streaming_response_cancel(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_cancel(self, client: AsyncOpenAI) -> None: + async def test_path_params_cancel(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.runs.with_raw_response.cancel( + await async_client.beta.threads.runs.with_raw_response.cancel( "string", thread_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `run_id` but received ''"): - await client.beta.threads.runs.with_raw_response.cancel( + await async_client.beta.threads.runs.with_raw_response.cancel( "", thread_id="string", ) @parametrize - async def test_method_submit_tool_outputs(self, client: AsyncOpenAI) -> None: - run = await client.beta.threads.runs.submit_tool_outputs( + async def test_method_submit_tool_outputs(self, async_client: AsyncOpenAI) -> None: + run = await async_client.beta.threads.runs.submit_tool_outputs( "string", thread_id="string", tool_outputs=[{}, {}, {}], @@ -607,8 +601,8 @@ async def test_method_submit_tool_outputs(self, client: AsyncOpenAI) -> None: assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_raw_response_submit_tool_outputs(self, client: AsyncOpenAI) -> None: - response = await client.beta.threads.runs.with_raw_response.submit_tool_outputs( + async def test_raw_response_submit_tool_outputs(self, async_client: AsyncOpenAI) -> None: + response = await async_client.beta.threads.runs.with_raw_response.submit_tool_outputs( "string", thread_id="string", tool_outputs=[{}, {}, {}], @@ -620,8 +614,8 @@ async def test_raw_response_submit_tool_outputs(self, client: AsyncOpenAI) -> No assert_matches_type(Run, run, path=["response"]) @parametrize - async def test_streaming_response_submit_tool_outputs(self, client: AsyncOpenAI) -> None: - async with client.beta.threads.runs.with_streaming_response.submit_tool_outputs( + async def test_streaming_response_submit_tool_outputs(self, async_client: AsyncOpenAI) -> None: + async with async_client.beta.threads.runs.with_streaming_response.submit_tool_outputs( "string", thread_id="string", tool_outputs=[{}, {}, {}], @@ -635,16 +629,16 @@ async def test_streaming_response_submit_tool_outputs(self, client: AsyncOpenAI) assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_submit_tool_outputs(self, client: AsyncOpenAI) -> None: + async def test_path_params_submit_tool_outputs(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `thread_id` but received ''"): - await client.beta.threads.runs.with_raw_response.submit_tool_outputs( + await async_client.beta.threads.runs.with_raw_response.submit_tool_outputs( "string", thread_id="", tool_outputs=[{}, {}, {}], ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `run_id` but received ''"): - await client.beta.threads.runs.with_raw_response.submit_tool_outputs( + await async_client.beta.threads.runs.with_raw_response.submit_tool_outputs( "", thread_id="string", tool_outputs=[{}, {}, {}], diff --git a/tests/api_resources/chat/test_completions.py b/tests/api_resources/chat/test_completions.py index 860ec80f48..4fa069ba2e 100644 --- a/tests/api_resources/chat/test_completions.py +++ b/tests/api_resources/chat/test_completions.py @@ -9,17 +9,13 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.types.chat import ChatCompletion base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestCompletions: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create_overload_1(self, client: OpenAI) -> None: @@ -249,13 +245,11 @@ def test_streaming_response_create_overload_2(self, client: OpenAI) -> None: class TestAsyncCompletions: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create_overload_1(self, client: AsyncOpenAI) -> None: - completion = await client.chat.completions.create( + async def test_method_create_overload_1(self, async_client: AsyncOpenAI) -> None: + completion = await async_client.chat.completions.create( messages=[ { "content": "string", @@ -267,8 +261,8 @@ async def test_method_create_overload_1(self, client: AsyncOpenAI) -> None: assert_matches_type(ChatCompletion, completion, path=["response"]) @parametrize - async def test_method_create_with_all_params_overload_1(self, client: AsyncOpenAI) -> None: - completion = await client.chat.completions.create( + async def test_method_create_with_all_params_overload_1(self, async_client: AsyncOpenAI) -> None: + completion = await async_client.chat.completions.create( messages=[ { "content": "string", @@ -330,8 +324,8 @@ async def test_method_create_with_all_params_overload_1(self, client: AsyncOpenA assert_matches_type(ChatCompletion, completion, path=["response"]) @parametrize - async def test_raw_response_create_overload_1(self, client: AsyncOpenAI) -> None: - response = await client.chat.completions.with_raw_response.create( + async def test_raw_response_create_overload_1(self, async_client: AsyncOpenAI) -> None: + response = await async_client.chat.completions.with_raw_response.create( messages=[ { "content": "string", @@ -347,8 +341,8 @@ async def test_raw_response_create_overload_1(self, client: AsyncOpenAI) -> None assert_matches_type(ChatCompletion, completion, path=["response"]) @parametrize - async def test_streaming_response_create_overload_1(self, client: AsyncOpenAI) -> None: - async with client.chat.completions.with_streaming_response.create( + async def test_streaming_response_create_overload_1(self, async_client: AsyncOpenAI) -> None: + async with async_client.chat.completions.with_streaming_response.create( messages=[ { "content": "string", @@ -366,8 +360,8 @@ async def test_streaming_response_create_overload_1(self, client: AsyncOpenAI) - assert cast(Any, response.is_closed) is True @parametrize - async def test_method_create_overload_2(self, client: AsyncOpenAI) -> None: - completion_stream = await client.chat.completions.create( + async def test_method_create_overload_2(self, async_client: AsyncOpenAI) -> None: + completion_stream = await async_client.chat.completions.create( messages=[ { "content": "string", @@ -380,8 +374,8 @@ async def test_method_create_overload_2(self, client: AsyncOpenAI) -> None: await completion_stream.response.aclose() @parametrize - async def test_method_create_with_all_params_overload_2(self, client: AsyncOpenAI) -> None: - completion_stream = await client.chat.completions.create( + async def test_method_create_with_all_params_overload_2(self, async_client: AsyncOpenAI) -> None: + completion_stream = await async_client.chat.completions.create( messages=[ { "content": "string", @@ -443,8 +437,8 @@ async def test_method_create_with_all_params_overload_2(self, client: AsyncOpenA await completion_stream.response.aclose() @parametrize - async def test_raw_response_create_overload_2(self, client: AsyncOpenAI) -> None: - response = await client.chat.completions.with_raw_response.create( + async def test_raw_response_create_overload_2(self, async_client: AsyncOpenAI) -> None: + response = await async_client.chat.completions.with_raw_response.create( messages=[ { "content": "string", @@ -460,8 +454,8 @@ async def test_raw_response_create_overload_2(self, client: AsyncOpenAI) -> None await stream.close() @parametrize - async def test_streaming_response_create_overload_2(self, client: AsyncOpenAI) -> None: - async with client.chat.completions.with_streaming_response.create( + async def test_streaming_response_create_overload_2(self, async_client: AsyncOpenAI) -> None: + async with async_client.chat.completions.with_streaming_response.create( messages=[ { "content": "string", diff --git a/tests/api_resources/fine_tuning/test_jobs.py b/tests/api_resources/fine_tuning/test_jobs.py index 50c7278855..204cc3b1f5 100644 --- a/tests/api_resources/fine_tuning/test_jobs.py +++ b/tests/api_resources/fine_tuning/test_jobs.py @@ -9,7 +9,6 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type -from openai._client import OpenAI, AsyncOpenAI from openai.pagination import SyncCursorPage, AsyncCursorPage from openai.types.fine_tuning import ( FineTuningJob, @@ -17,13 +16,10 @@ ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestJobs: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -232,21 +228,19 @@ def test_path_params_list_events(self, client: OpenAI) -> None: class TestAsyncJobs: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - job = await client.fine_tuning.jobs.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + job = await async_client.fine_tuning.jobs.create( model="gpt-3.5-turbo", training_file="file-abc123", ) assert_matches_type(FineTuningJob, job, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: - job = await client.fine_tuning.jobs.create( + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None: + job = await async_client.fine_tuning.jobs.create( model="gpt-3.5-turbo", training_file="file-abc123", hyperparameters={ @@ -260,8 +254,8 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(FineTuningJob, job, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.fine_tuning.jobs.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.fine_tuning.jobs.with_raw_response.create( model="gpt-3.5-turbo", training_file="file-abc123", ) @@ -272,8 +266,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(FineTuningJob, job, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.fine_tuning.jobs.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.fine_tuning.jobs.with_streaming_response.create( model="gpt-3.5-turbo", training_file="file-abc123", ) as response: @@ -286,15 +280,15 @@ async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - job = await client.fine_tuning.jobs.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + job = await async_client.fine_tuning.jobs.retrieve( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", ) assert_matches_type(FineTuningJob, job, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.fine_tuning.jobs.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.fine_tuning.jobs.with_raw_response.retrieve( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", ) @@ -304,8 +298,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(FineTuningJob, job, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.fine_tuning.jobs.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.fine_tuning.jobs.with_streaming_response.retrieve( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", ) as response: assert not response.is_closed @@ -317,28 +311,28 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `fine_tuning_job_id` but received ''"): - await client.fine_tuning.jobs.with_raw_response.retrieve( + await async_client.fine_tuning.jobs.with_raw_response.retrieve( "", ) @parametrize - async def test_method_list(self, client: AsyncOpenAI) -> None: - job = await client.fine_tuning.jobs.list() + async def test_method_list(self, async_client: AsyncOpenAI) -> None: + job = await async_client.fine_tuning.jobs.list() assert_matches_type(AsyncCursorPage[FineTuningJob], job, path=["response"]) @parametrize - async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: - job = await client.fine_tuning.jobs.list( + async def test_method_list_with_all_params(self, async_client: AsyncOpenAI) -> None: + job = await async_client.fine_tuning.jobs.list( after="string", limit=0, ) assert_matches_type(AsyncCursorPage[FineTuningJob], job, path=["response"]) @parametrize - async def test_raw_response_list(self, client: AsyncOpenAI) -> None: - response = await client.fine_tuning.jobs.with_raw_response.list() + async def test_raw_response_list(self, async_client: AsyncOpenAI) -> None: + response = await async_client.fine_tuning.jobs.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -346,8 +340,8 @@ async def test_raw_response_list(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[FineTuningJob], job, path=["response"]) @parametrize - async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: - async with client.fine_tuning.jobs.with_streaming_response.list() as response: + async def test_streaming_response_list(self, async_client: AsyncOpenAI) -> None: + async with async_client.fine_tuning.jobs.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -357,15 +351,15 @@ async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_method_cancel(self, client: AsyncOpenAI) -> None: - job = await client.fine_tuning.jobs.cancel( + async def test_method_cancel(self, async_client: AsyncOpenAI) -> None: + job = await async_client.fine_tuning.jobs.cancel( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", ) assert_matches_type(FineTuningJob, job, path=["response"]) @parametrize - async def test_raw_response_cancel(self, client: AsyncOpenAI) -> None: - response = await client.fine_tuning.jobs.with_raw_response.cancel( + async def test_raw_response_cancel(self, async_client: AsyncOpenAI) -> None: + response = await async_client.fine_tuning.jobs.with_raw_response.cancel( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", ) @@ -375,8 +369,8 @@ async def test_raw_response_cancel(self, client: AsyncOpenAI) -> None: assert_matches_type(FineTuningJob, job, path=["response"]) @parametrize - async def test_streaming_response_cancel(self, client: AsyncOpenAI) -> None: - async with client.fine_tuning.jobs.with_streaming_response.cancel( + async def test_streaming_response_cancel(self, async_client: AsyncOpenAI) -> None: + async with async_client.fine_tuning.jobs.with_streaming_response.cancel( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", ) as response: assert not response.is_closed @@ -388,22 +382,22 @@ async def test_streaming_response_cancel(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_cancel(self, client: AsyncOpenAI) -> None: + async def test_path_params_cancel(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `fine_tuning_job_id` but received ''"): - await client.fine_tuning.jobs.with_raw_response.cancel( + await async_client.fine_tuning.jobs.with_raw_response.cancel( "", ) @parametrize - async def test_method_list_events(self, client: AsyncOpenAI) -> None: - job = await client.fine_tuning.jobs.list_events( + async def test_method_list_events(self, async_client: AsyncOpenAI) -> None: + job = await async_client.fine_tuning.jobs.list_events( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", ) assert_matches_type(AsyncCursorPage[FineTuningJobEvent], job, path=["response"]) @parametrize - async def test_method_list_events_with_all_params(self, client: AsyncOpenAI) -> None: - job = await client.fine_tuning.jobs.list_events( + async def test_method_list_events_with_all_params(self, async_client: AsyncOpenAI) -> None: + job = await async_client.fine_tuning.jobs.list_events( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", after="string", limit=0, @@ -411,8 +405,8 @@ async def test_method_list_events_with_all_params(self, client: AsyncOpenAI) -> assert_matches_type(AsyncCursorPage[FineTuningJobEvent], job, path=["response"]) @parametrize - async def test_raw_response_list_events(self, client: AsyncOpenAI) -> None: - response = await client.fine_tuning.jobs.with_raw_response.list_events( + async def test_raw_response_list_events(self, async_client: AsyncOpenAI) -> None: + response = await async_client.fine_tuning.jobs.with_raw_response.list_events( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", ) @@ -422,8 +416,8 @@ async def test_raw_response_list_events(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncCursorPage[FineTuningJobEvent], job, path=["response"]) @parametrize - async def test_streaming_response_list_events(self, client: AsyncOpenAI) -> None: - async with client.fine_tuning.jobs.with_streaming_response.list_events( + async def test_streaming_response_list_events(self, async_client: AsyncOpenAI) -> None: + async with async_client.fine_tuning.jobs.with_streaming_response.list_events( "ft-AF1WoRqd3aJAHsqc9NY7iL8F", ) as response: assert not response.is_closed @@ -435,8 +429,8 @@ async def test_streaming_response_list_events(self, client: AsyncOpenAI) -> None assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_list_events(self, client: AsyncOpenAI) -> None: + async def test_path_params_list_events(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `fine_tuning_job_id` but received ''"): - await client.fine_tuning.jobs.with_raw_response.list_events( + await async_client.fine_tuning.jobs.with_raw_response.list_events( "", ) diff --git a/tests/api_resources/test_completions.py b/tests/api_resources/test_completions.py index a5e8dc809a..916cdd3cb6 100644 --- a/tests/api_resources/test_completions.py +++ b/tests/api_resources/test_completions.py @@ -10,16 +10,12 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type from openai.types import Completion -from openai._client import OpenAI, AsyncOpenAI base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestCompletions: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create_overload_1(self, client: OpenAI) -> None: @@ -139,21 +135,19 @@ def test_streaming_response_create_overload_2(self, client: OpenAI) -> None: class TestAsyncCompletions: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create_overload_1(self, client: AsyncOpenAI) -> None: - completion = await client.completions.create( + async def test_method_create_overload_1(self, async_client: AsyncOpenAI) -> None: + completion = await async_client.completions.create( model="string", prompt="This is a test.", ) assert_matches_type(Completion, completion, path=["response"]) @parametrize - async def test_method_create_with_all_params_overload_1(self, client: AsyncOpenAI) -> None: - completion = await client.completions.create( + async def test_method_create_with_all_params_overload_1(self, async_client: AsyncOpenAI) -> None: + completion = await async_client.completions.create( model="string", prompt="This is a test.", best_of=0, @@ -175,8 +169,8 @@ async def test_method_create_with_all_params_overload_1(self, client: AsyncOpenA assert_matches_type(Completion, completion, path=["response"]) @parametrize - async def test_raw_response_create_overload_1(self, client: AsyncOpenAI) -> None: - response = await client.completions.with_raw_response.create( + async def test_raw_response_create_overload_1(self, async_client: AsyncOpenAI) -> None: + response = await async_client.completions.with_raw_response.create( model="string", prompt="This is a test.", ) @@ -187,8 +181,8 @@ async def test_raw_response_create_overload_1(self, client: AsyncOpenAI) -> None assert_matches_type(Completion, completion, path=["response"]) @parametrize - async def test_streaming_response_create_overload_1(self, client: AsyncOpenAI) -> None: - async with client.completions.with_streaming_response.create( + async def test_streaming_response_create_overload_1(self, async_client: AsyncOpenAI) -> None: + async with async_client.completions.with_streaming_response.create( model="string", prompt="This is a test.", ) as response: @@ -201,8 +195,8 @@ async def test_streaming_response_create_overload_1(self, client: AsyncOpenAI) - assert cast(Any, response.is_closed) is True @parametrize - async def test_method_create_overload_2(self, client: AsyncOpenAI) -> None: - completion_stream = await client.completions.create( + async def test_method_create_overload_2(self, async_client: AsyncOpenAI) -> None: + completion_stream = await async_client.completions.create( model="string", prompt="This is a test.", stream=True, @@ -210,8 +204,8 @@ async def test_method_create_overload_2(self, client: AsyncOpenAI) -> None: await completion_stream.response.aclose() @parametrize - async def test_method_create_with_all_params_overload_2(self, client: AsyncOpenAI) -> None: - completion_stream = await client.completions.create( + async def test_method_create_with_all_params_overload_2(self, async_client: AsyncOpenAI) -> None: + completion_stream = await async_client.completions.create( model="string", prompt="This is a test.", stream=True, @@ -233,8 +227,8 @@ async def test_method_create_with_all_params_overload_2(self, client: AsyncOpenA await completion_stream.response.aclose() @parametrize - async def test_raw_response_create_overload_2(self, client: AsyncOpenAI) -> None: - response = await client.completions.with_raw_response.create( + async def test_raw_response_create_overload_2(self, async_client: AsyncOpenAI) -> None: + response = await async_client.completions.with_raw_response.create( model="string", prompt="This is a test.", stream=True, @@ -245,8 +239,8 @@ async def test_raw_response_create_overload_2(self, client: AsyncOpenAI) -> None await stream.close() @parametrize - async def test_streaming_response_create_overload_2(self, client: AsyncOpenAI) -> None: - async with client.completions.with_streaming_response.create( + async def test_streaming_response_create_overload_2(self, async_client: AsyncOpenAI) -> None: + async with async_client.completions.with_streaming_response.create( model="string", prompt="This is a test.", stream=True, diff --git a/tests/api_resources/test_embeddings.py b/tests/api_resources/test_embeddings.py index 77875fc46f..cd4ff8e391 100644 --- a/tests/api_resources/test_embeddings.py +++ b/tests/api_resources/test_embeddings.py @@ -10,16 +10,12 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type from openai.types import CreateEmbeddingResponse -from openai._client import OpenAI, AsyncOpenAI base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestEmbeddings: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -67,21 +63,19 @@ def test_streaming_response_create(self, client: OpenAI) -> None: class TestAsyncEmbeddings: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - embedding = await client.embeddings.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + embedding = await async_client.embeddings.create( input="The quick brown fox jumped over the lazy dog", model="text-embedding-ada-002", ) assert_matches_type(CreateEmbeddingResponse, embedding, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: - embedding = await client.embeddings.create( + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None: + embedding = await async_client.embeddings.create( input="The quick brown fox jumped over the lazy dog", model="text-embedding-ada-002", encoding_format="float", @@ -90,8 +84,8 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(CreateEmbeddingResponse, embedding, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.embeddings.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.embeddings.with_raw_response.create( input="The quick brown fox jumped over the lazy dog", model="text-embedding-ada-002", ) @@ -102,8 +96,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(CreateEmbeddingResponse, embedding, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.embeddings.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.embeddings.with_streaming_response.create( input="The quick brown fox jumped over the lazy dog", model="text-embedding-ada-002", ) as response: diff --git a/tests/api_resources/test_files.py b/tests/api_resources/test_files.py index 89ad9e222f..d1a17923a6 100644 --- a/tests/api_resources/test_files.py +++ b/tests/api_resources/test_files.py @@ -13,19 +13,15 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type from openai.types import FileObject, FileDeleted -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" class TestFiles: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -261,21 +257,19 @@ def test_path_params_retrieve_content(self, client: OpenAI) -> None: class TestAsyncFiles: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - file = await client.files.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + file = await async_client.files.create( file=b"raw file contents", purpose="fine-tune", ) assert_matches_type(FileObject, file, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.files.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.files.with_raw_response.create( file=b"raw file contents", purpose="fine-tune", ) @@ -286,8 +280,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(FileObject, file, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.files.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.files.with_streaming_response.create( file=b"raw file contents", purpose="fine-tune", ) as response: @@ -300,15 +294,15 @@ async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - file = await client.files.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + file = await async_client.files.retrieve( "string", ) assert_matches_type(FileObject, file, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.files.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.files.with_raw_response.retrieve( "string", ) @@ -318,8 +312,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(FileObject, file, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.files.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.files.with_streaming_response.retrieve( "string", ) as response: assert not response.is_closed @@ -331,27 +325,27 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): - await client.files.with_raw_response.retrieve( + await async_client.files.with_raw_response.retrieve( "", ) @parametrize - async def test_method_list(self, client: AsyncOpenAI) -> None: - file = await client.files.list() + async def test_method_list(self, async_client: AsyncOpenAI) -> None: + file = await async_client.files.list() assert_matches_type(AsyncPage[FileObject], file, path=["response"]) @parametrize - async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: - file = await client.files.list( + async def test_method_list_with_all_params(self, async_client: AsyncOpenAI) -> None: + file = await async_client.files.list( purpose="string", ) assert_matches_type(AsyncPage[FileObject], file, path=["response"]) @parametrize - async def test_raw_response_list(self, client: AsyncOpenAI) -> None: - response = await client.files.with_raw_response.list() + async def test_raw_response_list(self, async_client: AsyncOpenAI) -> None: + response = await async_client.files.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -359,8 +353,8 @@ async def test_raw_response_list(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncPage[FileObject], file, path=["response"]) @parametrize - async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: - async with client.files.with_streaming_response.list() as response: + async def test_streaming_response_list(self, async_client: AsyncOpenAI) -> None: + async with async_client.files.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -370,15 +364,15 @@ async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_method_delete(self, client: AsyncOpenAI) -> None: - file = await client.files.delete( + async def test_method_delete(self, async_client: AsyncOpenAI) -> None: + file = await async_client.files.delete( "string", ) assert_matches_type(FileDeleted, file, path=["response"]) @parametrize - async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: - response = await client.files.with_raw_response.delete( + async def test_raw_response_delete(self, async_client: AsyncOpenAI) -> None: + response = await async_client.files.with_raw_response.delete( "string", ) @@ -388,8 +382,8 @@ async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: assert_matches_type(FileDeleted, file, path=["response"]) @parametrize - async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: - async with client.files.with_streaming_response.delete( + async def test_streaming_response_delete(self, async_client: AsyncOpenAI) -> None: + async with async_client.files.with_streaming_response.delete( "string", ) as response: assert not response.is_closed @@ -401,17 +395,17 @@ async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_delete(self, client: AsyncOpenAI) -> None: + async def test_path_params_delete(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): - await client.files.with_raw_response.delete( + await async_client.files.with_raw_response.delete( "", ) @parametrize @pytest.mark.respx(base_url=base_url) - async def test_method_content(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + async def test_method_content(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None: respx_mock.get("/files/string/content").mock(return_value=httpx.Response(200, json={"foo": "bar"})) - file = await client.files.content( + file = await async_client.files.content( "string", ) assert isinstance(file, _legacy_response.HttpxBinaryResponseContent) @@ -419,10 +413,10 @@ async def test_method_content(self, client: AsyncOpenAI, respx_mock: MockRouter) @parametrize @pytest.mark.respx(base_url=base_url) - async def test_raw_response_content(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + async def test_raw_response_content(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None: respx_mock.get("/files/string/content").mock(return_value=httpx.Response(200, json={"foo": "bar"})) - response = await client.files.with_raw_response.content( + response = await async_client.files.with_raw_response.content( "string", ) @@ -433,9 +427,9 @@ async def test_raw_response_content(self, client: AsyncOpenAI, respx_mock: MockR @parametrize @pytest.mark.respx(base_url=base_url) - async def test_streaming_response_content(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + async def test_streaming_response_content(self, async_client: AsyncOpenAI, respx_mock: MockRouter) -> None: respx_mock.get("/files/string/content").mock(return_value=httpx.Response(200, json={"foo": "bar"})) - async with client.files.with_streaming_response.content( + async with async_client.files.with_streaming_response.content( "string", ) as response: assert not response.is_closed @@ -448,25 +442,25 @@ async def test_streaming_response_content(self, client: AsyncOpenAI, respx_mock: @parametrize @pytest.mark.respx(base_url=base_url) - async def test_path_params_content(self, client: AsyncOpenAI) -> None: + async def test_path_params_content(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): - await client.files.with_raw_response.content( + await async_client.files.with_raw_response.content( "", ) @parametrize - async def test_method_retrieve_content(self, client: AsyncOpenAI) -> None: + async def test_method_retrieve_content(self, async_client: AsyncOpenAI) -> None: with pytest.warns(DeprecationWarning): - file = await client.files.retrieve_content( + file = await async_client.files.retrieve_content( "string", ) assert_matches_type(str, file, path=["response"]) @parametrize - async def test_raw_response_retrieve_content(self, client: AsyncOpenAI) -> None: + async def test_raw_response_retrieve_content(self, async_client: AsyncOpenAI) -> None: with pytest.warns(DeprecationWarning): - response = await client.files.with_raw_response.retrieve_content( + response = await async_client.files.with_raw_response.retrieve_content( "string", ) @@ -476,9 +470,9 @@ async def test_raw_response_retrieve_content(self, client: AsyncOpenAI) -> None: assert_matches_type(str, file, path=["response"]) @parametrize - async def test_streaming_response_retrieve_content(self, client: AsyncOpenAI) -> None: + async def test_streaming_response_retrieve_content(self, async_client: AsyncOpenAI) -> None: with pytest.warns(DeprecationWarning): - async with client.files.with_streaming_response.retrieve_content( + async with async_client.files.with_streaming_response.retrieve_content( "string", ) as response: assert not response.is_closed @@ -490,9 +484,9 @@ async def test_streaming_response_retrieve_content(self, client: AsyncOpenAI) -> assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve_content(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve_content(self, async_client: AsyncOpenAI) -> None: with pytest.warns(DeprecationWarning): with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"): - await client.files.with_raw_response.retrieve_content( + await async_client.files.with_raw_response.retrieve_content( "", ) diff --git a/tests/api_resources/test_images.py b/tests/api_resources/test_images.py index 553bd018ee..b6cb2572ab 100644 --- a/tests/api_resources/test_images.py +++ b/tests/api_resources/test_images.py @@ -10,16 +10,12 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type from openai.types import ImagesResponse -from openai._client import OpenAI, AsyncOpenAI base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestImages: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create_variation(self, client: OpenAI) -> None: @@ -159,20 +155,18 @@ def test_streaming_response_generate(self, client: OpenAI) -> None: class TestAsyncImages: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create_variation(self, client: AsyncOpenAI) -> None: - image = await client.images.create_variation( + async def test_method_create_variation(self, async_client: AsyncOpenAI) -> None: + image = await async_client.images.create_variation( image=b"raw file contents", ) assert_matches_type(ImagesResponse, image, path=["response"]) @parametrize - async def test_method_create_variation_with_all_params(self, client: AsyncOpenAI) -> None: - image = await client.images.create_variation( + async def test_method_create_variation_with_all_params(self, async_client: AsyncOpenAI) -> None: + image = await async_client.images.create_variation( image=b"raw file contents", model="dall-e-2", n=1, @@ -183,8 +177,8 @@ async def test_method_create_variation_with_all_params(self, client: AsyncOpenAI assert_matches_type(ImagesResponse, image, path=["response"]) @parametrize - async def test_raw_response_create_variation(self, client: AsyncOpenAI) -> None: - response = await client.images.with_raw_response.create_variation( + async def test_raw_response_create_variation(self, async_client: AsyncOpenAI) -> None: + response = await async_client.images.with_raw_response.create_variation( image=b"raw file contents", ) @@ -194,8 +188,8 @@ async def test_raw_response_create_variation(self, client: AsyncOpenAI) -> None: assert_matches_type(ImagesResponse, image, path=["response"]) @parametrize - async def test_streaming_response_create_variation(self, client: AsyncOpenAI) -> None: - async with client.images.with_streaming_response.create_variation( + async def test_streaming_response_create_variation(self, async_client: AsyncOpenAI) -> None: + async with async_client.images.with_streaming_response.create_variation( image=b"raw file contents", ) as response: assert not response.is_closed @@ -207,16 +201,16 @@ async def test_streaming_response_create_variation(self, client: AsyncOpenAI) -> assert cast(Any, response.is_closed) is True @parametrize - async def test_method_edit(self, client: AsyncOpenAI) -> None: - image = await client.images.edit( + async def test_method_edit(self, async_client: AsyncOpenAI) -> None: + image = await async_client.images.edit( image=b"raw file contents", prompt="A cute baby sea otter wearing a beret", ) assert_matches_type(ImagesResponse, image, path=["response"]) @parametrize - async def test_method_edit_with_all_params(self, client: AsyncOpenAI) -> None: - image = await client.images.edit( + async def test_method_edit_with_all_params(self, async_client: AsyncOpenAI) -> None: + image = await async_client.images.edit( image=b"raw file contents", prompt="A cute baby sea otter wearing a beret", mask=b"raw file contents", @@ -229,8 +223,8 @@ async def test_method_edit_with_all_params(self, client: AsyncOpenAI) -> None: assert_matches_type(ImagesResponse, image, path=["response"]) @parametrize - async def test_raw_response_edit(self, client: AsyncOpenAI) -> None: - response = await client.images.with_raw_response.edit( + async def test_raw_response_edit(self, async_client: AsyncOpenAI) -> None: + response = await async_client.images.with_raw_response.edit( image=b"raw file contents", prompt="A cute baby sea otter wearing a beret", ) @@ -241,8 +235,8 @@ async def test_raw_response_edit(self, client: AsyncOpenAI) -> None: assert_matches_type(ImagesResponse, image, path=["response"]) @parametrize - async def test_streaming_response_edit(self, client: AsyncOpenAI) -> None: - async with client.images.with_streaming_response.edit( + async def test_streaming_response_edit(self, async_client: AsyncOpenAI) -> None: + async with async_client.images.with_streaming_response.edit( image=b"raw file contents", prompt="A cute baby sea otter wearing a beret", ) as response: @@ -255,15 +249,15 @@ async def test_streaming_response_edit(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_method_generate(self, client: AsyncOpenAI) -> None: - image = await client.images.generate( + async def test_method_generate(self, async_client: AsyncOpenAI) -> None: + image = await async_client.images.generate( prompt="A cute baby sea otter", ) assert_matches_type(ImagesResponse, image, path=["response"]) @parametrize - async def test_method_generate_with_all_params(self, client: AsyncOpenAI) -> None: - image = await client.images.generate( + async def test_method_generate_with_all_params(self, async_client: AsyncOpenAI) -> None: + image = await async_client.images.generate( prompt="A cute baby sea otter", model="dall-e-3", n=1, @@ -276,8 +270,8 @@ async def test_method_generate_with_all_params(self, client: AsyncOpenAI) -> Non assert_matches_type(ImagesResponse, image, path=["response"]) @parametrize - async def test_raw_response_generate(self, client: AsyncOpenAI) -> None: - response = await client.images.with_raw_response.generate( + async def test_raw_response_generate(self, async_client: AsyncOpenAI) -> None: + response = await async_client.images.with_raw_response.generate( prompt="A cute baby sea otter", ) @@ -287,8 +281,8 @@ async def test_raw_response_generate(self, client: AsyncOpenAI) -> None: assert_matches_type(ImagesResponse, image, path=["response"]) @parametrize - async def test_streaming_response_generate(self, client: AsyncOpenAI) -> None: - async with client.images.with_streaming_response.generate( + async def test_streaming_response_generate(self, async_client: AsyncOpenAI) -> None: + async with async_client.images.with_streaming_response.generate( prompt="A cute baby sea otter", ) as response: assert not response.is_closed diff --git a/tests/api_resources/test_models.py b/tests/api_resources/test_models.py index b41e50eb71..d031d54f6a 100644 --- a/tests/api_resources/test_models.py +++ b/tests/api_resources/test_models.py @@ -10,17 +10,13 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type from openai.types import Model, ModelDeleted -from openai._client import OpenAI, AsyncOpenAI from openai.pagination import SyncPage, AsyncPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestModels: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_retrieve(self, client: OpenAI) -> None: @@ -125,20 +121,18 @@ def test_path_params_delete(self, client: OpenAI) -> None: class TestAsyncModels: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_retrieve(self, client: AsyncOpenAI) -> None: - model = await client.models.retrieve( + async def test_method_retrieve(self, async_client: AsyncOpenAI) -> None: + model = await async_client.models.retrieve( "gpt-3.5-turbo", ) assert_matches_type(Model, model, path=["response"]) @parametrize - async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: - response = await client.models.with_raw_response.retrieve( + async def test_raw_response_retrieve(self, async_client: AsyncOpenAI) -> None: + response = await async_client.models.with_raw_response.retrieve( "gpt-3.5-turbo", ) @@ -148,8 +142,8 @@ async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: assert_matches_type(Model, model, path=["response"]) @parametrize - async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: - async with client.models.with_streaming_response.retrieve( + async def test_streaming_response_retrieve(self, async_client: AsyncOpenAI) -> None: + async with async_client.models.with_streaming_response.retrieve( "gpt-3.5-turbo", ) as response: assert not response.is_closed @@ -161,20 +155,20 @@ async def test_streaming_response_retrieve(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_retrieve(self, client: AsyncOpenAI) -> None: + async def test_path_params_retrieve(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `model` but received ''"): - await client.models.with_raw_response.retrieve( + await async_client.models.with_raw_response.retrieve( "", ) @parametrize - async def test_method_list(self, client: AsyncOpenAI) -> None: - model = await client.models.list() + async def test_method_list(self, async_client: AsyncOpenAI) -> None: + model = await async_client.models.list() assert_matches_type(AsyncPage[Model], model, path=["response"]) @parametrize - async def test_raw_response_list(self, client: AsyncOpenAI) -> None: - response = await client.models.with_raw_response.list() + async def test_raw_response_list(self, async_client: AsyncOpenAI) -> None: + response = await async_client.models.with_raw_response.list() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -182,8 +176,8 @@ async def test_raw_response_list(self, client: AsyncOpenAI) -> None: assert_matches_type(AsyncPage[Model], model, path=["response"]) @parametrize - async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: - async with client.models.with_streaming_response.list() as response: + async def test_streaming_response_list(self, async_client: AsyncOpenAI) -> None: + async with async_client.models.with_streaming_response.list() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -193,15 +187,15 @@ async def test_streaming_response_list(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_method_delete(self, client: AsyncOpenAI) -> None: - model = await client.models.delete( + async def test_method_delete(self, async_client: AsyncOpenAI) -> None: + model = await async_client.models.delete( "ft:gpt-3.5-turbo:acemeco:suffix:abc123", ) assert_matches_type(ModelDeleted, model, path=["response"]) @parametrize - async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: - response = await client.models.with_raw_response.delete( + async def test_raw_response_delete(self, async_client: AsyncOpenAI) -> None: + response = await async_client.models.with_raw_response.delete( "ft:gpt-3.5-turbo:acemeco:suffix:abc123", ) @@ -211,8 +205,8 @@ async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: assert_matches_type(ModelDeleted, model, path=["response"]) @parametrize - async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: - async with client.models.with_streaming_response.delete( + async def test_streaming_response_delete(self, async_client: AsyncOpenAI) -> None: + async with async_client.models.with_streaming_response.delete( "ft:gpt-3.5-turbo:acemeco:suffix:abc123", ) as response: assert not response.is_closed @@ -224,8 +218,8 @@ async def test_streaming_response_delete(self, client: AsyncOpenAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_delete(self, client: AsyncOpenAI) -> None: + async def test_path_params_delete(self, async_client: AsyncOpenAI) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `model` but received ''"): - await client.models.with_raw_response.delete( + await async_client.models.with_raw_response.delete( "", ) diff --git a/tests/api_resources/test_moderations.py b/tests/api_resources/test_moderations.py index 88d35f003d..285e738c0e 100644 --- a/tests/api_resources/test_moderations.py +++ b/tests/api_resources/test_moderations.py @@ -10,16 +10,12 @@ from openai import OpenAI, AsyncOpenAI from tests.utils import assert_matches_type from openai.types import ModerationCreateResponse -from openai._client import OpenAI, AsyncOpenAI base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" class TestModerations: - strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_create(self, client: OpenAI) -> None: @@ -62,28 +58,26 @@ def test_streaming_response_create(self, client: OpenAI) -> None: class TestAsyncModerations: - strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_create(self, client: AsyncOpenAI) -> None: - moderation = await client.moderations.create( + async def test_method_create(self, async_client: AsyncOpenAI) -> None: + moderation = await async_client.moderations.create( input="I want to kill them.", ) assert_matches_type(ModerationCreateResponse, moderation, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: - moderation = await client.moderations.create( + async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None: + moderation = await async_client.moderations.create( input="I want to kill them.", model="text-moderation-stable", ) assert_matches_type(ModerationCreateResponse, moderation, path=["response"]) @parametrize - async def test_raw_response_create(self, client: AsyncOpenAI) -> None: - response = await client.moderations.with_raw_response.create( + async def test_raw_response_create(self, async_client: AsyncOpenAI) -> None: + response = await async_client.moderations.with_raw_response.create( input="I want to kill them.", ) @@ -93,8 +87,8 @@ async def test_raw_response_create(self, client: AsyncOpenAI) -> None: assert_matches_type(ModerationCreateResponse, moderation, path=["response"]) @parametrize - async def test_streaming_response_create(self, client: AsyncOpenAI) -> None: - async with client.moderations.with_streaming_response.create( + async def test_streaming_response_create(self, async_client: AsyncOpenAI) -> None: + async with async_client.moderations.with_streaming_response.create( input="I want to kill them.", ) as response: assert not response.is_closed diff --git a/tests/conftest.py b/tests/conftest.py index c3a1efe9df..15af57e770 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,9 +1,17 @@ +from __future__ import annotations + +import os import asyncio import logging -from typing import Iterator +from typing import TYPE_CHECKING, Iterator, AsyncIterator import pytest +from openai import OpenAI, AsyncOpenAI + +if TYPE_CHECKING: + from _pytest.fixtures import FixtureRequest + pytest.register_assert_rewrite("tests.utils") logging.getLogger("openai").setLevel(logging.DEBUG) @@ -14,3 +22,28 @@ def event_loop() -> Iterator[asyncio.AbstractEventLoop]: loop = asyncio.new_event_loop() yield loop loop.close() + + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + +api_key = "My API Key" + + +@pytest.fixture(scope="session") +def client(request: FixtureRequest) -> Iterator[OpenAI]: + strict = getattr(request, "param", True) + if not isinstance(strict, bool): + raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") + + with OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client: + yield client + + +@pytest.fixture(scope="session") +async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncOpenAI]: + strict = getattr(request, "param", True) + if not isinstance(strict, bool): + raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") + + async with AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client: + yield client diff --git a/tests/test_client.py b/tests/test_client.py index 7aa473fe9b..3d2dd35821 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -19,7 +19,6 @@ from openai import OpenAI, AsyncOpenAI, APIResponseValidationError from openai._client import OpenAI, AsyncOpenAI from openai._models import BaseModel, FinalRequestOptions -from openai._response import APIResponse, AsyncAPIResponse from openai._constants import RAW_RESPONSE_HEADER from openai._streaming import Stream, AsyncStream from openai._exceptions import OpenAIError, APIStatusError, APITimeoutError, APIResponseValidationError @@ -665,33 +664,6 @@ def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str calculated = client._calculate_retry_timeout(remaining_retries, options, headers) assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType] - @mock.patch("openai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) - @pytest.mark.respx(base_url=base_url) - def test_streaming_response(self) -> None: - response = self.client.post( - "/chat/completions", - body=dict( - messages=[ - { - "role": "user", - "content": "Say this is a test", - } - ], - model="gpt-3.5-turbo", - ), - cast_to=APIResponse[bytes], - options={"headers": {RAW_RESPONSE_HEADER: "stream"}}, - ) - - assert not cast(Any, response.is_closed) - assert _get_open_connections(self.client) == 1 - - for _ in response.iter_bytes(): - ... - - assert cast(Any, response.is_closed) - assert _get_open_connections(self.client) == 0 - @mock.patch("openai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter) -> None: @@ -1372,33 +1344,6 @@ async def test_parse_retry_after_header(self, remaining_retries: int, retry_afte calculated = client._calculate_retry_timeout(remaining_retries, options, headers) assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType] - @mock.patch("openai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) - @pytest.mark.respx(base_url=base_url) - async def test_streaming_response(self) -> None: - response = await self.client.post( - "/chat/completions", - body=dict( - messages=[ - { - "role": "user", - "content": "Say this is a test", - } - ], - model="gpt-3.5-turbo", - ), - cast_to=AsyncAPIResponse[bytes], - options={"headers": {RAW_RESPONSE_HEADER: "stream"}}, - ) - - assert not cast(Any, response.is_closed) - assert _get_open_connections(self.client) == 1 - - async for _ in response.iter_bytes(): - ... - - assert cast(Any, response.is_closed) - assert _get_open_connections(self.client) == 0 - @mock.patch("openai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) async def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter) -> None: diff --git a/tests/test_utils/test_typing.py b/tests/test_utils/test_typing.py new file mode 100644 index 0000000000..690960802a --- /dev/null +++ b/tests/test_utils/test_typing.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +from typing import Generic, TypeVar, cast + +from openai._utils import extract_type_var_from_base + +_T = TypeVar("_T") +_T2 = TypeVar("_T2") +_T3 = TypeVar("_T3") + + +class BaseGeneric(Generic[_T]): + ... + + +class SubclassGeneric(BaseGeneric[_T]): + ... + + +class BaseGenericMultipleTypeArgs(Generic[_T, _T2, _T3]): + ... + + +class SubclassGenericMultipleTypeArgs(BaseGenericMultipleTypeArgs[_T, _T2, _T3]): + ... + + +class SubclassDifferentOrderGenericMultipleTypeArgs(BaseGenericMultipleTypeArgs[_T2, _T, _T3]): + ... + + +def test_extract_type_var() -> None: + assert ( + extract_type_var_from_base( + BaseGeneric[int], + index=0, + generic_bases=cast("tuple[type, ...]", (BaseGeneric,)), + ) + == int + ) + + +def test_extract_type_var_generic_subclass() -> None: + assert ( + extract_type_var_from_base( + SubclassGeneric[int], + index=0, + generic_bases=cast("tuple[type, ...]", (BaseGeneric,)), + ) + == int + ) + + +def test_extract_type_var_multiple() -> None: + typ = BaseGenericMultipleTypeArgs[int, str, None] + + generic_bases = cast("tuple[type, ...]", (BaseGenericMultipleTypeArgs,)) + assert extract_type_var_from_base(typ, index=0, generic_bases=generic_bases) == int + assert extract_type_var_from_base(typ, index=1, generic_bases=generic_bases) == str + assert extract_type_var_from_base(typ, index=2, generic_bases=generic_bases) == type(None) + + +def test_extract_type_var_generic_subclass_multiple() -> None: + typ = SubclassGenericMultipleTypeArgs[int, str, None] + + generic_bases = cast("tuple[type, ...]", (BaseGenericMultipleTypeArgs,)) + assert extract_type_var_from_base(typ, index=0, generic_bases=generic_bases) == int + assert extract_type_var_from_base(typ, index=1, generic_bases=generic_bases) == str + assert extract_type_var_from_base(typ, index=2, generic_bases=generic_bases) == type(None) + + +def test_extract_type_var_generic_subclass_different_ordering_multiple() -> None: + typ = SubclassDifferentOrderGenericMultipleTypeArgs[int, str, None] + + generic_bases = cast("tuple[type, ...]", (BaseGenericMultipleTypeArgs,)) + assert extract_type_var_from_base(typ, index=0, generic_bases=generic_bases) == int + assert extract_type_var_from_base(typ, index=1, generic_bases=generic_bases) == str + assert extract_type_var_from_base(typ, index=2, generic_bases=generic_bases) == type(None)