Coverage for src/bioimageio/spec/_internal/root_url.py: 74%

43 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-18 09:17 +0000

1from __future__ import annotations 

2 

3from pathlib import PurePosixPath 

4from typing import Any, ClassVar, Iterable 

5from urllib.parse import urlsplit, urlunsplit 

6 

7import pydantic 

8from pydantic import RootModel 

9 

10from .validated_string import ValidatedString 

11 

12 

13class RootHttpUrl(ValidatedString): 

14 """An untested HTTP URL, possibly a 'URL folder' or an invalid HTTP URL""" 

15 

16 root_model: ClassVar[type[RootModel[Any]]] = RootModel[pydantic.HttpUrl] 

17 _validated: pydantic.HttpUrl 

18 

19 def absolute(self): 

20 """analog to `absolute` method of pathlib.""" 

21 return self 

22 

23 @property 

24 def scheme(self) -> str: 

25 return self._validated.scheme 

26 

27 @property 

28 def host(self) -> str | None: 

29 return self._validated.host 

30 

31 @property 

32 def path(self) -> str | None: 

33 return self._validated.path 

34 

35 @property 

36 def parent(self) -> RootHttpUrl: 

37 parsed = urlsplit(str(self)) 

38 path = list(parsed.path.split("/")) 

39 if ( 

40 parsed.netloc == "zenodo.org" 

41 and parsed.path.startswith("/api/records/") 

42 and parsed.path.endswith("/content") 

43 ): 

44 path[-2:-1] = [] 

45 else: 

46 path = path[:-1] 

47 

48 return RootHttpUrl( 

49 urlunsplit( 

50 ( 

51 parsed.scheme, 

52 parsed.netloc, 

53 "/".join(path), 

54 parsed.query, 

55 parsed.fragment, 

56 ) 

57 ) 

58 ) 

59 

60 @property 

61 def parents(self) -> Iterable[RootHttpUrl]: 

62 """iterate over all URL parents (max 100)""" 

63 current = self 

64 for _ in range(100): 

65 current = current.parent 

66 yield current 

67 

68 @property 

69 def suffix(self) -> str: 

70 if self.path is None: 

71 return "" 

72 else: 

73 return PurePosixPath(self.path).suffix 

74 

75 def __truediv__(self, other: str) -> RootHttpUrl: 

76 parsed = urlsplit(str(self)) 

77 return RootHttpUrl( 

78 urlunsplit( 

79 ( 

80 parsed.scheme, 

81 parsed.netloc, 

82 f"{parsed.path.strip('/')}/{other.strip('/')}", 

83 parsed.query, 

84 parsed.fragment, 

85 ) 

86 ) 

87 )