xcpcio 0.63.5__py3-none-any.whl → 0.63.6__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.

Potentially problematic release.


This version of xcpcio might be problematic. Click here for more details.

@@ -0,0 +1,408 @@
1
+ """
2
+ Contest Service
3
+
4
+ Business logic layer for Contest API operations.
5
+ Handles file reading, data validation, and business operations.
6
+ """
7
+
8
+ import json
9
+ from pathlib import Path
10
+ from typing import Any, Dict, List, Optional, Union
11
+
12
+ from fastapi import HTTPException
13
+
14
+ from xcpcio.__version__ import __version__
15
+
16
+
17
+ class ContestService:
18
+ """Service class for contest-related operations"""
19
+
20
+ def __init__(self, contest_package_dir: Path):
21
+ """
22
+ Initialize the contest service.
23
+
24
+ Args:
25
+ contest_package_dir: Path to the contest package directory
26
+ """
27
+ self.contest_package_dir = contest_package_dir
28
+ if not self.contest_package_dir.exists():
29
+ raise ValueError(f"Contest package directory does not exist: {contest_package_dir}")
30
+
31
+ # Initialize data indexes for faster lookups
32
+ self._load_indexes()
33
+
34
+ def _load_indexes(self) -> None:
35
+ """Load and index commonly accessed data for faster lookups"""
36
+ # Load contest data
37
+ self.contest_data = self.load_json_file("contest.json")
38
+
39
+ # Load organizations and create index
40
+ organizations_data = self.load_json_file("organizations.json")
41
+ self.organizations_by_id = {org["id"]: org for org in organizations_data}
42
+
43
+ # Load teams and create index
44
+ teams_data = self.load_json_file("teams.json")
45
+ self.teams_by_id = {team["id"]: team for team in teams_data}
46
+
47
+ # Load problems and create index
48
+ problems_data = self.load_json_file("problems.json")
49
+ self.problems_by_id = {problem["id"]: problem for problem in problems_data}
50
+
51
+ # Load submissions and create index
52
+ submissions_data = self.load_json_file("submissions.json")
53
+ self.submissions_by_id = {submission["id"]: submission for submission in submissions_data}
54
+
55
+ def load_json_file(self, filepath: str) -> Union[Dict[str, Any], List[Any]]:
56
+ """
57
+ Load JSON data from contest package directory.
58
+
59
+ Args:
60
+ filepath: Relative path to JSON file within contest package
61
+
62
+ Returns:
63
+ Parsed JSON data
64
+
65
+ Raises:
66
+ HTTPException: If file not found or invalid JSON
67
+ """
68
+ full_path = self.contest_package_dir / filepath
69
+ try:
70
+ with open(full_path, "r", encoding="utf-8") as f:
71
+ return json.load(f)
72
+ except FileNotFoundError:
73
+ raise HTTPException(status_code=404, detail=f"File not found: {filepath}")
74
+ except json.JSONDecodeError as e:
75
+ raise HTTPException(status_code=500, detail=f"Invalid JSON in file {filepath}: {e}")
76
+
77
+ def get_contest_id(self) -> str:
78
+ """
79
+ Get contest ID from contest.json.
80
+
81
+ Returns:
82
+ Contest ID string
83
+ """
84
+ contest_data = self.load_json_file("contest.json")
85
+ return contest_data.get("id", "unknown")
86
+
87
+ def validate_contest_id(self, contest_id: str) -> None:
88
+ """
89
+ Validate that the provided contest ID matches the expected one.
90
+
91
+ Args:
92
+ contest_id: Contest ID to validate
93
+
94
+ Raises:
95
+ HTTPException: If contest ID doesn't match
96
+ """
97
+ expected_id = self.get_contest_id()
98
+ if contest_id != expected_id:
99
+ raise HTTPException(status_code=404, detail=f"Contest {contest_id} not found")
100
+
101
+ # API Information
102
+ def get_api_info(self) -> Dict[str, Any]:
103
+ """Get API information"""
104
+ return {
105
+ "version": "2023-06",
106
+ "version_url": "https://ccs-specs.icpc.io/2023-06/contest_api",
107
+ "name": "XCPCIO",
108
+ "provider": {
109
+ "name": "XCPCIO",
110
+ "version": __version__,
111
+ },
112
+ }
113
+
114
+ def get_access_info(self, contest_id: str) -> Dict[str, Any]:
115
+ """Get access information for current client"""
116
+ self.validate_contest_id(contest_id)
117
+ return {
118
+ "capabilities": [],
119
+ "endpoints": [
120
+ {
121
+ "type": "contest",
122
+ "properties": [
123
+ "id",
124
+ "name",
125
+ "formal_name",
126
+ "start_time",
127
+ "duration",
128
+ "scoreboard_type",
129
+ "penalty_time",
130
+ ],
131
+ },
132
+ {
133
+ "type": "problems",
134
+ "properties": ["id", "label", "name", "ordinal", "color", "rgb", "time_limit", "test_data_count"],
135
+ },
136
+ {"type": "teams", "properties": ["id", "name", "label", "organization_id", "group_ids", "hidden"]},
137
+ {"type": "organizations", "properties": ["id", "name", "formal_name"]},
138
+ {"type": "groups", "properties": ["id", "name"]},
139
+ {"type": "judgement-types", "properties": ["id", "name", "penalty", "solved"]},
140
+ {"type": "languages", "properties": ["id", "name", "extensions"]},
141
+ {
142
+ "type": "state",
143
+ "properties": ["started", "ended", "frozen", "thawed", "finalized", "end_of_updates"],
144
+ },
145
+ {
146
+ "type": "submissions",
147
+ "properties": ["id", "team_id", "problem_id", "language_id", "time", "contest_time"],
148
+ },
149
+ {
150
+ "type": "judgements",
151
+ "properties": ["id", "submission_id", "judgement_type_id", "start_time", "start_contest_time"],
152
+ },
153
+ {
154
+ "type": "runs",
155
+ "properties": [
156
+ "id",
157
+ "judgement_id",
158
+ "ordinal",
159
+ "judgement_type_id",
160
+ "time",
161
+ "contest_time",
162
+ "run_time",
163
+ ],
164
+ },
165
+ {
166
+ "type": "clarifications",
167
+ "properties": ["id", "from_team_id", "to_team_id", "problem_id", "text", "time", "contest_time"],
168
+ },
169
+ {"type": "awards", "properties": ["id", "citation", "team_ids"]},
170
+ ],
171
+ }
172
+
173
+ # Contest operations
174
+ def get_contests(self) -> List[Dict[str, Any]]:
175
+ """Get all contests"""
176
+ contest_data = self.load_json_file("contest.json")
177
+ return [contest_data]
178
+
179
+ def get_contest(self, contest_id: str) -> Dict[str, Any]:
180
+ """Get specific contest"""
181
+ self.validate_contest_id(contest_id)
182
+ return self.load_json_file("contest.json")
183
+
184
+ def get_contest_state(self, contest_id: str) -> Dict[str, Any]:
185
+ """Get contest state"""
186
+ self.validate_contest_id(contest_id)
187
+ return self.load_json_file("state.json")
188
+
189
+ # Problem operations
190
+ def get_problems(self, contest_id: str) -> List[Dict[str, Any]]:
191
+ """Get all problems"""
192
+ self.validate_contest_id(contest_id)
193
+ return self.load_json_file("problems.json")
194
+
195
+ def get_problem(self, contest_id: str, problem_id: str) -> Dict[str, Any]:
196
+ """Get specific problem"""
197
+ self.validate_contest_id(contest_id)
198
+ problems = self.load_json_file("problems.json")
199
+ for problem in problems:
200
+ if problem["id"] == problem_id:
201
+ return problem
202
+ raise HTTPException(status_code=404, detail=f"Problem {problem_id} not found")
203
+
204
+ # Team operations
205
+ def get_teams(self, contest_id: str, group_id: Optional[str] = None) -> List[Dict[str, Any]]:
206
+ """Get all teams, optionally filtered by group"""
207
+ self.validate_contest_id(contest_id)
208
+ teams = self.load_json_file("teams.json")
209
+
210
+ if group_id:
211
+ filtered_teams = []
212
+ for team in teams:
213
+ if group_id in team.get("group_ids", []):
214
+ filtered_teams.append(team)
215
+ return filtered_teams
216
+
217
+ return teams
218
+
219
+ def get_team(self, contest_id: str, team_id: str) -> Dict[str, Any]:
220
+ """Get specific team"""
221
+ self.validate_contest_id(contest_id)
222
+ teams = self.load_json_file("teams.json")
223
+ for team in teams:
224
+ if team["id"] == team_id:
225
+ return team
226
+ raise HTTPException(status_code=404, detail=f"Team {team_id} not found")
227
+
228
+ # Organization operations
229
+ def get_organizations(self, contest_id: str) -> List[Dict[str, Any]]:
230
+ """Get all organizations"""
231
+ self.validate_contest_id(contest_id)
232
+ return self.load_json_file("organizations.json")
233
+
234
+ def get_organization(self, contest_id: str, organization_id: str) -> Dict[str, Any]:
235
+ """Get specific organization"""
236
+ self.validate_contest_id(contest_id)
237
+ organizations = self.load_json_file("organizations.json")
238
+ for org in organizations:
239
+ if org["id"] == organization_id:
240
+ return org
241
+ raise HTTPException(status_code=404, detail=f"Organization {organization_id} not found")
242
+
243
+ # Group operations
244
+ def get_groups(self, contest_id: str) -> List[Dict[str, Any]]:
245
+ """Get all groups"""
246
+ self.validate_contest_id(contest_id)
247
+ return self.load_json_file("groups.json")
248
+
249
+ def get_group(self, contest_id: str, group_id: str) -> Dict[str, Any]:
250
+ """Get specific group"""
251
+ self.validate_contest_id(contest_id)
252
+ groups = self.load_json_file("groups.json")
253
+ for group in groups:
254
+ if group["id"] == group_id:
255
+ return group
256
+ raise HTTPException(status_code=404, detail=f"Group {group_id} not found")
257
+
258
+ # Language operations
259
+ def get_languages(self, contest_id: str) -> List[Dict[str, Any]]:
260
+ """Get all languages"""
261
+ self.validate_contest_id(contest_id)
262
+ return self.load_json_file("languages.json")
263
+
264
+ def get_language(self, contest_id: str, language_id: str) -> Dict[str, Any]:
265
+ """Get specific language"""
266
+ self.validate_contest_id(contest_id)
267
+ languages = self.load_json_file("languages.json")
268
+ for lang in languages:
269
+ if lang["id"] == language_id:
270
+ return lang
271
+ raise HTTPException(status_code=404, detail=f"Language {language_id} not found")
272
+
273
+ # Judgement type operations
274
+ def get_judgement_types(self, contest_id: str) -> List[Dict[str, Any]]:
275
+ """Get all judgement types"""
276
+ self.validate_contest_id(contest_id)
277
+ return self.load_json_file("judgement-types.json")
278
+
279
+ def get_judgement_type(self, contest_id: str, judgement_type_id: str) -> Dict[str, Any]:
280
+ """Get specific judgement type"""
281
+ self.validate_contest_id(contest_id)
282
+ judgement_types = self.load_json_file("judgement-types.json")
283
+ for jt in judgement_types:
284
+ if jt["id"] == judgement_type_id:
285
+ return jt
286
+ raise HTTPException(status_code=404, detail=f"Judgement type {judgement_type_id} not found")
287
+
288
+ # Submission operations
289
+ def get_submissions(
290
+ self, contest_id: str, team_id: Optional[str] = None, problem_id: Optional[str] = None
291
+ ) -> List[Dict[str, Any]]:
292
+ """Get all submissions, optionally filtered"""
293
+ self.validate_contest_id(contest_id)
294
+ submissions = self.load_json_file("submissions.json")
295
+
296
+ # Apply filters
297
+ if team_id:
298
+ submissions = [s for s in submissions if s.get("team_id") == team_id]
299
+ if problem_id:
300
+ submissions = [s for s in submissions if s.get("problem_id") == problem_id]
301
+
302
+ return submissions
303
+
304
+ def get_submission(self, contest_id: str, submission_id: str) -> Dict[str, Any]:
305
+ """Get specific submission"""
306
+ self.validate_contest_id(contest_id)
307
+ submissions = self.load_json_file("submissions.json")
308
+ for submission in submissions:
309
+ if submission["id"] == submission_id:
310
+ return submission
311
+ raise HTTPException(status_code=404, detail=f"Submission {submission_id} not found")
312
+
313
+ # Judgement operations
314
+ def get_judgements(self, contest_id: str, submission_id: Optional[str] = None) -> List[Dict[str, Any]]:
315
+ """Get all judgements, optionally filtered by submission"""
316
+ self.validate_contest_id(contest_id)
317
+ judgements = self.load_json_file("judgements.json")
318
+
319
+ if submission_id:
320
+ judgements = [j for j in judgements if j.get("submission_id") == submission_id]
321
+
322
+ return judgements
323
+
324
+ def get_judgement(self, contest_id: str, judgement_id: str) -> Dict[str, Any]:
325
+ """Get specific judgement"""
326
+ self.validate_contest_id(contest_id)
327
+ judgements = self.load_json_file("judgements.json")
328
+ for judgement in judgements:
329
+ if judgement["id"] == judgement_id:
330
+ return judgement
331
+ raise HTTPException(status_code=404, detail=f"Judgement {judgement_id} not found")
332
+
333
+ # Run operations
334
+ def get_runs(self, contest_id: str, judgement_id: Optional[str] = None) -> List[Dict[str, Any]]:
335
+ """Get all runs, optionally filtered by judgement"""
336
+ self.validate_contest_id(contest_id)
337
+ runs = self.load_json_file("runs.json")
338
+
339
+ if judgement_id:
340
+ runs = [r for r in runs if r.get("judgement_id") == judgement_id]
341
+
342
+ return runs
343
+
344
+ def get_run(self, contest_id: str, run_id: str) -> Dict[str, Any]:
345
+ """Get specific run"""
346
+ self.validate_contest_id(contest_id)
347
+ runs = self.load_json_file("runs.json")
348
+ for run in runs:
349
+ if run["id"] == run_id:
350
+ return run
351
+ raise HTTPException(status_code=404, detail=f"Run {run_id} not found")
352
+
353
+ # Clarification operations
354
+ def get_clarifications(
355
+ self,
356
+ contest_id: str,
357
+ from_team_id: Optional[str] = None,
358
+ to_team_id: Optional[str] = None,
359
+ problem_id: Optional[str] = None,
360
+ ) -> List[Dict[str, Any]]:
361
+ """Get all clarifications, optionally filtered"""
362
+ self.validate_contest_id(contest_id)
363
+ clarifications = self.load_json_file("clarifications.json")
364
+
365
+ # Apply filters (empty string means null)
366
+ if from_team_id is not None:
367
+ if from_team_id == "":
368
+ clarifications = [c for c in clarifications if c.get("from_team_id") is None]
369
+ else:
370
+ clarifications = [c for c in clarifications if c.get("from_team_id") == from_team_id]
371
+
372
+ if to_team_id is not None:
373
+ if to_team_id == "":
374
+ clarifications = [c for c in clarifications if c.get("to_team_id") is None]
375
+ else:
376
+ clarifications = [c for c in clarifications if c.get("to_team_id") == to_team_id]
377
+
378
+ if problem_id is not None:
379
+ if problem_id == "":
380
+ clarifications = [c for c in clarifications if c.get("problem_id") is None]
381
+ else:
382
+ clarifications = [c for c in clarifications if c.get("problem_id") == problem_id]
383
+
384
+ return clarifications
385
+
386
+ def get_clarification(self, contest_id: str, clarification_id: str) -> Dict[str, Any]:
387
+ """Get specific clarification"""
388
+ self.validate_contest_id(contest_id)
389
+ clarifications = self.load_json_file("clarifications.json")
390
+ for clarification in clarifications:
391
+ if clarification["id"] == clarification_id:
392
+ return clarification
393
+ raise HTTPException(status_code=404, detail=f"Clarification {clarification_id} not found")
394
+
395
+ # Award operations
396
+ def get_awards(self, contest_id: str) -> List[Dict[str, Any]]:
397
+ """Get all awards"""
398
+ self.validate_contest_id(contest_id)
399
+ return self.load_json_file("awards.json")
400
+
401
+ def get_award(self, contest_id: str, award_id: str) -> Dict[str, Any]:
402
+ """Get specific award"""
403
+ self.validate_contest_id(contest_id)
404
+ awards = self.load_json_file("awards.json")
405
+ for award in awards:
406
+ if award["id"] == award_id:
407
+ return award
408
+ raise HTTPException(status_code=404, detail=f"Award {award_id} not found")
@@ -1,11 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xcpcio
3
- Version: 0.63.5
3
+ Version: 0.63.6
4
4
  Summary: xcpcio python lib
