122122 ObjReadReq ,
123123 ObjSchema ,
124124 ObjSchemaForInsert ,
125+ ProjectsInfoReq ,
125126 Query ,
126127 RefsReadBatchReq ,
127128 StartedCallSchemaForInsert ,
@@ -338,6 +339,10 @@ def __init__(
338339 # Set Client project name with updated project name
339340 self .project = resp .project_name
340341
342+ # Cache external -> internal project ID mapping
343+ self ._project_id_map : dict [str , str ] = {}
344+ self ._fetch_project_id_map ()
345+
341346 self ._server_call_processor : AsyncBatchProcessor | CallBatchProcessor | None = (
342347 None
343348 )
@@ -355,6 +360,30 @@ def __init__(
355360 self ._server_feedback_processor = self .server .get_feedback_processor ()
356361 self .send_file_cache = WeaveClientSendFileCache ()
357362
363+ def _fetch_project_id_map (
364+ self , project_ids : list [str ] | None = None
365+ ) -> None :
366+ """Fetch and cache the external -> internal project ID mapping.
367+
368+ Args:
369+ project_ids: External project IDs in 'entity/project' format.
370+ Defaults to the current project.
371+ """
372+ if project_ids is None :
373+ project_ids = [to_project_id (self .entity , self .project )]
374+ try :
375+ res = self .server .projects_info ( # type: ignore[attr-defined]
376+ ProjectsInfoReq (project_ids = project_ids )
377+ )
378+ self ._project_id_map .update (
379+ {
380+ item .external_project_id : item .internal_project_id
381+ for item in res
382+ }
383+ )
384+ except Exception :
385+ logger .debug ("Failed to fetch projects info" , exc_info = True )
386+
358387 ################ High Level Convenience Methods ################
359388
360389 @trace_sentry .global_trace_sentry .watch ()
0 commit comments