Coverage for youversion/models/commons.py: 100%
33 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-26 11:31 +0100
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-26 11:31 +0100
1"""Common models for YouVersion API responses."""
3from typing import Any, Protocol
5try:
6 from typing import TypeAlias
7except ImportError:
8 # Python < 3.10 compatibility
9 from typing import TypeAlias
12class ReactionModelProtocol(Protocol):
13 """Protocol for reaction-based models (comments, likes)."""
15 enabled: bool
16 count: int
17 strings: dict[str, Any]
18 all: list[Any]
20 def __getattr__(self, name: str) -> Any:
21 """Allow access to dynamically added fields."""
22 class_name = self.__class__.__name__
23 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
26# Type alias for convenience
27ReactionModel: TypeAlias = ReactionModelProtocol
30class BodyImageProtocol(Protocol):
31 """Protocol for body image objects."""
33 height: int
34 width: int
35 url: str
37 def __getattr__(self, name: str) -> Any:
38 """Allow access to dynamically added fields."""
39 class_name = self.__class__.__name__
40 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
43# Type alias for convenience
44BodyImage: TypeAlias = BodyImageProtocol
47class ActionProtocol(Protocol):
48 """Protocol for action objects."""
50 deletable: bool
51 editable: bool
52 read: bool
53 show: bool
55 def __getattr__(self, name: str) -> Any:
56 """Allow access to dynamically added fields."""
57 class_name = self.__class__.__name__
58 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
61# Type alias for convenience
62Action: TypeAlias = ActionProtocol
65class UserProtocol(Protocol):
66 """Protocol for user objects."""
68 id: Any | None # Can be str or int
69 path: str
70 user_name: str | None
72 def __getattr__(self, name: str) -> Any:
73 """Allow access to dynamically added fields."""
74 class_name = self.__class__.__name__
75 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
78# Type alias for convenience
79User: TypeAlias = UserProtocol
82class CommentProtocol(Protocol):
83 """Protocol for comment objects."""
85 enabled: bool
86 count: int
87 strings: dict[str, Any]
88 all: list[Any]
90 def __getattr__(self, name: str) -> Any:
91 """Allow access to dynamically added fields."""
92 class_name = self.__class__.__name__
93 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
96# Type alias for convenience
97Comment: TypeAlias = CommentProtocol
100class LikeProtocol(Protocol):
101 """Protocol for like objects."""
103 enabled: bool
104 count: int
105 strings: dict[str, Any]
106 all: list[Any]
107 is_liked: bool
108 user_ids: list[int] | None
110 def __getattr__(self, name: str) -> Any:
111 """Allow access to dynamically added fields."""
112 class_name = self.__class__.__name__
113 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
116# Type alias for convenience
117Like: TypeAlias = LikeProtocol