skillforge-client 0.3.0__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 (147) hide show
  1. skillforge_client/__init__.py +8 -0
  2. skillforge_client/api/__init__.py +1 -0
  3. skillforge_client/api/auth/__init__.py +1 -0
  4. skillforge_client/api/auth/create_application_client_endpoint_api_v1_auth_clients_post.py +166 -0
  5. skillforge_client/api/auth/create_application_client_secret_endpoint_api_v1_auth_clients_client_id_secrets_post.py +182 -0
  6. skillforge_client/api/auth/create_token_api_v1_auth_token_post.py +165 -0
  7. skillforge_client/api/auth/grant_application_client_scopes_endpoint_api_v1_auth_clients_client_id_scopes_post.py +182 -0
  8. skillforge_client/api/auth/read_application_client_api_v1_auth_clients_client_id_get.py +161 -0
  9. skillforge_client/api/auth/read_application_clients_api_v1_auth_clients_get.py +133 -0
  10. skillforge_client/api/auth/revoke_application_client_scope_endpoint_api_v1_auth_clients_client_id_scopes_scope_key_delete.py +173 -0
  11. skillforge_client/api/auth/revoke_application_client_secret_endpoint_api_v1_auth_clients_client_id_secrets_secret_id_delete.py +174 -0
  12. skillforge_client/api/auth/update_application_client_endpoint_api_v1_auth_clients_client_id_patch.py +182 -0
  13. skillforge_client/api/bot/__init__.py +1 -0
  14. skillforge_client/api/bot/add_user_to_group_endpoint_api_v1_bot_users_discord_id_groups_group_key_put.py +199 -0
  15. skillforge_client/api/bot/cancel_operation_endpoint_api_v1_bot_operations_operation_id_cancel_post.py +203 -0
  16. skillforge_client/api/bot/check_authorization_endpoint_api_v1_bot_authz_check_post.py +206 -0
  17. skillforge_client/api/bot/claim_jobs_endpoint_api_v1_bot_jobs_claim_post.py +210 -0
  18. skillforge_client/api/bot/commit_student_activation_endpoint_api_v1_bot_students_activations_operation_id_commit_post.py +204 -0
  19. skillforge_client/api/bot/commit_student_deactivation_endpoint_api_v1_bot_students_guild_id_student_discord_id_deactivate_operation_id_commit_post.py +211 -0
  20. skillforge_client/api/bot/commit_student_pop_endpoint_api_v1_bot_students_guild_id_student_discord_id_pop_operation_id_commit_post.py +211 -0
  21. skillforge_client/api/bot/commit_student_stash_endpoint_api_v1_bot_students_guild_id_student_discord_id_stash_operation_id_commit_post.py +211 -0
  22. skillforge_client/api/bot/commit_tutor_activation_endpoint_api_v1_bot_tutors_activations_operation_id_commit_post.py +204 -0
  23. skillforge_client/api/bot/commit_tutor_deactivation_endpoint_api_v1_bot_tutors_guild_id_tutor_discord_id_deactivate_operation_id_commit_post.py +211 -0
  24. skillforge_client/api/bot/complete_job_endpoint_api_v1_bot_jobs_job_id_complete_post.py +183 -0
  25. skillforge_client/api/bot/deactivate_discord_account_endpoint_api_v1_bot_users_discord_id_account_delete.py +197 -0
  26. skillforge_client/api/bot/delete_command_env_endpoint_api_v1_bot_command_envs_guild_id_channel_id_kind_delete.py +204 -0
  27. skillforge_client/api/bot/fail_job_endpoint_api_v1_bot_jobs_job_id_fail_post.py +228 -0
  28. skillforge_client/api/bot/job_queue_summary_endpoint_api_v1_bot_jobs_summary_get.py +202 -0
  29. skillforge_client/api/bot/link_discord_account_endpoint_api_v1_bot_users_discord_id_account_put.py +227 -0
  30. skillforge_client/api/bot/list_jobs_endpoint_api_v1_bot_jobs_get.py +243 -0
  31. skillforge_client/api/bot/list_operations_endpoint_api_v1_bot_operations_get.py +302 -0
  32. skillforge_client/api/bot/prepare_student_activation_endpoint_api_v1_bot_students_activations_prepare_post.py +181 -0
  33. skillforge_client/api/bot/prepare_student_deactivation_endpoint_api_v1_bot_students_guild_id_student_discord_id_deactivate_prepare_post.py +190 -0
  34. skillforge_client/api/bot/prepare_student_pop_endpoint_api_v1_bot_students_guild_id_student_discord_id_pop_prepare_post.py +190 -0
  35. skillforge_client/api/bot/prepare_student_stash_endpoint_api_v1_bot_students_guild_id_student_discord_id_stash_prepare_post.py +190 -0
  36. skillforge_client/api/bot/prepare_tutor_activation_endpoint_api_v1_bot_tutors_activations_prepare_post.py +181 -0
  37. skillforge_client/api/bot/prepare_tutor_deactivation_endpoint_api_v1_bot_tutors_guild_id_tutor_discord_id_deactivate_prepare_post.py +190 -0
  38. skillforge_client/api/bot/read_job_api_v1_bot_jobs_job_id_get.py +186 -0
  39. skillforge_client/api/bot/read_operation_api_v1_bot_operations_operation_id_get.py +186 -0
  40. skillforge_client/api/bot/read_principal_api_v1_bot_runtime_principals_discord_id_get.py +177 -0
  41. skillforge_client/api/bot/read_principals_batch_api_v1_bot_runtime_principals_batch_post.py +189 -0
  42. skillforge_client/api/bot/read_student_context_api_v1_bot_runtime_students_guild_id_discord_id_get.py +191 -0
  43. skillforge_client/api/bot/read_student_contexts_batch_api_v1_bot_runtime_students_guild_id_batch_post.py +205 -0
  44. skillforge_client/api/bot/read_tutor_context_api_v1_bot_runtime_tutors_guild_id_discord_id_get.py +191 -0
  45. skillforge_client/api/bot/read_tutor_contexts_batch_api_v1_bot_runtime_tutors_guild_id_batch_post.py +205 -0
  46. skillforge_client/api/bot/remove_user_from_group_endpoint_api_v1_bot_users_discord_id_groups_group_key_delete.py +197 -0
  47. skillforge_client/api/bot/resolve_command_env_endpoint_api_v1_bot_runtime_command_envs_resolve_get.py +234 -0
  48. skillforge_client/api/bot/upsert_command_env_endpoint_api_v1_bot_command_envs_put.py +181 -0
  49. skillforge_client/api/bot/upsert_discord_user_endpoint_api_v1_bot_users_discord_id_put.py +213 -0
  50. skillforge_client/api/default/__init__.py +1 -0
  51. skillforge_client/api/default/root_get.py +81 -0
  52. skillforge_client/api/system/__init__.py +1 -0
  53. skillforge_client/api/system/dependencies_health_check_health_dependencies_get.py +136 -0
  54. skillforge_client/api/system/dependency_health_check_health_dependencies_dependency_name_get.py +170 -0
  55. skillforge_client/api/system/liveness_check_health_live_get.py +132 -0
  56. skillforge_client/api/system/system_health_check_health_get.py +136 -0
  57. skillforge_client/api/system/worker_health_check_health_workers_worker_name_get.py +170 -0
  58. skillforge_client/api/system/workers_health_check_health_workers_get.py +136 -0
  59. skillforge_client/client.py +268 -0
  60. skillforge_client/errors.py +16 -0
  61. skillforge_client/models/__init__.py +167 -0
  62. skillforge_client/models/access_token_response.py +85 -0
  63. skillforge_client/models/application_client_create_request.py +91 -0
  64. skillforge_client/models/application_client_response.py +149 -0
  65. skillforge_client/models/application_client_scope_grant_request.py +61 -0
  66. skillforge_client/models/application_client_secret_create_request.py +104 -0
  67. skillforge_client/models/application_client_secret_response.py +160 -0
  68. skillforge_client/models/application_client_status.py +9 -0
  69. skillforge_client/models/application_client_update_request.py +124 -0
  70. skillforge_client/models/authorization_check_request.py +78 -0
  71. skillforge_client/models/authorization_check_response.py +61 -0
  72. skillforge_client/models/body_create_token_api_v1_auth_token_post.py +123 -0
  73. skillforge_client/models/bot_job.py +119 -0
  74. skillforge_client/models/bot_job_payload.py +47 -0
  75. skillforge_client/models/bot_principal.py +148 -0
  76. skillforge_client/models/command_env_channel_response.py +100 -0
  77. skillforge_client/models/command_env_kind.py +9 -0
  78. skillforge_client/models/command_env_upsert_request.py +100 -0
  79. skillforge_client/models/contact_info_profile.py +92 -0
  80. skillforge_client/models/contact_info_type.py +9 -0
  81. skillforge_client/models/created_client_secret_response.py +75 -0
  82. skillforge_client/models/dependencies_health_check_response.py +77 -0
  83. skillforge_client/models/dependencies_health_check_response_checks.py +56 -0
  84. skillforge_client/models/dependency_health_check_response.py +72 -0
  85. skillforge_client/models/dependency_name.py +8 -0
  86. skillforge_client/models/discord_account_link_request.py +82 -0
  87. skillforge_client/models/discord_account_link_response.py +86 -0
  88. skillforge_client/models/discord_account_profile.py +77 -0
  89. skillforge_client/models/discord_id_batch_request.py +62 -0
  90. skillforge_client/models/discord_user_response.py +87 -0
  91. skillforge_client/models/discord_user_upsert_request.py +81 -0
  92. skillforge_client/models/error_response.py +61 -0
  93. skillforge_client/models/external_accounts_profile.py +124 -0
  94. skillforge_client/models/group_membership_response.py +69 -0
  95. skillforge_client/models/health_check_response.py +63 -0
  96. skillforge_client/models/health_status.py +10 -0
  97. skillforge_client/models/http_validation_error.py +79 -0
  98. skillforge_client/models/job_claim_request.py +113 -0
  99. skillforge_client/models/job_detail.py +239 -0
  100. skillforge_client/models/job_detail_payload.py +47 -0
  101. skillforge_client/models/job_fail_request.py +82 -0
  102. skillforge_client/models/job_kind_counts.py +92 -0
  103. skillforge_client/models/job_list_item.py +225 -0
  104. skillforge_client/models/job_page.py +100 -0
  105. skillforge_client/models/job_queue_summary.py +106 -0
  106. skillforge_client/models/job_response.py +187 -0
  107. skillforge_client/models/job_status.py +11 -0
  108. skillforge_client/models/job_status_counts.py +86 -0
  109. skillforge_client/models/member_role.py +10 -0
  110. skillforge_client/models/microsoft_account_profile.py +61 -0
  111. skillforge_client/models/operation_cancel_response.py +108 -0
  112. skillforge_client/models/operation_kind.py +13 -0
  113. skillforge_client/models/operation_page.py +100 -0
  114. skillforge_client/models/operation_response.py +257 -0
  115. skillforge_client/models/operation_response_plan.py +47 -0
  116. skillforge_client/models/operation_status.py +12 -0
  117. skillforge_client/models/operation_summary.py +243 -0
  118. skillforge_client/models/operational_profile.py +178 -0
  119. skillforge_client/models/party_relation_type.py +10 -0
  120. skillforge_client/models/person_profile.py +69 -0
  121. skillforge_client/models/principal_batch.py +84 -0
  122. skillforge_client/models/relation_profile.py +81 -0
  123. skillforge_client/models/relation_profile_direction.py +9 -0
  124. skillforge_client/models/student_activation_commit_request.py +61 -0
  125. skillforge_client/models/student_activation_prepare_request.py +77 -0
  126. skillforge_client/models/student_channel_state.py +9 -0
  127. skillforge_client/models/student_context.py +140 -0
  128. skillforge_client/models/student_context_batch.py +83 -0
  129. skillforge_client/models/system_health_check_response.py +87 -0
  130. skillforge_client/models/transition_commit_response.py +108 -0
  131. skillforge_client/models/transition_prepare_response.py +95 -0
  132. skillforge_client/models/transition_prepare_response_plan.py +47 -0
  133. skillforge_client/models/tutor_activation_commit_request.py +69 -0
  134. skillforge_client/models/tutor_activation_prepare_request.py +69 -0
  135. skillforge_client/models/tutor_context.py +99 -0
  136. skillforge_client/models/tutor_context_batch.py +83 -0
  137. skillforge_client/models/validation_error.py +123 -0
  138. skillforge_client/models/validation_error_context.py +47 -0
  139. skillforge_client/models/worker_health_check_response.py +72 -0
  140. skillforge_client/models/worker_name.py +8 -0
  141. skillforge_client/models/workers_health_check_response.py +77 -0
  142. skillforge_client/models/workers_health_check_response_checks.py +56 -0
  143. skillforge_client/py.typed +1 -0
  144. skillforge_client/types.py +54 -0
  145. skillforge_client-0.3.0.dist-info/METADATA +83 -0
  146. skillforge_client-0.3.0.dist-info/RECORD +147 -0
  147. skillforge_client-0.3.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,100 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import TYPE_CHECKING, Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ if TYPE_CHECKING:
