xcpcio 0.63.5__tar.gz → 0.63.7__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.5 → xcpcio-0.63.7}/.gitignore +2 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/PKG-INFO +4 -1
- xcpcio-0.63.7/app/contest_api_server.py +77 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/cli/ccs_archiver_cli.py +2 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/pyproject.toml +11 -1
- xcpcio-0.63.7/task.md +22 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/uv.lock +100 -46
- xcpcio-0.63.7/xcpcio/__version__.py +4 -0
- xcpcio-0.63.7/xcpcio/ccs/__init__.py +3 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/__init__.py +9 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/dependencies.py +48 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/__init__.py +52 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/access.py +18 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/accounts.py +35 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/awards.py +33 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/clarifications.py +34 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/contests.py +119 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/general.py +33 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/groups.py +34 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/judgement_types.py +34 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/judgements.py +35 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/languages.py +34 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/organizations.py +71 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/problems.py +69 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/runs.py +35 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/submissions.py +71 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/routes/teams.py +69 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/server.py +83 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/services/__init__.py +9 -0
- xcpcio-0.63.7/xcpcio/ccs/api_server/services/contest_service.py +325 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/xcpcio/ccs/contest_archiver.py +2 -3
- xcpcio-0.63.5/xcpcio/__version__.py +0 -1
- xcpcio-0.63.5/xcpcio/ccs/__init__.py +0 -3
- {xcpcio-0.63.5 → xcpcio-0.63.7}/.python-version +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/README.md +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/scripts/generate_ccs_models.sh +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/tests/__init__.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/tests/test_contest.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/tests/test_submission.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/tests/test_team.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/tests/test_types.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/xcpcio/__init__.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/xcpcio/ccs/model/__init__.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/xcpcio/ccs/model/model_2023_06/__init__.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/xcpcio/ccs/model/model_2023_06/model.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/xcpcio/constants.py +0 -0
- {xcpcio-0.63.5 → xcpcio-0.63.7}/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.7
|
|
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.7/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,52 @@
|
|
|
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
|
+
accounts,
|
|
12
|
+
awards,
|
|
13
|
+
clarifications,
|
|
14
|
+
contests,
|
|
15
|
+
general,
|
|
16
|
+
groups,
|
|
17
|
+
judgement_types,
|
|
18
|
+
judgements,
|
|
19
|
+
languages,
|
|
20
|
+
organizations,
|
|
21
|
+
problems,
|
|
22
|
+
runs,
|
|
23
|
+
submissions,
|
|
24
|
+
teams,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def create_router() -> APIRouter:
|
|
29
|
+
"""Create and configure the main API router"""
|
|
30
|
+
router = APIRouter(prefix="/api")
|
|
31
|
+
|
|
32
|
+
# Include all route modules
|
|
33
|
+
router.include_router(access.router, tags=["Access"])
|
|
34
|
+
router.include_router(accounts.router, tags=["Accounts"])
|
|
35
|
+
router.include_router(awards.router, tags=["Awards"])
|
|
36
|
+
router.include_router(clarifications.router, tags=["Clarifications"])
|
|
37
|
+
router.include_router(contests.router, tags=["Contests"])
|
|
38
|
+
router.include_router(general.router, tags=["General"])
|
|
39
|
+
router.include_router(groups.router, tags=["Groups"])
|
|
40
|
+
router.include_router(judgements.router, tags=["Judgements"])
|
|
41
|
+
router.include_router(judgement_types.router, tags=["Judgement types"])
|
|
42
|
+
router.include_router(languages.router, tags=["Languages"])
|
|
43
|
+
router.include_router(organizations.router, tags=["Organizations"])
|
|
44
|
+
router.include_router(problems.router, tags=["Problems"])
|
|
45
|
+
router.include_router(runs.router, tags=["Runs"])
|
|
46
|
+
router.include_router(submissions.router, tags=["Submissions"])
|
|
47
|
+
router.include_router(teams.router, tags=["Teams"])
|
|
48
|
+
|
|
49
|
+
return router
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
__all__ = ["create_router"]
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
response_model=Dict[str, Any],
|
|
16
|
+
)
|
|
17
|
+
async def get_access(contest_id: str, service: ContestServiceDep) -> Dict[str, Any]:
|
|
18
|
+
return service.get_access(contest_id)
|