Coverage for cli/_image_uri.py: 100%

15 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-15 15:07 +0000

1""" 

2ECR image URI helpers — pure functions, no AWS calls. 

3 

4Lives in its own small module so both ``cli.images`` (which builds and 

5manages images) and ``cli.inference`` (which has to rewrite URIs to 

6target the local region of each deployed endpoint) can depend on it 

7without forming an import cycle. 

8 

9Static-analysis tools (CodeQL, pyright) flag deferred-import cycles 

10even when both imports happen inside method bodies, because the 

11resulting module-level dependency graph still has a cycle. Splitting 

12the helper out keeps the dependency graph a DAG: ``cli.images`` and 

13``cli.inference`` both depend on ``cli._image_uri``, and neither 

14depends on the other. 

15""" 

16 

17from __future__ import annotations 

18 

19import re 

20 

21# ECR registry host shape: 

22# <account-id>.dkr.ecr.<region>.amazonaws.com 

23_ECR_HOST_RE = re.compile(r"^(?P<account>\d+)\.dkr\.ecr\.(?P<region>[a-z0-9-]+)\.amazonaws\.com$") 

24 

25 

26def rewrite_image_uri_for_region(uri: str, region: str) -> str: 

27 """Rewrite an ECR image URI to target a specific region's replica. 

28 

29 Pure helper — no AWS calls. Detects ECR URIs by matching the 

30 ``<account>.dkr.ecr.<region>.amazonaws.com`` host shape and swaps 

31 the region segment when it matches. Non-ECR refs (Docker Hub, 

32 GHCR, etc.) are returned unchanged. 

33 

34 Args: 

35 uri: The image URI (with optional ``host/path:tag`` shape). 

36 region: Target AWS region for the rewrite. 

37 

38 Returns: 

39 The rewritten URI when the input is an ECR URI; otherwise the 

40 original input. 

41 """ 

42 if "://" in uri: 

43 # Not a bare image ref (looks like a URL with a scheme). 

44 return uri 

45 parts = uri.split("/", 1) 

46 host = parts[0] 

47 match = _ECR_HOST_RE.match(host) 

48 if match is None: 

49 return uri 

50 new_host = f"{match.group('account')}.dkr.ecr.{region}.amazonaws.com" 

51 if len(parts) > 1: 

52 return f"{new_host}/{parts[1]}" 

53 return new_host