5
5
  Project-URL: homepage, https://github.com/xcpcio/xcpcio
6
6
  Project-URL: documentation, https://github.com/xcpcio/xcpcio
7
7
  Project-URL: repository, https://github.com/xcpcio/xcpcio
8
8
  Author-email: Dup4 <hi@dup4.com>
9
+ Maintainer-email: Dup4 <hi@dup4.com>, cubercsl <hi@cubercsl.site>
9
10
  License-Expression: MIT
10
11
  Keywords: xcpcio
11
12
  Classifier: Programming Language :: Python :: 3
@@ -18,10 +19,12 @@ Requires-Python: >=3.11
18
19
  Requires-Dist: aiofiles>=23.0.0
19
20
  Requires-Dist: aiohttp>=3.8.0
20
21
  Requires-Dist: click>=8.0.0
22
+ Requires-Dist: fastapi>=0.117.1
21
23
  Requires-Dist: pydantic>=2.11.7
22
24
  Requires-Dist: pyyaml>=6.0.0
23
25
  Requires-Dist: semver>=3.0.0
24
26
  Requires-Dist: tenacity>=8.0.0
27
+ Requires-Dist: uvicorn>=0.36.0
25
28
  Description-Content-Type: text/markdown
26
29
 
27
30
  # xcpcio-python
