docket-client 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. docket/__init__.py +8 -0
  2. docket/api/__init__.py +1 -0
  3. docket/api/access/__init__.py +1 -0
  4. docket/api/access/add_principal.py +193 -0
  5. docket/api/access/archive_role_assignment.py +182 -0
  6. docket/api/access/create_api_token.py +198 -0
  7. docket/api/access/create_application_principal.py +188 -0
  8. docket/api/access/create_role_assignment.py +194 -0
  9. docket/api/access/list_api_tokens.py +184 -0
  10. docket/api/access/list_principals.py +184 -0
  11. docket/api/access/list_role_assignments.py +200 -0
  12. docket/api/access/revoke_api_token.py +173 -0
  13. docket/api/identity/__init__.py +1 -0
  14. docket/api/identity/create_my_api_token.py +206 -0
  15. docket/api/identity/get_me.py +127 -0
  16. docket/api/identity/list_my_api_tokens.py +151 -0
  17. docket/api/identity/revoke_my_api_token.py +178 -0
  18. docket/api/recurring_acquisitions/__init__.py +1 -0
  19. docket/api/recurring_acquisitions/archive_recurring_acquisition.py +207 -0
  20. docket/api/recurring_acquisitions/create_recurring_acquisition.py +218 -0
  21. docket/api/recurring_acquisitions/get_recurring_acquisition.py +163 -0
  22. docket/api/recurring_acquisitions/list_recurring_acquisitions.py +248 -0
  23. docket/api/recurring_acquisitions/preview_recurring_acquisition.py +187 -0
  24. docket/api/recurring_acquisitions/preview_split_recurring_acquisition.py +232 -0
  25. docket/api/recurring_acquisitions/split_recurring_acquisition.py +258 -0
  26. docket/api/runs/__init__.py +1 -0
  27. docket/api/runs/get_run.py +160 -0
  28. docket/api/runs/list_runs.py +180 -0
  29. docket/api/runs/report_run_outcome.py +206 -0
  30. docket/api/scheduled_acquisitions/__init__.py +1 -0
  31. docket/api/scheduled_acquisitions/archive_scheduled_acquisition.py +203 -0
  32. docket/api/scheduled_acquisitions/create_scheduled_acquisition.py +185 -0
  33. docket/api/scheduled_acquisitions/get_resolved_settings.py +169 -0
  34. docket/api/scheduled_acquisitions/get_scheduled_acquisition.py +159 -0
  35. docket/api/scheduled_acquisitions/list_active_acquisitions.py +297 -0
  36. docket/api/scheduled_acquisitions/list_runs_for_scheduled_acquisition.py +191 -0
  37. docket/api/scheduled_acquisitions/list_scheduled_acquisitions.py +332 -0
  38. docket/api/scheduled_acquisitions/preview_scheduled_acquisition_edit.py +224 -0
  39. docket/api/scheduled_acquisitions/set_planning_status.py +199 -0
  40. docket/api/scheduled_acquisitions/start_run.py +221 -0
  41. docket/api/scheduled_acquisitions/update_scheduled_acquisition.py +226 -0
  42. docket/api/settings/__init__.py +1 -0
  43. docket/api/settings/list_behavior_curriculum_discriminator_values.py +188 -0
  44. docket/api/settings/list_behavior_curriculum_settings.py +199 -0
  45. docket/api/settings/list_fip_discriminator_values.py +184 -0
  46. docket/api/settings/list_fip_settings.py +195 -0
  47. docket/api/settings/list_live_behavior_curriculum_settings.py +233 -0
  48. docket/api/settings/list_live_fip_settings.py +225 -0
  49. docket/api/settings/preview_behavior_curriculum_settings.py +191 -0
  50. docket/api/settings/preview_fip_settings.py +177 -0
  51. docket/api/settings/push_behavior_curriculum_settings.py +222 -0
  52. docket/api/settings/push_fip_settings.py +206 -0
  53. docket/api/templates/__init__.py +1 -0
  54. docket/api/templates/archive_template.py +203 -0
  55. docket/api/templates/create_template.py +206 -0
  56. docket/api/templates/get_template.py +159 -0
  57. docket/api/templates/list_templates.py +174 -0
  58. docket/api/templates/update_template.py +234 -0
  59. docket/api/vocabulary/__init__.py +1 -0
  60. docket/api/vocabulary/list_instruments.py +165 -0
  61. docket/api/vocabulary/list_persons.py +132 -0
  62. docket/api/vocabulary/list_projects.py +132 -0
  63. docket/api/vocabulary/list_subjects.py +132 -0
  64. docket/api/vocabulary/lookup_person.py +166 -0
  65. docket/api/vocabulary/lookup_subject.py +166 -0
  66. docket/api/vocabulary/sync_vocabulary.py +148 -0
  67. docket/client.py +272 -0
  68. docket/errors.py +16 -0
  69. docket/models/__init__.py +221 -0
  70. docket/models/access_role.py +12 -0
  71. docket/models/access_role_nullable_type_1.py +12 -0
  72. docket/models/access_role_nullable_type_2_type_1.py +12 -0
  73. docket/models/access_role_nullable_type_3_type_1.py +12 -0
  74. docket/models/acquisition_variable.py +72 -0
  75. docket/models/acquisition_warning.py +126 -0
  76. docket/models/add_principal_request.py +83 -0
  77. docket/models/api_token_response.py +271 -0
  78. docket/models/api_token_status.py +10 -0
  79. docket/models/archive_recurring_acquisition_request.py +77 -0
  80. docket/models/archive_recurring_acquisition_response.py +83 -0
  81. docket/models/archive_scheduled_acquisition_request.py +78 -0
  82. docket/models/archive_template_request.py +66 -0
  83. docket/models/auth_mode.py +10 -0
  84. docket/models/behavior_curriculum_push_settings_request.py +85 -0
  85. docket/models/behavior_curriculum_settings.py +55 -0
  86. docket/models/behavior_curriculum_settings_preview_response.py +102 -0
  87. docket/models/behavior_curriculum_settings_preview_response_promoted.py +50 -0
  88. docket/models/behavior_curriculum_settings_version_response.py +160 -0
  89. docket/models/behavior_curriculum_settings_version_response_promoted.py +50 -0
  90. docket/models/caller_kind.py +11 -0
  91. docket/models/create_api_token_request.py +97 -0
  92. docket/models/create_application_principal_request.py +65 -0
  93. docket/models/create_personal_api_token_request.py +167 -0
  94. docket/models/create_recurring_acquisition_request.py +269 -0
  95. docket/models/create_role_assignment_request.py +99 -0
  96. docket/models/create_scheduled_acquisition_request.py +265 -0
  97. docket/models/create_template_request.py +323 -0
  98. docket/models/created_api_token_response.py +82 -0
  99. docket/models/effective_status.py +15 -0
  100. docket/models/fip_color.py +13 -0
  101. docket/models/fip_fiber.py +93 -0
  102. docket/models/fip_mode.py +9 -0
  103. docket/models/fip_push_settings_request.py +82 -0
  104. docket/models/fip_settings.py +91 -0
  105. docket/models/fip_settings_preview_response.py +97 -0
  106. docket/models/fip_settings_preview_response_promoted.py +50 -0
  107. docket/models/fip_settings_version_response.py +155 -0
  108. docket/models/fip_settings_version_response_promoted.py +50 -0
  109. docket/models/future_occurrences.py +9 -0
  110. docket/models/get_resolved_settings_response_200.py +65 -0
  111. docket/models/held_role_response.py +116 -0
  112. docket/models/http_validation_problem_details.py +204 -0
  113. docket/models/http_validation_problem_details_errors.py +59 -0
  114. docket/models/instrument_response.py +91 -0
  115. docket/models/kept_occurrence.py +85 -0
  116. docket/models/kept_occurrence_reason.py +10 -0
  117. docket/models/list_active_acquisitions_effective_status_item.py +15 -0
  118. docket/models/list_scheduled_acquisitions_planning_status.py +11 -0
  119. docket/models/me_caller.py +118 -0
  120. docket/models/me_permission.py +98 -0
  121. docket/models/me_response.py +158 -0
  122. docket/models/me_role.py +75 -0
  123. docket/models/occurrence_preview.py +121 -0
  124. docket/models/occurrence_summary.py +126 -0
  125. docket/models/occurrence_warnings.py +91 -0
  126. docket/models/permission_action.py +12 -0
  127. docket/models/person_assignment.py +74 -0
  128. docket/models/person_lookup_response.py +131 -0
  129. docket/models/person_response.py +103 -0
  130. docket/models/person_role.py +9 -0
  131. docket/models/personal_token_limits.py +92 -0
  132. docket/models/planning_status.py +11 -0
  133. docket/models/principal_kind.py +9 -0
  134. docket/models/principal_response.py +216 -0
  135. docket/models/problem_details.py +177 -0
  136. docket/models/project_response.py +75 -0
  137. docket/models/recurrence_exception_kind.py +13 -0
  138. docket/models/recurrence_exception_response.py +103 -0
  139. docket/models/recurrence_frequency.py +9 -0
  140. docket/models/recurrence_preview_response.py +101 -0
  141. docket/models/recurrence_rule.py +207 -0
  142. docket/models/recurring_acquisition_created_response.py +123 -0
  143. docket/models/recurring_acquisition_detail_response.py +105 -0
  144. docket/models/recurring_acquisition_response.py +326 -0
  145. docket/models/report_run_outcome_request.py +89 -0
  146. docket/models/resolution_mode.py +10 -0
  147. docket/models/resolved_settings.py +73 -0
  148. docket/models/role_assignment_response.py +157 -0
  149. docket/models/role_origin.py +10 -0
  150. docket/models/role_source_kind.py +10 -0
  151. docket/models/run_origin.py +9 -0
  152. docket/models/run_outcome.py +9 -0
  153. docket/models/run_response.py +181 -0
  154. docket/models/run_settings_snapshot.py +72 -0
  155. docket/models/run_start_response.py +91 -0
  156. docket/models/run_start_response_settings.py +65 -0
  157. docket/models/run_status.py +11 -0
  158. docket/models/scheduled_acquisition_edit_preview_response.py +150 -0
  159. docket/models/scheduled_acquisition_response.py +366 -0
  160. docket/models/set_planning_status_request.py +90 -0
  161. docket/models/settings_selector.py +138 -0
  162. docket/models/skipped_occurrence.py +85 -0
  163. docket/models/split_preview_response.py +129 -0
  164. docket/models/split_recurring_acquisition_request.py +261 -0
  165. docket/models/split_recurring_acquisition_response.py +159 -0
  166. docket/models/start_run_request.py +73 -0
  167. docket/models/subject_lookup_response.py +149 -0
  168. docket/models/subject_response.py +128 -0
  169. docket/models/sync_counts.py +80 -0
  170. docket/models/sync_response.py +81 -0
  171. docket/models/template_response.py +302 -0
  172. docket/models/update_scheduled_acquisition_request.py +235 -0
  173. docket/models/update_template_request.py +279 -0
  174. docket/models/weekday.py +14 -0
  175. docket/types.py +54 -0
  176. docket_auth/__init__.py +239 -0
  177. docket_client-0.3.2.dist-info/METADATA +233 -0
  178. docket_client-0.3.2.dist-info/RECORD +188 -0
  179. docket_client-0.3.2.dist-info/WHEEL +4 -0
  180. docket_client-0.3.2.dist-info/entry_points.txt +2 -0
  181. docket_mcp/__init__.py +6 -0
  182. docket_mcp/api.py +207 -0
  183. docket_mcp/config.py +57 -0
  184. docket_mcp/server.py +78 -0
  185. docket_mcp/signin.py +155 -0
  186. docket_mcp/slots.py +80 -0
  187. docket_mcp/times.py +160 -0
  188. docket_mcp/tools.py +1202 -0
