Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions google/genai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@

__version__ = version.__version__

__all__ = ['Client', 'interactions', 'types']
__all__ = ['Client', 'credentials', 'interactions', 'types']


def __getattr__(name: str) -> Any:
if name == 'interactions':
module = importlib.import_module('.interactions', __name__)
if name in ('credentials', 'interactions'):
module = importlib.import_module(f'.{name}', __name__)
globals()[name] = module
return module
raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
73 changes: 73 additions & 0 deletions google/genai/_gaos/google_genai.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
)
from .sdk import AsyncGenAI, GenAI
from .types import environments
from .types import credentials
from .types import interactions
from .types.security import Security
from .utils import BackoffStrategy, RetryConfig, eventstreaming
Expand All @@ -56,6 +57,8 @@
from .webhooks import Webhooks as GeneratedWebhooks
from .environments import AsyncEnvironments as GeneratedAsyncEnvironments
from .environments import Environments as GeneratedEnvironments
from .credentials import AsyncCredentials as GeneratedAsyncCredentials
from .credentials import Credentials as GeneratedCredentials
from .files import AsyncFiles as GeneratedAsyncFiles
from .files import Files as GeneratedFiles

Expand Down Expand Up @@ -611,6 +614,76 @@ async def ping(self, *args: Any, **kwargs: Any) -> Any:
return await async_wrap_sdk_call(super().ping, *args, **kwargs)


class GeminiNextGenCredentials(GeneratedCredentials):
"""Public credentials resource backed by the NextGen client.

Subclasses the generated resource so every public method is wrapped in
`wrap_sdk_call`, translating per-operation `GenAiError` raises into the
status-code `APIError` hierarchy exposed at the
`google.genai._interactions` import surface.
"""

def __init__(self, api_client: Any):
sdk = build_google_genai_client(api_client)
super().__init__(sdk.sdk_configuration, parent_ref=sdk)

if not TYPE_CHECKING:
@property
def with_raw_response(self):
return _RawResponseAccessorProxy(super().with_raw_response)

@property
def with_streaming_response(self):
return _RawResponseAccessorProxy(super().with_streaming_response)

def create(self, *args: Any, **kwargs: Any) -> Any:
return wrap_sdk_call(super().create, *args, **kwargs)

def list(self, *args: Any, **kwargs: Any) -> Any:
return wrap_sdk_call(super().list, *args, **kwargs)

def get(self, *args: Any, **kwargs: Any) -> Any:
return wrap_sdk_call(super().get, *args, **kwargs)

def update(self, *args: Any, **kwargs: Any) -> Any:
return wrap_sdk_call(super().update, *args, **kwargs)

def delete(self, *args: Any, **kwargs: Any) -> Any:
return wrap_sdk_call(super().delete, *args, **kwargs)


class AsyncGeminiNextGenCredentials(GeneratedAsyncCredentials):
"""Async public credentials resource backed by the NextGen client."""

def __init__(self, api_client: Any):
sdk = build_google_genai_async_client(api_client)
super().__init__(sdk.sdk_configuration, parent_ref=sdk)

if not TYPE_CHECKING:
@property
def with_raw_response(self):
return _AsyncRawResponseAccessorProxy(super().with_raw_response)

@property
def with_streaming_response(self):
return _AsyncRawResponseAccessorProxy(super().with_streaming_response)

async def create(self, *args: Any, **kwargs: Any) -> Any:
return await async_wrap_sdk_call(super().create, *args, **kwargs)

async def list(self, *args: Any, **kwargs: Any) -> Any:
return await async_wrap_sdk_call(super().list, *args, **kwargs)

async def get(self, *args: Any, **kwargs: Any) -> Any:
return await async_wrap_sdk_call(super().get, *args, **kwargs)

async def update(self, *args: Any, **kwargs: Any) -> Any:
return await async_wrap_sdk_call(super().update, *args, **kwargs)

async def delete(self, *args: Any, **kwargs: Any) -> Any:
return await async_wrap_sdk_call(super().delete, *args, **kwargs)


