1414from yandex .cloud .endpoint .api_endpoint_service_pb2_grpc import ApiEndpointServiceStub
1515
1616from ._auth import BaseAuth , get_auth_provider
17- from ._exceptions import AioRpcError
17+ from ._exceptions import AioRpcError , UnknownEndpointError
1818from ._retry import RETRY_KIND_METADATA_KEY , RetryKind , RetryPolicy
1919from ._types .misc import PathLike , coerce_path
2020from ._utils .lock import LazyLock
@@ -44,7 +44,7 @@ class AsyncCloudClient:
4444 def __init__ (
4545 self ,
4646 * ,
47- endpoint : str ,
47+ endpoint : str | None ,
4848 auth : BaseAuth | str | None ,
4949 service_map : dict [str , str ],
5050 interceptors : Sequence [grpc .aio .ClientInterceptor ] | None ,
@@ -78,6 +78,10 @@ def __init__(
7878
7979 async def _init_service_map (self , timeout : float ):
8080 metadata = await self ._get_metadata (auth_required = False , timeout = timeout , retry_kind = RetryKind .SINGLE )
81+
82+ if not self ._endpoint :
83+ raise RuntimeError ('This method should be never called while endpoint=None' )
84+
8185 channel = self ._new_channel (self ._endpoint )
8286 async with channel :
8387 stub = ApiEndpointServiceStub (channel )
@@ -89,8 +93,30 @@ async def _init_service_map(self, timeout: float):
8993 for endpoint in response .endpoints :
9094 self ._service_map [endpoint .id ] = endpoint .address
9195
96+ async def _discover_service_endpoint (
97+ self ,
98+ service_name : str ,
99+ stub_class : type [StubType ],
100+ timeout : float
101+ ) -> str :
102+ endpoint : str | None
92103 # TODO: add a validation for unknown services in override
93- self ._service_map .update (self ._service_map_override )
104+ if endpoint := self ._service_map_override .get (service_name ):
105+ return endpoint
106+
107+ if self ._endpoint is None :
108+ raise UnknownEndpointError (
109+ "due to `endpoint` SDK param explicitly set to `None` you need to define "
110+ f"{ service_name !r} endpoint manually at `service_map` SDK param"
111+ )
112+
113+ if not self ._service_map :
114+ await self ._init_service_map (timeout = timeout )
115+
116+ if endpoint := self ._service_map .get (service_name ):
117+ return endpoint
118+
119+ raise UnknownEndpointError (f'failed to find endpoint for { service_name = } and { stub_class = } ' )
94120
95121 async def _get_metadata (
96122 self ,
@@ -172,19 +198,12 @@ async def _get_channel(
172198 return self ._channels [stub_class ]
173199
174200 service_name = service_name if service_name else service_for_ctor (stub_class )
175- if not self ._service_map :
176- await self ._init_service_map (timeout = timeout )
177-
178- if not (endpoint := self ._service_map .get (service_name )):
179- # NB: this fix will work if service_map will change ai-assistant to ai-assistants
180- # (and retrospectively if user will stuck with this version)
181- # and if _service_for_ctor will change ai-assistants to ai-assistant
182- if service_name in ('ai-assistant' , 'ai-assistants' ):
183- service_name = 'ai-assistant' if service_name == 'ai-assistants' else 'ai-assistants'
184- if not (endpoint := self ._service_map .get (service_name )):
185- raise ValueError (f'failed to find endpoint for { service_name = } and { stub_class = } ' )
186- else :
187- raise ValueError (f'failed to find endpoint for { service_name = } and { stub_class = } ' )
201+
202+ endpoint = await self ._discover_service_endpoint (
203+ service_name = service_name ,
204+ stub_class = stub_class ,
205+ timeout = timeout
206+ )
188207
189208 self ._endpoints [stub_class ] = endpoint
190209 channel = self ._channels [stub_class ] = self ._new_channel (endpoint )
0 commit comments