@@ -0,0 +1,216 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ from ..types import UNSET, Unset
10
+
11
+ from ..models.principal_kind import PrincipalKind
12
+ from ..types import UNSET, Unset
13
+ from typing import cast
14
+ import datetime
15
+
16
+ if TYPE_CHECKING:
17
+ from ..models.held_role_response import HeldRoleResponse
18
+
19
+
20
+ T = TypeVar("T", bound="PrincipalResponse")
21
+
22
+
23
+ @_attrs_define
24
+ class PrincipalResponse:
25
+ """A person or application Docket knows about.
26
+
27
+ Attributes:
28
+ object_id (str): Directory object id (the identity key).
29
+ kind (PrincipalKind): What kind of directory principal a role is held by.
30
+ display_name (str): For display only.
31
+ user_principal_name (None | str): Sign-in name; for display only, never an identity key. Null for applications.
32
+ first_seen_at (datetime.datetime | None):
33
+ last_seen_at (datetime.datetime | None):
34
+ is_bootstrap (bool): True for object ids in `Auth:BootstrapAdmins`: always Admin, set in server configuration.
35
+ roles (list[HeldRoleResponse]): Their roles: active assignments, plus Admin when bootstrap. The default role is
36
+ not listed.
37
+ last_interactive_sign_in_at (datetime.datetime | None | Unset): Last time they presented an Entra token
38
+ themselves (API tokens do not count), accurate to a few minutes. Their API tokens work only while this is
39
+ recent.
40
+ """
41
+
42
+ object_id: str
43
+ kind: PrincipalKind
44
+ display_name: str
45
+ user_principal_name: None | str
46
+ first_seen_at: datetime.datetime | None
47
+ last_seen_at: datetime.datetime | None
48
+ is_bootstrap: bool
49
+ roles: list[HeldRoleResponse]
50
+ last_interactive_sign_in_at: datetime.datetime | None | Unset = UNSET
51
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
52
+
53
+ def to_dict(self) -> dict[str, Any]:
54
+ from ..models.held_role_response import HeldRoleResponse
55
+
56
+ object_id = self.object_id
57
+
58
+ kind = self.kind.value
59
+
60
+ display_name = self.display_name
61
+
62
+ user_principal_name: None | str
63
+ user_principal_name = self.user_principal_name
64
+
65
+ first_seen_at: None | str
66
+ if isinstance(self.first_seen_at, datetime.datetime):
67
+ first_seen_at = self.first_seen_at.isoformat()
68
+ else:
69
+ first_seen_at = self.first_seen_at
70
+
71
+ last_seen_at: None | str
72
+ if isinstance(self.last_seen_at, datetime.datetime):
73
+ last_seen_at = self.last_seen_at.isoformat()
74
+ else:
75
+ last_seen_at = self.last_seen_at
76
+
77
+ is_bootstrap = self.is_bootstrap
78
+
79
+ roles = []
80
+ for roles_item_data in self.roles:
81
+ roles_item = roles_item_data.to_dict()
82
+ roles.append(roles_item)
83
+
84
+ last_interactive_sign_in_at: None | str | Unset
85
+ if isinstance(self.last_interactive_sign_in_at, Unset):
86
+ last_interactive_sign_in_at = UNSET
87
+ elif isinstance(self.last_interactive_sign_in_at, datetime.datetime):
88
+ last_interactive_sign_in_at = self.last_interactive_sign_in_at.isoformat()
89
+ else:
90
+ last_interactive_sign_in_at = self.last_interactive_sign_in_at
91
+
92
+ field_dict: dict[str, Any] = {}
93
+ field_dict.update(self.additional_properties)
94
+ field_dict.update(
95
+ {
96
+ "object_id": object_id,
97
+ "kind": kind,
98
+ "display_name": display_name,
99
+ "user_principal_name": user_principal_name,
100
+ "first_seen_at": first_seen_at,
101
+ "last_seen_at": last_seen_at,
102
+ "is_bootstrap": is_bootstrap,
103
+ "roles": roles,
104
+ }
105
+ )
106
+ if last_interactive_sign_in_at is not UNSET:
107
+ field_dict["last_interactive_sign_in_at"] = last_interactive_sign_in_at
108
+
109
+ return field_dict
110
+
111
+ @classmethod
112
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
113
+ from ..models.held_role_response import HeldRoleResponse
114
+
115
+ d = dict(src_dict)
116
+ object_id = d.pop("object_id")
117
+
118
+ kind = PrincipalKind(d.pop("kind"))
119
+
120
+ display_name = d.pop("display_name")
121
+
122
+ def _parse_user_principal_name(data: object) -> None | str:
123
+ if data is None:
124
+ return data
125
+ return cast(None | str, data)
126
+
127
+ user_principal_name = _parse_user_principal_name(d.pop("user_principal_name"))
128
+
129
+ def _parse_first_seen_at(data: object) -> datetime.datetime | None:
130
+ if data is None:
131
+ return data
132
+ try:
133
+ if not isinstance(data, str):
134
+ raise TypeError()
135
+ componentsschemas_instant_nullable_type_1 = datetime.datetime.fromisoformat(data)
136
+
137
+ return componentsschemas_instant_nullable_type_1
138
+ except (TypeError, ValueError, AttributeError, KeyError):
139
+ pass
140
+ return cast(datetime.datetime | None, data)
141
+
142
+ first_seen_at = _parse_first_seen_at(d.pop("first_seen_at"))
143
+
144
+ def _parse_last_seen_at(data: object) -> datetime.datetime | None:
145
+ if data is None:
146
+ return data
147
+ try:
148
+ if not isinstance(data, str):
149
+ raise TypeError()
150
+ componentsschemas_instant_nullable_type_1 = datetime.datetime.fromisoformat(data)
151
+
152
+ return componentsschemas_instant_nullable_type_1
153
+ except (TypeError, ValueError, AttributeError, KeyError):
154
+ pass
155
+ return cast(datetime.datetime | None, data)
156
+
157
+ last_seen_at = _parse_last_seen_at(d.pop("last_seen_at"))
158
+
159
+ is_bootstrap = d.pop("is_bootstrap")
160
+
161
+ roles = []
162
+ _roles = d.pop("roles")
163
+ for roles_item_data in _roles:
164
+ roles_item = HeldRoleResponse.from_dict(roles_item_data)
165
+
166
+ roles.append(roles_item)
167
+
168
+ def _parse_last_interactive_sign_in_at(data: object) -> datetime.datetime | None | Unset:
169
+ if data is None:
170
+ return data
171
+ if isinstance(data, Unset):
172
+ return data
173
+ try:
174
+ if not isinstance(data, str):
175
+ raise TypeError()
176
+ last_interactive_sign_in_at_type_1 = datetime.datetime.fromisoformat(data)
177
+
178
+ return last_interactive_sign_in_at_type_1
179
+ except (TypeError, ValueError, AttributeError, KeyError):
180
+ pass
181
+ return cast(datetime.datetime | None | Unset, data)
182
+
183
+ last_interactive_sign_in_at = _parse_last_interactive_sign_in_at(
184
+ d.pop("last_interactive_sign_in_at", UNSET)
185
+ )
186
+
187
+ principal_response = cls(
188
+ object_id=object_id,
189
+ kind=kind,
190
+ display_name=display_name,
191
+ user_principal_name=user_principal_name,
192
+ first_seen_at=first_seen_at,
193
+ last_seen_at=last_seen_at,
194
+ is_bootstrap=is_bootstrap,
195
+ roles=roles,
196
+ last_interactive_sign_in_at=last_interactive_sign_in_at,
197
+ )
198
+
199
+ principal_response.additional_properties = d
200
+ return principal_response
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
@@ -0,0 +1,177 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ from ..types import UNSET, Unset
10
+
11
+ from ..types import UNSET, Unset
12
+ from typing import cast
13
+
14
+
15
+ T = TypeVar("T", bound="ProblemDetails")
16
+
17
+
18
+ @_attrs_define
19
+ class ProblemDetails:
20
+ """
21
+ Attributes:
22
+ code (str): Stable machine-readable error code, e.g. not_found, validation_failed, version_conflict,
23
+ settings_not_available.
24
+ request_id (str): Correlation id of the request (the X-Request-Id response header); quote it when reporting a
25
+ problem.
26
+ type_ (None | str | Unset):
27
+ title (None | str | Unset):
28
+ status (int | None | Unset):
29
+ detail (None | str | Unset):
30
+ instance (None | str | Unset):
31
+ """
32
+
33
+ code: str
34
+ request_id: str
35
+ type_: None | str | Unset = UNSET
36
+ title: None | str | Unset = UNSET
37
+ status: int | None | Unset = UNSET
38
+ detail: None | str | Unset = UNSET
39
+ instance: None | str | Unset = UNSET
40
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
41
+
42
+ def to_dict(self) -> dict[str, Any]:
43
+ code = self.code
44
+
45
+ request_id = self.request_id
46
+
47
+ type_: None | str | Unset
48
+ if isinstance(self.type_, Unset):
49
+ type_ = UNSET
50
+ else:
51
+ type_ = self.type_
52
+
53
+ title: None | str | Unset
54
+ if isinstance(self.title, Unset):
55
+ title = UNSET
56
+ else:
57
+ title = self.title
58
+
59
+ status: int | None | Unset
60
+ if isinstance(self.status, Unset):
61
+ status = UNSET
62
+ else:
63
+ status = self.status
64
+
65
+ detail: None | str | Unset
66
+ if isinstance(self.detail, Unset):
67
+ detail = UNSET
68
+ else:
69
+ detail = self.detail
70
+
71
+ instance: None | str | Unset
72
+ if isinstance(self.instance, Unset):
73
+ instance = UNSET
74
+ else:
75
+ instance = self.instance
76
+
77
+ field_dict: dict[str, Any] = {}
78
+ field_dict.update(self.additional_properties)
79
+ field_dict.update(
80
+ {
81
+ "code": code,
82
+ "request_id": request_id,
83
+ }
84
+ )
85
+ if type_ is not UNSET:
86
+ field_dict["type"] = type_
87
+ if title is not UNSET:
88
+ field_dict["title"] = title
89
+ if status is not UNSET:
90
+ field_dict["status"] = status
91
+ if detail is not UNSET:
92
+ field_dict["detail"] = detail
93
+ if instance is not UNSET:
94
+ field_dict["instance"] = instance
95
+
96
+ return field_dict
97
+
98
+ @classmethod
99
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
100
+ d = dict(src_dict)
101
+ code = d.pop("code")
102
+
103
+ request_id = d.pop("request_id")
104
+
105
+ def _parse_type_(data: object) -> None | str | Unset:
106
+ if data is None:
107
+ return data
108
+ if isinstance(data, Unset):
109
+ return data
110
+ return cast(None | str | Unset, data)
111
+
112
+ type_ = _parse_type_(d.pop("type", UNSET))
113
+
114
+ def _parse_title(data: object) -> None | str | Unset:
115
+ if data is None:
116
+ return data
117
+ if isinstance(data, Unset):
118
+ return data
119
+ return cast(None | str | Unset, data)
120
+
121
+ title = _parse_title(d.pop("title", UNSET))
122
+
123
+ def _parse_status(data: object) -> int | None | Unset:
124
+ if data is None:
125
+ return data
126
+ if isinstance(data, Unset):
127
+ return data
128
+ return cast(int | None | Unset, data)
129
+
130
+ status = _parse_status(d.pop("status", UNSET))
131
+
132
+ def _parse_detail(data: object) -> None | str | Unset:
133
+ if data is None:
134
+ return data
135
+ if isinstance(data, Unset):
136
+ return data
137
+ return cast(None | str | Unset, data)
138
+
139
+ detail = _parse_detail(d.pop("detail", UNSET))
140
+
141
+ def _parse_instance(data: object) -> None | str | Unset:
142
+ if data is None:
143
+ return data
144
+ if isinstance(data, Unset):
145
+ return data
146
+ return cast(None | str | Unset, data)
147
+
148
+ instance = _parse_instance(d.pop("instance", UNSET))
149
+
150
+ problem_details = cls(
151
+ code=code,
152
+ request_id=request_id,
153
+ type_=type_,
154
+ title=title,
155
+ status=status,
156
+ detail=detail,
157
+ instance=instance,
158
+ )
159
+
160
+ problem_details.additional_properties = d
161
+ return problem_details
162
+
163
+ @property
164
+ def additional_keys(self) -> list[str]:
165
+ return list(self.additional_properties.keys())
166
+
167
+ def __getitem__(self, key: str) -> Any:
168
+ return self.additional_properties[key]
169
+
170
+ def __setitem__(self, key: str, value: Any) -> None:
171
+ self.additional_properties[key] = value
172
+
173
+ def __delitem__(self, key: str) -> None:
174
+ del self.additional_properties[key]
175
+
176
+ def __contains__(self, key: str) -> bool:
177
+ return key in self.additional_properties
@@ -0,0 +1,75 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ from ..types import UNSET, Unset
10
+
11
+ from typing import cast
12
+ import datetime
13
+
14
+
15
+ T = TypeVar("T", bound="ProjectResponse")
16
+
17
+
18
+ @_attrs_define
19
+ class ProjectResponse:
20
+ """
21
+ Attributes:
22
+ id (str):
23
+ synced_at (datetime.datetime): UTC instant, ISO 8601 with offset, e.g. 2026-10-15T16:00:00Z.
24
+ """
25
+
26
+ id: str
27
+ synced_at: datetime.datetime
28
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
29
+
30
+ def to_dict(self) -> dict[str, Any]:
31
+ id = self.id
32
+
33
+ synced_at = self.synced_at.isoformat()
34
+
35
+ field_dict: dict[str, Any] = {}
36
+ field_dict.update(self.additional_properties)
37
+ field_dict.update(
38
+ {
39
+ "id": id,
40
+ "synced_at": synced_at,
41
+ }
42
+ )
43
+
44
+ return field_dict
45
+
46
+ @classmethod
47
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
48
+ d = dict(src_dict)
49
+ id = d.pop("id")
50
+
51
+ synced_at = datetime.datetime.fromisoformat(d.pop("synced_at"))
52
+
53
+ project_response = cls(
54
+ id=id,
55
+ synced_at=synced_at,
56
+ )
57
+
58
+ project_response.additional_properties = d
59
+ return project_response
60
+
61
+ @property
62
+ def additional_keys(self) -> list[str]:
63
+ return list(self.additional_properties.keys())
64
+
65
+ def __getitem__(self, key: str) -> Any:
66
+ return self.additional_properties[key]
67
+
68
+ def __setitem__(self, key: str, value: Any) -> None:
69
+ self.additional_properties[key] = value
70
+
71
+ def __delitem__(self, key: str) -> None:
72
+ del self.additional_properties[key]
73
+
74
+ def __contains__(self, key: str) -> bool:
75
+ return key in self.additional_properties
@@ -0,0 +1,13 @@
1
+ from enum import Enum
2
+
3
+
4
+ class RecurrenceExceptionKind(str, Enum):
5
+ ARCHIVED = "archived"
6
+ EDITED = "edited"
7
+ KEPT_FROM_PREVIOUS = "kept_from_previous"
8
+ REMOVED_IN_PREVIOUS = "removed_in_previous"
9
+ SKIPPED_DST_AMBIGUOUS = "skipped_dst_ambiguous"
10
+ SKIPPED_DST_GAP = "skipped_dst_gap"
11
+
12
+ def __str__(self) -> str:
13
+ return str(self.value)
@@ -0,0 +1,103 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ from ..types import UNSET, Unset
10
+
11
+ from ..models.recurrence_exception_kind import RecurrenceExceptionKind
12
+ from typing import cast
13
+ import datetime
14
+
15
+
16
+ T = TypeVar("T", bound="RecurrenceExceptionResponse")
17
+
18
+
19
+ @_attrs_define
20
+ class RecurrenceExceptionResponse:
21
+ """A recorded exception to the rule.
22
+
23
+ Attributes:
24
+ occurrence_local_date (datetime.date): Calendar date, e.g. 2026-10-15.
25
+ kind (RecurrenceExceptionKind): Why an occurrence has no acquisition, or what happened to it afterwards.
26
+ scheduled_acquisition_id (int | None): The occurrence this is about; null for DST-skipped dates. For
27
+ `kept_from_previous` it is the
28
+ kept occurrence of the previous series.
29
+ created_at (datetime.datetime): UTC instant, ISO 8601 with offset, e.g. 2026-10-15T16:00:00Z.
30
+ """
31
+
32
+ occurrence_local_date: datetime.date
33
+ kind: RecurrenceExceptionKind
34
+ scheduled_acquisition_id: int | None
35
+ created_at: datetime.datetime
36
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
37
+
38
+ def to_dict(self) -> dict[str, Any]:
39
+ occurrence_local_date = self.occurrence_local_date.isoformat()
40
+
41
+ kind = self.kind.value
42
+
43
+ scheduled_acquisition_id: int | None
44
+ scheduled_acquisition_id = self.scheduled_acquisition_id
45
+
46
+ created_at = self.created_at.isoformat()
47
+
48
+ field_dict: dict[str, Any] = {}
49
+ field_dict.update(self.additional_properties)
50
+ field_dict.update(
51
+ {
52
+ "occurrence_local_date": occurrence_local_date,
53
+ "kind": kind,
54
+ "scheduled_acquisition_id": scheduled_acquisition_id,
55
+ "created_at": created_at,
56
+ }
57
+ )
58
+
59
+ return field_dict
60
+
61
+ @classmethod
62
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
63
+ d = dict(src_dict)
64
+ occurrence_local_date = datetime.date.fromisoformat(d.pop("occurrence_local_date"))
65
+
66
+ kind = RecurrenceExceptionKind(d.pop("kind"))
67
+
68
+ def _parse_scheduled_acquisition_id(data: object) -> int | None:
69
+ if data is None:
70
+ return data
71
+ return cast(int | None, data)
72
+
73
+ scheduled_acquisition_id = _parse_scheduled_acquisition_id(
74
+ d.pop("scheduled_acquisition_id")
75
+ )
76
+
77
+ created_at = datetime.datetime.fromisoformat(d.pop("created_at"))
78
+
79
+ recurrence_exception_response = cls(
80
+ occurrence_local_date=occurrence_local_date,
81
+ kind=kind,
82
+ scheduled_acquisition_id=scheduled_acquisition_id,
83
+ created_at=created_at,
84
+ )
85
+
86
+ recurrence_exception_response.additional_properties = d
87
+ return recurrence_exception_response
88
+
89
+ @property
90
+ def additional_keys(self) -> list[str]:
91
+ return list(self.additional_properties.keys())
92
+
93
+ def __getitem__(self, key: str) -> Any:
94
+ return self.additional_properties[key]
95
+
96
+ def __setitem__(self, key: str, value: Any) -> None:
97
+ self.additional_properties[key] = value
98
+
99
+ def __delitem__(self, key: str) -> None:
100
+ del self.additional_properties[key]
101
+
102
+ def __contains__(self, key: str) -> bool:
103
+ return key in self.additional_properties
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+
4
+ class RecurrenceFrequency(str, Enum):
5
+ DAILY = "daily"
6
+ WEEKLY = "weekly"
7
+
8
+ def __str__(self) -> str:
9
+ return str(self.value)
@@ -0,0 +1,101 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ from ..types import UNSET, Unset
10
+
11
+ from typing import cast
12
+
13
+ if TYPE_CHECKING:
14
+ from ..models.occurrence_preview import OccurrencePreview
15
+ from ..models.skipped_occurrence import SkippedOccurrence
16
+
17
+
18
+ T = TypeVar("T", bound="RecurrencePreviewResponse")
19
+
20
+
21
+ @_attrs_define
22
+ class RecurrencePreviewResponse:
23
+ """What creating the series would do. Nothing was written.
24
+
25
+ Attributes:
26
+ occurrences (list[OccurrencePreview]): Occurrences that would be created, in order.
27
+ skipped (list[SkippedOccurrence]): Occurrences that would be skipped, in order.
28
+ """
29
+
30
+ occurrences: list[OccurrencePreview]
31
+ skipped: list[SkippedOccurrence]
32
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
33
+
34
+ def to_dict(self) -> dict[str, Any]:
35
+ from ..models.occurrence_preview import OccurrencePreview
36
+ from ..models.skipped_occurrence import SkippedOccurrence
37
+
38
+ occurrences = []
39
+ for occurrences_item_data in self.occurrences:
40
+ occurrences_item = occurrences_item_data.to_dict()
41
+ occurrences.append(occurrences_item)
42
+
43
+ skipped = []
44
+ for skipped_item_data in self.skipped:
45
+ skipped_item = skipped_item_data.to_dict()
46
+ skipped.append(skipped_item)
47
+
48
+ field_dict: dict[str, Any] = {}
49
+ field_dict.update(self.additional_properties)
50
+ field_dict.update(
51
+ {
52
+ "occurrences": occurrences,
53
+ "skipped": skipped,
54
+ }
55
+ )
56
+
57
+ return field_dict
58
+
59
+ @classmethod
60
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
61
+ from ..models.occurrence_preview import OccurrencePreview
62
+ from ..models.skipped_occurrence import SkippedOccurrence
63
+
64
+ d = dict(src_dict)
65
+ occurrences = []
66
+ _occurrences = d.pop("occurrences")
67
+ for occurrences_item_data in _occurrences:
68
+ occurrences_item = OccurrencePreview.from_dict(occurrences_item_data)
69
+
70
+ occurrences.append(occurrences_item)
71
+
72
+ skipped = []
73
+ _skipped = d.pop("skipped")
74
+ for skipped_item_data in _skipped:
75
+ skipped_item = SkippedOccurrence.from_dict(skipped_item_data)
76
+
77
+ skipped.append(skipped_item)
78
+
79
+ recurrence_preview_response = cls(
80
+ occurrences=occurrences,
81
+ skipped=skipped,
82
+ )
83
+
84
+ recurrence_preview_response.additional_properties = d
85
+ return recurrence_preview_response
86
+
87
+ @property
88
+ def additional_keys(self) -> list[str]:
89
+ return list(self.additional_properties.keys())
90
+
91
+ def __getitem__(self, key: str) -> Any:
92
+ return self.additional_properties[key]
93
+
94
+ def __setitem__(self, key: str, value: Any) -> None:
95
+ self.additional_properties[key] = value
96
+
97
+ def __delitem__(self, key: str) -> None:
98
+ del self.additional_properties[key]
99
+
100
+ def __contains__(self, key: str) -> bool:
101
+ return key in self.additional_properties