class GeminiNextGenAgents(GeneratedAgents):
"""Public agents resource backed by the NextGen client.

Expand Down
38 changes: 38 additions & 0 deletions google/genai/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@
if TYPE_CHECKING:
from ._gaos.google_genai import (
AsyncGeminiNextGenAgents,
AsyncGeminiNextGenCredentials,
AsyncGeminiNextGenEnvironments,
AsyncGeminiNextGenInteractions,
AsyncGeminiNextGenTriggers,
AsyncGeminiNextGenWebhooks,
GeminiNextGenAgents,
GeminiNextGenCredentials,
GeminiNextGenEnvironments,
GeminiNextGenInteractions,
GeminiNextGenTriggers,
Expand All @@ -58,6 +60,7 @@
_agent_experimental_warned = False
_trigger_experimental_warned = False
_environment_experimental_warned = False
_credential_experimental_warned = False


class AsyncClient:
Expand All @@ -81,6 +84,7 @@ def __init__(self, api_client: BaseApiClient):
self._webhooks: Optional[AsyncGeminiNextGenWebhooks] = None
self._triggers: Optional[AsyncGeminiNextGenTriggers] = None
self._environments: Optional[AsyncGeminiNextGenEnvironments] = None
self._credentials: Optional[AsyncGeminiNextGenCredentials] = None

@property
def _nextgen_client(self) -> AsyncGeminiNextGenAPI:
Expand Down Expand Up @@ -157,6 +161,23 @@ def environments(self) -> AsyncGeminiNextGenEnvironments:
self._environments = AsyncGeminiNextGenEnvironments(self._api_client)
return self._environments

@property
def credentials(self) -> AsyncGeminiNextGenCredentials:
"""Credentials resource."""
global _credential_experimental_warned
if not _credential_experimental_warned:
_credential_experimental_warned = True
warnings.warn(
'Credentials usage is experimental and may change in future versions.',
category=UserWarning,
stacklevel=1,
)
if self._credentials is None:
from ._gaos.google_genai import AsyncGeminiNextGenCredentials

self._credentials = AsyncGeminiNextGenCredentials(self._api_client)
return self._credentials

@property
def models(self) -> AsyncModels:
return self._models
Expand Down Expand Up @@ -411,6 +432,7 @@ def __init__(
self._webhooks: Optional[GeminiNextGenWebhooks] = None
self._triggers: Optional[GeminiNextGenTriggers] = None
self._environments: Optional[GeminiNextGenEnvironments] = None
self._credentials: Optional[GeminiNextGenCredentials] = None

@staticmethod
def _get_api_client(
Expand Down Expand Up @@ -522,6 +544,22 @@ def environments(self) -> GeminiNextGenEnvironments:
self._environments = GeminiNextGenEnvironments(self._api_client)
return self._environments

@property
def credentials(self) -> GeminiNextGenCredentials:
global _credential_experimental_warned
if not _credential_experimental_warned:
_credential_experimental_warned = True
warnings.warn(
'Credentials usage is experimental and may change in future versions.',
category=UserWarning,
stacklevel=2,
)
if self._credentials is None:
from ._gaos.google_genai import GeminiNextGenCredentials

self._credentials = GeminiNextGenCredentials(self._api_client)
return self._credentials

@property
def chats(self) -> Chats:
return Chats(modules=self.models)
Expand Down
31 changes: 31 additions & 0 deletions google/genai/credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Expose Google GenAI credential types."""

from ._gaos.models.listcredentials import ListCredentialsRequestParam as CredentialListParams
from ._gaos.types.credentials.credential import Credential
from ._gaos.types.credentials.credentialcreateparams import CredentialCreateParams
from ._gaos.types.credentials.credentiallistresponse import CredentialListResponse
from ._gaos.types.credentials.credentialupdate import CredentialUpdateParam as CredentialUpdateParams
from ._gaos.types.interactions.empty import Empty as CredentialDeleteResponse

__all__ = [
"Credential",
"CredentialCreateParams",
"CredentialDeleteResponse",
"CredentialListParams",
"CredentialListResponse",
"CredentialUpdateParams",
]
Loading
Loading