|
8 | 8 |
|
9 | 9 |
|
10 | 10 | class Vanity(Resource): |
11 | | - """Represents a Vanity resource with the ability to destroy itself.""" |
| 11 | + """A vanity resource. |
| 12 | +
|
| 13 | + Vanities maintain custom URL paths assigned to content. |
| 14 | +
|
| 15 | + Warnings |
| 16 | + -------- |
| 17 | + Vanity paths may only contain alphanumeric characters, hyphens, underscores, and slashes. |
| 18 | +
|
| 19 | + Vanities cannot have children. For example, if the vanity path "/finance/" exists, the vanity path "/finance/budget/" cannot. But, if "/finance" does not exist, both "/finance/budget/" and "/finance/report" are allowed. |
| 20 | +
|
| 21 | + The following vanities are reserved by Connect: |
| 22 | + - `/__` |
| 23 | + - `/favicon.ico` |
| 24 | + - `/connect` |
| 25 | + - `/apps` |
| 26 | + - `/users` |
| 27 | + - `/groups` |
| 28 | + - `/setpassword` |
| 29 | + - `/user-completion` |
| 30 | + - `/confirm` |
| 31 | + - `/recent` |
| 32 | + - `/reports` |
| 33 | + - `/plots` |
| 34 | + - `/unpublished` |
| 35 | + - `/settings` |
| 36 | + - `/metrics` |
| 37 | + - `/tokens` |
| 38 | + - `/help` |
| 39 | + - `/login` |
| 40 | + - `/welcome` |
| 41 | + - `/register` |
| 42 | + - `/resetpassword` |
| 43 | + - `/content` |
| 44 | + """ |
| 45 | + |
| 46 | + _fuid: str = "content_guid" |
| 47 | + """str : the foreign unique identifier field that points to the owner of this vanity, default is 'content_guid'""" |
12 | 48 |
|
13 | 49 | def __init__( |
14 | 50 | self, |
15 | 51 | /, |
16 | 52 | params: ResourceParameters, |
17 | 53 | *, |
18 | | - after_destroy: AfterDestroyCallback = lambda: None, |
| 54 | + after_destroy: Optional[AfterDestroyCallback] = None, |
19 | 55 | **kwargs, |
20 | 56 | ): |
| 57 | + """Initialize a Vanity. |
| 58 | +
|
| 59 | + Parameters |
| 60 | + ---------- |
| 61 | + params : ResourceParameters |
| 62 | + after_destroy : AfterDestroyCallback, optional |
| 63 | + Called after the Vanity is successfully destroyed, by default None |
| 64 | + """ |
21 | 65 | super().__init__(params, **kwargs) |
22 | 66 | self._after_destroy = after_destroy |
23 | 67 |
|
24 | 68 | def destroy(self) -> None: |
25 | | - """Destroy the vanity resource.""" |
| 69 | + """Destroy the vanity. |
| 70 | +
|
| 71 | + Raises |
| 72 | + ------ |
| 73 | + ValueError |
| 74 | + If the foreign unique identifier is missing or its value is `None`. |
| 75 | +
|
| 76 | + Warnings |
| 77 | + -------- |
| 78 | + This operation is irreversible. |
| 79 | +
|
| 80 | + Note |
| 81 | + ---- |
| 82 | + This action requires administrator privileges. |
| 83 | + """ |
26 | 84 | fuid = self.get("content_guid") |
27 | 85 | if fuid is None: |
28 | 86 | raise ValueError("Missing value for required field: 'content_guid'.") |
29 | 87 | endpoint = self.params.url + f"v1/content/{fuid}/vanity" |
30 | 88 | self.params.session.delete(endpoint) |
31 | | - self._after_destroy() |
| 89 | + |
| 90 | + if self._after_destroy: |
| 91 | + self._after_destroy() |
32 | 92 |
|
33 | 93 |
|
34 | 94 | class Vanities(Resources): |
35 | | - """Manages a collection of Vanity resources.""" |
| 95 | + """Manages a collection of vanities.""" |
36 | 96 |
|
37 | 97 | def all(self) -> List[Vanity]: |
38 | | - """Retrieve all vanity resources.""" |
| 98 | + """Retrieve all vanities. |
| 99 | +
|
| 100 | + Returns |
| 101 | + ------- |
| 102 | + List[Vanity] |
| 103 | +
|
| 104 | + Notes |
| 105 | + ----- |
| 106 | + This action requires administrator privileges. |
| 107 | + """ |
39 | 108 | endpoint = self.params.url + "v1/vanities" |
40 | 109 | response = self.params.session.get(endpoint) |
41 | 110 | results = response.json() |
42 | 111 | return [Vanity(self.params, **result) for result in results] |
43 | 112 |
|
44 | 113 |
|
45 | 114 | class VanityMixin(Resource): |
46 | | - """Mixin class to add vanity management capabilities to a resource.""" |
| 115 | + """Mixin class to add a vanity attribute to a resource.""" |
| 116 | + |
| 117 | + _uid: str = "guid" |
| 118 | + """str : the unique identifier field for this resource""" |
47 | 119 |
|
48 | 120 | def __init__(self, /, params: ResourceParameters, **kwargs): |
49 | 121 | super().__init__(params, **kwargs) |
@@ -71,37 +143,99 @@ def vanity(self) -> Optional[Vanity]: |
71 | 143 |
|
72 | 144 | @vanity.setter |
73 | 145 | def vanity(self, value: Union[str, dict]) -> None: |
74 | | - """Set the vanity using a path or dictionary of attributes.""" |
| 146 | + """Set the vanity. |
| 147 | +
|
| 148 | + Parameters |
| 149 | + ---------- |
| 150 | + value : str or dict |
| 151 | + The value can be a string or a dictionary. If provided as a string, it represents the vanity path. If provided as a dictionary, it contains key-value pairs with detailed information about the object. |
| 152 | + """ |
75 | 153 | if isinstance(value, str): |
76 | 154 | self.set_vanity(path=value) |
77 | 155 | elif isinstance(value, dict): |
78 | 156 | self.set_vanity(**value) |
79 | | - self.reset() |
| 157 | + self.reset_vanity() |
80 | 158 |
|
81 | 159 | @vanity.deleter |
82 | 160 | def vanity(self) -> None: |
83 | | - """Delete the vanity resource.""" |
| 161 | + """Destroy the vanity. |
| 162 | +
|
| 163 | + Warnings |
| 164 | + -------- |
| 165 | + This operation is irreversible. |
| 166 | +
|
| 167 | + Note |
| 168 | + ---- |
| 169 | + This action requires administrator privileges. |
| 170 | +
|
| 171 | + See Also |
| 172 | + -------- |
| 173 | + reset_vanity |
| 174 | + """ |
84 | 175 | if self._vanity: |
85 | 176 | self._vanity.destroy() |
86 | | - self.reset() |
| 177 | + self.reset_vanity() |
87 | 178 |
|
88 | | - def reset(self) -> None: |
89 | | - """Reset the cached vanity resource.""" |
| 179 | + def reset_vanity(self) -> None: |
| 180 | + """Unload the cached vanity. |
| 181 | +
|
| 182 | + Forces the next access, if any, to query the vanity from the Connect server. |
| 183 | + """ |
90 | 184 | self._vanity = None |
91 | 185 |
|
92 | 186 | @overload |
93 | | - def set_vanity(self, *, path: str) -> None: ... |
| 187 | + def set_vanity(self, *, path: str) -> None: |
| 188 | + """Set the vanity. |
| 189 | +
|
| 190 | + Parameters |
| 191 | + ---------- |
| 192 | + path : str |
| 193 | + The vanity path. |
| 194 | +
|
| 195 | + Raises |
| 196 | + ------ |
| 197 | + ValueError |
| 198 | + If the unique identifier field is missing or the value is None. |
| 199 | + """ |
| 200 | + ... |
94 | 201 |
|
95 | 202 | @overload |
96 | | - def set_vanity(self, *, path: str, force: bool) -> None: ... |
| 203 | + def set_vanity(self, *, path: str, force: bool) -> None: |
| 204 | + """Set the vanity. |
| 205 | +
|
| 206 | + Parameters |
| 207 | + ---------- |
| 208 | + path : str |
| 209 | + The vanity path. |
| 210 | + force : bool |
| 211 | + If `True`, overwrite the ownership of this vanity to this resource, default `False` |
| 212 | +
|
| 213 | + Raises |
| 214 | + ------ |
| 215 | + ValueError |
| 216 | + If the unique identifier field is missing or the value is None. |
| 217 | + """ |
| 218 | + ... |
97 | 219 |
|
98 | 220 | @overload |
99 | | - def set_vanity(self, **attributes) -> None: ... |
| 221 | + def set_vanity(self, **attributes) -> None: |
| 222 | + """Set the vanity. |
| 223 | +
|
| 224 | + Parameters |
| 225 | + ---------- |
| 226 | + **attributes : dict, optional |
| 227 | + Arbitrary vanity attributes. All attributes are passed as the request body to POST 'v1/content/:guid/vanity' |
| 228 | +
|
| 229 | + Possible keys may include: |
| 230 | + - `path` : str |
| 231 | + - `force` : bool |
| 232 | + """ |
| 233 | + ... |
100 | 234 |
|
101 | 235 | def set_vanity(self, **attributes) -> None: |
102 | | - """Set or update the vanity resource with given attributes.""" |
103 | | - uid = self.get("guid") |
104 | | - if uid is None: |
105 | | - raise ValueError("Missing value for required field: 'guid'.") |
106 | | - endpoint = self.params.url + f"v1/content/{uid}/vanity" |
| 236 | + """Set the vanity.""" |
| 237 | + v = self.get(self._uid) |
| 238 | + if v is None: |
| 239 | + raise ValueError(f"Missing value for required field: '{self._uid}'.") |
| 240 | + endpoint = self.params.url + f"v1/content/{v}/vanity" |
107 | 241 | self.params.session.put(endpoint, json=attributes) |
0 commit comments