xcpcio 0.63.4__tar.gz → 0.63.6__tar.gz
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.
- {xcpcio-0.63.4 → xcpcio-0.63.6}/.gitignore +2 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/PKG-INFO +4 -1
- xcpcio-0.63.6/app/contest_api_server.py +77 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/cli/ccs_archiver_cli.py +2 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/pyproject.toml +11 -1
- xcpcio-0.63.6/task.md +22 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/uv.lock +100 -46
- xcpcio-0.63.6/xcpcio/__version__.py +4 -0
- xcpcio-0.63.6/xcpcio/ccs/__init__.py +3 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/__init__.py +9 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/dependencies.py +48 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/__init__.py +50 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/access.py +20 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/awards.py +38 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/clarifications.py +42 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/contests.py +74 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/general.py +32 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/groups.py +41 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/judgement_types.py +41 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/judgements.py +40 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/languages.py +41 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/organizations.py +82 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/problems.py +77 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/runs.py +40 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/submissions.py +82 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/routes/teams.py +82 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/server.py +83 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/services/__init__.py +9 -0
- xcpcio-0.63.6/xcpcio/ccs/api_server/services/contest_service.py +408 -0
- xcpcio-0.63.4/xcpcio/__version__.py +0 -1
- xcpcio-0.63.4/xcpcio/ccs/__init__.py +0 -3
- {xcpcio-0.63.4 → xcpcio-0.63.6}/.python-version +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/README.md +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/scripts/generate_ccs_models.sh +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/tests/__init__.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/tests/test_contest.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/tests/test_submission.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/tests/test_team.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/tests/test_types.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/xcpcio/__init__.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/xcpcio/ccs/contest_archiver.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/xcpcio/ccs/model/__init__.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/xcpcio/ccs/model/model_2023_06/__init__.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/xcpcio/ccs/model/model_2023_06/model.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/xcpcio/constants.py +0 -0
- {xcpcio-0.63.4 → xcpcio-0.63.6}/xcpcio/types.py +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xcpcio
|
|
3
|
-
Version: 0.63.
|
|
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,77 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
|
|
6
|
+
from xcpcio import __version__
|
|
7
|
+
from xcpcio.ccs.api_server.server import ContestAPIServer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def setup_logging(level: str = "INFO"):
|
|
11
|
+
"""Setup logging configuration"""
|
|
12
|
+
logging.basicConfig(
|
|
13
|
+
level=getattr(logging, level.upper()),
|
|
14
|
+
format="%(asctime)s [%(name)s] %(filename)s:%(lineno)d %(levelname)s: %(message)s",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.command()
|
|
19
|
+
@click.version_option(__version__)
|
|
20
|
+
@click.option(
|
|
21
|
+
"--contest-dir",
|
|
22
|
+
"-d",
|
|
23
|
+
required=True,
|
|
24
|
+
type=click.Path(exists=True, file_okay=False, dir_okay=True, path_type=Path),
|
|
25
|
+
help="Contest package directory path",
|
|
26
|
+
)
|
|
27
|
+
@click.option("--host", default="0.0.0.0", help="Host to bind to")
|
|
28
|
+
@click.option("--port", default=8000, type=int, help="Port to bind to")
|
|
29
|
+
@click.option("--reload", is_flag=True, help="Enable auto-reload for development")
|
|
30
|
+
@click.option(
|
|
31
|
+
"--log-level",
|
|
32
|
+
default="info",
|
|
33
|
+
type=click.Choice(["debug", "info", "warning", "error", "critical"], case_sensitive=False),
|
|
34
|
+
help="Log level",
|
|
35
|
+
)
|
|
36
|
+
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose logging (same as --log-level debug)")
|
|
37
|
+
def main(contest_dir: Path, host: str, port: int, reload: bool, log_level: str, verbose: bool):
|
|
38
|
+
"""
|
|
39
|
+
Start the Contest API Server.
|
|
40
|
+
|
|
41
|
+
Examples:
|
|
42
|
+
|
|
43
|
+
# Start server with contest directory
|
|
44
|
+
contest-api-server -d /path/to/contest
|
|
45
|
+
|
|
46
|
+
# Custom host and port
|
|
47
|
+
contest-api-server -d /path/to/contest --host 127.0.0.1 --port 9000
|
|
48
|
+
|
|
49
|
+
# Enable reload for development
|
|
50
|
+
contest-api-server -d /path/to/contest --reload
|
|
51
|
+
"""
|
|
52
|
+
# Setup logging
|
|
53
|
+
if verbose:
|
|
54
|
+
log_level = "debug"
|
|
55
|
+
setup_logging(log_level.upper())
|
|
56
|
+
|
|
57
|
+
# Display configuration
|
|
58
|
+
click.echo("Starting Contest API Server...")
|
|
59
|
+
click.echo(f"Contest directory: {contest_dir}")
|
|
60
|
+
click.echo(f"Host: {host}")
|
|
61
|
+
click.echo(f"Port: {port}")
|
|
62
|
+
click.echo(f"Reload: {reload}")
|
|
63
|
+
click.echo(f"Log level: {log_level}")
|
|
64
|
+
|
|
65
|
+
# Create and run server
|
|
66
|
+
try:
|
|
67
|
+
server = ContestAPIServer(contest_dir)
|
|
68
|
+
server.run(host=host, port=port, reload=reload, log_level=log_level.lower())
|
|
69
|
+
except KeyboardInterrupt:
|
|
70
|
+
click.echo("\nServer stopped by user")
|
|
71
|
+
except Exception as e:
|
|
72
|
+
click.echo(f"Error starting server: {e}", err=True)
|
|
73
|
+
raise click.Abort()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
main()
|
|
@@ -5,6 +5,7 @@ from typing import Optional
|
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
8
|
+
from xcpcio import __version__
|
|
8
9
|
from xcpcio.ccs.contest_archiver import APICredentials, ArchiveConfig, ContestArchiver
|
|
9
10
|
|
|
10
11
|
|
|
@@ -17,6 +18,7 @@ def setup_logging(level: str = "INFO"):
|
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
@click.command()
|
|
21
|
+
@click.version_option(__version__)
|
|
20
22
|
@click.option("--base-url", required=True, help="Base URL of the CCS API (e.g., https://example.com/api)")
|
|
21
23
|
@click.option("--contest-id", required=True, help="Contest ID to dump")
|
|
22
24
|
@click.option(
|
|
@@ -3,6 +3,10 @@ name = "xcpcio"
|
|
|
3
3
|
description = "xcpcio python lib"
|
|
4
4
|
readme = "README.md"
|
|
5
5
|
authors = [ { name = "Dup4", email = "hi@dup4.com" } ]
|
|
6
|
+
maintainers = [
|
|
7
|
+
{ name = "Dup4", email = "hi@dup4.com" },
|
|
8
|
+
{ name = "cubercsl", email = "hi@cubercsl.site" },
|
|
9
|
+
]
|
|
6
10
|
license = "MIT"
|
|
7
11
|
keywords = [ "xcpcio" ]
|
|
8
12
|
classifiers = [
|
|
@@ -22,6 +26,8 @@ dependencies = [
|
|
|
22
26
|
"pyyaml>=6.0.0",
|
|
23
27
|
"semver>=3.0.0",
|
|
24
28
|
"tenacity>=8.0.0",
|
|
29
|
+
"fastapi>=0.117.1",
|
|
30
|
+
"uvicorn>=0.36.0",
|
|
25
31
|
]
|
|
26
32
|
dynamic = ["version"]
|
|
27
33
|
|
|
@@ -37,10 +43,14 @@ ccs-archiver = "cli.ccs_archiver_cli:main"
|
|
|
37
43
|
line-length = 120
|
|
38
44
|
|
|
39
45
|
[build-system]
|
|
40
|
-
requires = ["hatchling"]
|
|
46
|
+
requires = ["hatchling", "hatch-nodejs-version"]
|
|
41
47
|
build-backend = "hatchling.build"
|
|
42
48
|
|
|
43
49
|
[tool.hatch.version]
|
|
50
|
+
source = "nodejs"
|
|
51
|
+
path = "../package.json"
|
|
52
|
+
|
|
53
|
+
[tool.hatch.build.hooks.version]
|
|
44
54
|
path = "xcpcio/__version__.py"
|
|
45
55
|
|
|
46
56
|
[dependency-groups]
|
xcpcio-0.63.6/task.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Task
|
|
2
|
+
|
|
3
|
+
<import>
|
|
4
|
+
|
|
5
|
+
你的活动范围仅限于 ./ 之下,请务必不要超出此范围
|
|
6
|
+
|
|
7
|
+
</import>
|
|
8
|
+
|
|
9
|
+
您需要写一个 api server:
|
|
10
|
+
|
|
11
|
+
* 使用 python3,基于 fastapi 和 asyncio
|
|
12
|
+
* 用一个单文件写出来即可,不用拆文件,并且需要将所有功能封装成一个 class,class 命名为 ContestAPIServer
|
|
13
|
+
* 写入 ./xcpcio/ccs/contest_api_server.py 中
|
|
14
|
+
* 这个 APIServer 需要基于 fastapi 提供 swagger api docs,api docs 中的 response_model 请使用 ./xcpcio/ccs/model/__init__.py 中的东西
|
|
15
|
+
* 在本地有一个 contest package dir,你需要基于这个 dir,提供 contest api,但是 contest package api 需要作为一个配置项可配置,而不是写死
|
|
16
|
+
* contest package dir 的文件结构可以查阅 [Contest_Package.md][Contest_Package.md]
|
|
17
|
+
* contest api 的相关接口你可以查阅 [Contest_API.md][Contest_API.md]
|
|
18
|
+
* 本地的 contest package 你可以使用参考这个路径: ./output/2024hk
|
|
19
|
+
* 关于 [Contest_API.md][Contest_API.md] 中定义的那些数据结构,已经生成好了,你可以查阅 ./xcpcio/ccs/model/__init__.py,你可以直接使用
|
|
20
|
+
|
|
21
|
+
[Contest_Package.md]: ./ccs-specs/Contest_Package.md
|
|
22
|
+
[Contest_API.md]: ./ccs-specs/Contest_API.md
|
|
@@ -112,16 +112,16 @@ wheels = [
|
|
|
112
112
|
|
|
113
113
|
[[package]]
|
|
114
114
|
name = "anyio"
|
|
115
|
-
version = "4.
|
|
115
|
+
version = "4.11.0"
|
|
116
116
|
source = { registry = "https://pypi.org/simple" }
|
|
117
117
|
dependencies = [
|
|
118
118
|
{ name = "idna" },
|
|
119
119
|
{ name = "sniffio" },
|
|
120
120
|
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
|
121
121
|
]
|
|
122
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
122
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" }
|
|
123
123
|
wheels = [
|
|
124
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
124
|
+
{ url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" },
|
|
125
125
|
]
|
|
126
126
|
|
|
127
127
|
[[package]]
|
|
@@ -153,7 +153,7 @@ wheels = [
|
|
|
153
153
|
|
|
154
154
|
[[package]]
|
|
155
155
|
name = "black"
|
|
156
|
-
version = "25.
|
|
156
|
+
version = "25.9.0"
|
|
157
157
|
source = { registry = "https://pypi.org/simple" }
|
|
158
158
|
dependencies = [
|
|
159
159
|
{ name = "click" },
|
|
@@ -161,22 +161,23 @@ dependencies = [
|
|
|
161
161
|
{ name = "packaging" },
|
|
162
162
|
{ name = "pathspec" },
|
|
163
163
|
{ name = "platformdirs" },
|
|
164
|
+
{ name = "pytokens" },
|
|
164
165
|
]
|
|
165
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
166
|
+
sdist = { url = "https://files.pythonhosted.org/packages/4b/43/20b5c90612d7bdb2bdbcceeb53d588acca3bb8f0e4c5d5c751a2c8fdd55a/black-25.9.0.tar.gz", hash = "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619", size = 648393, upload-time = "2025-09-19T00:27:37.758Z" }
|
|
166
167
|
wheels = [
|
|
167
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
168
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
169
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
170
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
171
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
172
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
173
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
174
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
175
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
176
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
177
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
178
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
179
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
168
|
+
{ url = "https://files.pythonhosted.org/packages/b7/f4/7531d4a336d2d4ac6cc101662184c8e7d068b548d35d874415ed9f4116ef/black-25.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:456386fe87bad41b806d53c062e2974615825c7a52159cde7ccaeb0695fa28fa", size = 1698727, upload-time = "2025-09-19T00:31:14.264Z" },
|
|
169
|
+
{ url = "https://files.pythonhosted.org/packages/28/f9/66f26bfbbf84b949cc77a41a43e138d83b109502cd9c52dfc94070ca51f2/black-25.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a16b14a44c1af60a210d8da28e108e13e75a284bf21a9afa6b4571f96ab8bb9d", size = 1555679, upload-time = "2025-09-19T00:31:29.265Z" },
|
|
170
|
+
{ url = "https://files.pythonhosted.org/packages/bf/59/61475115906052f415f518a648a9ac679d7afbc8da1c16f8fdf68a8cebed/black-25.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaf319612536d502fdd0e88ce52d8f1352b2c0a955cc2798f79eeca9d3af0608", size = 1617453, upload-time = "2025-09-19T00:30:42.24Z" },
|
|
171
|
+
{ url = "https://files.pythonhosted.org/packages/7f/5b/20fd5c884d14550c911e4fb1b0dae00d4abb60a4f3876b449c4d3a9141d5/black-25.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:c0372a93e16b3954208417bfe448e09b0de5cc721d521866cd9e0acac3c04a1f", size = 1333655, upload-time = "2025-09-19T00:30:56.715Z" },
|
|
172
|
+
{ url = "https://files.pythonhosted.org/packages/fb/8e/319cfe6c82f7e2d5bfb4d3353c6cc85b523d677ff59edc61fdb9ee275234/black-25.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1b9dc70c21ef8b43248f1d86aedd2aaf75ae110b958a7909ad8463c4aa0880b0", size = 1742012, upload-time = "2025-09-19T00:33:08.678Z" },
|
|
173
|
+
{ url = "https://files.pythonhosted.org/packages/94/cc/f562fe5d0a40cd2a4e6ae3f685e4c36e365b1f7e494af99c26ff7f28117f/black-25.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8e46eecf65a095fa62e53245ae2795c90bdecabd53b50c448d0a8bcd0d2e74c4", size = 1581421, upload-time = "2025-09-19T00:35:25.937Z" },
|
|
174
|
+
{ url = "https://files.pythonhosted.org/packages/84/67/6db6dff1ebc8965fd7661498aea0da5d7301074b85bba8606a28f47ede4d/black-25.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9101ee58ddc2442199a25cb648d46ba22cd580b00ca4b44234a324e3ec7a0f7e", size = 1655619, upload-time = "2025-09-19T00:30:49.241Z" },
|
|
175
|
+
{ url = "https://files.pythonhosted.org/packages/10/10/3faef9aa2a730306cf469d76f7f155a8cc1f66e74781298df0ba31f8b4c8/black-25.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:77e7060a00c5ec4b3367c55f39cf9b06e68965a4f2e61cecacd6d0d9b7ec945a", size = 1342481, upload-time = "2025-09-19T00:31:29.625Z" },
|
|
176
|
+
{ url = "https://files.pythonhosted.org/packages/48/99/3acfea65f5e79f45472c45f87ec13037b506522719cd9d4ac86484ff51ac/black-25.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175", size = 1742165, upload-time = "2025-09-19T00:34:10.402Z" },
|
|
177
|
+
{ url = "https://files.pythonhosted.org/packages/3a/18/799285282c8236a79f25d590f0222dbd6850e14b060dfaa3e720241fd772/black-25.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f", size = 1581259, upload-time = "2025-09-19T00:32:49.685Z" },
|
|
178
|
+
{ url = "https://files.pythonhosted.org/packages/f1/ce/883ec4b6303acdeca93ee06b7622f1fa383c6b3765294824165d49b1a86b/black-25.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831", size = 1655583, upload-time = "2025-09-19T00:30:44.505Z" },
|
|
179
|
+
{ url = "https://files.pythonhosted.org/packages/21/17/5c253aa80a0639ccc427a5c7144534b661505ae2b5a10b77ebe13fa25334/black-25.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:846d58e3ce7879ec1ffe816bb9df6d006cd9590515ed5d17db14e17666b2b357", size = 1343428, upload-time = "2025-09-19T00:32:13.839Z" },
|
|
180
|
+
{ url = "https://files.pythonhosted.org/packages/1b/46/863c90dcd3f9d41b109b7f19032ae0db021f0b2a81482ba0a1e28c84de86/black-25.9.0-py3-none-any.whl", hash = "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae", size = 203363, upload-time = "2025-09-19T00:27:35.724Z" },
|
|
180
181
|
]
|
|
181
182
|
|
|
182
183
|
[[package]]
|
|
@@ -235,14 +236,14 @@ wheels = [
|
|
|
235
236
|
|
|
236
237
|
[[package]]
|
|
237
238
|
name = "click"
|
|
238
|
-
version = "8.
|
|
239
|
+
version = "8.3.0"
|
|
239
240
|
source = { registry = "https://pypi.org/simple" }
|
|
240
241
|
dependencies = [
|
|
241
242
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
242
243
|
]
|
|
243
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
244
|
+
sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" }
|
|
244
245
|
wheels = [
|
|
245
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
246
|
+
{ url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" },
|
|
246
247
|
]
|
|
247
248
|
|
|
248
249
|
[[package]]
|
|
@@ -337,6 +338,20 @@ wheels = [
|
|
|
337
338
|
{ url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" },
|
|
338
339
|
]
|
|
339
340
|
|
|
341
|
+
[[package]]
|
|
342
|
+
name = "fastapi"
|
|
343
|
+
version = "0.117.1"
|
|
344
|
+
source = { registry = "https://pypi.org/simple" }
|
|
345
|
+
dependencies = [
|
|
346
|
+
{ name = "pydantic" },
|
|
347
|
+
{ name = "starlette" },
|
|
348
|
+
{ name = "typing-extensions" },
|
|
349
|
+
]
|
|
350
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7e/7e/d9788300deaf416178f61fb3c2ceb16b7d0dc9f82a08fdb87a5e64ee3cc7/fastapi-0.117.1.tar.gz", hash = "sha256:fb2d42082d22b185f904ca0ecad2e195b851030bd6c5e4c032d1c981240c631a", size = 307155, upload-time = "2025-09-20T20:16:56.663Z" }
|
|
351
|
+
wheels = [
|
|
352
|
+
{ url = "https://files.pythonhosted.org/packages/6d/45/d9d3e8eeefbe93be1c50060a9d9a9f366dba66f288bb518a9566a23a8631/fastapi-0.117.1-py3-none-any.whl", hash = "sha256:33c51a0d21cab2b9722d4e56dbb9316f3687155be6b276191790d8da03507552", size = 95959, upload-time = "2025-09-20T20:16:53.661Z" },
|
|
353
|
+
]
|
|
354
|
+
|
|
340
355
|
[[package]]
|
|
341
356
|
name = "filelock"
|
|
342
357
|
version = "3.19.1"
|
|
@@ -959,7 +974,7 @@ wheels = [
|
|
|
959
974
|
|
|
960
975
|
[[package]]
|
|
961
976
|
name = "pydantic"
|
|
962
|
-
version = "2.11.
|
|
977
|
+
version = "2.11.9"
|
|
963
978
|
source = { registry = "https://pypi.org/simple" }
|
|
964
979
|
dependencies = [
|
|
965
980
|
{ name = "annotated-types" },
|
|
@@ -967,9 +982,9 @@ dependencies = [
|
|
|
967
982
|
{ name = "typing-extensions" },
|
|
968
983
|
{ name = "typing-inspection" },
|
|
969
984
|
]
|
|
970
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
985
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495, upload-time = "2025-09-13T11:26:39.325Z" }
|
|
971
986
|
wheels = [
|
|
972
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
987
|
+
{ url = "https://files.pythonhosted.org/packages/3e/d3/108f2006987c58e76691d5ae5d200dd3e0f532cb4e5fa3560751c3a1feba/pydantic-2.11.9-py3-none-any.whl", hash = "sha256:c42dd626f5cfc1c6950ce6205ea58c93efa406da65f479dcb4029d5934857da2", size = 444855, upload-time = "2025-09-13T11:26:36.909Z" },
|
|
973
988
|
]
|
|
974
989
|
|
|
975
990
|
[[package]]
|
|
@@ -1062,6 +1077,15 @@ wheels = [
|
|
|
1062
1077
|
{ url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" },
|
|
1063
1078
|
]
|
|
1064
1079
|
|
|
1080
|
+
[[package]]
|
|
1081
|
+
name = "pytokens"
|
|
1082
|
+
version = "0.1.10"
|
|
1083
|
+
source = { registry = "https://pypi.org/simple" }
|
|
1084
|
+
sdist = { url = "https://files.pythonhosted.org/packages/30/5f/e959a442435e24f6fb5a01aec6c657079ceaca1b3baf18561c3728d681da/pytokens-0.1.10.tar.gz", hash = "sha256:c9a4bfa0be1d26aebce03e6884ba454e842f186a59ea43a6d3b25af58223c044", size = 12171, upload-time = "2025-02-19T14:51:22.001Z" }
|
|
1085
|
+
wheels = [
|
|
1086
|
+
{ url = "https://files.pythonhosted.org/packages/60/e5/63bed382f6a7a5ba70e7e132b8b7b8abbcf4888ffa6be4877698dcfbed7d/pytokens-0.1.10-py3-none-any.whl", hash = "sha256:db7b72284e480e69fb085d9f251f66b3d2df8b7166059261258ff35f50fb711b", size = 12046, upload-time = "2025-02-19T14:51:18.694Z" },
|
|
1087
|
+
]
|
|
1088
|
+
|
|
1065
1089
|
[[package]]
|
|
1066
1090
|
name = "pywin32-ctypes"
|
|
1067
1091
|
version = "0.2.3"
|
|
@@ -1121,28 +1145,28 @@ wheels = [
|
|
|
1121
1145
|
|
|
1122
1146
|
[[package]]
|
|
1123
1147
|
name = "ruff"
|
|
1124
|
-
version = "0.
|
|
1125
|
-
source = { registry = "https://pypi.org/simple" }
|
|
1126
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1127
|
-
wheels = [
|
|
1128
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1129
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1130
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1131
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1132
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1133
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1134
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1135
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1136
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1137
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1138
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1139
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1140
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1141
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1142
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1143
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1144
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1145
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1148
|
+
version = "0.13.1"
|
|
1149
|
+
source = { registry = "https://pypi.org/simple" }
|
|
1150
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ab/33/c8e89216845615d14d2d42ba2bee404e7206a8db782f33400754f3799f05/ruff-0.13.1.tar.gz", hash = "sha256:88074c3849087f153d4bb22e92243ad4c1b366d7055f98726bc19aa08dc12d51", size = 5397987, upload-time = "2025-09-18T19:52:44.33Z" }
|
|
1151
|
+
wheels = [
|
|
1152
|
+
{ url = "https://files.pythonhosted.org/packages/f3/41/ca37e340938f45cfb8557a97a5c347e718ef34702546b174e5300dbb1f28/ruff-0.13.1-py3-none-linux_armv6l.whl", hash = "sha256:b2abff595cc3cbfa55e509d89439b5a09a6ee3c252d92020bd2de240836cf45b", size = 12304308, upload-time = "2025-09-18T19:51:56.253Z" },
|
|
1153
|
+
{ url = "https://files.pythonhosted.org/packages/ff/84/ba378ef4129415066c3e1c80d84e539a0d52feb250685091f874804f28af/ruff-0.13.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:4ee9f4249bf7f8bb3984c41bfaf6a658162cdb1b22e3103eabc7dd1dc5579334", size = 12937258, upload-time = "2025-09-18T19:52:00.184Z" },
|
|
1154
|
+
{ url = "https://files.pythonhosted.org/packages/8d/b6/ec5e4559ae0ad955515c176910d6d7c93edcbc0ed1a3195a41179c58431d/ruff-0.13.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5c5da4af5f6418c07d75e6f3224e08147441f5d1eac2e6ce10dcce5e616a3bae", size = 12214554, upload-time = "2025-09-18T19:52:02.753Z" },
|
|
1155
|
+
{ url = "https://files.pythonhosted.org/packages/70/d6/cb3e3b4f03b9b0c4d4d8f06126d34b3394f6b4d764912fe80a1300696ef6/ruff-0.13.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80524f84a01355a59a93cef98d804e2137639823bcee2931f5028e71134a954e", size = 12448181, upload-time = "2025-09-18T19:52:05.279Z" },
|
|
1156
|
+
{ url = "https://files.pythonhosted.org/packages/d2/ea/bf60cb46d7ade706a246cd3fb99e4cfe854efa3dfbe530d049c684da24ff/ruff-0.13.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff7f5ce8d7988767dd46a148192a14d0f48d1baea733f055d9064875c7d50389", size = 12104599, upload-time = "2025-09-18T19:52:07.497Z" },
|
|
1157
|
+
{ url = "https://files.pythonhosted.org/packages/2d/3e/05f72f4c3d3a69e65d55a13e1dd1ade76c106d8546e7e54501d31f1dc54a/ruff-0.13.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c55d84715061f8b05469cdc9a446aa6c7294cd4bd55e86a89e572dba14374f8c", size = 13791178, upload-time = "2025-09-18T19:52:10.189Z" },
|
|
1158
|
+
{ url = "https://files.pythonhosted.org/packages/81/e7/01b1fc403dd45d6cfe600725270ecc6a8f8a48a55bc6521ad820ed3ceaf8/ruff-0.13.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ac57fed932d90fa1624c946dc67a0a3388d65a7edc7d2d8e4ca7bddaa789b3b0", size = 14814474, upload-time = "2025-09-18T19:52:12.866Z" },
|
|
1159
|
+
{ url = "https://files.pythonhosted.org/packages/fa/92/d9e183d4ed6185a8df2ce9faa3f22e80e95b5f88d9cc3d86a6d94331da3f/ruff-0.13.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c366a71d5b4f41f86a008694f7a0d75fe409ec298685ff72dc882f882d532e36", size = 14217531, upload-time = "2025-09-18T19:52:15.245Z" },
|
|
1160
|
+
{ url = "https://files.pythonhosted.org/packages/3b/4a/6ddb1b11d60888be224d721e01bdd2d81faaf1720592858ab8bac3600466/ruff-0.13.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4ea9d1b5ad3e7a83ee8ebb1229c33e5fe771e833d6d3dcfca7b77d95b060d38", size = 13265267, upload-time = "2025-09-18T19:52:17.649Z" },
|
|
1161
|
+
{ url = "https://files.pythonhosted.org/packages/81/98/3f1d18a8d9ea33ef2ad508f0417fcb182c99b23258ec5e53d15db8289809/ruff-0.13.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0f70202996055b555d3d74b626406476cc692f37b13bac8828acff058c9966a", size = 13243120, upload-time = "2025-09-18T19:52:20.332Z" },
|
|
1162
|
+
{ url = "https://files.pythonhosted.org/packages/8d/86/b6ce62ce9c12765fa6c65078d1938d2490b2b1d9273d0de384952b43c490/ruff-0.13.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:f8cff7a105dad631085d9505b491db33848007d6b487c3c1979dd8d9b2963783", size = 13443084, upload-time = "2025-09-18T19:52:23.032Z" },
|
|
1163
|
+
{ url = "https://files.pythonhosted.org/packages/a1/6e/af7943466a41338d04503fb5a81b2fd07251bd272f546622e5b1599a7976/ruff-0.13.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:9761e84255443316a258dd7dfbd9bfb59c756e52237ed42494917b2577697c6a", size = 12295105, upload-time = "2025-09-18T19:52:25.263Z" },
|
|
1164
|
+
{ url = "https://files.pythonhosted.org/packages/3f/97/0249b9a24f0f3ebd12f007e81c87cec6d311de566885e9309fcbac5b24cc/ruff-0.13.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:3d376a88c3102ef228b102211ef4a6d13df330cb0f5ca56fdac04ccec2a99700", size = 12072284, upload-time = "2025-09-18T19:52:27.478Z" },
|
|
1165
|
+
{ url = "https://files.pythonhosted.org/packages/f6/85/0b64693b2c99d62ae65236ef74508ba39c3febd01466ef7f354885e5050c/ruff-0.13.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cbefd60082b517a82c6ec8836989775ac05f8991715d228b3c1d86ccc7df7dae", size = 12970314, upload-time = "2025-09-18T19:52:30.212Z" },
|
|
1166
|
+
{ url = "https://files.pythonhosted.org/packages/96/fc/342e9f28179915d28b3747b7654f932ca472afbf7090fc0c4011e802f494/ruff-0.13.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:dd16b9a5a499fe73f3c2ef09a7885cb1d97058614d601809d37c422ed1525317", size = 13422360, upload-time = "2025-09-18T19:52:32.676Z" },
|
|
1167
|
+
{ url = "https://files.pythonhosted.org/packages/37/54/6177a0dc10bce6f43e392a2192e6018755473283d0cf43cc7e6afc182aea/ruff-0.13.1-py3-none-win32.whl", hash = "sha256:55e9efa692d7cb18580279f1fbb525146adc401f40735edf0aaeabd93099f9a0", size = 12178448, upload-time = "2025-09-18T19:52:35.545Z" },
|
|
1168
|
+
{ url = "https://files.pythonhosted.org/packages/64/51/c6a3a33d9938007b8bdc8ca852ecc8d810a407fb513ab08e34af12dc7c24/ruff-0.13.1-py3-none-win_amd64.whl", hash = "sha256:3a3fb595287ee556de947183489f636b9f76a72f0fa9c028bdcabf5bab2cc5e5", size = 13286458, upload-time = "2025-09-18T19:52:38.198Z" },
|
|
1169
|
+
{ url = "https://files.pythonhosted.org/packages/fd/04/afc078a12cf68592345b1e2d6ecdff837d286bac023d7a22c54c7a698c5b/ruff-0.13.1-py3-none-win_arm64.whl", hash = "sha256:c0bae9ffd92d54e03c2bf266f466da0a65e145f298ee5b5846ed435f6a00518a", size = 12437893, upload-time = "2025-09-18T19:52:41.283Z" },
|
|
1146
1170
|
]
|
|
1147
1171
|
|
|
1148
1172
|
[[package]]
|
|
@@ -1185,6 +1209,19 @@ wheels = [
|
|
|
1185
1209
|
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
|
|
1186
1210
|
]
|
|
1187
1211
|
|
|
1212
|
+
[[package]]
|
|
1213
|
+
name = "starlette"
|
|
1214
|
+
version = "0.48.0"
|
|
1215
|
+
source = { registry = "https://pypi.org/simple" }
|
|
1216
|
+
dependencies = [
|
|
1217
|
+
{ name = "anyio" },
|
|
1218
|
+
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
|
1219
|
+
]
|
|
1220
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a7/a5/d6f429d43394057b67a6b5bbe6eae2f77a6bf7459d961fdb224bf206eee6/starlette-0.48.0.tar.gz", hash = "sha256:7e8cee469a8ab2352911528110ce9088fdc6a37d9876926e73da7ce4aa4c7a46", size = 2652949, upload-time = "2025-09-13T08:41:05.699Z" }
|
|
1221
|
+
wheels = [
|
|
1222
|
+
{ url = "https://files.pythonhosted.org/packages/be/72/2db2f49247d0a18b4f1bb9a5a39a0162869acf235f3a96418363947b3d46/starlette-0.48.0-py3-none-any.whl", hash = "sha256:0764ca97b097582558ecb498132ed0c7d942f233f365b86ba37770e026510659", size = 73736, upload-time = "2025-09-13T08:41:03.869Z" },
|
|
1223
|
+
]
|
|
1224
|
+
|
|
1188
1225
|
[[package]]
|
|
1189
1226
|
name = "tenacity"
|
|
1190
1227
|
version = "9.1.2"
|
|
@@ -1331,6 +1368,19 @@ wheels = [
|
|
|
1331
1368
|
{ url = "https://files.pythonhosted.org/packages/f9/00/2c7a93bbe93b74dc0496a8e875bac11027cb30c29636c106c6e49038b95f/uv-0.8.22-py3-none-win_arm64.whl", hash = "sha256:2a436b941b6e79fe1e1065b705a5689d72210f4367cbe885e19910cbcde2e4a1", size = 19778983, upload-time = "2025-09-23T20:35:12.188Z" },
|
|
1332
1369
|
]
|
|
1333
1370
|
|
|
1371
|
+
[[package]]
|
|
1372
|
+
name = "uvicorn"
|
|
1373
|
+
version = "0.37.0"
|
|
1374
|
+
source = { registry = "https://pypi.org/simple" }
|
|
1375
|
+
dependencies = [
|
|
1376
|
+
{ name = "click" },
|
|
1377
|
+
{ name = "h11" },
|
|
1378
|
+
]
|
|
1379
|
+
sdist = { url = "https://files.pythonhosted.org/packages/71/57/1616c8274c3442d802621abf5deb230771c7a0fec9414cb6763900eb3868/uvicorn-0.37.0.tar.gz", hash = "sha256:4115c8add6d3fd536c8ee77f0e14a7fd2ebba939fed9b02583a97f80648f9e13", size = 80367, upload-time = "2025-09-23T13:33:47.486Z" }
|
|
1380
|
+
wheels = [
|
|
1381
|
+
{ url = "https://files.pythonhosted.org/packages/85/cd/584a2ceb5532af99dd09e50919e3615ba99aa127e9850eafe5f31ddfdb9a/uvicorn-0.37.0-py3-none-any.whl", hash = "sha256:913b2b88672343739927ce381ff9e2ad62541f9f8289664fa1d1d3803fa2ce6c", size = 67976, upload-time = "2025-09-23T13:33:45.842Z" },
|
|
1382
|
+
]
|
|
1383
|
+
|
|
1334
1384
|
[[package]]
|
|
1335
1385
|
name = "virtualenv"
|
|
1336
1386
|
version = "20.34.0"
|
|
@@ -1352,10 +1402,12 @@ dependencies = [
|
|
|
1352
1402
|
{ name = "aiofiles" },
|
|
1353
1403
|
{ name = "aiohttp" },
|
|
1354
1404
|
{ name = "click" },
|
|
1405
|
+
{ name = "fastapi" },
|
|
1355
1406
|
{ name = "pydantic" },
|
|
1356
1407
|
{ name = "pyyaml" },
|
|
1357
1408
|
{ name = "semver" },
|
|
1358
1409
|
{ name = "tenacity" },
|
|
1410
|
+
{ name = "uvicorn" },
|
|
1359
1411
|
]
|
|
1360
1412
|
|
|
1361
1413
|
[package.dev-dependencies]
|
|
@@ -1371,10 +1423,12 @@ requires-dist = [
|
|
|
1371
1423
|
{ name = "aiofiles", specifier = ">=23.0.0" },
|
|
1372
1424
|
{ name = "aiohttp", specifier = ">=3.8.0" },
|
|
1373
1425
|
{ name = "click", specifier = ">=8.0.0" },
|
|
1426
|
+
{ name = "fastapi", specifier = ">=0.117.1" },
|
|
1374
1427
|
{ name = "pydantic", specifier = ">=2.11.7" },
|
|
1375
1428
|
{ name = "pyyaml", specifier = ">=6.0.0" },
|
|
1376
1429
|
{ name = "semver", specifier = ">=3.0.0" },
|
|
1377
1430
|
{ name = "tenacity", specifier = ">=8.0.0" },
|
|
1431
|
+
{ name = "uvicorn", specifier = ">=0.36.0" },
|
|
1378
1432
|
]
|
|
1379
1433
|
|
|
1380
1434
|
[package.metadata.requires-dev]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
FastAPI Dependencies
|
|
3
|
+
|
|
4
|
+
Dependency injection system for Contest API Server.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Annotated
|
|
9
|
+
|
|
10
|
+
from fastapi import Depends
|
|
11
|
+
|
|
12
|
+
from .services.contest_service import ContestService
|
|
13
|
+
|
|
14
|
+
# Global contest service instance cache
|
|
15
|
+
_contest_service_instance = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_contest_service() -> ContestService:
|
|
19
|
+
"""
|
|
20
|
+
Dependency that provides ContestService instance.
|
|
21
|
+
|
|
22
|
+
This is configured by the main server class and cached globally.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
ContestService instance
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
RuntimeError: If service not configured
|
|
29
|
+
"""
|
|
30
|
+
global _contest_service_instance
|
|
31
|
+
if _contest_service_instance is None:
|
|
32
|
+
raise RuntimeError("ContestService not configured. Call configure_dependencies() first.")
|
|
33
|
+
return _contest_service_instance
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def configure_dependencies(contest_package_dir: Path) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Configure the dependency injection system.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
contest_package_dir: Path to contest package directory
|
|
42
|
+
"""
|
|
43
|
+
global _contest_service_instance
|
|
44
|
+
_contest_service_instance = ContestService(contest_package_dir)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# Type alias for dependency injection
|
|
48
|
+
ContestServiceDep = Annotated[ContestService, Depends(get_contest_service)]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Routes package for Contest API Server
|
|
3
|
+
|
|
4
|
+
Contains all API route definitions organized by functionality.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from fastapi import APIRouter
|
|
8
|
+
|
|
9
|
+
from . import (
|
|
10
|
+
access,
|
|
11
|
+
awards,
|
|
12
|
+
clarifications,
|
|
13
|
+
contests,
|
|
14
|
+
general,
|
|
15
|
+
groups,
|
|
16
|
+
judgement_types,
|
|
17
|
+
judgements,
|
|
18
|
+
languages,
|
|
19
|
+
organizations,
|
|
20
|
+
problems,
|
|
21
|
+
runs,
|
|
22
|
+
submissions,
|
|
23
|
+
teams,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def create_router() -> APIRouter:
|
|
28
|
+
"""Create and configure the main API router"""
|
|
29
|
+
router = APIRouter(prefix="/api")
|
|
30
|
+
|
|
31
|
+
# Include all route modules
|
|
32
|
+
router.include_router(access.router, tags=["Access"])
|
|
33
|
+
router.include_router(awards.router, tags=["Awards"])
|
|
34
|
+
router.include_router(clarifications.router, tags=["Clarifications"])
|
|
35
|
+
router.include_router(contests.router, tags=["Contests"])
|
|
36
|
+
router.include_router(general.router, tags=["General"])
|
|
37
|
+
router.include_router(groups.router, tags=["Groups"])
|
|
38
|
+
router.include_router(judgements.router, tags=["Judgements"])
|
|
39
|
+
router.include_router(judgement_types.router, tags=["Judgement types"])
|
|
40
|
+
router.include_router(languages.router, tags=["Languages"])
|
|
41
|
+
router.include_router(organizations.router, tags=["Organizations"])
|
|
42
|
+
router.include_router(problems.router, tags=["Problems"])
|
|
43
|
+
router.include_router(runs.router, tags=["Runs"])
|
|
44
|
+
router.include_router(submissions.router, tags=["Submissions"])
|
|
45
|
+
router.include_router(teams.router, tags=["Teams"])
|
|
46
|
+
|
|
47
|
+
return router
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
__all__ = ["create_router"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any, Dict
|
|
3
|
+
|
|
4
|
+
from fastapi import APIRouter
|
|
5
|
+
|
|
6
|
+
from ..dependencies import ContestServiceDep
|
|
7
|
+
|
|
8
|
+
router = APIRouter()
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@router.get(
|
|
13
|
+
"/contests/{contest_id}/access",
|
|
14
|
+
summary="Get Access Information",
|
|
15
|
+
description="Get access capabilities and visible endpoints for current client",
|
|
16
|
+
response_model=Dict[str, Any],
|
|
17
|
+
)
|
|
18
|
+
async def get_access(contest_id: str, service: ContestServiceDep) -> Dict[str, Any]:
|
|
19
|
+
"""Get access information for the current client"""
|
|
20
|
+
return service.get_access_info(contest_id)
|