Coverage for src/hush_hush/_generated/models/object_metadata.py: 54%

97 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-10-16 16:01 +0000

1# Code generated by openapi-python-client from hush-hush/api/openapi.yaml; DO NOT EDIT. 

2 

3from __future__ import annotations 

4 

5import datetime 

6from collections.abc import Mapping 

7from typing import TYPE_CHECKING, Any, TypeVar, cast 

8from uuid import UUID 

9 

10from attrs import define as _attrs_define 

11from attrs import field as _attrs_field 

12 

13from ..types import UNSET, Unset 

14 

15if TYPE_CHECKING: 

16 from ..models.actor import Actor 

17 

18 

19T = TypeVar("T", bound="ObjectMetadata") 

20 

21 

22@_attrs_define 

23class ObjectMetadata: 

24 """ 

25 Attributes: 

26 id (UUID): The object's UUID. Several objects can share a name (each is a variant, with its own value and 

27 consumers), so this is what tells them apart and what `id` selects. 

28 slug (str): A caller-chosen, unique identifier for an object - what every 

29 documented request path (URL, CLI, API) addresses it by. Letters of 

30 either case, digits, `_` and `-`, starting with a letter or digit; 

31 names are case-sensitive, so `Api_Token` and `api_token` are two 

32 secrets. Create and rename follow the same rule. The 

33 object's internal id is a separate, opaque value never exposed to 

34 or accepted from a caller (specs/secret-objects/spec.md's 

35 "Internal id decoupled from user-facing slug" requirement). 

36 tags (list[str]): Labels for grouping and filtering objects (`GET /objects?tag=`). 

37 Free-form, 1 to 32 characters from `a-z 0-9 . _ / -`, at most 10 

38 per object. Uppercase is converted to lowercase and duplicates are dropped. 

39 Metadata only - never part of the sealed value. A response always 

40 carries the array, empty when the object has none. 

41 used_by (list[str] | Unset): The consumers (repos or hosts) recorded as depending on this 

42 object. Set at creation, and replaceable later via 

43 UpdateObjectRequest's own used_by field - a plain value update 

44 that omits it leaves the list as it was. 

45 A consumer named more than once is recorded once. 

46 description (str | Unset): A free-text label set at creation, for a reader who only knows the 

47 slug. Fixed at creation - there is no way to change it later. 

48 keep_readable_copy (bool | Unset): Requests that the owner's own escrowed identity public key be 

49 included as an additional decrypt recipient, alongside whatever 

50 consumer recipients the client already resolved 

51 (specs/secret-objects/spec.md's "Opt-in owner-recipient inclusion 

52 at create time" requirement). Omitting this field (the default) 

53 means the owner is not added as a recipient - this service never 

54 makes ownership imply decrypt access on its own. 

55 

56 This is a client-side sealing instruction, not something this 

57 service enforces or verifies: it never decrypts, and never adds a 

58 recipient to `value` itself - the caller has to add the owner's 

59 public key (`GET /auth/identity`) to its own recipient list before 

60 sealing. A create or update response echoes back exactly what that 

61 same request asked for; it isn't persisted, so a later fetch never 

62 carries this field. 

63 created_at (datetime.datetime | Unset): When the object was created. Returned by `GET /objects`; left 

64 out of a create or update response. 

65 updated_at (datetime.datetime | Unset): When the object's value was last replaced - equal to 

66 `created_at` for an object never updated. Returned by 

67 `GET /objects`; left out of a create or update response. 

68 created_by (Actor | Unset): Who performed an audited write. `type` is `session` (the admin 

69 account, `id` is its actor id), `token` (a write token, `id` is its 

70 token id) or `consumer_token` (a consumer token, `id` is its id) - 

71 the same values `GET /audit-log` reports. 

72 updated_by (Actor | Unset): Who performed an audited write. `type` is `session` (the admin 

73 account, `id` is its actor id), `token` (a write token, `id` is its 

74 token id) or `consumer_token` (a consumer token, `id` is its id) - 

75 the same values `GET /audit-log` reports. 

76 """ 

77 

78 id: UUID 

79 slug: str 

80 tags: list[str] 

81 used_by: list[str] | Unset = UNSET 

82 description: str | Unset = UNSET 

83 keep_readable_copy: bool | Unset = UNSET 

84 created_at: datetime.datetime | Unset = UNSET 

85 updated_at: datetime.datetime | Unset = UNSET 

86 created_by: Actor | Unset = UNSET 

87 updated_by: Actor | Unset = UNSET 

