Commit 4aa7cbee

Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
2024-01-05 05:26:07
chore: use property declarations for resource members (#1047)
This will speedup client instantiation in certain cases.
1 parent c4db321
src/openai/resources/audio/audio.py
@@ -2,9 +2,8 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
-
 from .speech import Speech, AsyncSpeech, SpeechWithRawResponse, AsyncSpeechWithRawResponse
+from ..._compat import cached_property
 from ..._resource import SyncAPIResource, AsyncAPIResource
 from .translations import Translations, AsyncTranslations, TranslationsWithRawResponse, AsyncTranslationsWithRawResponse
 from .transcriptions import (
@@ -14,38 +13,43 @@ from .transcriptions import (
     AsyncTranscriptionsWithRawResponse,
 )
 
-if TYPE_CHECKING:
-    from ..._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Audio", "AsyncAudio"]
 
 
 class Audio(SyncAPIResource):
-    transcriptions: Transcriptions
-    translations: Translations
-    speech: Speech
-    with_raw_response: AudioWithRawResponse
+    @cached_property
+    def transcriptions(self) -> Transcriptions:
+        return Transcriptions(self._client)
+
+    @cached_property
+    def translations(self) -> Translations:
+        return Translations(self._client)
+
+    @cached_property
+    def speech(self) -> Speech:
+        return Speech(self._client)
 
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.transcriptions = Transcriptions(client)
-        self.translations = Translations(client)
-        self.speech = Speech(client)
-        self.with_raw_response = AudioWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AudioWithRawResponse:
+        return AudioWithRawResponse(self)
 
 
 class AsyncAudio(AsyncAPIResource):
-    transcriptions: AsyncTranscriptions
-    translations: AsyncTranslations
-    speech: AsyncSpeech
-    with_raw_response: AsyncAudioWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.transcriptions = AsyncTranscriptions(client)
-        self.translations = AsyncTranslations(client)
-        self.speech = AsyncSpeech(client)
-        self.with_raw_response = AsyncAudioWithRawResponse(self)
+    @cached_property
+    def transcriptions(self) -> AsyncTranscriptions:
+        return AsyncTranscriptions(self._client)
+
+    @cached_property
+    def translations(self) -> AsyncTranslations:
+        return AsyncTranslations(self._client)
+
+    @cached_property
+    def speech(self) -> AsyncSpeech:
+        return AsyncSpeech(self._client)
+
+    @cached_property
+    def with_raw_response(self) -> AsyncAudioWithRawResponse:
+        return AsyncAudioWithRawResponse(self)
 
 
 class AudioWithRawResponse:
src/openai/resources/audio/speech.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Union
+from typing import Union
 from typing_extensions import Literal
 
 import httpx
@@ -15,6 +15,7 @@ from ..._types import (
     NotGiven,
 )
 from ..._utils import maybe_transform
+from ..._compat import cached_property
 from ..._resource import SyncAPIResource, AsyncAPIResource
 from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ...types.audio import speech_create_params
@@ -23,18 +24,13 @@ from ..._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from ..._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Speech", "AsyncSpeech"]
 
 
 class Speech(SyncAPIResource):
-    with_raw_response: SpeechWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = SpeechWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> SpeechWithRawResponse:
+        return SpeechWithRawResponse(self)
 
     def create(
         self,
@@ -99,11 +95,9 @@ class Speech(SyncAPIResource):
 
 
 class AsyncSpeech(AsyncAPIResource):
-    with_raw_response: AsyncSpeechWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncSpeechWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncSpeechWithRawResponse:
+        return AsyncSpeechWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/audio/transcriptions.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Union, Mapping, cast
+from typing import Union, Mapping, cast
 from typing_extensions import Literal
 
 import httpx
@@ -16,6 +16,7 @@ from ..._types import (
     FileTypes,
 )
 from ..._utils import extract_files, maybe_transform, deepcopy_minimal
+from ..._compat import cached_property
 from ..._resource import SyncAPIResource, AsyncAPIResource
 from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ...types.audio import Transcription, transcription_create_params
@@ -23,18 +24,13 @@ from ..._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from ..._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Transcriptions", "AsyncTranscriptions"]
 
 
 class Transcriptions(SyncAPIResource):
-    with_raw_response: TranscriptionsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = TranscriptionsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> TranscriptionsWithRawResponse:
+        return TranscriptionsWithRawResponse(self)
 
     def create(
         self,
@@ -117,11 +113,9 @@ class Transcriptions(SyncAPIResource):
 
 
 class AsyncTranscriptions(AsyncAPIResource):
-    with_raw_response: AsyncTranscriptionsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncTranscriptionsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncTranscriptionsWithRawResponse:
+        return AsyncTranscriptionsWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/audio/translations.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Union, Mapping, cast
+from typing import Union, Mapping, cast
 from typing_extensions import Literal
 
 import httpx
@@ -16,6 +16,7 @@ from ..._types import (
     FileTypes,
 )
 from ..._utils import extract_files, maybe_transform, deepcopy_minimal
+from ..._compat import cached_property
 from ..._resource import SyncAPIResource, AsyncAPIResource
 from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ...types.audio import Translation, translation_create_params
@@ -23,18 +24,13 @@ from ..._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from ..._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Translations", "AsyncTranslations"]
 
 
 class Translations(SyncAPIResource):
-    with_raw_response: TranslationsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = TranslationsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> TranslationsWithRawResponse:
+        return TranslationsWithRawResponse(self)
 
     def create(
         self,
@@ -110,11 +106,9 @@ class Translations(SyncAPIResource):
 
 
 class AsyncTranslations(AsyncAPIResource):
-    with_raw_response: AsyncTranslationsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncTranslationsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncTranslationsWithRawResponse:
+        return AsyncTranslationsWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/beta/assistants/assistants.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, List, Optional
+from typing import List, Optional
 from typing_extensions import Literal
 
 import httpx
@@ -16,6 +16,7 @@ from ...._types import (
     NotGiven,
 )
 from ...._utils import maybe_transform
+from ...._compat import cached_property
 from ...._resource import SyncAPIResource, AsyncAPIResource
 from ...._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ....pagination import SyncCursorPage, AsyncCursorPage
@@ -31,20 +32,17 @@ from ...._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from ...._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Assistants", "AsyncAssistants"]
 
 
 class Assistants(SyncAPIResource):
-    files: Files
-    with_raw_response: AssistantsWithRawResponse
+    @cached_property
+    def files(self) -> Files:
+        return Files(self._client)
 
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.files = Files(client)
-        self.with_raw_response = AssistantsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AssistantsWithRawResponse:
+        return AssistantsWithRawResponse(self)
 
     def create(
         self,
@@ -331,13 +329,13 @@ class Assistants(SyncAPIResource):
 
 
 class AsyncAssistants(AsyncAPIResource):
-    files: AsyncFiles
-    with_raw_response: AsyncAssistantsWithRawResponse
+    @cached_property
+    def files(self) -> AsyncFiles:
+        return AsyncFiles(self._client)
 
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.files = AsyncFiles(client)
-        self.with_raw_response = AsyncAssistantsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncAssistantsWithRawResponse:
+        return AsyncAssistantsWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/beta/assistants/files.py
@@ -2,7 +2,6 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
 from typing_extensions import Literal
 
 import httpx
@@ -15,6 +14,7 @@ from ...._types import (
     NotGiven,
 )
 from ...._utils import maybe_transform
+from ...._compat import cached_property
 from ...._resource import SyncAPIResource, AsyncAPIResource
 from ...._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ....pagination import SyncCursorPage, AsyncCursorPage
@@ -22,25 +22,15 @@ from ...._base_client import (
     AsyncPaginator,
     make_request_options,
 )
-from ....types.beta.assistants import (
-    AssistantFile,
-    FileDeleteResponse,
-    file_list_params,
-    file_create_params,
-)
-
-if TYPE_CHECKING:
-    from ...._client import OpenAI, AsyncOpenAI
+from ....types.beta.assistants import AssistantFile, FileDeleteResponse, file_list_params, file_create_params
 
 __all__ = ["Files", "AsyncFiles"]
 
 
 class Files(SyncAPIResource):
-    with_raw_response: FilesWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = FilesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> FilesWithRawResponse:
+        return FilesWithRawResponse(self)
 
     def create(
         self,
@@ -215,11 +205,9 @@ class Files(SyncAPIResource):
 
 
 class AsyncFiles(AsyncAPIResource):
-    with_raw_response: AsyncFilesWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncFilesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncFilesWithRawResponse:
+        return AsyncFilesWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/beta/threads/messages/files.py
@@ -2,7 +2,6 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
 from typing_extensions import Literal
 
 import httpx
@@ -15,6 +14,7 @@ from ....._types import (
     NotGiven,
 )
 from ....._utils import maybe_transform
+from ....._compat import cached_property
 from ....._resource import SyncAPIResource, AsyncAPIResource
 from ....._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from .....pagination import SyncCursorPage, AsyncCursorPage
@@ -24,18 +24,13 @@ from ....._base_client import (
 )
 from .....types.beta.threads.messages import MessageFile, file_list_params
 
-if TYPE_CHECKING:
-    from ....._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Files", "AsyncFiles"]
 
 
 class Files(SyncAPIResource):
-    with_raw_response: FilesWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = FilesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> FilesWithRawResponse:
+        return FilesWithRawResponse(self)
 
     def retrieve(
         self,
@@ -140,11 +135,9 @@ class Files(SyncAPIResource):
 
 
 class AsyncFiles(AsyncAPIResource):
-    with_raw_response: AsyncFilesWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncFilesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncFilesWithRawResponse:
+        return AsyncFilesWithRawResponse(self)
 
     async def retrieve(
         self,
src/openai/resources/beta/threads/messages/messages.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, List, Optional
+from typing import List, Optional
 from typing_extensions import Literal
 
 import httpx
@@ -16,6 +16,7 @@ from ....._types import (
     NotGiven,
 )
 from ....._utils import maybe_transform
+from ....._compat import cached_property
 from ....._resource import SyncAPIResource, AsyncAPIResource
 from ....._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from .....pagination import SyncCursorPage, AsyncCursorPage
@@ -23,27 +24,19 @@ from ....._base_client import (
     AsyncPaginator,
     make_request_options,
 )
-from .....types.beta.threads import (
-    ThreadMessage,
-    message_list_params,
-    message_create_params,
-    message_update_params,
-)
-
-if TYPE_CHECKING:
-    from ....._client import OpenAI, AsyncOpenAI
+from .....types.beta.threads import ThreadMessage, message_list_params, message_create_params, message_update_params
 
 __all__ = ["Messages", "AsyncMessages"]
 
 
 class Messages(SyncAPIResource):
-    files: Files
-    with_raw_response: MessagesWithRawResponse
+    @cached_property
+    def files(self) -> Files:
+        return Files(self._client)
 
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.files = Files(client)
-        self.with_raw_response = MessagesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> MessagesWithRawResponse:
+        return MessagesWithRawResponse(self)
 
     def create(
         self,
@@ -245,13 +238,13 @@ class Messages(SyncAPIResource):
 
 
 class AsyncMessages(AsyncAPIResource):
-    files: AsyncFiles
-    with_raw_response: AsyncMessagesWithRawResponse
+    @cached_property
+    def files(self) -> AsyncFiles:
+        return AsyncFiles(self._client)
 
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.files = AsyncFiles(client)
-        self.with_raw_response = AsyncMessagesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncMessagesWithRawResponse:
+        return AsyncMessagesWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/beta/threads/runs/runs.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, List, Optional
+from typing import List, Optional
 from typing_extensions import Literal
 
 import httpx
@@ -16,6 +16,7 @@ from ....._types import (
     NotGiven,
 )
 from ....._utils import maybe_transform
+from ....._compat import cached_property
 from ....._resource import SyncAPIResource, AsyncAPIResource
 from ....._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from .....pagination import SyncCursorPage, AsyncCursorPage
@@ -31,20 +32,17 @@ from .....types.beta.threads import (
     run_submit_tool_outputs_params,
 )
 
-if TYPE_CHECKING:
-    from ....._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Runs", "AsyncRuns"]
 
 
 class Runs(SyncAPIResource):
-    steps: Steps
-    with_raw_response: RunsWithRawResponse
+    @cached_property
+    def steps(self) -> Steps:
+        return Steps(self._client)
 
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.steps = Steps(client)
-        self.with_raw_response = RunsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> RunsWithRawResponse:
+        return RunsWithRawResponse(self)
 
     def create(
         self,
@@ -335,13 +333,13 @@ class Runs(SyncAPIResource):
 
 
 class AsyncRuns(AsyncAPIResource):
-    steps: AsyncSteps
-    with_raw_response: AsyncRunsWithRawResponse
+    @cached_property
+    def steps(self) -> AsyncSteps:
+        return AsyncSteps(self._client)
 
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.steps = AsyncSteps(client)
-        self.with_raw_response = AsyncRunsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncRunsWithRawResponse:
+        return AsyncRunsWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/beta/threads/runs/steps.py
@@ -2,7 +2,6 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
 from typing_extensions import Literal
 
 import httpx
@@ -15,6 +14,7 @@ from ....._types import (
     NotGiven,
 )
 from ....._utils import maybe_transform
+from ....._compat import cached_property
 from ....._resource import SyncAPIResource, AsyncAPIResource
 from ....._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from .....pagination import SyncCursorPage, AsyncCursorPage
@@ -24,18 +24,13 @@ from ....._base_client import (
 )
 from .....types.beta.threads.runs import RunStep, step_list_params
 
-if TYPE_CHECKING:
-    from ....._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Steps", "AsyncSteps"]
 
 
 class Steps(SyncAPIResource):
-    with_raw_response: StepsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = StepsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> StepsWithRawResponse:
+        return StepsWithRawResponse(self)
 
     def retrieve(
         self,
@@ -139,11 +134,9 @@ class Steps(SyncAPIResource):
 
 
 class AsyncSteps(AsyncAPIResource):
-    with_raw_response: AsyncStepsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncStepsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncStepsWithRawResponse:
+        return AsyncStepsWithRawResponse(self)
 
     async def retrieve(
         self,
src/openai/resources/beta/threads/threads.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, List, Optional
+from typing import List, Optional
 
 import httpx
 
@@ -16,6 +16,8 @@ from ...._types import (
     NotGiven,
 )
 from ...._utils import maybe_transform
+from .runs.runs import Runs, AsyncRuns
+from ...._compat import cached_property
 from ...._resource import SyncAPIResource, AsyncAPIResource
 from ...._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ....types.beta import (
@@ -28,24 +30,24 @@ from ....types.beta import (
 from ...._base_client import (
     make_request_options,
 )
+from .messages.messages import Messages, AsyncMessages
 from ....types.beta.threads import Run
 
-if TYPE_CHECKING:
-    from ...._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Threads", "AsyncThreads"]
 
 
 class Threads(SyncAPIResource):
-    runs: Runs
-    messages: Messages
-    with_raw_response: ThreadsWithRawResponse
+    @cached_property
+    def runs(self) -> Runs:
+        return Runs(self._client)
+
+    @cached_property
+    def messages(self) -> Messages:
+        return Messages(self._client)
 
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.runs = Runs(client)
-        self.messages = Messages(client)
-        self.with_raw_response = ThreadsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> ThreadsWithRawResponse:
+        return ThreadsWithRawResponse(self)
 
     def create(
         self,
@@ -270,15 +272,17 @@ class Threads(SyncAPIResource):
 
 
 class AsyncThreads(AsyncAPIResource):
-    runs: AsyncRuns
-    messages: AsyncMessages
-    with_raw_response: AsyncThreadsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.runs = AsyncRuns(client)
-        self.messages = AsyncMessages(client)
-        self.with_raw_response = AsyncThreadsWithRawResponse(self)
+    @cached_property
+    def runs(self) -> AsyncRuns:
+        return AsyncRuns(self._client)
+
+    @cached_property
+    def messages(self) -> AsyncMessages:
+        return AsyncMessages(self._client)
+
+    @cached_property
+    def with_raw_response(self) -> AsyncThreadsWithRawResponse:
+        return AsyncThreadsWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/beta/beta.py
@@ -2,40 +2,42 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
-
 from .threads import Threads, AsyncThreads, ThreadsWithRawResponse, AsyncThreadsWithRawResponse
+from ..._compat import cached_property
 from .assistants import Assistants, AsyncAssistants, AssistantsWithRawResponse, AsyncAssistantsWithRawResponse
 from ..._resource import SyncAPIResource, AsyncAPIResource
-
-if TYPE_CHECKING:
-    from ..._client import OpenAI, AsyncOpenAI
+from .threads.threads import Threads, AsyncThreads
+from .assistants.assistants import Assistants, AsyncAssistants
 
 __all__ = ["Beta", "AsyncBeta"]
 
 
 class Beta(SyncAPIResource):
-    assistants: Assistants
-    threads: Threads
-    with_raw_response: BetaWithRawResponse
+    @cached_property
+    def assistants(self) -> Assistants:
+        return Assistants(self._client)
+
+    @cached_property
+    def threads(self) -> Threads:
+        return Threads(self._client)
 
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.assistants = Assistants(client)
-        self.threads = Threads(client)
-        self.with_raw_response = BetaWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> BetaWithRawResponse:
+        return BetaWithRawResponse(self)
 
 
 class AsyncBeta(AsyncAPIResource):
-    assistants: AsyncAssistants
-    threads: AsyncThreads
-    with_raw_response: AsyncBetaWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.assistants = AsyncAssistants(client)
-        self.threads = AsyncThreads(client)
-        self.with_raw_response = AsyncBetaWithRawResponse(self)
+    @cached_property
+    def assistants(self) -> AsyncAssistants:
+        return AsyncAssistants(self._client)
+
+    @cached_property
+    def threads(self) -> AsyncThreads:
+        return AsyncThreads(self._client)
+
+    @cached_property
+    def with_raw_response(self) -> AsyncBetaWithRawResponse:
+        return AsyncBetaWithRawResponse(self)
 
 
 class BetaWithRawResponse:
src/openai/resources/chat/chat.py
@@ -2,35 +2,31 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
-
+from ..._compat import cached_property
 from ..._resource import SyncAPIResource, AsyncAPIResource
 from .completions import Completions, AsyncCompletions, CompletionsWithRawResponse, AsyncCompletionsWithRawResponse
 
-if TYPE_CHECKING:
-    from ..._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Chat", "AsyncChat"]
 
 
 class Chat(SyncAPIResource):
-    completions: Completions
-    with_raw_response: ChatWithRawResponse
+    @cached_property
+    def completions(self) -> Completions:
+        return Completions(self._client)
 
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.completions = Completions(client)
-        self.with_raw_response = ChatWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> ChatWithRawResponse:
+        return ChatWithRawResponse(self)
 
 
 class AsyncChat(AsyncAPIResource):
-    completions: AsyncCompletions
-    with_raw_response: AsyncChatWithRawResponse
+    @cached_property
+    def completions(self) -> AsyncCompletions:
+        return AsyncCompletions(self._client)
 
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.completions = AsyncCompletions(client)
-        self.with_raw_response = AsyncChatWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncChatWithRawResponse:
+        return AsyncChatWithRawResponse(self)
 
 
 class ChatWithRawResponse:
src/openai/resources/chat/completions.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Dict, List, Union, Optional, overload
+from typing import Dict, List, Union, Optional, overload
 from typing_extensions import Literal
 
 import httpx
@@ -15,6 +15,7 @@ from ..._types import (
     NotGiven,
 )
 from ..._utils import required_args, maybe_transform
+from ..._compat import cached_property
 from ..._resource import SyncAPIResource, AsyncAPIResource
 from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ..._streaming import Stream, AsyncStream
@@ -30,18 +31,13 @@ from ..._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from ..._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Completions", "AsyncCompletions"]
 
 
 class Completions(SyncAPIResource):
-    with_raw_response: CompletionsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = CompletionsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> CompletionsWithRawResponse:
+        return CompletionsWithRawResponse(self)
 
     @overload
     def create(
@@ -687,11 +683,9 @@ class Completions(SyncAPIResource):
 
 
 class AsyncCompletions(AsyncAPIResource):
-    with_raw_response: AsyncCompletionsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncCompletionsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncCompletionsWithRawResponse:
+        return AsyncCompletionsWithRawResponse(self)
 
     @overload
     async def create(
src/openai/resources/fine_tuning/fine_tuning.py
@@ -2,35 +2,31 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
-
 from .jobs import Jobs, AsyncJobs, JobsWithRawResponse, AsyncJobsWithRawResponse
+from ..._compat import cached_property
 from ..._resource import SyncAPIResource, AsyncAPIResource
 
-if TYPE_CHECKING:
-    from ..._client import OpenAI, AsyncOpenAI
-
 __all__ = ["FineTuning", "AsyncFineTuning"]
 
 
 class FineTuning(SyncAPIResource):
-    jobs: Jobs
-    with_raw_response: FineTuningWithRawResponse
+    @cached_property
+    def jobs(self) -> Jobs:
+        return Jobs(self._client)
 
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.jobs = Jobs(client)
-        self.with_raw_response = FineTuningWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> FineTuningWithRawResponse:
+        return FineTuningWithRawResponse(self)
 
 
 class AsyncFineTuning(AsyncAPIResource):
-    jobs: AsyncJobs
-    with_raw_response: AsyncFineTuningWithRawResponse
+    @cached_property
+    def jobs(self) -> AsyncJobs:
+        return AsyncJobs(self._client)
 
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.jobs = AsyncJobs(client)
-        self.with_raw_response = AsyncFineTuningWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncFineTuningWithRawResponse:
+        return AsyncFineTuningWithRawResponse(self)
 
 
 class FineTuningWithRawResponse:
src/openai/resources/fine_tuning/jobs.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Union, Optional
+from typing import Union, Optional
 from typing_extensions import Literal
 
 import httpx
@@ -15,6 +15,7 @@ from ..._types import (
     NotGiven,
 )
 from ..._utils import maybe_transform
+from ..._compat import cached_property
 from ..._resource import SyncAPIResource, AsyncAPIResource
 from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ...pagination import SyncCursorPage, AsyncCursorPage
@@ -30,18 +31,13 @@ from ...types.fine_tuning import (
     job_list_events_params,
 )
 
-if TYPE_CHECKING:
-    from ..._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Jobs", "AsyncJobs"]
 
 
 class Jobs(SyncAPIResource):
-    with_raw_response: JobsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = JobsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> JobsWithRawResponse:
+        return JobsWithRawResponse(self)
 
     def create(
         self,
@@ -289,11 +285,9 @@ class Jobs(SyncAPIResource):
 
 
 class AsyncJobs(AsyncAPIResource):
-    with_raw_response: AsyncJobsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncJobsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncJobsWithRawResponse:
+        return AsyncJobsWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/completions.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Dict, List, Union, Optional, overload
+from typing import Dict, List, Union, Optional, overload
 from typing_extensions import Literal
 
 import httpx
@@ -16,6 +16,7 @@ from .._types import (
     NotGiven,
 )
 from .._utils import required_args, maybe_transform
+from .._compat import cached_property
 from .._resource import SyncAPIResource, AsyncAPIResource
 from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from .._streaming import Stream, AsyncStream
@@ -23,18 +24,13 @@ from .._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from .._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Completions", "AsyncCompletions"]
 
 
 class Completions(SyncAPIResource):
-    with_raw_response: CompletionsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = CompletionsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> CompletionsWithRawResponse:
+        return CompletionsWithRawResponse(self)
 
     @overload
     def create(
@@ -601,11 +597,9 @@ class Completions(SyncAPIResource):
 
 
 class AsyncCompletions(AsyncAPIResource):
-    with_raw_response: AsyncCompletionsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncCompletionsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncCompletionsWithRawResponse:
+        return AsyncCompletionsWithRawResponse(self)
 
     @overload
     async def create(
src/openai/resources/edits.py
@@ -3,7 +3,7 @@
 from __future__ import annotations
 
 import typing_extensions
-from typing import TYPE_CHECKING, Union, Optional
+from typing import Union, Optional
 from typing_extensions import Literal
 
 import httpx
@@ -17,24 +17,20 @@ from .._types import (
     NotGiven,
 )
 from .._utils import maybe_transform
+from .._compat import cached_property
 from .._resource import SyncAPIResource, AsyncAPIResource
 from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from .._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from .._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Edits", "AsyncEdits"]
 
 
 class Edits(SyncAPIResource):
-    with_raw_response: EditsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = EditsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> EditsWithRawResponse:
+        return EditsWithRawResponse(self)
 
     @typing_extensions.deprecated(
         "The Edits API is deprecated; please use Chat Completions instead.\n\nhttps://openai.com/blog/gpt-4-api-general-availability#deprecation-of-the-edits-api\n"
@@ -109,11 +105,9 @@ class Edits(SyncAPIResource):
 
 
 class AsyncEdits(AsyncAPIResource):
-    with_raw_response: AsyncEditsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncEditsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncEditsWithRawResponse:
+        return AsyncEditsWithRawResponse(self)
 
     @typing_extensions.deprecated(
         "The Edits API is deprecated; please use Chat Completions instead.\n\nhttps://openai.com/blog/gpt-4-api-general-availability#deprecation-of-the-edits-api\n"
src/openai/resources/embeddings.py
@@ -3,7 +3,7 @@
 from __future__ import annotations
 
 import base64
-from typing import TYPE_CHECKING, List, Union, cast
+from typing import List, Union, cast
 from typing_extensions import Literal
 
 import httpx
@@ -17,6 +17,7 @@ from .._types import (
     NotGiven,
 )
 from .._utils import is_given, maybe_transform
+from .._compat import cached_property
 from .._extras import numpy as np, has_numpy
 from .._resource import SyncAPIResource, AsyncAPIResource
 from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
@@ -24,18 +25,13 @@ from .._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from .._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Embeddings", "AsyncEmbeddings"]
 
 
 class Embeddings(SyncAPIResource):
-    with_raw_response: EmbeddingsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = EmbeddingsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> EmbeddingsWithRawResponse:
+        return EmbeddingsWithRawResponse(self)
 
     def create(
         self,
@@ -125,11 +121,9 @@ class Embeddings(SyncAPIResource):
 
 
 class AsyncEmbeddings(AsyncAPIResource):
-    with_raw_response: AsyncEmbeddingsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncEmbeddingsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncEmbeddingsWithRawResponse:
+        return AsyncEmbeddingsWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/files.py
@@ -4,17 +4,12 @@ from __future__ import annotations
 
 import time
 import typing_extensions
-from typing import TYPE_CHECKING, Mapping, cast
+from typing import Mapping, cast
 from typing_extensions import Literal
 
 import httpx
 
-from ..types import (
-    FileObject,
-    FileDeleted,
-    file_list_params,
-    file_create_params,
-)
+from ..types import FileObject, FileDeleted, file_list_params, file_create_params
 from .._types import (
     NOT_GIVEN,
     Body,
@@ -24,6 +19,7 @@ from .._types import (
     FileTypes,
 )
 from .._utils import extract_files, maybe_transform, deepcopy_minimal
+from .._compat import cached_property
 from .._resource import SyncAPIResource, AsyncAPIResource
 from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ..pagination import SyncPage, AsyncPage
@@ -33,18 +29,13 @@ from .._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from .._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Files", "AsyncFiles"]
 
 
 class Files(SyncAPIResource):
-    with_raw_response: FilesWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = FilesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> FilesWithRawResponse:
+        return FilesWithRawResponse(self)
 
     def create(
         self,
@@ -304,11 +295,9 @@ class Files(SyncAPIResource):
 
 
 class AsyncFiles(AsyncAPIResource):
-    with_raw_response: AsyncFilesWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncFilesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncFilesWithRawResponse:
+        return AsyncFilesWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/fine_tunes.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, List, Union, Optional, overload
+from typing import List, Union, Optional, overload
 from typing_extensions import Literal
 
 import httpx
@@ -22,6 +22,7 @@ from .._types import (
     NotGiven,
 )
 from .._utils import maybe_transform
+from .._compat import cached_property
 from .._resource import SyncAPIResource, AsyncAPIResource
 from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from .._streaming import Stream, AsyncStream
@@ -31,18 +32,13 @@ from .._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from .._client import OpenAI, AsyncOpenAI
-
 __all__ = ["FineTunes", "AsyncFineTunes"]
 
 
 class FineTunes(SyncAPIResource):
-    with_raw_response: FineTunesWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = FineTunesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> FineTunesWithRawResponse:
+        return FineTunesWithRawResponse(self)
 
     def create(
         self,
@@ -416,11 +412,9 @@ class FineTunes(SyncAPIResource):
 
 
 class AsyncFineTunes(AsyncAPIResource):
-    with_raw_response: AsyncFineTunesWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncFineTunesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncFineTunesWithRawResponse:
+        return AsyncFineTunesWithRawResponse(self)
 
     async def create(
         self,
src/openai/resources/images.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Union, Mapping, Optional, cast
+from typing import Union, Mapping, Optional, cast
 from typing_extensions import Literal
 
 import httpx
@@ -22,24 +22,20 @@ from .._types import (
     FileTypes,
 )
 from .._utils import extract_files, maybe_transform, deepcopy_minimal
+from .._compat import cached_property
 from .._resource import SyncAPIResource, AsyncAPIResource
 from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from .._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from .._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Images", "AsyncImages"]
 
 
 class Images(SyncAPIResource):
-    with_raw_response: ImagesWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = ImagesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> ImagesWithRawResponse:
+        return ImagesWithRawResponse(self)
 
     def create_variation(
         self,
@@ -280,11 +276,9 @@ class Images(SyncAPIResource):
 
 
 class AsyncImages(AsyncAPIResource):
-    with_raw_response: AsyncImagesWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncImagesWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncImagesWithRawResponse:
+        return AsyncImagesWithRawResponse(self)
 
     async def create_variation(
         self,
src/openai/resources/models.py
@@ -2,8 +2,6 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
-
 import httpx
 
 from ..types import Model, ModelDeleted
@@ -14,6 +12,7 @@ from .._types import (
     Headers,
     NotGiven,
 )
+from .._compat import cached_property
 from .._resource import SyncAPIResource, AsyncAPIResource
 from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from ..pagination import SyncPage, AsyncPage
@@ -22,18 +21,13 @@ from .._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from .._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Models", "AsyncModels"]
 
 
 class Models(SyncAPIResource):
-    with_raw_response: ModelsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = ModelsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> ModelsWithRawResponse:
+        return ModelsWithRawResponse(self)
 
     def retrieve(
         self,
@@ -125,11 +119,9 @@ class Models(SyncAPIResource):
 
 
 class AsyncModels(AsyncAPIResource):
-    with_raw_response: AsyncModelsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncModelsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncModelsWithRawResponse:
+        return AsyncModelsWithRawResponse(self)
 
     async def retrieve(
         self,
src/openai/resources/moderations.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, List, Union
+from typing import List, Union
 from typing_extensions import Literal
 
 import httpx
@@ -16,24 +16,20 @@ from .._types import (
     NotGiven,
 )
 from .._utils import maybe_transform
+from .._compat import cached_property
 from .._resource import SyncAPIResource, AsyncAPIResource
 from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
 from .._base_client import (
     make_request_options,
 )
 
-if TYPE_CHECKING:
-    from .._client import OpenAI, AsyncOpenAI
-
 __all__ = ["Moderations", "AsyncModerations"]
 
 
 class Moderations(SyncAPIResource):
-    with_raw_response: ModerationsWithRawResponse
-
-    def __init__(self, client: OpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = ModerationsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> ModerationsWithRawResponse:
+        return ModerationsWithRawResponse(self)
 
     def create(
         self,
@@ -87,11 +83,9 @@ class Moderations(SyncAPIResource):
 
 
 class AsyncModerations(AsyncAPIResource):
-    with_raw_response: AsyncModerationsWithRawResponse
-
-    def __init__(self, client: AsyncOpenAI) -> None:
-        super().__init__(client)
-        self.with_raw_response = AsyncModerationsWithRawResponse(self)
+    @cached_property
+    def with_raw_response(self) -> AsyncModerationsWithRawResponse:
+        return AsyncModerationsWithRawResponse(self)
 
     async def create(
         self,
src/openai/_compat.py
@@ -173,3 +173,13 @@ else:
 
         class GenericModel(pydantic.generics.GenericModel, pydantic.BaseModel):
             ...
+
+
+# cached properties
+if TYPE_CHECKING:
+    cached_property = property
+else:
+    try:
+        from functools import cached_property as cached_property
+    except ImportError:
+        from cached_property import cached_property as cached_property
pyproject.toml
@@ -14,6 +14,7 @@ dependencies = [
     "anyio>=3.5.0, <5",
     "distro>=1.7.0, <2",
     "sniffio",
+    "cached-property; python_version < '3.8'",
     "tqdm > 4"
 ]
 requires-python = ">= 3.7.1"