icpc-api 0.1.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.
- icpc/__init__.py +32 -0
- icpc/api/__init__.py +18 -0
- icpc/api/common.py +97 -0
- icpc/api/contest.py +253 -0
- icpc/api/person.py +139 -0
- icpc/api/public.py +65 -0
- icpc/api/staff.py +83 -0
- icpc/api/team.py +335 -0
- icpc/auth/__init__.py +28 -0
- icpc/auth/cognito.py +142 -0
- icpc/auth/flows.py +314 -0
- icpc/auth/provider.py +29 -0
- icpc/auth/srp.py +185 -0
- icpc/auth/store.py +223 -0
- icpc/auth/tokens.py +86 -0
- icpc/cli/__init__.py +20 -0
- icpc/cli/columns.py +555 -0
- icpc/cli/main.py +1156 -0
- icpc/cli/render.py +160 -0
- icpc/config.py +57 -0
- icpc/errors.py +159 -0
- icpc/facade/__init__.py +6 -0
- icpc/facade/client.py +606 -0
- icpc/facade/domain.py +198 -0
- icpc/models/__init__.py +60 -0
- icpc/models/_generated.py +566 -0
- icpc/models/base.py +41 -0
- icpc/models/blobs.py +81 -0
- icpc/models/common.py +61 -0
- icpc/models/entities.py +522 -0
- icpc/models/enums.py +192 -0
- icpc/models/mixins.py +44 -0
- icpc/py.typed +0 -0
- icpc/search/__init__.py +99 -0
- icpc/search/_generated.py +1814 -0
- icpc/search/dsl.py +124 -0
- icpc/search/endpoint.py +173 -0
- icpc/search/fields.py +59 -0
- icpc/transport/__init__.py +29 -0
- icpc/transport/_shared.py +121 -0
- icpc/transport/async_client.py +120 -0
- icpc/transport/operation.py +139 -0
- icpc/transport/sync_client.py +121 -0
- icpc_api-0.1.0.dist-info/METADATA +143 -0
- icpc_api-0.1.0.dist-info/RECORD +50 -0
- icpc_api-0.1.0.dist-info/WHEEL +5 -0
- icpc_api-0.1.0.dist-info/entry_points.txt +2 -0
- icpc_api-0.1.0.dist-info/licenses/LICENSE +21 -0
- icpc_api-0.1.0.dist-info/licenses/THIRD-PARTY-LICENSES.md +220 -0
- icpc_api-0.1.0.dist-info/top_level.txt +1 -0
icpc/models/enums.py
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Wire enumerations.
|
|
2
|
+
|
|
3
|
+
Server returns these lists from the ``/aspectfaces`` form registry. Model fields
|
|
4
|
+
are typed ``Enum | str`` so that unrecognised values arrive as strings.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from enum import StrEnum
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"Consent",
|
|
13
|
+
"ContestType",
|
|
14
|
+
"EligibilityStatus",
|
|
15
|
+
"ExportType",
|
|
16
|
+
"InstitutionUnitType",
|
|
17
|
+
"MemberRole",
|
|
18
|
+
"ParticipantRole",
|
|
19
|
+
"PublicPagesVisibility",
|
|
20
|
+
"Sex",
|
|
21
|
+
"ShirtSize",
|
|
22
|
+
"TeamStatus",
|
|
23
|
+
"Title",
|
|
24
|
+
"coach_roles",
|
|
25
|
+
"contestant_roles",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TeamStatus(StrEnum):
|
|
30
|
+
"""Team registration status. Complete, from ``…team.businessobjects.Team``.
|
|
31
|
+
|
|
32
|
+
The frontend labels the third one "Rejected"; the wire value is ``CANCELED``.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
PENDING = "PENDING"
|
|
36
|
+
ACCEPTED = "ACCEPTED"
|
|
37
|
+
CANCELED = "CANCELED"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class MemberRole(StrEnum):
|
|
41
|
+
"""A person's role on a team, from ``…team.businessobjects.TeamMember``."""
|
|
42
|
+
|
|
43
|
+
COACH = "COACH"
|
|
44
|
+
COCOACH = "COCOACH"
|
|
45
|
+
#: A contestant who also coaches: counted as *both* a contestant and a coach.
|
|
46
|
+
CONTESTANT_COACH = "CONTESTANT_COACH"
|
|
47
|
+
CONTESTANT = "CONTESTANT"
|
|
48
|
+
ATTENDEE = "ATTENDEE"
|
|
49
|
+
RESERVE = "RESERVE"
|
|
50
|
+
STAFF = "STAFF"
|
|
51
|
+
#: Not in the server's current option list, but older contests may still
|
|
52
|
+
#: carry it. Treated like ``CONTESTANT_COACH``: both a contestant and a coach.
|
|
53
|
+
STUDENT_COACH = "STUDENT_COACH"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ParticipantRole(StrEnum):
|
|
57
|
+
"""A person's role at a contest, independent of any team."""
|
|
58
|
+
|
|
59
|
+
CONTESTANT = "CONTESTANT"
|
|
60
|
+
COACH = "COACH"
|
|
61
|
+
COCOACH = "COCOACH"
|
|
62
|
+
RESERVE = "RESERVE"
|
|
63
|
+
ATTENDEE = "ATTENDEE"
|
|
64
|
+
STAFF = "STAFF"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class Consent(StrEnum):
|
|
68
|
+
"""A registration consent answer.
|
|
69
|
+
|
|
70
|
+
Several columns read like booleans — ``includeEmail``,
|
|
71
|
+
``employmentOpportunities``, ``informOtherContests``, ``inform``, ``icpcRules``,
|
|
72
|
+
``mediaUse`` — but the wire carries words, so ``bool`` simply fails to parse.
|
|
73
|
+
Complete, from ``…person.businessobjects.PersonInfoAbstract``.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
AGREE = "AGREE"
|
|
77
|
+
DISAGREE = "DISAGREE"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class Sex(StrEnum):
|
|
81
|
+
"""Complete, from ``…person.businessobjects.PersonInfoAbstract``."""
|
|
82
|
+
|
|
83
|
+
FEMALE = "FEMALE"
|
|
84
|
+
MALE = "MALE"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class EligibilityStatus(StrEnum):
|
|
88
|
+
"""Eligibility verdict on a team.
|
|
89
|
+
|
|
90
|
+
Complete, from ``…team.businessobjects.Eligibility``. A full-object team write
|
|
91
|
+
recomputes this and drops any ``VERIFIED_*`` value.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
NOT_RESOLVED = "NOT_RESOLVED"
|
|
95
|
+
NO_ISSUES_FOUND = "NO_ISSUES_FOUND"
|
|
96
|
+
PREDICTED_INELIGIBLE = "PREDICTED_INELIGIBLE"
|
|
97
|
+
VERIFIED_ELIGIBLE = "VERIFIED_ELIGIBLE"
|
|
98
|
+
VERIFIED_INELIGIBLE = "VERIFIED_INELIGIBLE"
|
|
99
|
+
ELIGIBILITY_CHECK_NOT_REQUIRED = "ELIGIBILITY_CHECK_NOT_REQUIRED"
|
|
100
|
+
VALIDATED_BY_LOWER_CONTEST = "VALIDATED_BY_LOWER_CONTEST"
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class ContestType(StrEnum):
|
|
104
|
+
"""Complete, from ``…contest.businessobjects.ContestSettings``."""
|
|
105
|
+
|
|
106
|
+
WORLD_FINALS = "WORLD_FINALS"
|
|
107
|
+
REGIONALS = "REGIONALS"
|
|
108
|
+
QUALIFIER = "QUALIFIER"
|
|
109
|
+
PRACTICE = "PRACTICE"
|
|
110
|
+
CAMP = "CAMP"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class PublicPagesVisibility(StrEnum):
|
|
114
|
+
"""Whether a contest's public pages list people. Not a boolean, despite the name.
|
|
115
|
+
|
|
116
|
+
Complete, from ``…contest.businessobjects.ContestSettings``.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
WITH_PEOPLE = "WITH_PEOPLE"
|
|
120
|
+
WITHOUT_PEOPLE = "WITHOUT_PEOPLE"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class Title(StrEnum):
|
|
124
|
+
"""Complete, from ``…person.businessobjects.PersonInfoAbstract``."""
|
|
125
|
+
|
|
126
|
+
DR = "DR"
|
|
127
|
+
DRS = "DRS"
|
|
128
|
+
IR = "IR"
|
|
129
|
+
MISS = "MISS"
|
|
130
|
+
MR = "MR"
|
|
131
|
+
MRS = "MRS"
|
|
132
|
+
MS = "MS"
|
|
133
|
+
PROFESSOR = "PROFESSOR"
|
|
134
|
+
NONE = "NONE"
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class InstitutionUnitType(StrEnum):
|
|
138
|
+
"""What kind of institution a unit is.
|
|
139
|
+
|
|
140
|
+
Observed values only: the ``InstitutionUnit`` schema endpoint answers 500.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
UNIVERSITY_GRADUATE = "UNIVERSITY_GRADUATE"
|
|
144
|
+
UNIVERSITY_NO_GRADUATE = "UNIVERSITY_NO_GRADUATE"
|
|
145
|
+
HIGH_SCHOOL = "HIGH_SCHOOL"
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class ShirtSize(StrEnum):
|
|
149
|
+
"""Complete, from ``…person.businessobjects.PersonInfoAbstract``."""
|
|
150
|
+
|
|
151
|
+
XS = "XS"
|
|
152
|
+
S = "S"
|
|
153
|
+
M = "M"
|
|
154
|
+
L = "L"
|
|
155
|
+
XL = "XL"
|
|
156
|
+
XXL = "XXL"
|
|
157
|
+
XXXL = "XXXL"
|
|
158
|
+
XXXXL = "XXXXL"
|
|
159
|
+
XXXXXL = "XXXXXL"
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class ExportType(StrEnum):
|
|
163
|
+
"""Formats accepted by the ``/export`` sibling of a search endpoint."""
|
|
164
|
+
|
|
165
|
+
CSV = "CSV"
|
|
166
|
+
TSV = "TSV"
|
|
167
|
+
TAB = "TAB"
|
|
168
|
+
TXT = "TXT"
|
|
169
|
+
EXCEL = "EXCEL"
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def contestant_roles() -> frozenset[str]:
|
|
173
|
+
"""Roles that count as competing."""
|
|
174
|
+
return frozenset(
|
|
175
|
+
{
|
|
176
|
+
MemberRole.CONTESTANT,
|
|
177
|
+
MemberRole.STUDENT_COACH,
|
|
178
|
+
MemberRole.CONTESTANT_COACH,
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def coach_roles() -> frozenset[str]:
|
|
184
|
+
"""Roles that count as coaching."""
|
|
185
|
+
return frozenset(
|
|
186
|
+
{
|
|
187
|
+
MemberRole.COACH,
|
|
188
|
+
MemberRole.COCOACH,
|
|
189
|
+
MemberRole.STUDENT_COACH,
|
|
190
|
+
MemberRole.CONTESTANT_COACH,
|
|
191
|
+
}
|
|
192
|
+
)
|
icpc/models/mixins.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Behaviour attached to generated rows that carry JSON-in-a-string columns.
|
|
2
|
+
|
|
3
|
+
The annotations are under ``TYPE_CHECKING`` on purpose: pydantic collects fields
|
|
4
|
+
from every base class's annotations, and re-declaring them here would fight with the
|
|
5
|
+
generated ones. At runtime these are plain attribute reads on the model.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from icpc.models.blobs import TeamMemberBlob, parse_extra_fields, parse_members
|
|
13
|
+
|
|
14
|
+
__all__ = ["HasExtraFields", "HasTeamMembers"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class HasTeamMembers:
|
|
18
|
+
"""A row whose ``teamMembers`` column holds the roster as a JSON string."""
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
team_members: str | None
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def member_blobs(self) -> list[TeamMemberBlob]:
|
|
25
|
+
"""The roster embedded in this row. Useful if ``teammember`` was not
|
|
26
|
+
fetched.
|
|
27
|
+
"""
|
|
28
|
+
return parse_members(self.team_members)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class HasExtraFields:
|
|
32
|
+
"""A row whose ``extraField`` column holds custom-question answers."""
|
|
33
|
+
|
|
34
|
+
if TYPE_CHECKING:
|
|
35
|
+
extra_field: str | None
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def extras(self) -> dict[str, str]:
|
|
39
|
+
"""Answers to the contest's custom registration questions.
|
|
40
|
+
|
|
41
|
+
Keys are the contest's own question labels, so they differ between
|
|
42
|
+
contests and are frequently not in English.
|
|
43
|
+
"""
|
|
44
|
+
return parse_extra_fields(self.extra_field)
|
icpc/py.typed
ADDED
|
File without changes
|
icpc/search/__init__.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""The ``q=`` search DSL, typed columns, and the generated endpoint catalogue."""
|
|
2
|
+
|
|
3
|
+
from icpc.search import _generated as endpoints
|
|
4
|
+
from icpc.search._generated import (
|
|
5
|
+
CertificateFields,
|
|
6
|
+
ContestParticipantFields,
|
|
7
|
+
InstitutionFields,
|
|
8
|
+
PromoteFields,
|
|
9
|
+
StaffFields,
|
|
10
|
+
StaffFundingFields,
|
|
11
|
+
StaffMemberFields,
|
|
12
|
+
StaffTshirtFields,
|
|
13
|
+
StandingsFields,
|
|
14
|
+
TeamFields,
|
|
15
|
+
TeamMemberFields,
|
|
16
|
+
TeamSummaryFields,
|
|
17
|
+
Top20Fields,
|
|
18
|
+
TransportationMissingFields,
|
|
19
|
+
TshirtFields,
|
|
20
|
+
contest_institutions,
|
|
21
|
+
contest_missing_transportation,
|
|
22
|
+
contest_participants,
|
|
23
|
+
contest_promote_candidates,
|
|
24
|
+
contest_public_staff_members,
|
|
25
|
+
contest_staff,
|
|
26
|
+
contest_staff_certificates,
|
|
27
|
+
contest_staff_funding,
|
|
28
|
+
contest_staff_members,
|
|
29
|
+
contest_staff_tshirts,
|
|
30
|
+
contest_standings,
|
|
31
|
+
contest_team_certificates,
|
|
32
|
+
contest_team_members,
|
|
33
|
+
contest_team_summaries,
|
|
34
|
+
contest_teams,
|
|
35
|
+
contest_top20,
|
|
36
|
+
site_coach_tshirts,
|
|
37
|
+
site_cocoach_tshirts,
|
|
38
|
+
site_contestant_tshirts,
|
|
39
|
+
site_home_teams,
|
|
40
|
+
site_institutions,
|
|
41
|
+
site_participants,
|
|
42
|
+
site_team_certificates,
|
|
43
|
+
site_team_members,
|
|
44
|
+
site_teams,
|
|
45
|
+
)
|
|
46
|
+
from icpc.search.dsl import Direction, Filter, FilterMode, Q, SortKey
|
|
47
|
+
from icpc.search.endpoint import SearchEndpoint
|
|
48
|
+
from icpc.search.fields import Field
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
"CertificateFields",
|
|
52
|
+
"ContestParticipantFields",
|
|
53
|
+
"Direction",
|
|
54
|
+
"Field",
|
|
55
|
+
"Filter",
|
|
56
|
+
"FilterMode",
|
|
57
|
+
"InstitutionFields",
|
|
58
|
+
"PromoteFields",
|
|
59
|
+
"Q",
|
|
60
|
+
"SearchEndpoint",
|
|
61
|
+
"SortKey",
|
|
62
|
+
"StaffFields",
|
|
63
|
+
"StaffFundingFields",
|
|
64
|
+
"StaffMemberFields",
|
|
65
|
+
"StaffTshirtFields",
|
|
66
|
+
"StandingsFields",
|
|
67
|
+
"TeamFields",
|
|
68
|
+
"TeamMemberFields",
|
|
69
|
+
"TeamSummaryFields",
|
|
70
|
+
"Top20Fields",
|
|
71
|
+
"TransportationMissingFields",
|
|
72
|
+
"TshirtFields",
|
|
73
|
+
"contest_institutions",
|
|
74
|
+
"contest_missing_transportation",
|
|
75
|
+
"contest_participants",
|
|
76
|
+
"contest_promote_candidates",
|
|
77
|
+
"contest_public_staff_members",
|
|
78
|
+
"contest_staff",
|
|
79
|
+
"contest_staff_certificates",
|
|
80
|
+
"contest_staff_funding",
|
|
81
|
+
"contest_staff_members",
|
|
82
|
+
"contest_staff_tshirts",
|
|
83
|
+
"contest_standings",
|
|
84
|
+
"contest_team_certificates",
|
|
85
|
+
"contest_team_members",
|
|
86
|
+
"contest_team_summaries",
|
|
87
|
+
"contest_teams",
|
|
88
|
+
"contest_top20",
|
|
89
|
+
"endpoints",
|
|
90
|
+
"site_coach_tshirts",
|
|
91
|
+
"site_cocoach_tshirts",
|
|
92
|
+
"site_contestant_tshirts",
|
|
93
|
+
"site_home_teams",
|
|
94
|
+
"site_institutions",
|
|
95
|
+
"site_participants",
|
|
96
|
+
"site_team_certificates",
|
|
97
|
+
"site_team_members",
|
|
98
|
+
"site_teams",
|
|
99
|
+
]
|