88 additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) 

89 

90 def to_dict(self) -> dict[str, Any]: 

91 id = str(self.id) 

92 

93 slug = self.slug 

94 

95 tags = self.tags 

96 

97 used_by: list[str] | Unset = UNSET 

98 if not isinstance(self.used_by, Unset): 

99 used_by = self.used_by 

100 

101 description = self.description 

102 

103 keep_readable_copy = self.keep_readable_copy 

104 

105 created_at: str | Unset = UNSET 

106 if not isinstance(self.created_at, Unset): 

107 created_at = self.created_at.isoformat() 

108 

109 updated_at: str | Unset = UNSET 

110 if not isinstance(self.updated_at, Unset): 

111 updated_at = self.updated_at.isoformat() 

112 

113 created_by: dict[str, Any] | Unset = UNSET 

114 if not isinstance(self.created_by, Unset): 

115 created_by = self.created_by.to_dict() 

116 

117 updated_by: dict[str, Any] | Unset = UNSET 

118 if not isinstance(self.updated_by, Unset): 

119 updated_by = self.updated_by.to_dict() 

120 

121 field_dict: dict[str, Any] = {} 

122 field_dict.update(self.additional_properties) 

123 field_dict.update( 

124 { 

125 "id": id, 

126 "slug": slug, 

127 "tags": tags, 

128 } 

129 ) 

130 if used_by is not UNSET: 

131 field_dict["used_by"] = used_by 

132 if description is not UNSET: 

133 field_dict["description"] = description 

134 if keep_readable_copy is not UNSET: 

135 field_dict["keep_readable_copy"] = keep_readable_copy 

136 if created_at is not UNSET: 

137 field_dict["created_at"] = created_at 

138 if updated_at is not UNSET: 

139 field_dict["updated_at"] = updated_at 

140 if created_by is not UNSET: 

141 field_dict["created_by"] = created_by 

142 if updated_by is not UNSET: 

143 field_dict["updated_by"] = updated_by 

144 

145 return field_dict 

146 

147 @classmethod 

148 def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: 

149 from ..models.actor import Actor # noqa: PLC0415 

150 

151 d = dict(src_dict) 

152 id = UUID(d.pop("id")) 

153 

154 slug = d.pop("slug") 

155 

156 tags = cast(list[str], d.pop("tags")) 

157 

158 used_by = cast(list[str], d.pop("used_by", UNSET)) 

159 

160 description = d.pop("description", UNSET) 

161 

162 keep_readable_copy = d.pop("keep_readable_copy", UNSET) 

163 

164 _created_at = d.pop("created_at", UNSET) 

165 created_at: datetime.datetime | Unset 

166 if isinstance(_created_at, Unset): 

167 created_at = UNSET 

168 else: 

169 created_at = datetime.datetime.fromisoformat(_created_at) 

170 

171 _updated_at = d.pop("updated_at", UNSET) 

172 updated_at: datetime.datetime | Unset 

173 if isinstance(_updated_at, Unset): 

174 updated_at = UNSET 

175 else: 

176 updated_at = datetime.datetime.fromisoformat(_updated_at) 

177 

178 _created_by = d.pop("created_by", UNSET) 

179 created_by: Actor | Unset 

180 created_by = UNSET if isinstance(_created_by, Unset) else Actor.from_dict(_created_by) 

181 

182 _updated_by = d.pop("updated_by", UNSET) 

183 updated_by: Actor | Unset 

184 updated_by = UNSET if isinstance(_updated_by, Unset) else Actor.from_dict(_updated_by) 

185 

186 object_metadata = cls( 

187 id=id, 

188 slug=slug, 

189 tags=tags, 

190 used_by=used_by, 

191 description=description, 

192 keep_readable_copy=keep_readable_copy, 

193 created_at=created_at, 

194 updated_at=updated_at, 

195 created_by=created_by, 

196 updated_by=updated_by, 

197 ) 

198 

199 object_metadata.additional_properties = d 

200 return object_metadata 

201 

202 @property 

203 def additional_keys(self) -> list[str]: 

204 return list(self.additional_properties.keys()) 

205 

206 def __getitem__(self, key: str) -> Any: 

207 return self.additional_properties[key] 

208 

209 def __setitem__(self, key: str, value: Any) -> None: 

210 self.additional_properties[key] = value 

211 

212 def __delitem__(self, key: str) -> None: 

213 del self.additional_properties[key] 

214 

215 def __contains__(self, key: str) -> bool: 

216 return key in self.additional_properties