10
+ from ..models.job_list_item import JobListItem
11
+
12
+
13
+ T = TypeVar("T", bound="JobPage")
14
+
15
+
16
+ @_attrs_define
17
+ class JobPage:
18
+ """A page of jobs plus the total match count, for offset pagination.
19
+
20
+ Attributes:
21
+ items (list[JobListItem]):
22
+ limit (int):
23
+ offset (int):
24
+ total (int):
25
+ """
26
+
27
+ items: list[JobListItem]
28
+ limit: int
29
+ offset: int
30
+ total: int
31
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
32
+
33
+ def to_dict(self) -> dict[str, Any]:
34
+ items = []
35
+ for items_item_data in self.items:
36
+ items_item = items_item_data.to_dict()
37
+ items.append(items_item)
38
+
39
+ limit = self.limit
40
+
41
+ offset = self.offset
42
+
43
+ total = self.total
44
+
45
+ field_dict: dict[str, Any] = {}
46
+ field_dict.update(self.additional_properties)
47
+ field_dict.update(
48
+ {
49
+ "items": items,
50
+ "limit": limit,
51
+ "offset": offset,
52
+ "total": total,
53
+ }
54
+ )
55
+
56
+ return field_dict
57
+
58
+ @classmethod
59
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
60
+ from ..models.job_list_item import JobListItem
61
+
62
+ d = dict(src_dict)
63
+ items = []
64
+ _items = d.pop("items")
65
+ for items_item_data in _items:
66
+ items_item = JobListItem.from_dict(items_item_data)
67
+
68
+ items.append(items_item)
69
+
70
+ limit = d.pop("limit")
71
+
72
+ offset = d.pop("offset")
73
+
74
+ total = d.pop("total")
75
+
76
+ job_page = cls(
77
+ items=items,
78
+ limit=limit,
79
+ offset=offset,
80
+ total=total,
81
+ )
82
+
83
+ job_page.additional_properties = d
84
+ return job_page
85
+
86
+ @property
87
+ def additional_keys(self) -> list[str]:
88
+ return list(self.additional_properties.keys())
89
+
90
+ def __getitem__(self, key: str) -> Any:
91
+ return self.additional_properties[key]
92
+
93
+ def __setitem__(self, key: str, value: Any) -> None:
94
+ self.additional_properties[key] = value
95
+
96
+ def __delitem__(self, key: str) -> None:
97
+ del self.additional_properties[key]
98
+
99
+ def __contains__(self, key: str) -> bool:
100
+ return key in self.additional_properties
@@ -0,0 +1,106 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import TYPE_CHECKING, Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ if TYPE_CHECKING:
10
+ from ..models.job_kind_counts import JobKindCounts
11
+ from ..models.job_status_counts import JobStatusCounts
12
+
13
+
14
+ T = TypeVar("T", bound="JobQueueSummary")
15
+
16
+
17
+ @_attrs_define
18
+ class JobQueueSummary:
19
+ """Queue funnel: global depth (``total``/``open``) and status counts, plus a per-kind breakdown.
20
+
21
+ ``open`` is outstanding work -- ``pending`` (including jobs delayed by retry backoff) plus
22
+ ``claimed``. Terminal counts are historical totals (rows are retained). ``by_kind`` is sorted by
23
+ kind and scoped to whatever ``kind`` filter the summary was fetched with.
24
+
25
+ Attributes:
26
+ by_kind (list[JobKindCounts]):
27
+ open_ (int):
28
+ statuses (JobStatusCounts): Job counts for every status in the queue funnel, zero-filled (no silent gaps).
29
+ total (int):
30
+ """
31
+
32
+ by_kind: list[JobKindCounts]
33
+ open_: int
34
+ statuses: JobStatusCounts
35
+ total: int
36
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
37
+
38
+ def to_dict(self) -> dict[str, Any]:
39
+ by_kind = []
40
+ for by_kind_item_data in self.by_kind:
41
+ by_kind_item = by_kind_item_data.to_dict()
42
+ by_kind.append(by_kind_item)
43
+
44
+ open_ = self.open_
45
+
46
+ statuses = self.statuses.to_dict()
47
+
48
+ total = self.total
49
+
50
+ field_dict: dict[str, Any] = {}
51
+ field_dict.update(self.additional_properties)
52
+ field_dict.update(
53
+ {
54
+ "by_kind": by_kind,
55
+ "open": open_,
56
+ "statuses": statuses,
57
+ "total": total,
58
+ }
59
+ )
60
+
61
+ return field_dict
62
+
63
+ @classmethod
64
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
65
+ from ..models.job_kind_counts import JobKindCounts
66
+ from ..models.job_status_counts import JobStatusCounts
67
+
68
+ d = dict(src_dict)
69
+ by_kind = []
70
+ _by_kind = d.pop("by_kind")
71
+ for by_kind_item_data in _by_kind:
72
+ by_kind_item = JobKindCounts.from_dict(by_kind_item_data)
73
+
74
+ by_kind.append(by_kind_item)
75
+
76
+ open_ = d.pop("open")
77
+
78
+ statuses = JobStatusCounts.from_dict(d.pop("statuses"))
79
+
80
+ total = d.pop("total")
81
+
82
+ job_queue_summary = cls(
83
+ by_kind=by_kind,
84
+ open_=open_,
85
+ statuses=statuses,
86
+ total=total,
87
+ )
88
+
89
+ job_queue_summary.additional_properties = d
90
+ return job_queue_summary
91
+
92
+ @property
93
+ def additional_keys(self) -> list[str]:
94
+ return list(self.additional_properties.keys())
95
+
96
+ def __getitem__(self, key: str) -> Any:
97
+ return self.additional_properties[key]
98
+
99
+ def __setitem__(self, key: str, value: Any) -> None:
100
+ self.additional_properties[key] = value
101
+
102
+ def __delitem__(self, key: str) -> None:
103
+ del self.additional_properties[key]
104
+
105
+ def __contains__(self, key: str) -> bool:
106
+ return key in self.additional_properties
@@ -0,0 +1,187 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ from collections.abc import Mapping
5
+ from typing import Any, TypeVar, cast
6
+ from uuid import UUID
7
+
8
+ from attrs import define as _attrs_define
9
+ from attrs import field as _attrs_field
10
+
11
+ from ..models.job_status import JobStatus
12
+
13
+ T = TypeVar("T", bound="JobResponse")
14
+
15
+
16
+ @_attrs_define
17
+ class JobResponse:
18
+ """State view returned after completing or failing a job.
19
+
20
+ Attributes:
21
+ attempt (int):
22
+ available_at (datetime.datetime):
23
+ claimed_at (datetime.datetime | None):
24
+ completed_at (datetime.datetime | None):
25
+ failed_at (datetime.datetime | None):
26
+ job_id (UUID):
27
+ kind (str):
28
+ last_error (None | str):
29
+ status (JobStatus):
30
+ """
31
+
32
+ attempt: int
33
+ available_at: datetime.datetime
34
+ claimed_at: datetime.datetime | None
35
+ completed_at: datetime.datetime | None
36
+ failed_at: datetime.datetime | None
37
+ job_id: UUID
38
+ kind: str
39
+ last_error: None | str
40
+ status: JobStatus
41
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
42
+
43
+ def to_dict(self) -> dict[str, Any]:
44
+ attempt = self.attempt
45
+
46
+ available_at = self.available_at.isoformat()
47
+
48
+ claimed_at: None | str
49
+ if isinstance(self.claimed_at, datetime.datetime):
50
+ claimed_at = self.claimed_at.isoformat()
51
+ else:
52
+ claimed_at = self.claimed_at
53
+
54
+ completed_at: None | str
55
+ if isinstance(self.completed_at, datetime.datetime):
56
+ completed_at = self.completed_at.isoformat()
57
+ else:
58
+ completed_at = self.completed_at
59
+
60
+ failed_at: None | str
61
+ if isinstance(self.failed_at, datetime.datetime):
62
+ failed_at = self.failed_at.isoformat()
63
+ else:
64
+ failed_at = self.failed_at
65
+
66
+ job_id = str(self.job_id)
67
+
68
+ kind = self.kind
69
+
70
+ last_error: None | str
71
+ last_error = self.last_error
72
+
73
+ status = self.status.value
74
+
75
+ field_dict: dict[str, Any] = {}
76
+ field_dict.update(self.additional_properties)
77
+ field_dict.update(
78
+ {
79
+ "attempt": attempt,
80
+ "available_at": available_at,
81
+ "claimed_at": claimed_at,
82
+ "completed_at": completed_at,
83
+ "failed_at": failed_at,
84
+ "job_id": job_id,
85
+ "kind": kind,
86
+ "last_error": last_error,
87
+ "status": status,
88
+ }
89
+ )
90
+
91
+ return field_dict
92
+
93
+ @classmethod
94
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
95
+ d = dict(src_dict)
96
+ attempt = d.pop("attempt")
97
+
98
+ available_at = datetime.datetime.fromisoformat(d.pop("available_at"))
99
+
100
+ def _parse_claimed_at(data: object) -> datetime.datetime | None:
101
+ if data is None:
102
+ return data
103
+ try:
104
+ if not isinstance(data, str):
105
+ raise TypeError()
106
+ claimed_at_type_0 = datetime.datetime.fromisoformat(data)
107
+
108
+ return claimed_at_type_0
109
+ except (TypeError, ValueError, AttributeError, KeyError):
110
+ pass
111
+ return cast(datetime.datetime | None, data)
112
+
113
+ claimed_at = _parse_claimed_at(d.pop("claimed_at"))
114
+
115
+ def _parse_completed_at(data: object) -> datetime.datetime | None:
116
+ if data is None:
117
+ return data
118
+ try:
119
+ if not isinstance(data, str):
120
+ raise TypeError()
121
+ completed_at_type_0 = datetime.datetime.fromisoformat(data)
122
+
123
+ return completed_at_type_0
124
+ except (TypeError, ValueError, AttributeError, KeyError):
125
+ pass
126
+ return cast(datetime.datetime | None, data)
127
+
128
+ completed_at = _parse_completed_at(d.pop("completed_at"))
129
+
130
+ def _parse_failed_at(data: object) -> datetime.datetime | None:
131
+ if data is None:
132
+ return data
133
+ try:
134
+ if not isinstance(data, str):
135
+ raise TypeError()
136
+ failed_at_type_0 = datetime.datetime.fromisoformat(data)
137
+
138
+ return failed_at_type_0
139
+ except (TypeError, ValueError, AttributeError, KeyError):
140
+ pass
141
+ return cast(datetime.datetime | None, data)
142
+
143
+ failed_at = _parse_failed_at(d.pop("failed_at"))
144
+
145
+ job_id = UUID(d.pop("job_id"))
146
+
147
+ kind = d.pop("kind")
148
+
149
+ def _parse_last_error(data: object) -> None | str:
150
+ if data is None:
151
+ return data
152
+ return cast(None | str, data)
153
+
154
+ last_error = _parse_last_error(d.pop("last_error"))
155
+
156
+ status = JobStatus(d.pop("status"))
157
+
158
+ job_response = cls(
159
+ attempt=attempt,
160
+ available_at=available_at,
161
+ claimed_at=claimed_at,
162
+ completed_at=completed_at,
163
+ failed_at=failed_at,
164
+ job_id=job_id,
165
+ kind=kind,
166
+ last_error=last_error,
167
+ status=status,
168
+ )
169
+
170
+ job_response.additional_properties = d
171
+ return job_response
172
+
173
+ @property
174
+ def additional_keys(self) -> list[str]:
175
+ return list(self.additional_properties.keys())
176
+
177
+ def __getitem__(self, key: str) -> Any:
178
+ return self.additional_properties[key]
179
+
180
+ def __setitem__(self, key: str, value: Any) -> None:
181
+ self.additional_properties[key] = value
182
+
183
+ def __delitem__(self, key: str) -> None:
184
+ del self.additional_properties[key]
185
+
186
+ def __contains__(self, key: str) -> bool:
187
+ return key in self.additional_properties
@@ -0,0 +1,11 @@
1
+ from enum import Enum
2
+
3
+
4
+ class JobStatus(str, Enum):
5
+ CLAIMED = "claimed"
6
+ COMPLETED = "completed"
7
+ FAILED = "failed"
8
+ PENDING = "pending"
9
+
10
+ def __str__(self) -> str:
11
+ return str(self.value)
@@ -0,0 +1,86 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ T = TypeVar("T", bound="JobStatusCounts")
10
+
11
+
12
+ @_attrs_define
13
+ class JobStatusCounts:
14
+ """Job counts for every status in the queue funnel, zero-filled (no silent gaps).
15
+
16
+ Attributes:
17
+ claimed (int):
18
+ completed (int):
19
+ failed (int):
20
+ pending (int):
21
+ """
22
+
23
+ claimed: int
24
+ completed: int
25
+ failed: int
26
+ pending: int
27
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
28
+
29
+ def to_dict(self) -> dict[str, Any]:
30
+ claimed = self.claimed
31
+
32
+ completed = self.completed
33
+
34
+ failed = self.failed
35
+
36
+ pending = self.pending
37
+
38
+ field_dict: dict[str, Any] = {}
39
+ field_dict.update(self.additional_properties)
40
+ field_dict.update(
41
+ {
42
+ "claimed": claimed,
43
+ "completed": completed,
44
+ "failed": failed,
45
+ "pending": pending,
46
+ }
47
+ )
48
+
49
+ return field_dict
50
+
51
+ @classmethod
52
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
53
+ d = dict(src_dict)
54
+ claimed = d.pop("claimed")
55
+
56
+ completed = d.pop("completed")
57
+
58
+ failed = d.pop("failed")
59
+
60
+ pending = d.pop("pending")
61
+
62
+ job_status_counts = cls(
63
+ claimed=claimed,
64
+ completed=completed,
65
+ failed=failed,
66
+ pending=pending,
67
+ )
68
+
69
+ job_status_counts.additional_properties = d
70
+ return job_status_counts
71
+
72
+ @property
73
+ def additional_keys(self) -> list[str]:
74
+ return list(self.additional_properties.keys())
75
+
76
+ def __getitem__(self, key: str) -> Any:
77
+ return self.additional_properties[key]
78
+
79
+ def __setitem__(self, key: str, value: Any) -> None:
80
+ self.additional_properties[key] = value
81
+
82
+ def __delitem__(self, key: str) -> None:
83
+ del self.additional_properties[key]
84
+
85
+ def __contains__(self, key: str) -> bool:
86
+ return key in self.additional_properties
@@ -0,0 +1,10 @@
1
+ from enum import Enum
2
+
3
+
4
+ class MemberRole(str, Enum):
5
+ ADMIN = "admin"
6
+ STUDENT = "student"
7
+ TUTOR = "tutor"
8
+
9
+ def __str__(self) -> str:
10
+ return str(self.value)
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ T = TypeVar("T", bound="MicrosoftAccountProfile")
10
+
11
+
12
+ @_attrs_define
13
+ class MicrosoftAccountProfile:
14
+ """
15
+ Attributes:
16
+ user_id (str):
17
+ """
18
+
19
+ user_id: str
20
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
21
+
22
+ def to_dict(self) -> dict[str, Any]:
23
+ user_id = self.user_id
24
+
25
+ field_dict: dict[str, Any] = {}
26
+ field_dict.update(self.additional_properties)
27
+ field_dict.update(
28
+ {
29
+ "user_id": user_id,
30
+ }
31
+ )
32
+
33
+ return field_dict
34
+
35
+ @classmethod
36
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
37
+ d = dict(src_dict)
38
+ user_id = d.pop("user_id")
39
+
40
+ microsoft_account_profile = cls(
41
+ user_id=user_id,
42
+ )
43
+
44
+ microsoft_account_profile.additional_properties = d
45
+ return microsoft_account_profile
46
+
47
+ @property
48
+ def additional_keys(self) -> list[str]:
49
+ return list(self.additional_properties.keys())
50
+
51
+ def __getitem__(self, key: str) -> Any:
52
+ return self.additional_properties[key]
53
+
54
+ def __setitem__(self, key: str, value: Any) -> None:
55
+ self.additional_properties[key] = value
56
+
57
+ def __delitem__(self, key: str) -> None:
58
+ del self.additional_properties[key]
59
+
60
+ def __contains__(self, key: str) -> bool:
61
+ return key in self.additional_properties
@@ -0,0 +1,108 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ from collections.abc import Mapping
5
+ from typing import Any, TypeVar, cast
6
+ from uuid import UUID
7
+
8
+ from attrs import define as _attrs_define
9
+ from attrs import field as _attrs_field
10
+
11
+ from ..models.operation_kind import OperationKind
12
+ from ..models.operation_status import OperationStatus
13
+
14
+ T = TypeVar("T", bound="OperationCancelResponse")
15
+
16
+
17
+ @_attrs_define
18
+ class OperationCancelResponse:
19
+ """
20
+ Attributes:
21
+ cancelled_at (datetime.datetime | None):
22
+ kind (OperationKind):
23
+ operation_id (UUID):
24
+ status (OperationStatus):
25
+ """
26
+
27
+ cancelled_at: datetime.datetime | None
28
+ kind: OperationKind
29
+ operation_id: UUID
30
+ status: OperationStatus
31
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
32
+
33
+ def to_dict(self) -> dict[str, Any]:
34
+ cancelled_at: None | str
35
+ if isinstance(self.cancelled_at, datetime.datetime):
36
+ cancelled_at = self.cancelled_at.isoformat()
37
+ else:
38
+ cancelled_at = self.cancelled_at
39
+
40
+ kind = self.kind.value
41
+
42
+ operation_id = str(self.operation_id)
43
+
44
+ status = self.status.value
45
+
46
+ field_dict: dict[str, Any] = {}
47
+ field_dict.update(self.additional_properties)
48
+ field_dict.update(
49
+ {
50
+ "cancelled_at": cancelled_at,
51
+ "kind": kind,
52
+ "operation_id": operation_id,
53
+ "status": status,
54
+ }
55
+ )
56
+
57
+ return field_dict
58
+
59
+ @classmethod
60
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
61
+ d = dict(src_dict)
62
+
63
+ def _parse_cancelled_at(data: object) -> datetime.datetime | None:
64
+ if data is None:
65
+ return data
66
+ try:
67
+ if not isinstance(data, str):
68
+ raise TypeError()
69
+ cancelled_at_type_0 = datetime.datetime.fromisoformat(data)
70
+
71
+ return cancelled_at_type_0
72
+ except (TypeError, ValueError, AttributeError, KeyError):
73
+ pass
74
+ return cast(datetime.datetime | None, data)
75
+
76
+ cancelled_at = _parse_cancelled_at(d.pop("cancelled_at"))
77
+
78
+ kind = OperationKind(d.pop("kind"))
79
+
80
+ operation_id = UUID(d.pop("operation_id"))
81
+
82
+ status = OperationStatus(d.pop("status"))
83
+
84
+ operation_cancel_response = cls(
85
+ cancelled_at=cancelled_at,
86
+ kind=kind,
87
+ operation_id=operation_id,
88
+ status=status,
89
+ )
90
+
91
+ operation_cancel_response.additional_properties = d
92
+ return operation_cancel_response
93
+
94
+ @property
95
+ def additional_keys(self) -> list[str]:
96
+ return list(self.additional_properties.keys())
97
+
98
+ def __getitem__(self, key: str) -> Any:
99
+ return self.additional_properties[key]
100
+
101
+ def __setitem__(self, key: str, value: Any) -> None:
102
+ self.additional_properties[key] = value
103
+
104
+ def __delitem__(self, key: str) -> None:
105
+ del self.additional_properties[key]
106
+
107
+ def __contains__(self, key: str) -> bool:
108
+ return key in self.additional_properties
@@ -0,0 +1,13 @@
1
+ from enum import Enum
2
+
3
+
4
+ class OperationKind(str, Enum):
5
+ STUDENT_ACTIVATE = "student_activate"
6
+ STUDENT_DEACTIVATE = "student_deactivate"
7
+ STUDENT_POP = "student_pop"
8
+ STUDENT_STASH = "student_stash"
9
+ TUTOR_ACTIVATE = "tutor_activate"
10
+ TUTOR_DEACTIVATE = "tutor_deactivate"
11
+
12
+ def __str__(self) -> str:
13
+ return str(self.value)