@@ -0,0 +1,33 @@
1
+ xcpcio/__init__.py,sha256=kjd6itqBRSQ-OT83qUJXHt81KQQDRUtaIuykzfaWXLM,121
2
+ xcpcio/__version__.py,sha256=rmZgql2iMibrRXQ70oij5TmONsjXyGZIxE3EUzW1_1E,172
3
+ xcpcio/constants.py,sha256=MjpAgNXiBlUsx1S09m7JNT-nekNDR-aE6ggvGL3fg0I,2297
4
+ xcpcio/types.py,sha256=AkYby2haJgxwtozlgaPMG2ryAZdvsSc3sH-p6qXcM4g,6575
5
+ xcpcio/ccs/__init__.py,sha256=LSoKFblEuSoIVBYcUxOFF8fn2bH2R6kSg9xNrBfzC0g,99
6
+ xcpcio/ccs/contest_archiver.py,sha256=FKpUn1IGfa-UNf63OJ5eff7rxOEqXCvFYRLsvkMbUJc,16203
7
+ xcpcio/ccs/api_server/__init__.py,sha256=ASvVJ_ibGkXFDSNmy05eb9gESXRS8hjYHCrBecSnaS0,174
8
+ xcpcio/ccs/api_server/dependencies.py,sha256=5nosGVwY-3Mq7eK9C5ZOMEJFozzzw_kLlpCraFbJ9wY,1225
9
+ xcpcio/ccs/api_server/server.py,sha256=3gft3MqDXvKWug5UCLhdV681bcQMRrewDkwQ7qSPtRU,2598
10
+ xcpcio/ccs/api_server/routes/__init__.py,sha256=imTyDjc9Md3OIr7GniHi3i1vmfzSTKppuUjVREtd8b4,1461
11
+ xcpcio/ccs/api_server/routes/access.py,sha256=8f21NmvVLaFopb5q4MnifOHbhadDZuNHr0BIYc9nmqY,579
12
+ xcpcio/ccs/api_server/routes/awards.py,sha256=uj56ty2k7N5KXfQuWTvvTXSa7HO29CUfEhO8S85hlM0,1069
13
+ xcpcio/ccs/api_server/routes/clarifications.py,sha256=JX7FNbv_4mRdpuV0aSzGwjjmW-4SwTbmAOlm51MNpf4,1644
14
+ xcpcio/ccs/api_server/routes/contests.py,sha256=bJeMaGegei59rD-5YE0ptYcNsPdJqc73KnntRpShzZk,2560
15
+ xcpcio/ccs/api_server/routes/general.py,sha256=9WsnjlomsU13vvozOVHSRIzgReuLGzPln3xwDb8i-gY,933
16
+ xcpcio/ccs/api_server/routes/groups.py,sha256=8hOT_2rz329M_7hcfggRxLU-g8aV2xp6w3aMYlfOPNs,1087
17
+ xcpcio/ccs/api_server/routes/judgement_types.py,sha256=pMOFBQ1LqKhCTLNBGzopCOEmTnWsuVg67dTuItJaCsM,1268
18
+ xcpcio/ccs/api_server/routes/judgements.py,sha256=9GMaEkD8erhqaSItlZQdLzKz-1XL7MD2SQinnD_CZFg,1339
19
+ xcpcio/ccs/api_server/routes/languages.py,sha256=DUNRd3q_Hm5F8-3nCiAMpqqxzG_9zcU5_N8ACefqjOE,1176
20
+ xcpcio/ccs/api_server/routes/organizations.py,sha256=fWnKTCmxd3c1leYsRuJHuuTs0CZr-l_-Jl-8_wY_Ojk,2889
21
+ xcpcio/ccs/api_server/routes/problems.py,sha256=0Ba3fz09UfTGYmYYYJYFGmIpgIvJaa1Fg-5pcLcxEMY,2774
22
+ xcpcio/ccs/api_server/routes/runs.py,sha256=uBPeM5ChI3LxR__pBSyDxsbcE4NyL6eKVdvF4TEOk5g,1248
23
+ xcpcio/ccs/api_server/routes/submissions.py,sha256=81-KbQLUKCqgGE-aCTO7-Pg2QyTJc_Mu_Ys8N0oF1tU,3161
24
+ xcpcio/ccs/api_server/routes/teams.py,sha256=y_aJykzgewmOQtXOJe2s0s7DQmnKjD3805Q5VTcdlIQ,2725
25
+ xcpcio/ccs/api_server/services/__init__.py,sha256=WQLNrLVomhtICl8HlFYaCoRewIHVZfUiiwrSBUOOWDg,171
26
+ xcpcio/ccs/api_server/services/contest_service.py,sha256=EbSDrkVg18Th9kAuYAin4InHCOI7hWkkDJR1u1xlEtk,16186
27
+ xcpcio/ccs/model/__init__.py,sha256=cZE1q5JY-iHDEKZpsx0UZaMhH-23H4oAHaYOkW7dZ5s,43
28
+ xcpcio/ccs/model/model_2023_06/__init__.py,sha256=OmDQZqmigBpL64LXk5lIOGoQ3Uqis8-2z6qQpOO5aJc,167
29
+ xcpcio/ccs/model/model_2023_06/model.py,sha256=bVMDWpJTwPSpz1fHPxWrWerxCBIboH3LKVZpIZGQ2pY,15287
30
+ xcpcio-0.63.6.dist-info/METADATA,sha256=uEBCmgoTkMCCrO-zLZGdzDjhYb9n51mabFs4lwEV0II,1079
31
+ xcpcio-0.63.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
+ xcpcio-0.63.6.dist-info/entry_points.txt,sha256=qvzh8oDJxIHqTN-rg2lRN6xR99AqxbWnlAQI7uzDibI,59
33
+ xcpcio-0.63.6.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- xcpcio/__init__.py,sha256=kjd6itqBRSQ-OT83qUJXHt81KQQDRUtaIuykzfaWXLM,121
2
- xcpcio/__version__.py,sha256=0Inh2IrO1TDWHZQNNWZG7RQoT8GKZUEeRoZnIhcVdWI,23
3
- xcpcio/constants.py,sha256=MjpAgNXiBlUsx1S09m7JNT-nekNDR-aE6ggvGL3fg0I,2297
4
- xcpcio/types.py,sha256=AkYby2haJgxwtozlgaPMG2ryAZdvsSc3sH-p6qXcM4g,6575
5
- xcpcio/ccs/__init__.py,sha256=qjkSo9lS8dJyNqiGljCnbS1cr7J8jj72pqcCzf_v0Ig,75
6
- xcpcio/ccs/contest_archiver.py,sha256=FKpUn1IGfa-UNf63OJ5eff7rxOEqXCvFYRLsvkMbUJc,16203
7
- xcpcio/ccs/model/__init__.py,sha256=cZE1q5JY-iHDEKZpsx0UZaMhH-23H4oAHaYOkW7dZ5s,43
8
- xcpcio/ccs/model/model_2023_06/__init__.py,sha256=OmDQZqmigBpL64LXk5lIOGoQ3Uqis8-2z6qQpOO5aJc,167
9
- xcpcio/ccs/model/model_2023_06/model.py,sha256=bVMDWpJTwPSpz1fHPxWrWerxCBIboH3LKVZpIZGQ2pY,15287
10
- xcpcio-0.63.5.dist-info/METADATA,sha256=KK0d6SVxSWCkNyD-6fYSO5GZnV2L9dT8FA_hE7o2hp0,950
11
- xcpcio-0.63.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
- xcpcio-0.63.5.dist-info/entry_points.txt,sha256=qvzh8oDJxIHqTN-rg2lRN6xR99AqxbWnlAQI7uzDibI,59
13
- xcpcio-0.63.5.dist-info/RECORD,,