dothat 1.0.0__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.
- dothat-1.0.0/.gitignore +3 -0
- dothat-1.0.0/PKG-INFO +13 -0
- dothat-1.0.0/README.md +0 -0
- dothat-1.0.0/dothat/VERSION +2 -0
- dothat-1.0.0/dothat/__init__.py +9 -0
- dothat-1.0.0/dothat/cli.py +97 -0
- dothat-1.0.0/dothat/default_tasks/__init__.py +3 -0
- dothat-1.0.0/dothat/default_tasks/_actions.py +8 -0
- dothat-1.0.0/dothat/default_tasks/_params.py +11 -0
- dothat-1.0.0/dothat/default_tasks/_tasks.py +19 -0
- dothat-1.0.0/dothat/di.py +27 -0
- dothat-1.0.0/dothat/initialization/__init__.py +45 -0
- dothat-1.0.0/dothat/initialization/templates/_tasks/__init__.py +3 -0
- dothat-1.0.0/dothat/initialization/templates/_tasks/_actions.py +38 -0
- dothat-1.0.0/dothat/initialization/templates/_tasks/_consts.py +5 -0
- dothat-1.0.0/dothat/initialization/templates/_tasks/_params.py +20 -0
- dothat-1.0.0/dothat/initialization/templates/_tasks/_tasks.py +39 -0
- dothat-1.0.0/dothat/logging.py +30 -0
- dothat-1.0.0/dothat/models/__init__.py +9 -0
- dothat-1.0.0/dothat/models/actions.py +54 -0
- dothat-1.0.0/dothat/models/params.py +42 -0
- dothat-1.0.0/dothat/project_config/__init__.py +46 -0
- dothat-1.0.0/dothat/py.typed +0 -0
- dothat-1.0.0/dothat/registry.py +80 -0
- dothat-1.0.0/dothat/task_builder.py +138 -0
- dothat-1.0.0/dothat/task_generator.py +32 -0
- dothat-1.0.0/dothat/tasks_core/default_tasks/__init__.py +3 -0
- dothat-1.0.0/dothat/tasks_core/default_tasks/_actions.py +8 -0
- dothat-1.0.0/dothat/tasks_core/default_tasks/_params.py +11 -0
- dothat-1.0.0/dothat/tasks_core/default_tasks/_tasks.py +19 -0
- dothat-1.0.0/environment.toml +3 -0
- dothat-1.0.0/pyproject.toml +55 -0
- dothat-1.0.0/uv.lock +253 -0
dothat-1.0.0/.gitignore
ADDED
dothat-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: dothat
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: framework for python tasks and actions management
|
|
5
|
+
Author: PivLab Dev
|
|
6
|
+
Author-email: Arsenii Nikulin <a.nikulin@pivlab.dev>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Requires-Python: <4.0,>=3.11
|
|
9
|
+
Requires-Dist: click<9.0.0,>=8.4.1
|
|
10
|
+
Requires-Dist: gitpython<4.0.0,>=3.1.57
|
|
11
|
+
Requires-Dist: injector>=0.24.0
|
|
12
|
+
Requires-Dist: loguru<1.0.0,>=0.7.3
|
|
13
|
+
Requires-Dist: pydantic>=2.13.5
|
dothat-1.0.0/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import builtins
|
|
2
|
+
import dataclasses
|
|
3
|
+
import pathlib
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
import injector
|
|
7
|
+
|
|
8
|
+
from dothat.di import Module
|
|
9
|
+
from dothat.logging import logger as LOGGER
|
|
10
|
+
from dothat.registry import TaskRegistry
|
|
11
|
+
from dothat.task_builder import Task
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclasses.dataclass
|
|
15
|
+
class DothatContext:
|
|
16
|
+
di: injector.Injector
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_registry(di: injector.Injector, module: str | None) -> dict[str, Task]:
|
|
20
|
+
if module:
|
|
21
|
+
return di.get(TaskRegistry).load_tasks_from_module(module)
|
|
22
|
+
return di.get(TaskRegistry).tasks
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@click.group()
|
|
26
|
+
@click.option(
|
|
27
|
+
"--config",
|
|
28
|
+
type=pathlib.Path,
|
|
29
|
+
envvar="ENVIRONMENT_TOML_PATH",
|
|
30
|
+
default=pathlib.Path(
|
|
31
|
+
"environment.toml",
|
|
32
|
+
),
|
|
33
|
+
)
|
|
34
|
+
@click.pass_context
|
|
35
|
+
def cli(ctx: click.Context, config: pathlib.Path):
|
|
36
|
+
ctx.obj = DothatContext(di=injector.Injector([Module(config_path=config)]))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@cli.command()
|
|
40
|
+
@click.option("--module", default=None)
|
|
41
|
+
@click.pass_obj
|
|
42
|
+
def list(dothat_context: DothatContext, module: str | None):
|
|
43
|
+
_registry = get_registry(dothat_context.di, module)
|
|
44
|
+
|
|
45
|
+
for key, task in _registry.items():
|
|
46
|
+
click.echo(f"R {key:<50} {task.doc}")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@cli.command()
|
|
50
|
+
@click.argument("task_name")
|
|
51
|
+
@click.option("--module", default=None)
|
|
52
|
+
@click.pass_obj
|
|
53
|
+
def help(dothat_context: DothatContext, task_name: str, module: str):
|
|
54
|
+
_registry = get_registry(di=dothat_context.di, module=module)
|
|
55
|
+
|
|
56
|
+
task = _registry[task_name]
|
|
57
|
+
|
|
58
|
+
click.echo(f"{task_name} {task.doc}")
|
|
59
|
+
|
|
60
|
+
for param in task.params:
|
|
61
|
+
description: builtins.list[str] = [f"config: {param.name}"]
|
|
62
|
+
|
|
63
|
+
if param.env_var:
|
|
64
|
+
description.append(f"environ: {param.env_var}")
|
|
65
|
+
if param.type is bool and param.inverse:
|
|
66
|
+
description.append(f"opposite of {param.inverse}")
|
|
67
|
+
|
|
68
|
+
click.echo(f" --{param.long:<30} ({', '.join(description)})")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@cli.command(
|
|
72
|
+
context_settings={
|
|
73
|
+
"ignore_unknown_options": True,
|
|
74
|
+
"allow_extra_args": True,
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
@click.argument("task_name")
|
|
78
|
+
@click.pass_context
|
|
79
|
+
@click.option("--module", default=None)
|
|
80
|
+
def run(ctx: click.Context, task_name: str, module: str | None):
|
|
81
|
+
_registry = get_registry(di=ctx.obj.di, module=module)
|
|
82
|
+
|
|
83
|
+
task = _registry.get(task_name)
|
|
84
|
+
|
|
85
|
+
if task is None:
|
|
86
|
+
raise click.ClickException(f"Unknown task: {task_name}")
|
|
87
|
+
task = task.model_copy(deep=True)
|
|
88
|
+
|
|
89
|
+
task.parse_task_params(args=ctx.args, di=ctx.obj.di)
|
|
90
|
+
|
|
91
|
+
LOGGER.debug(f"running task: {task.basename}")
|
|
92
|
+
|
|
93
|
+
task.exec_task(inj=ctx.obj.di)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
if __name__ == "__main__":
|
|
97
|
+
cli()
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from dothat.initialization import TemplateGenerator
|
|
2
|
+
from dothat.models.actions import InteractivePythonAction
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class InitializeDefaultProject(InteractivePythonAction):
|
|
6
|
+
def impl(self, *, force: bool, **_) -> None:
|
|
7
|
+
templategenerator = TemplateGenerator()
|
|
8
|
+
templategenerator.generate_project_structure(force=force)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from collections.abc import Iterator
|
|
2
|
+
|
|
3
|
+
from dothat.default_tasks import _actions, _params
|
|
4
|
+
from dothat.task_builder import Task, TaskBuilderImpl
|
|
5
|
+
from dothat.task_generator import TaskGeneratorImpl
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class InitializeDefaultProject(TaskBuilderImpl):
|
|
9
|
+
_basename = "init"
|
|
10
|
+
|
|
11
|
+
def apply(self):
|
|
12
|
+
return self.with_actions((_actions.InitializeDefaultProject,)).with_params((_params.force(),))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CiTaskGenerator(TaskGeneratorImpl):
|
|
16
|
+
task_init = InitializeDefaultProject
|
|
17
|
+
|
|
18
|
+
def load_tasks(self) -> Iterator[Task]:
|
|
19
|
+
yield from super().load_tasks()
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
|
|
3
|
+
import injector
|
|
4
|
+
|
|
5
|
+
from dothat.models.params import Params
|
|
6
|
+
from dothat.project_config import ProjectConfig
|
|
7
|
+
from dothat.registry import TaskRegistry
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ConfigPath:
|
|
11
|
+
def __init__(self, path: pathlib.Path) -> None:
|
|
12
|
+
self.path = path
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Module(injector.Module):
|
|
16
|
+
def __init__(self, config_path: pathlib.Path = pathlib.Path("environment.toml")) -> None:
|
|
17
|
+
self.config_path = config_path
|
|
18
|
+
|
|
19
|
+
def configure(self, binder: injector.Binder) -> None:
|
|
20
|
+
binder.bind(ConfigPath, to=ConfigPath(self.config_path))
|
|
21
|
+
binder.bind(TaskRegistry, scope=injector.singleton)
|
|
22
|
+
binder.bind(Params, scope=injector.singleton)
|
|
23
|
+
|
|
24
|
+
@injector.singleton
|
|
25
|
+
@injector.provider
|
|
26
|
+
def provide_config(self, cfg_path: ConfigPath) -> ProjectConfig:
|
|
27
|
+
return ProjectConfig.from_file(cfg_path.path)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
import shutil
|
|
3
|
+
from importlib.resources import as_file, files
|
|
4
|
+
|
|
5
|
+
from dothat.logging import logger as LOGGER
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TemplateGenerator:
|
|
9
|
+
def generate_project_structure(
|
|
10
|
+
self,
|
|
11
|
+
destination: pathlib.Path = pathlib.Path("."),
|
|
12
|
+
force: bool = False,
|
|
13
|
+
) -> None:
|
|
14
|
+
template = files("dothat.initialization") / "templates"
|
|
15
|
+
|
|
16
|
+
LOGGER.info("Copying project template from {}", template)
|
|
17
|
+
|
|
18
|
+
with as_file(template) as template_path:
|
|
19
|
+
self._copy_template(
|
|
20
|
+
template_path,
|
|
21
|
+
destination,
|
|
22
|
+
force=force,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def _copy_template(
|
|
27
|
+
source: pathlib.Path,
|
|
28
|
+
destination: pathlib.Path,
|
|
29
|
+
*,
|
|
30
|
+
force: bool,
|
|
31
|
+
) -> None:
|
|
32
|
+
for source_path in source.rglob("*"):
|
|
33
|
+
relative_path = source_path.relative_to(source)
|
|
34
|
+
destination_path = destination / relative_path
|
|
35
|
+
|
|
36
|
+
if source_path.is_dir():
|
|
37
|
+
destination_path.mkdir(parents=True, exist_ok=True)
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
if destination_path.exists() and not force:
|
|
41
|
+
LOGGER.debug("Skipping existing file: {}", destination_path)
|
|
42
|
+
continue
|
|
43
|
+
|
|
44
|
+
destination_path.parent.mkdir(parents=True, exist_ok=True)
|
|
45
|
+
shutil.copy2(source_path, destination_path)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
import typing
|
|
3
|
+
|
|
4
|
+
from dothat import InteractivePythonAction, InteractiveShlex
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SetupSsh(InteractivePythonAction):
|
|
8
|
+
def impl(self, **_):
|
|
9
|
+
ssh_private_key = "123"
|
|
10
|
+
|
|
11
|
+
ssh_dir = pathlib.Path("/root/.ssh")
|
|
12
|
+
ssh_dir.mkdir(exist_ok=True)
|
|
13
|
+
ssh_dir.chmod(0o600)
|
|
14
|
+
|
|
15
|
+
private_key_file = ssh_dir / "id_ci"
|
|
16
|
+
private_key_file.write_text(ssh_private_key)
|
|
17
|
+
private_key_file.chmod(0o600)
|
|
18
|
+
|
|
19
|
+
ssh_config_file = ssh_dir / "config"
|
|
20
|
+
ssh_config_data = [
|
|
21
|
+
"Host gl.pivlab.dev",
|
|
22
|
+
" IdentityFile /root/.ssh/id_ci",
|
|
23
|
+
" IdentitiesOnly yes",
|
|
24
|
+
" StrictHostKeyChecking no",
|
|
25
|
+
" UserKnownHostsFile /dev/null",
|
|
26
|
+
]
|
|
27
|
+
ssh_config_file.write_text("\n".join(ssh_config_data))
|
|
28
|
+
ssh_config_file.chmod(0o644)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class SetupGitInsteadOf(InteractiveShlex):
|
|
32
|
+
def impl(self, **_: typing.Any) -> list[list[str]]:
|
|
33
|
+
|
|
34
|
+
return [
|
|
35
|
+
["git", "config", "--global", "user.email", "ci@pivlab.space"],
|
|
36
|
+
["git", "config", "--global", "user.name", "CI"],
|
|
37
|
+
["git", "config", "--global", "init.defaultBranch", "master"],
|
|
38
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from dothat import Param
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def flavor() -> Param:
|
|
5
|
+
return Param(
|
|
6
|
+
name="flavor",
|
|
7
|
+
long="flavor",
|
|
8
|
+
default="release",
|
|
9
|
+
type=str,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def insecure() -> Param:
|
|
14
|
+
return Param(
|
|
15
|
+
name="insecure",
|
|
16
|
+
long="insecure",
|
|
17
|
+
default=False,
|
|
18
|
+
type=bool,
|
|
19
|
+
inverse="secure",
|
|
20
|
+
)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from collections.abc import Iterator
|
|
2
|
+
|
|
3
|
+
from _tasks import _actions, _params
|
|
4
|
+
from _tasks._consts import Tasks
|
|
5
|
+
from dothat.task_builder import Task, TaskBuilderImpl
|
|
6
|
+
from dothat.task_generator import TaskGeneratorImpl
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestBaseTask(TaskBuilderImpl):
|
|
10
|
+
_basename = Tasks.test_task
|
|
11
|
+
|
|
12
|
+
def apply(self):
|
|
13
|
+
self.model.doc = "test task"
|
|
14
|
+
self.with_actions((_actions.SetupSsh,))
|
|
15
|
+
return self
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TaskGenerator(TaskGeneratorImpl):
|
|
19
|
+
task_generate_docs = TestBaseTask
|
|
20
|
+
|
|
21
|
+
def load_tasks(self) -> Iterator[Task]:
|
|
22
|
+
yield from super().load_tasks()
|
|
23
|
+
|
|
24
|
+
targets = self._config.extra.get("targets", [])
|
|
25
|
+
|
|
26
|
+
for target in targets:
|
|
27
|
+
yield (
|
|
28
|
+
self.builder(TestBaseTask)
|
|
29
|
+
.apply()
|
|
30
|
+
.with_name(target)
|
|
31
|
+
.with_params(
|
|
32
|
+
(
|
|
33
|
+
self._params.ci(),
|
|
34
|
+
_params.flavor(),
|
|
35
|
+
_params.insecure(),
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
.build()
|
|
39
|
+
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from loguru import logger
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def setup_logger(debug: bool = False) -> None:
|
|
7
|
+
logger.remove()
|
|
8
|
+
|
|
9
|
+
level = "DEBUG" if debug else "INFO"
|
|
10
|
+
|
|
11
|
+
logger.add(
|
|
12
|
+
sys.stdout,
|
|
13
|
+
level=level,
|
|
14
|
+
colorize=True,
|
|
15
|
+
format=(
|
|
16
|
+
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
|
|
17
|
+
"<level>{level: <8}</level> | "
|
|
18
|
+
"<cyan>{name}</cyan>:"
|
|
19
|
+
"<cyan>{function}</cyan>:"
|
|
20
|
+
"<cyan>{line}</cyan> - "
|
|
21
|
+
"<level>{message}</level>"
|
|
22
|
+
),
|
|
23
|
+
backtrace=True,
|
|
24
|
+
diagnose=debug,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
setup_logger(debug=True)
|
|
29
|
+
|
|
30
|
+
__all__ = ["logger"]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import shlex
|
|
3
|
+
import subprocess
|
|
4
|
+
import typing
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from collections.abc import Iterable
|
|
7
|
+
|
|
8
|
+
import injector
|
|
9
|
+
|
|
10
|
+
from dothat.logging import logger as LOGGER
|
|
11
|
+
from dothat.project_config import ProjectConfig
|
|
12
|
+
|
|
13
|
+
ActionResult = typing.Any
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@injector.inject
|
|
17
|
+
@dataclasses.dataclass
|
|
18
|
+
class ActionBuilderImpl(ABC):
|
|
19
|
+
_di: injector.Injector
|
|
20
|
+
_config: ProjectConfig
|
|
21
|
+
|
|
22
|
+
@abstractmethod
|
|
23
|
+
def impl(self, **kwargs: typing.Any) -> ActionResult: ...
|
|
24
|
+
|
|
25
|
+
@abstractmethod
|
|
26
|
+
def execute(self, **kwargs: typing.Any): ...
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class InteractivePythonAction(ActionBuilderImpl):
|
|
30
|
+
@typing.override
|
|
31
|
+
def impl(self, **kwargs: typing.Any) -> None:
|
|
32
|
+
raise NotImplementedError
|
|
33
|
+
|
|
34
|
+
@typing.override
|
|
35
|
+
def execute(self, **kwargs: typing.Any) -> None:
|
|
36
|
+
LOGGER.debug(f"running InteractivePythonAction action: {self.__class__.__name__}")
|
|
37
|
+
self.impl(**kwargs)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class InteractiveShlex(ActionBuilderImpl):
|
|
41
|
+
@typing.override
|
|
42
|
+
def impl(self, **kwargs: typing.Any) -> Iterable[list[str]]:
|
|
43
|
+
raise NotImplementedError
|
|
44
|
+
|
|
45
|
+
@typing.override
|
|
46
|
+
def execute(self, **kwargs: typing.Any) -> None:
|
|
47
|
+
LOGGER.debug(f"running InteractiveShlex action: {self.__class__.__name__}")
|
|
48
|
+
|
|
49
|
+
commands = [shlex.join(cmd) for cmd in self.impl(**kwargs)]
|
|
50
|
+
|
|
51
|
+
script = " && ".join(commands)
|
|
52
|
+
|
|
53
|
+
LOGGER.info("running: {}", script)
|
|
54
|
+
subprocess.run(script, shell=True, check=True)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import typing
|
|
3
|
+
|
|
4
|
+
import injector
|
|
5
|
+
import pydantic
|
|
6
|
+
|
|
7
|
+
from dothat.project_config import ProjectConfig
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Param(pydantic.BaseModel):
|
|
11
|
+
name: str
|
|
12
|
+
default: typing.Any = None
|
|
13
|
+
long: str
|
|
14
|
+
|
|
15
|
+
short: typing.Optional[str] = ""
|
|
16
|
+
type: typing.Callable[[typing.Any], typing.Any] = lambda x: x
|
|
17
|
+
help: typing.Optional[str] = None
|
|
18
|
+
env_var: typing.Optional[str] = None
|
|
19
|
+
inverse: typing.Optional[str] = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@injector.inject
|
|
23
|
+
@dataclasses.dataclass
|
|
24
|
+
class Params:
|
|
25
|
+
config: ProjectConfig
|
|
26
|
+
|
|
27
|
+
def ci(self):
|
|
28
|
+
return Param(
|
|
29
|
+
name="ci",
|
|
30
|
+
long="ci",
|
|
31
|
+
type=bool,
|
|
32
|
+
default=False,
|
|
33
|
+
env_var="CI",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def from_config(self, key: str, **kwargs):
|
|
37
|
+
return Param(
|
|
38
|
+
name=f"extra__{key}",
|
|
39
|
+
long=key.replace("_", "-"),
|
|
40
|
+
default=(self.config.extra.model_extra or {}).get(key),
|
|
41
|
+
**kwargs,
|
|
42
|
+
)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
import tomllib
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
|
+
|
|
7
|
+
from dothat.logging import logger as LOGGER
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class System(BaseModel):
|
|
11
|
+
tasks_module: typing.Optional[str] = None
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Extra(BaseModel):
|
|
15
|
+
model_config = ConfigDict(extra="allow")
|
|
16
|
+
|
|
17
|
+
system: System = Field(default_factory=System)
|
|
18
|
+
|
|
19
|
+
def __getitem__(self, key: str) -> typing.Any:
|
|
20
|
+
|
|
21
|
+
if self.model_extra is None:
|
|
22
|
+
raise KeyError(key)
|
|
23
|
+
|
|
24
|
+
return self.model_extra[key]
|
|
25
|
+
|
|
26
|
+
def get(self, key: str, default: typing.Any = None) -> typing.Any:
|
|
27
|
+
return (self.model_extra or {}).get(key, default)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ProjectConfig(BaseModel):
|
|
31
|
+
@classmethod
|
|
32
|
+
def from_file(
|
|
33
|
+
cls,
|
|
34
|
+
path: pathlib.Path = pathlib.Path("environment.toml"),
|
|
35
|
+
) -> "ProjectConfig":
|
|
36
|
+
if not path.exists():
|
|
37
|
+
LOGGER.debug("ProjectConfig is not provided: file is not exists")
|
|
38
|
+
data = {}
|
|
39
|
+
else:
|
|
40
|
+
data = tomllib.loads(path.read_text())
|
|
41
|
+
|
|
42
|
+
_cfg = cls.model_validate(data)
|
|
43
|
+
|
|
44
|
+
return _cfg
|
|
45
|
+
|
|
46
|
+
extra: Extra = Field(default_factory=Extra)
|
|
File without changes
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import importlib.util
|
|
2
|
+
import pathlib
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import injector
|
|
6
|
+
|
|
7
|
+
from dothat.default_tasks import CiTaskGenerator
|
|
8
|
+
from dothat.logging import logger as LOGGER
|
|
9
|
+
from dothat.project_config import ProjectConfig
|
|
10
|
+
from dothat.task_builder import Task
|
|
11
|
+
from dothat.task_generator import TaskGenerator
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TaskRegistry:
|
|
15
|
+
@injector.inject
|
|
16
|
+
def __init__(self, config: ProjectConfig, di: injector.Injector) -> None:
|
|
17
|
+
self._di = di
|
|
18
|
+
self._config = config
|
|
19
|
+
|
|
20
|
+
self._tasks: dict[str, Task] | None = None
|
|
21
|
+
|
|
22
|
+
def _load_module(self, module: str):
|
|
23
|
+
|
|
24
|
+
module_path = pathlib.Path(module)
|
|
25
|
+
|
|
26
|
+
LOGGER.debug(f"Tasks loaded from module: {module_path}")
|
|
27
|
+
|
|
28
|
+
if module_path.is_file():
|
|
29
|
+
module_name = module_path.stem
|
|
30
|
+
|
|
31
|
+
spec = importlib.util.spec_from_file_location(module_name, module_path)
|
|
32
|
+
if spec is None or spec.loader is None:
|
|
33
|
+
raise ImportError(f"Could not load module from {module_path}")
|
|
34
|
+
|
|
35
|
+
module_obj = importlib.util.module_from_spec(spec)
|
|
36
|
+
sys.modules[module_name] = module_obj
|
|
37
|
+
spec.loader.exec_module(module_obj)
|
|
38
|
+
return module_obj
|
|
39
|
+
|
|
40
|
+
sys.path.insert(0, str(module_path.parent))
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
module_obj = __import__(module, fromlist=["TaskGenerator"])
|
|
44
|
+
finally:
|
|
45
|
+
sys.path.remove(str(module_path.parent))
|
|
46
|
+
|
|
47
|
+
return module_obj
|
|
48
|
+
|
|
49
|
+
def _load_tasks_from_generator(self, generator: TaskGenerator) -> dict[str, Task]:
|
|
50
|
+
registry: dict[str, Task] = {}
|
|
51
|
+
|
|
52
|
+
for task in generator.load_tasks():
|
|
53
|
+
if not task.basename:
|
|
54
|
+
raise ValueError("Task basename is not set.")
|
|
55
|
+
taskname = task.basename if not task.name else ":".join([task.basename, task.name])
|
|
56
|
+
registry[taskname] = task
|
|
57
|
+
|
|
58
|
+
return registry
|
|
59
|
+
|
|
60
|
+
def load_tasks_from_module(self, module: str | None) -> dict[str, Task]:
|
|
61
|
+
if not module:
|
|
62
|
+
LOGGER.warning("module with tasks not found")
|
|
63
|
+
return {}
|
|
64
|
+
|
|
65
|
+
module_obj = self._load_module(module)
|
|
66
|
+
|
|
67
|
+
generator: TaskGenerator = self._di.create_object(module_obj.TaskGenerator)
|
|
68
|
+
|
|
69
|
+
registry: dict[str, Task] = self._load_tasks_from_generator(generator)
|
|
70
|
+
|
|
71
|
+
return registry
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def tasks(self) -> dict[str, Task]:
|
|
75
|
+
if self._tasks is None:
|
|
76
|
+
self._tasks = {
|
|
77
|
+
**self.load_tasks_from_module(self._config.extra.system.tasks_module),
|
|
78
|
+
**self._load_tasks_from_generator(self._di.create_object(CiTaskGenerator)),
|
|
79
|
+
}
|
|
80
|
+
return self._tasks
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import os
|
|
3
|
+
import typing
|
|
4
|
+
from collections.abc import Iterable
|
|
5
|
+
from enum import Enum
|
|
6
|
+
|
|
7
|
+
import injector
|
|
8
|
+
import pydantic
|
|
9
|
+
|
|
10
|
+
from dothat.models.actions import ActionBuilderImpl
|
|
11
|
+
from dothat.models.params import Param, Params
|
|
12
|
+
from dothat.project_config import ProjectConfig
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Task(pydantic.BaseModel):
|
|
16
|
+
basename: typing.Optional[str] = None
|
|
17
|
+
|
|
18
|
+
name: typing.Optional[str] = None
|
|
19
|
+
|
|
20
|
+
doc: str = ""
|
|
21
|
+
|
|
22
|
+
actions: typing.Optional[list[type["ActionBuilderImpl"]]] = None
|
|
23
|
+
|
|
24
|
+
parsed_params: dict[str, typing.Any] = {}
|
|
25
|
+
|
|
26
|
+
params: list[Param] = pydantic.Field(default_factory=lambda: [])
|
|
27
|
+
|
|
28
|
+
def parse_task_params(self, args: list[str], di: injector.Injector):
|
|
29
|
+
_config = di.get(ProjectConfig)
|
|
30
|
+
|
|
31
|
+
if _config.extra.model_extra:
|
|
32
|
+
for key, val in _config.extra.model_extra.items():
|
|
33
|
+
self.parsed_params[f"extra__{key}"] = val
|
|
34
|
+
|
|
35
|
+
args_iter = iter(args)
|
|
36
|
+
|
|
37
|
+
for arg in args_iter:
|
|
38
|
+
if arg.startswith("--"):
|
|
39
|
+
key = arg.removeprefix("--")
|
|
40
|
+
param = next(
|
|
41
|
+
(p for p in self.params if key in [p.long, p.inverse]),
|
|
42
|
+
None,
|
|
43
|
+
)
|
|
44
|
+
elif arg.startswith("-"):
|
|
45
|
+
key = arg.removeprefix("-")
|
|
46
|
+
param = next(
|
|
47
|
+
(p for p in self.params if key in [p.short, p.inverse]),
|
|
48
|
+
None,
|
|
49
|
+
)
|
|
50
|
+
else:
|
|
51
|
+
continue
|
|
52
|
+
|
|
53
|
+
if not param:
|
|
54
|
+
raise ValueError(f"Unknown parameter: --{key}")
|
|
55
|
+
|
|
56
|
+
if param.type is bool:
|
|
57
|
+
self.parsed_params[param.name] = True if key == param.long or key == param.short else False
|
|
58
|
+
continue
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
value = next(args_iter)
|
|
62
|
+
except StopIteration as err:
|
|
63
|
+
raise StopIteration from err
|
|
64
|
+
|
|
65
|
+
self.parsed_params[param.name] = param.type(value)
|
|
66
|
+
|
|
67
|
+
def exec_task(self, inj: injector.Injector):
|
|
68
|
+
if not self.actions:
|
|
69
|
+
raise RuntimeError("not found actions to execute.")
|
|
70
|
+
for action_cls in self.actions:
|
|
71
|
+
action = inj.create_object(action_cls)
|
|
72
|
+
action.execute(**self.parsed_params)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class TaskBulder:
|
|
76
|
+
def build(self) -> Task:
|
|
77
|
+
raise NotImplementedError
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@injector.inject
|
|
81
|
+
@dataclasses.dataclass
|
|
82
|
+
class TaskBuilderImpl(TaskBulder):
|
|
83
|
+
_basename: typing.ClassVar[str | Enum | None] = None
|
|
84
|
+
|
|
85
|
+
_params: Params
|
|
86
|
+
_config: ProjectConfig
|
|
87
|
+
|
|
88
|
+
model: Task = dataclasses.field(init=False, default_factory=Task)
|
|
89
|
+
|
|
90
|
+
def __post_init__(self):
|
|
91
|
+
"extension point for childs"
|
|
92
|
+
|
|
93
|
+
def apply(self):
|
|
94
|
+
return self
|
|
95
|
+
|
|
96
|
+
def build(self) -> Task:
|
|
97
|
+
if not self._basename:
|
|
98
|
+
raise ValueError("task name not set.")
|
|
99
|
+
|
|
100
|
+
if not self.model.doc:
|
|
101
|
+
self.model.doc = ".".join(
|
|
102
|
+
[
|
|
103
|
+
self.__class__.__module__,
|
|
104
|
+
self.__class__.__name__,
|
|
105
|
+
]
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
if isinstance(self._basename, str):
|
|
109
|
+
self.model.basename = self._basename
|
|
110
|
+
else:
|
|
111
|
+
self.model.basename = self._basename.value
|
|
112
|
+
|
|
113
|
+
return self.model.model_copy(deep=True)
|
|
114
|
+
|
|
115
|
+
def with_actions(self, actions: Iterable[type[ActionBuilderImpl]]):
|
|
116
|
+
self.model.actions = list(actions)
|
|
117
|
+
return self
|
|
118
|
+
|
|
119
|
+
def with_params(self: typing.Self, params: Iterable[Param]) -> typing.Self:
|
|
120
|
+
self.model.params = list(params)
|
|
121
|
+
|
|
122
|
+
params_dict = {}
|
|
123
|
+
for param in params:
|
|
124
|
+
params_dict[param.name] = os.getenv(param.env_var, param.default) if param.env_var else param.default
|
|
125
|
+
self.model.parsed_params = params_dict
|
|
126
|
+
|
|
127
|
+
return self
|
|
128
|
+
|
|
129
|
+
def replace_param(self, param_name: str, param: str, default: str):
|
|
130
|
+
self.model.parsed_params[param_name] = param or default
|
|
131
|
+
|
|
132
|
+
def with_name(self, name: str):
|
|
133
|
+
self.model.name = name
|
|
134
|
+
return self
|
|
135
|
+
|
|
136
|
+
def with_doc(self, doc: str):
|
|
137
|
+
self.model.doc = doc
|
|
138
|
+
return self
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
from collections.abc import Iterator
|
|
3
|
+
|
|
4
|
+
import injector
|
|
5
|
+
|
|
6
|
+
from dothat.models.params import Params
|
|
7
|
+
from dothat.project_config import ProjectConfig
|
|
8
|
+
from dothat.task_builder import Task, TaskBuilderImpl
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TaskGenerator:
|
|
12
|
+
def load_tasks(self) -> Iterator[Task]:
|
|
13
|
+
raise NotImplementedError
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@injector.inject
|
|
17
|
+
@dataclasses.dataclass
|
|
18
|
+
class TaskGeneratorImpl(TaskGenerator):
|
|
19
|
+
_config: ProjectConfig
|
|
20
|
+
_di: injector.Injector
|
|
21
|
+
_params: Params
|
|
22
|
+
|
|
23
|
+
def _auto_load_tasks(self) -> Iterator[Task]:
|
|
24
|
+
for name, cls in vars(type(self)).items():
|
|
25
|
+
if name.startswith("task_") and isinstance(cls, type) and issubclass(cls, TaskBuilderImpl):
|
|
26
|
+
yield self._di.create_object(cls).apply().build()
|
|
27
|
+
|
|
28
|
+
def builder(self, task_class: type[TaskBuilderImpl]) -> TaskBuilderImpl:
|
|
29
|
+
return self._di.create_object(task_class)
|
|
30
|
+
|
|
31
|
+
def load_tasks(self) -> Iterator[Task]:
|
|
32
|
+
yield from self._auto_load_tasks()
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from dothat.initialization import TemplateGenerator
|
|
2
|
+
from dothat.models.actions import InteractivePythonAction
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class InitializeDefaultProject(InteractivePythonAction):
|
|
6
|
+
def impl(self, *, force: bool, **_) -> None:
|
|
7
|
+
templategenerator = TemplateGenerator()
|
|
8
|
+
templategenerator.generate_project_structure(force=force)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from collections.abc import Iterator
|
|
2
|
+
|
|
3
|
+
from dothat.default_tasks import _actions, _params
|
|
4
|
+
from dothat.task_builder import Task, TaskBuilderImpl
|
|
5
|
+
from dothat.task_generator import TaskGeneratorImpl
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class InitializeDefaultProject(TaskBuilderImpl):
|
|
9
|
+
_basename = "init"
|
|
10
|
+
|
|
11
|
+
def apply(self):
|
|
12
|
+
return self.with_actions((_actions.InitializeDefaultProject,)).with_params((_params.force(),))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CiTaskGenerator(TaskGeneratorImpl):
|
|
16
|
+
task_init = InitializeDefaultProject
|
|
17
|
+
|
|
18
|
+
def load_tasks(self) -> Iterator[Task]:
|
|
19
|
+
yield from super().load_tasks()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "dothat"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "framework for python tasks and actions management"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "Arsenii Nikulin", email = "a.nikulin@pivlab.dev" },
|
|
9
|
+
{ name = "PivLab Dev" },
|
|
10
|
+
]
|
|
11
|
+
requires-python = ">=3.11,<4.0"
|
|
12
|
+
|
|
13
|
+
dependencies = [
|
|
14
|
+
"click>=8.4.1,<9.0.0",
|
|
15
|
+
"gitpython>=3.1.57,<4.0.0",
|
|
16
|
+
"injector>=0.24.0",
|
|
17
|
+
"loguru>=0.7.3,<1.0.0",
|
|
18
|
+
"pydantic>=2.13.5",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.scripts]
|
|
22
|
+
dothat = "dothat.cli:cli"
|
|
23
|
+
|
|
24
|
+
[tool.ruff]
|
|
25
|
+
target-version = "py311"
|
|
26
|
+
line-length = 120
|
|
27
|
+
exclude = [
|
|
28
|
+
".git",
|
|
29
|
+
".mypy_cache",
|
|
30
|
+
".pyenv",
|
|
31
|
+
".pytest_cache",
|
|
32
|
+
".pytype",
|
|
33
|
+
".ruff_cache",
|
|
34
|
+
".venv",
|
|
35
|
+
".vscode",
|
|
36
|
+
"__pypackages__",
|
|
37
|
+
"_build",
|
|
38
|
+
"buck-out",
|
|
39
|
+
"build",
|
|
40
|
+
"dist",
|
|
41
|
+
"node_modules",
|
|
42
|
+
"site-packages",
|
|
43
|
+
"*venv*",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint]
|
|
47
|
+
select = ["E", "F", "W", "I", "B"]
|
|
48
|
+
|
|
49
|
+
[tool.ruff.format]
|
|
50
|
+
quote-style = "double"
|
|
51
|
+
indent-style = "space"
|
|
52
|
+
|
|
53
|
+
[build-system]
|
|
54
|
+
requires = ["hatchling"]
|
|
55
|
+
build-backend = "hatchling.build"
|
dothat-1.0.0/uv.lock
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 3
|
|
3
|
+
requires-python = ">=3.11, <4.0"
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "annotated-types"
|
|
7
|
+
version = "0.8.0"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" }
|
|
10
|
+
wheels = [
|
|
11
|
+
{ url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" },
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[package]]
|
|
15
|
+
name = "click"
|
|
16
|
+
version = "8.5.0"
|
|
17
|
+
source = { registry = "https://pypi.org/simple" }
|
|
18
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c7/0e/7fa0ef50764b67090eca4114772a2abf8b6148198475e54c660b97caeee6/click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34", size = 382235, upload-time = "2026-08-26T13:33:14.56Z" }
|
|
19
|
+
wheels = [
|
|
20
|
+
{ url = "https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", size = 125251, upload-time = "2026-08-26T13:33:12.928Z" },
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[[package]]
|
|
24
|
+
name = "colorama"
|
|
25
|
+
version = "0.4.6"
|
|
26
|
+
source = { registry = "https://pypi.org/simple" }
|
|
27
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
28
|
+
wheels = [
|
|
29
|
+
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[[package]]
|
|
33
|
+
name = "dothat"
|
|
34
|
+
version = "1.0.0"
|
|
35
|
+
source = { editable = "." }
|
|
36
|
+
dependencies = [
|
|
37
|
+
{ name = "click" },
|
|
38
|
+
{ name = "gitpython" },
|
|
39
|
+
{ name = "injector" },
|
|
40
|
+
{ name = "loguru" },
|
|
41
|
+
{ name = "pydantic" },
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[package.metadata]
|
|
45
|
+
requires-dist = [
|
|
46
|
+
{ name = "click", specifier = ">=8.4.1,<9.0.0" },
|
|
47
|
+
{ name = "gitpython", specifier = ">=3.1.57,<4.0.0" },
|
|
48
|
+
{ name = "injector", specifier = ">=0.24.0" },
|
|
49
|
+
{ name = "loguru", specifier = ">=0.7.3,<1.0.0" },
|
|
50
|
+
{ name = "pydantic", specifier = ">=2.13.5" },
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[[package]]
|
|
54
|
+
name = "gitdb"
|
|
55
|
+
version = "4.0.12"
|
|
56
|
+
source = { registry = "https://pypi.org/simple" }
|
|
57
|
+
dependencies = [
|
|
58
|
+
{ name = "smmap" },
|
|
59
|
+
]
|
|
60
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" }
|
|
61
|
+
wheels = [
|
|
62
|
+
{ url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" },
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[[package]]
|
|
66
|
+
name = "gitpython"
|
|
67
|
+
version = "3.1.62"
|
|
68
|
+
source = { registry = "https://pypi.org/simple" }
|
|
69
|
+
dependencies = [
|
|
70
|
+
{ name = "gitdb" },
|
|
71
|
+
]
|
|
72
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e0/db/3ca813cbacb23ab6fe46ff38a9b5ef8e73e970c8051f2ce903aacafe0446/gitpython-3.1.62.tar.gz", hash = "sha256:1791de66309bc0c7cfca40bf8d2e3de7ca091cbf94e6051be1ad0722c61062af", size = 231728, upload-time = "2026-09-07T02:57:21.155Z" }
|
|
73
|
+
wheels = [
|
|
74
|
+
{ url = "https://files.pythonhosted.org/packages/d6/0b/29d7965215f8ef830a7ca1f42997fe13e5693d85e9edb18f938d063ef5f2/gitpython-3.1.62-py3-none-any.whl", hash = "sha256:7002251225e10e29d2e1f49e6532613fe5d5d9f0b6f1f02997a52b38fe56899e", size = 222753, upload-time = "2026-09-07T02:57:19.762Z" },
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
[[package]]
|
|
78
|
+
name = "injector"
|
|
79
|
+
version = "0.24.0"
|
|
80
|
+
source = { registry = "https://pypi.org/simple" }
|
|
81
|
+
sdist = { url = "https://files.pythonhosted.org/packages/17/6c/de0f64b2b8d7d8cd3206bd6fb54ebb0c7c2e2fe0f2d16103756ff1bf803b/injector-0.24.0.tar.gz", hash = "sha256:e85a75d1516cff2f03170f3fd1219f56acb25c9a05e307819ae0dcde3dad3d3f", size = 55988, upload-time = "2026-01-09T12:10:41.782Z" }
|
|
82
|
+
wheels = [
|
|
83
|
+
{ url = "https://files.pythonhosted.org/packages/5f/db/953aeee405f1466832f212f61496ee07c29f7f027f7591b71b06bd08a418/injector-0.24.0-py3-none-any.whl", hash = "sha256:47294c7a7fdb811f0d1b442a1e0152bb2fc28b2ccaaba4cba44e5e125e0da2d0", size = 21504, upload-time = "2026-01-09T12:10:40.329Z" },
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[[package]]
|
|
87
|
+
name = "loguru"
|
|
88
|
+
version = "0.7.3"
|
|
89
|
+
source = { registry = "https://pypi.org/simple" }
|
|
90
|
+
dependencies = [
|
|
91
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
92
|
+
{ name = "win32-setctime", marker = "sys_platform == 'win32'" },
|
|
93
|
+
]
|
|
94
|
+
sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" }
|
|
95
|
+
wheels = [
|
|
96
|
+
{ url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" },
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
[[package]]
|
|
100
|
+
name = "pydantic"
|
|
101
|
+
version = "2.13.5"
|
|
102
|
+
source = { registry = "https://pypi.org/simple" }
|
|
103
|
+
dependencies = [
|
|
104
|
+
{ name = "annotated-types" },
|
|
105
|
+
{ name = "pydantic-core" },
|
|
106
|
+
{ name = "typing-extensions" },
|
|
107
|
+
{ name = "typing-inspection" },
|
|
108
|
+
]
|
|
109
|
+
sdist = { url = "https://files.pythonhosted.org/packages/53/ef/fc4f868f4e2cee79f863883abffceff107875f569b848507319842d2a681/pydantic-2.13.5.tar.gz", hash = "sha256:51a9c5f7b2f8e636f04c6cada605d9b6a3bf1348fdf945a3d8869b19bba0ee08", size = 845750, upload-time = "2026-08-28T14:04:00.916Z" }
|
|
110
|
+
wheels = [
|
|
111
|
+
{ url = "https://files.pythonhosted.org/packages/eb/47/c95ffc2009878c7aac0c5e08528022dcb885933252a88b5f170058014464/pydantic-2.13.5-py3-none-any.whl", hash = "sha256:346a034f080da3755d8e9cb5e00e8b07de1d39e4f6e2c87d8ab7cafa0b269a73", size = 472589, upload-time = "2026-08-28T14:03:59.136Z" },
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
[[package]]
|
|
115
|
+
name = "pydantic-core"
|
|
116
|
+
version = "2.46.5"
|
|
117
|
+
source = { registry = "https://pypi.org/simple" }
|
|
118
|
+
dependencies = [
|
|
119
|
+
{ name = "typing-extensions" },
|
|
120
|
+
]
|
|
121
|
+
sdist = { url = "https://files.pythonhosted.org/packages/af/f9/8a06bea35ef8daf588f707784c973a7046e0034c8d8cfb08828eeffb8b75/pydantic_core-2.46.5.tar.gz", hash = "sha256:10416c15b8839ecc4ef4d0885da76da6fd0f67333a0eb8aff6d93c4b8f2910fc", size = 472262, upload-time = "2026-08-28T10:01:31.677Z" }
|
|
122
|
+
wheels = [
|
|
123
|
+
{ url = "https://files.pythonhosted.org/packages/a2/b6/81d2d19ea0be2c03664381b59f65fa72fc7969decedae00bc2c4ad835708/pydantic_core-2.46.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a1dee1b804ff4d11c663636cf15d2ea47e9f79cd56c033fb1cbf08924842a48f", size = 2074737, upload-time = "2026-08-28T09:57:57.711Z" },
|
|
124
|
+
{ url = "https://files.pythonhosted.org/packages/0c/18/b70da8300e292df4099684ea11b1958043580d2f50d2dc8bf7e542bdd84a/pydantic_core-2.46.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d625a186a65201c23a9e3b8ed9c47e90a026e03256608cc91851c6709096844f", size = 1921751, upload-time = "2026-08-28T09:57:59.265Z" },
|
|
125
|
+
{ url = "https://files.pythonhosted.org/packages/e7/1a/0d590341b6ffa4b4aca83508e6b8db4761aaeacfc15a25ca3815876d4797/pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f8507560a9284e1370bb048ed4282012fbef4e8d109875b95e884d228552061", size = 1948231, upload-time = "2026-08-28T09:58:00.678Z" },
|
|
126
|
+
{ url = "https://files.pythonhosted.org/packages/7d/1d/02eb35761c51f2f7b1b042d6ab4cda6600f0c8c88a2243b3f734376201e5/pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f93c5fe914d75fbec9a49209b00da5f08e9e467d69da2b1510c81940cfd10be", size = 2020708, upload-time = "2026-08-28T09:58:02.267Z" },
|
|
127
|
+
{ url = "https://files.pythonhosted.org/packages/4a/ea/f86073830e35d508cc8ddf9c3d9e6e6840fcb88d34bf726b0b4710186f27/pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c767f552b21b10f774aeac128e828eafb796adfa1b666a18bf6321453c3a", size = 2194914, upload-time = "2026-08-28T09:58:03.934Z" },
|
|
128
|
+
{ url = "https://files.pythonhosted.org/packages/bb/d7/fc36240d7791ce90939e51608568c33bfdae26202016f9770c229a487d86/pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:701b2e04b560eeb4bddf7a25ab8ca476176e34fdbd9a0e18196f0d12d4685f0b", size = 2235622, upload-time = "2026-08-28T09:58:05.516Z" },
|
|
129
|
+
{ url = "https://files.pythonhosted.org/packages/cf/bc/3fa2d76b83162820a17da7f645b28d1cba99fc8e1e5fc6517067ec450fa1/pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49776eab08766a08dfff7012f8b422dcd7e25e43b316eedf0477c24fcfa84b7c", size = 2062091, upload-time = "2026-08-28T09:58:07.135Z" },
|
|
130
|
+
{ url = "https://files.pythonhosted.org/packages/ab/9a/095d557bb492c90cd8a70a6dd048bf793d433d03d86c81c11e912e4cd049/pydantic_core-2.46.5-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:a2468d93d181667a7abd66e1b64bb9f76f361b0fef8faddf687456453576f5ee", size = 2089904, upload-time = "2026-08-28T09:58:08.814Z" },
|
|
131
|
+
{ url = "https://files.pythonhosted.org/packages/24/98/7b76b1ad10a19a617a52aaa1d80e159115af939b095e86f8e756fd52e0df/pydantic_core-2.46.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53feb344243bb9510a9dec7bf3cf1b64d88a98af5dc7872a5160465f8b198c8e", size = 2132244, upload-time = "2026-08-28T09:58:10.435Z" },
|
|
132
|
+
{ url = "https://files.pythonhosted.org/packages/20/32/7d6ca365fadba186a0c8f85de1a701663bce81efd309d9479be58687622f/pydantic_core-2.46.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cd5214352ae68f3b5e9af7768bdc5253695ee069675db3480518420b3be881f2", size = 2143901, upload-time = "2026-08-28T09:58:12.033Z" },
|
|
133
|
+
{ url = "https://files.pythonhosted.org/packages/f8/09/eb9a6aa57f22fd1541a9c0aa2a1f3aeef3ec65347d33e10a6da2f43e0ee9/pydantic_core-2.46.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:9432f3598db432cb51c5b37fdbf29a60fcccc79e30d37a05022776a6bc4ab689", size = 2299425, upload-time = "2026-08-28T09:58:13.614Z" },
|
|
134
|
+
{ url = "https://files.pythonhosted.org/packages/8a/f9/548a5bb9d4ba8cd26e26daf48052236f6b38bb61e7b7241fbc3c995719eb/pydantic_core-2.46.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8feeac04b5794e513e710af2f9c87d49f31a6dc47967bb264a1fed61a8989bec", size = 2318566, upload-time = "2026-08-28T09:58:15.199Z" },
|
|
135
|
+
{ url = "https://files.pythonhosted.org/packages/4a/20/06454d18834c02c406c9133f1a3b485305fd9ee984f9636c2f730bef6a9d/pydantic_core-2.46.5-cp311-cp311-win32.whl", hash = "sha256:892a881d5f68c2b9ea304b7a6c2c60d9343df578a311b0f86b94bc8f1ffe8129", size = 1954258, upload-time = "2026-08-28T09:58:16.813Z" },
|
|
136
|
+
{ url = "https://files.pythonhosted.org/packages/9e/c2/718b9deb4b72453b5d8c7447a3b14cb77bef36917ef5f514e0948a4096a0/pydantic_core-2.46.5-cp311-cp311-win_amd64.whl", hash = "sha256:40375c2d05acec10323e45dfe2077ac44bc74659008614af5069034e2cfc781c", size = 2041030, upload-time = "2026-08-28T09:58:18.288Z" },
|
|
137
|
+
{ url = "https://files.pythonhosted.org/packages/67/ea/c1d1a5b72d6e1ff7f377a4d9199f6591f095beb5b409a8a5d89f7238d939/pydantic_core-2.46.5-cp311-cp311-win_arm64.whl", hash = "sha256:28a6a556cd3b6066bea827857f9d9cce027c96f776e512f544a581f9e42161f8", size = 2009234, upload-time = "2026-08-28T09:58:19.929Z" },
|
|
138
|
+
{ url = "https://files.pythonhosted.org/packages/82/3f/76358795aa7a8c6d4f36e2cb828ad1c90ee118e1393a9281664f5aade9d4/pydantic_core-2.46.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b9fe6fb92520e3fd61f2e49000b6911b188824f089b75973ea06d6267f0b476d", size = 2076516, upload-time = "2026-08-28T09:58:21.576Z" },
|
|
139
|
+
{ url = "https://files.pythonhosted.org/packages/db/50/26b091836076ce4cb2fac264186936acc069e0595772cfd02a563bc4761a/pydantic_core-2.46.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a39ac25a9a2fa4072efdb429833c4a4c8009a51ff9eea3eeae131713cd27991e", size = 1922874, upload-time = "2026-08-28T09:58:23.766Z" },
|
|
140
|
+
{ url = "https://files.pythonhosted.org/packages/09/f0/2a8ce3849e299d44e2d2c196b6082643a3235565a735cb51db7a6261f614/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fdc8b93a41521988916eeaa271173fcca7fa0803d62f87675aac8dcec1c8e29", size = 1951772, upload-time = "2026-08-28T09:58:25.435Z" },
|
|
141
|
+
{ url = "https://files.pythonhosted.org/packages/87/46/ac0dc8bdd9e6048183a14eb127764e7ad9240021c17513074a4711b0e31e/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b98134087d9de723658d17a42c7d0da8d6e2ef08015dee7dc93889047315f5e4", size = 2031832, upload-time = "2026-08-28T09:58:27.102Z" },
|
|
142
|
+
{ url = "https://files.pythonhosted.org/packages/c4/c2/339de5bef7be36301a2231eaa52e62163742c2281f11b5f4892bc79785cd/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e652ab17569c94bff5475520f907b7148b8c24036a8ebbe5cf7cf7493d28579a", size = 2208645, upload-time = "2026-08-28T09:58:28.948Z" },
|
|
143
|
+
{ url = "https://files.pythonhosted.org/packages/7b/a0/9ff22b797724262da14427abaed4dd1d864a139693fc5e7809114376a716/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d925f3d9afd05a8c0fb3a1031463a8d59ebe5e2afad297e29c78be19e13b4e62", size = 2265935, upload-time = "2026-08-28T09:58:30.625Z" },
|
|
144
|
+
{ url = "https://files.pythonhosted.org/packages/c0/a4/eb9409ec0736e50aa70a412f16c204ed149516846912f7e6724d4c73ee53/pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc5be0abd4a407e200d844b404e33639a554e7bd0d448e7b9ae181be4789ac2", size = 2066284, upload-time = "2026-08-28T09:58:32.289Z" },
|
|
145
|
+
{ url = "https://files.pythonhosted.org/packages/c0/02/7f6156ffc926857f1c37c07d9a388682865a81830ab6a1b637082c25e399/pydantic_core-2.46.5-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:816ff0a6550ffc06c098ccd2e0698600f9aa7da192a79eaa6f9af504a35db869", size = 2105889, upload-time = "2026-08-28T09:58:33.986Z" },
|
|
146
|
+
{ url = "https://files.pythonhosted.org/packages/92/b1/e781d357ebe09fc929f995700f1b3503e8897f1cece183ecb1300d4d67e9/pydantic_core-2.46.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c7ea57fc63aa7da93a1bd2d644e6577befae10c52c4e36377635eea1056a74f5", size = 2158006, upload-time = "2026-08-28T09:58:35.647Z" },
|
|
147
|
+
{ url = "https://files.pythonhosted.org/packages/70/0a/644597d84ab400e50609c192120b85c9681c22d3a20461b9060a79be0a7a/pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:efd62a42486f1bda5d24cb4f63d15a3c7768375fe83d36f9417b4ad7a2fb20b3", size = 2158408, upload-time = "2026-08-28T09:58:37.38Z" },
|
|
148
|
+
{ url = "https://files.pythonhosted.org/packages/1e/ee/ca3b7b3a4b3769ffe9ce9432a7c9be755de9593a46d3b0d54d0409323e44/pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:2bc9419666990c06d7397831f2126a1ecc3594aaa3ff7de5bf2d066802f4e07b", size = 2309609, upload-time = "2026-08-28T09:58:39.22Z" },
|
|
149
|
+
{ url = "https://files.pythonhosted.org/packages/ce/52/39fa1f451486019524ca685020390e7ca351832fd874530ba30c8628e6dc/pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:18a09e1e1011b462f2e32774f25859ef1223d5c2b0546a633cf56654710721e0", size = 2342618, upload-time = "2026-08-28T09:58:40.89Z" },
|
|
150
|
+
{ url = "https://files.pythonhosted.org/packages/81/5e/468fc630568c61dcef3cd47ad32ffbeed9af643f49208d1ea86ab4f890c4/pydantic_core-2.46.5-cp312-cp312-win32.whl", hash = "sha256:5cb482e9e84c851f4e623fe4acc1ced89168cf1fe18f7089db4548c8f5bbb65b", size = 1939475, upload-time = "2026-08-28T09:58:42.591Z" },
|
|
151
|
+
{ url = "https://files.pythonhosted.org/packages/cf/c9/4c19f41b84cf6b622a72fbeed7665b25d47a187d68d47d0d430c07f23268/pydantic_core-2.46.5-cp312-cp312-win_amd64.whl", hash = "sha256:5e81740c09e310f5aa5cbd3e434a01c154d4bef93241c7877b39f211d2b78ba8", size = 2043140, upload-time = "2026-08-28T09:58:44.272Z" },
|
|
152
|
+
{ url = "https://files.pythonhosted.org/packages/af/dd/0c1a050299147c746e5256db16d645ab5efd4f78c59937d581a0524e74a2/pydantic_core-2.46.5-cp312-cp312-win_arm64.whl", hash = "sha256:f7b0ec93a2893de856652154d73b7ba622f26fa97726487dcac373de5f4c6084", size = 1997729, upload-time = "2026-08-28T09:58:46.13Z" },
|
|
153
|
+
{ url = "https://files.pythonhosted.org/packages/f5/37/5abe39a8372a61d3dc3c1338fc504281c01b32fdb3169cd7187153b56d3e/pydantic_core-2.46.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:b7ca9034437b6022f941f4857459562ee00a560b97e7cce8a0ec5a74fc6766e0", size = 2075885, upload-time = "2026-08-28T09:58:47.856Z" },
|
|
154
|
+
{ url = "https://files.pythonhosted.org/packages/21/43/6323b1f8b217780454c61304bcd2b38ae4762f50754414124603ccc90bb2/pydantic_core-2.46.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f332f0e72a5a0400141f830744e141bf9f97917878dbe968669e8a7fefea78ff", size = 1922768, upload-time = "2026-08-28T09:58:49.58Z" },
|
|
155
|
+
{ url = "https://files.pythonhosted.org/packages/0f/a3/c05ca796e1197618a774b01e596aeedfefc2f7d8c01ae3054e910b120e8a/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:193375f3548919d3f0b60936ca113ada3e38f264f91b9b8e0508efaad57be931", size = 1951241, upload-time = "2026-08-28T09:58:51.511Z" },
|
|
156
|
+
{ url = "https://files.pythonhosted.org/packages/68/32/33bc39ac705c52cffc908e8389f9754fdb208aea5c69cceddf4eb3ce99af/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79bdfa52f843137045b2d081cc05c120ba6665d29b7559c2c47690906f39279f", size = 2031975, upload-time = "2026-08-28T09:58:53.166Z" },
|
|
157
|
+
{ url = "https://files.pythonhosted.org/packages/b0/70/2333e885c0f6a67bc105c5916965dac9b57f2718ee20d81d1a06a4ebdc13/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24922243639cbdac66c75fcb6fd6495a9cb52b213d62f9a0d16f0310b1ff8038", size = 2208542, upload-time = "2026-08-28T09:58:55.017Z" },
|
|
158
|
+
{ url = "https://files.pythonhosted.org/packages/f7/ea/296debfb4264207bbda5936133892e027c0a58875ad53ebd512fba8ec3a2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c76fe65e607be28c7fd4d56fc3c42b1583aa058ce3408b7ad0fd540171d31f9f", size = 2264692, upload-time = "2026-08-28T09:58:56.767Z" },
|
|
159
|
+
{ url = "https://files.pythonhosted.org/packages/d3/f2/9e4de77a6271e07a76d2d58b11c091a979c191ed2939bf80067568b369d2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f7b393a8b3da82f5c1fc0751e6d01ac6c55b93c18226a60bdfba4a724efafd1", size = 2066633, upload-time = "2026-08-28T09:58:58.531Z" },
|
|
160
|
+
{ url = "https://files.pythonhosted.org/packages/8d/db/f9e9d0c97445987b2084823d5c240de88087338f04fc2cfaa2df186b8049/pydantic_core-2.46.5-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:7ac031912d54f3d83ef3b3eb98dfabc1608802e2202263d25957eeed40b94761", size = 2105235, upload-time = "2026-08-28T09:59:00.421Z" },
|
|
161
|
+
{ url = "https://files.pythonhosted.org/packages/07/c5/79169b047b3b2c3e99e04bc76372af9637e0bf6db638274fa927df96369e/pydantic_core-2.46.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:837b396ca3d7b74091ca623f6cbd8351bd42d670a79c2683e79fb089f06a2de5", size = 2157367, upload-time = "2026-08-28T09:59:02.442Z" },
|
|
162
|
+
{ url = "https://files.pythonhosted.org/packages/26/b5/ba6057afb7c291bd449f51b867f95aef2072941c4ce4e5c31d6ffd132d3b/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:5ee239d575f80b08eca11f6e20f90c4c695de7825c67eefe6091fbf20dda648e", size = 2158420, upload-time = "2026-08-28T09:59:04.2Z" },
|
|
163
|
+
{ url = "https://files.pythonhosted.org/packages/6e/28/2057abecaafdc22912afa819603a51f0a62d40643b7c4871c51721fea9be/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:e80675d75ae2cd14372cb65cad5400d9347a3d3f6c13000183f22dfd027283ed", size = 2309588, upload-time = "2026-08-28T09:59:06.048Z" },
|
|
164
|
+
{ url = "https://files.pythonhosted.org/packages/71/9d/881156dc404e27479c4246128d73538464cab4a239bec61995e227644c30/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c4b71f10dd532fb7a5cbc8f58707779e64f03a258c2bf8bfbaecfcd9970b519", size = 2341866, upload-time = "2026-08-28T09:59:08.539Z" },
|
|
165
|
+
{ url = "https://files.pythonhosted.org/packages/5a/38/d66f443a259f84d13babdceae568e572b0ed26da17ca5d0a649ebb110a67/pydantic_core-2.46.5-cp313-cp313-win32.whl", hash = "sha256:97bf8de4d541598c94a59344eeb988a94c08ff76b5723c41f6567ec18c7892ea", size = 1938580, upload-time = "2026-08-28T09:59:10.402Z" },
|
|
166
|
+
{ url = "https://files.pythonhosted.org/packages/2c/1e/1d5371213f4cc9a7ed70c0bfcc7911de22311ee99a662a56077d7292d2ac/pydantic_core-2.46.5-cp313-cp313-win_amd64.whl", hash = "sha256:15f4a94963c95accac15b7b657bb177d3ad82bb90b0d0526d9a9b85079925db5", size = 2041980, upload-time = "2026-08-28T09:59:12.396Z" },
|
|
167
|
+
{ url = "https://files.pythonhosted.org/packages/5a/48/4222d90b1c67568bace4dec6dca6271449c66de3595d72b6d098f5fde597/pydantic_core-2.46.5-cp313-cp313-win_arm64.whl", hash = "sha256:d22a945598fb91236b4dd793a6e42e4f3dd7740bb5aace5ebd7d4c08d13bb575", size = 1997213, upload-time = "2026-08-28T09:59:14.245Z" },
|
|
168
|
+
{ url = "https://files.pythonhosted.org/packages/8e/8a/14596f2a8367da50cf7cbac48169ee5d9c8e11d486a3b527082384630c72/pydantic_core-2.46.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c1c43ad4339643d70ebb8124e1305a7dab423001eff58bb41a0f731adbc98355", size = 2074081, upload-time = "2026-08-28T09:59:16.141Z" },
|
|
169
|
+
{ url = "https://files.pythonhosted.org/packages/ae/d5/d8a4eb6d6c7f66b91dd37c576d76e9e60fba900caf5372c17bcf949febc2/pydantic_core-2.46.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1a353f84de772f423b5ffb11d7ae352fbbef0f446f3c0b0af0f8236d7233606e", size = 1920497, upload-time = "2026-08-28T09:59:18.065Z" },
|
|
170
|
+
{ url = "https://files.pythonhosted.org/packages/8e/26/092079428f86e927e030b2c0ced87df69dbb1c875cdeaa67bf42ea2be746/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5086029a57366b8cf81b130a43908738095c270c21a8d7f0e8bdfdb89718e2f3", size = 1952130, upload-time = "2026-08-28T09:59:20.476Z" },
|
|
171
|
+
{ url = "https://files.pythonhosted.org/packages/08/c3/8ec0e290a9ebaebd64047bf5fda94be835c6b1551b02437e4b76778fbcd7/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46c25dda9d092a06c08db76ffe0a197107904d0dfac653f7d5306bbcd6d6119c", size = 2026371, upload-time = "2026-08-28T09:59:22.227Z" },
|
|
172
|
+
{ url = "https://files.pythonhosted.org/packages/01/72/4fd20ad520fb8da0157f95b27a7eb05a72790ef08138e7701ac972c342ea/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37ea7b83c935e5b0d68c9449b82651accf78a10828b2c02b2f2d9e9496446c21", size = 2202822, upload-time = "2026-08-28T09:59:24.277Z" },
|
|
173
|
+
{ url = "https://files.pythonhosted.org/packages/31/b0/d16e0771206b29314f0d52198b720be21e8a99ab2bf11e3bc0d7c9cebdff/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e64e88d5585bea9ce95861079de72006c7fa6d3df4e3a3b65ba31eb979c15c9f", size = 2262756, upload-time = "2026-08-28T09:59:26.608Z" },
|
|
174
|
+
{ url = "https://files.pythonhosted.org/packages/2c/9b/59634b7ac631c63b2a37760eb6943af3e29573d6b59a4abc5e7f019d4cee/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d510bac3ee52247af28ed4bb18a1e799f040ac60fd2bf5ccd4c92f1fbe786f", size = 2068352, upload-time = "2026-08-28T09:59:29.044Z" },
|
|
175
|
+
{ url = "https://files.pythonhosted.org/packages/08/7c/570abb1ad2155348dc754ea91be22e5aaa18eb6d69a6068f7c6f2679a6ed/pydantic_core-2.46.5-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:a2a5e1d0ff29adddc9f6d6821a66302e4493f8ca898b715b6b1182c2c201ea0a", size = 2104777, upload-time = "2026-08-28T09:59:30.95Z" },
|
|
176
|
+
{ url = "https://files.pythonhosted.org/packages/8e/25/5bf74adc65a1ac5b7be3f6cb0bcb5433615c1598a801c19d830d84c98ded/pydantic_core-2.46.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:03b9666e41e35d8909852ba191a0607520f81b74eaf12ccf8737005dbb313821", size = 2156312, upload-time = "2026-08-28T09:59:32.604Z" },
|
|
177
|
+
{ url = "https://files.pythonhosted.org/packages/90/6a/2ef38830675e050121040618135564ed56b860b45433b02d9b4ebece46f3/pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:a91c17edf6eea2402cb5457b4c89e99bc5ed1004aa34c4adf1d4258c1a5c22c2", size = 2150067, upload-time = "2026-08-28T09:59:34.453Z" },
|
|
178
|
+
{ url = "https://files.pythonhosted.org/packages/90/ef/a7dbb03a14a64c2a4621f989c615ed9a892535a6cad938fc27079f919d80/pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b49924c73a235e969511bf2aabdff3beebf9820931f646c80274d5d780010c47", size = 2304516, upload-time = "2026-08-28T09:59:36.194Z" },
|
|
179
|
+
{ url = "https://files.pythonhosted.org/packages/68/f8/6bb4c4b80e8a6fde1904c64a51c62a1d04fcdfa3ea521a66b2ddefa1d885/pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:2cbd9a5eff05e51c447c34dfa4632145b26b09120cf04bd0c871e44c1a5e1c9a", size = 2335223, upload-time = "2026-08-28T09:59:37.931Z" },
|
|
180
|
+
{ url = "https://files.pythonhosted.org/packages/2a/80/f46b8c681195190b2c1f1c7c0a81abce60663e987613e09ef64d433dd96b/pydantic_core-2.46.5-cp314-cp314-win32.whl", hash = "sha256:2d5d76654becf5efd62c9e51c3756c67b49498b0c9a40884934c40807adbd074", size = 1934827, upload-time = "2026-08-28T09:59:39.836Z" },
|
|
181
|
+
{ url = "https://files.pythonhosted.org/packages/f7/3c/60674207246bc0a4009d2391b7c7251c7159f279c8d2ab8aae8ef46f3dee/pydantic_core-2.46.5-cp314-cp314-win_amd64.whl", hash = "sha256:fa10ef4112775900e7a0661068635eb67b2ab824fbde764de6e0e21982a93db0", size = 2042648, upload-time = "2026-08-28T09:59:41.792Z" },
|
|
182
|
+
{ url = "https://files.pythonhosted.org/packages/69/0c/117c562c7c1babdf44576b72a5e496906506c93690387ecfbca7c729ae2e/pydantic_core-2.46.5-cp314-cp314-win_arm64.whl", hash = "sha256:045ab3b6d308439e32b81cc173bba5b9018bc6ed896afd0c65b3b009b1699af5", size = 1989652, upload-time = "2026-08-28T09:59:43.702Z" },
|
|
183
|
+
{ url = "https://files.pythonhosted.org/packages/e8/66/9336ae58f9eb68c41d121894e52c4c89eccb07eb8f602a04ee9c3f37736a/pydantic_core-2.46.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8816f3d218beb4b787de5c9759c259b8fa61f9dec42dc7811f320a33771778b7", size = 2065829, upload-time = "2026-08-28T09:59:45.364Z" },
|
|
184
|
+
{ url = "https://files.pythonhosted.org/packages/c5/02/bc19b47a96c2d3109760711acf22369e56bd7e405ca52f7ade164d2ead57/pydantic_core-2.46.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:bce57638e08ac148e5778cce7feb968307a727d66f8e2274a543d0cf0c9ad6a3", size = 1905716, upload-time = "2026-08-28T09:59:47.18Z" },
|
|
185
|
+
{ url = "https://files.pythonhosted.org/packages/52/a4/70b47c0509923dd98ccfed04fb3e32ea3849c82a0ff2205bb41009b43c00/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:976e1128455aa595ea04c79ccfedff1aaeab96ee013fcc916bed120c4f0ad94f", size = 1934216, upload-time = "2026-08-28T09:59:49.241Z" },
|
|
186
|
+
{ url = "https://files.pythonhosted.org/packages/52/ab/aa03b65f7bb198585edf806b906c3223ecf1795543e39e23aec4cce27ad2/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b891faeedeafba41b2983e5001a81b6a915b69544c7e7570d1989ce1c36ac7", size = 2010635, upload-time = "2026-08-28T09:59:51.692Z" },
|
|
187
|
+
{ url = "https://files.pythonhosted.org/packages/3c/8b/0da06343f30b84ec549aafd309c6456223d5dc8bd36af504c573faad561d/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f194189415698233dd1114a093a9b56e61e2c57e11b469be3b0506f46f0771c", size = 2209369, upload-time = "2026-08-28T09:59:53.582Z" },
|
|
188
|
+
{ url = "https://files.pythonhosted.org/packages/d6/5b/844c4defaa34a3df66eb9257087d121d70c201298b96abdf9f492fc2f1bf/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82a36973cf8a2ef5406f4fe2edbf8ed0c99629535d959e0b100c76a32535a111", size = 2253238, upload-time = "2026-08-28T09:59:55.484Z" },
|
|
189
|
+
{ url = "https://files.pythonhosted.org/packages/f4/64/a4e536cb16d7f61a7fd3120b46c577fc7fa7325992f69c4f52bc786d77d8/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdbb78909f52b981d3b2d56b97328d71eb0b974c36bd77c920123a7ebb192829", size = 2065740, upload-time = "2026-08-28T09:59:58.038Z" },
|
|
190
|
+
{ url = "https://files.pythonhosted.org/packages/5f/75/aaa38c6bc2d085f6605b34eabdc6a8a4e0b2e61fc9c8e6e52b28e97b3125/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:52e24eacdb536cade636aa90fb851835222becff8484b7001fdc78cb0290f2aa", size = 2087425, upload-time = "2026-08-28T09:59:59.898Z" },
|
|
191
|
+
{ url = "https://files.pythonhosted.org/packages/55/ae/fcab4cfc39aba3689e1d20c8b5250ad280957022c09af2ed9cd585602a5e/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:37ae34309d7bd8c0d61ab839668058f2a7962ea1fc51d105d2db228fe0618034", size = 2139306, upload-time = "2026-08-28T10:00:03.057Z" },
|
|
192
|
+
{ url = "https://files.pythonhosted.org/packages/2d/f4/f1d03a4bc9d9acbc62f4d742b8a319af52f71885079868b2ff8e48a651ee/pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:0cdbada856a1c69a7624a64d3d9aefe79300bd6ef827b43a4f265010b9b55184", size = 2144589, upload-time = "2026-08-28T10:00:05.645Z" },
|
|
193
|
+
{ url = "https://files.pythonhosted.org/packages/83/f3/7a53bb1356de514a4cd295f25b6ac39237895620c0462d2592b76c16e114/pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:545f26c504b27c3758439a5e6d9349931f0a04f855668d5fe323c89e82300a38", size = 2288882, upload-time = "2026-08-28T10:00:07.931Z" },
|
|
194
|
+
{ url = "https://files.pythonhosted.org/packages/cd/94/5a81583660c175c59d49ffb09f4b3a44debeaf86a19fca664ae1cdd9ee32/pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:ff218293c9c806138dca139765e3b067621be52bcd93cdc14c7711be7ddc90a9", size = 2335210, upload-time = "2026-08-28T10:00:10.177Z" },
|
|
195
|
+
{ url = "https://files.pythonhosted.org/packages/5a/9f/5d685c2693b972d1a59c998586e8823712b66603aeff47ee60a4bdaafd37/pydantic_core-2.46.5-cp314-cp314t-win32.whl", hash = "sha256:97cf3eb53a8cccacf9d46686a0926186c9bfb5574f2ed66d3639d5fe117cd3a9", size = 1921180, upload-time = "2026-08-28T10:00:12.35Z" },
|
|
196
|
+
{ url = "https://files.pythonhosted.org/packages/70/12/5c94ee16d65a37a15f9e869f5e6256df111154491173801a4c5e800ab548/pydantic_core-2.46.5-cp314-cp314t-win_amd64.whl", hash = "sha256:d2f9fc07a8042a8f95925b35c4f04f469707c981fc33245b6ca187cf5d2dd290", size = 2020515, upload-time = "2026-08-28T10:00:14.774Z" },
|
|
197
|
+
{ url = "https://files.pythonhosted.org/packages/63/19/67830dda664e6bdf9285ee2e40f355d0d7d6b92aa0c42e8d217bb8d33d36/pydantic_core-2.46.5-cp314-cp314t-win_arm64.whl", hash = "sha256:acf8a67ba51f4ca9ddbd0e6b3000a65ac51ab734661778b3e7ba64d99a710f2f", size = 1989276, upload-time = "2026-08-28T10:00:16.984Z" },
|
|
198
|
+
{ url = "https://files.pythonhosted.org/packages/af/1e/ecca01fce348f7e8afa9572441ff6f7d1cc70d21e4859f33944d10877e1e/pydantic_core-2.46.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:c14ad3bdc85ee7f318742c457ca3968a92126d144b15721c759033bfb06296c2", size = 2075342, upload-time = "2026-08-28T10:00:51.353Z" },
|
|
199
|
+
{ url = "https://files.pythonhosted.org/packages/1f/4c/af80c7a8032dfc897040ad5cb772bebde529a381186499e6e29987f23f8c/pydantic_core-2.46.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0bddb4020d8f04175865ccd17eff3040874fc11fb593f424edb452653b4b947c", size = 1907219, upload-time = "2026-08-28T10:00:53.438Z" },
|
|
200
|
+
{ url = "https://files.pythonhosted.org/packages/be/3e/54d89e2b092e778716bf6153634ef479e955f48c261090be23aa1e0fb0b5/pydantic_core-2.46.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2471fd51c61c610e1dcf7de44d7299283661654d11264ab4802b303368d69c47", size = 1953393, upload-time = "2026-08-28T10:00:55.58Z" },
|
|
201
|
+
{ url = "https://files.pythonhosted.org/packages/ea/89/828ee90cda28ce17bdefaa3a6eaf74fe430e113295a10e6126beca559d6c/pydantic_core-2.46.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b10ec717381bdbfafef34607824db4c91de69ff085e4fca3b2af91b4fa17e68a", size = 2099024, upload-time = "2026-08-28T10:00:57.794Z" },
|
|
202
|
+
{ url = "https://files.pythonhosted.org/packages/df/dd/053c2e4303f791f3b8f8a14ab0b22008e8eb21d868c0c90b4f9be705b76a/pydantic_core-2.46.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:013d6f3483d81e02e7c328831808f336c8596ee33b4bd4026b9ffb1e960b8942", size = 2062540, upload-time = "2026-08-28T10:01:00.318Z" },
|
|
203
|
+
{ url = "https://files.pythonhosted.org/packages/d7/dd/a18df751a5e37dd51bfad7f68e766999125bebe68c9e1d10a493ad01bd63/pydantic_core-2.46.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:e9c134bb666dd54b778b9fc0d2b50cbb7f979b9e3716f26a88c9ab3b6fc1dd0f", size = 1902040, upload-time = "2026-08-28T10:01:02.529Z" },
|
|
204
|
+
{ url = "https://files.pythonhosted.org/packages/b7/13/01d40f9d07ce8a779fd6e0bd8ad4fba91309500dd67b869e2e219d261a6d/pydantic_core-2.46.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:347ec774390c87326a2e4929d58d3f7e8763a104d5d35f4cd595a4c952366433", size = 1967479, upload-time = "2026-08-28T10:01:05.004Z" },
|
|
205
|
+
{ url = "https://files.pythonhosted.org/packages/fa/04/c81d4841331c2178b6fb09ae225425e110ed72d990c9fe556c4ec03d1013/pydantic_core-2.46.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e24d8f05fa2d28513d94e877e9c75ad66175376209b3977f916e240e623193c", size = 2111034, upload-time = "2026-08-28T10:01:07.345Z" },
|
|
206
|
+
{ url = "https://files.pythonhosted.org/packages/20/21/22102e9950b3049526d20e811b95396508377d87651edd2b80d2b3d28659/pydantic_core-2.46.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ab4b66edffb32d9e951efb3814bd104b8367a7501b81b955cacb5726d897389f", size = 2071333, upload-time = "2026-08-28T10:01:09.636Z" },
|
|
207
|
+
{ url = "https://files.pythonhosted.org/packages/d8/18/87aefa427d191e6d3ab1447f1efc1cdcac86af1069239b133e8a0fd7f7c9/pydantic_core-2.46.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:337639ba62a11acde6ef3aeb08c8ea755f8ef1fe5e513356c0f36a2b0d7568b0", size = 1912713, upload-time = "2026-08-28T10:01:12.285Z" },
|
|
208
|
+
{ url = "https://files.pythonhosted.org/packages/1f/93/fd89e9ad49b1805ca94d24ce1088b7d305f05c35ffafcedb9819d03588a0/pydantic_core-2.46.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:413a717a410d0c817ef5b786a059415550b3794e1d0c2abffd9efb93a3d9f7b4", size = 2090926, upload-time = "2026-08-28T10:01:15.19Z" },
|
|
209
|
+
{ url = "https://files.pythonhosted.org/packages/6f/45/8e59dab6acf8d35f02f0a958980074f31038968bdb2c983fcae9d1efee03/pydantic_core-2.46.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1e449def1945a462c464331254e5a44fca7c3b4f9aedf59ec2f50f8066dd8e25", size = 2131303, upload-time = "2026-08-28T10:01:17.937Z" },
|
|
210
|
+
{ url = "https://files.pythonhosted.org/packages/d5/a5/e1d4dc5180dd887a9522efc1f8716b8692b7606b1d3273d7862eaf66be44/pydantic_core-2.46.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a445486499897b88a7d6c310c88ed64dd37b1b59bfd7ae9107490bbb362f47d6", size = 2145128, upload-time = "2026-08-28T10:01:20.694Z" },
|
|
211
|
+
{ url = "https://files.pythonhosted.org/packages/c2/d7/ad493864a7fb21c0c4df98f965e2db430cb25a9d7369b5778d5016c09fd9/pydantic_core-2.46.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:2d330aaba8621b1edcec8ae2c4050f63b84ccf6d98723a8f212e9684713abf0e", size = 2294560, upload-time = "2026-08-28T10:01:23.495Z" },
|
|
212
|
+
{ url = "https://files.pythonhosted.org/packages/02/8e/b41c84c913f29973a268e6c2b5bbf13c95adb9956c126d10da11ba3b2bef/pydantic_core-2.46.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b6acfb46a814762367fb7ba0828b0a17d441b92ce249a0e007474c9072662dda", size = 2317531, upload-time = "2026-08-28T10:01:26.334Z" },
|
|
213
|
+
{ url = "https://files.pythonhosted.org/packages/db/1d/068464f23075f66a8f1b806935e9cd9363ee446636ea70d2c22ee8659dbf/pydantic_core-2.46.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d0a24b40877af2de4950252be9d21eaf7fb07660f3c2cae1f56c6b599ada5266", size = 2140686, upload-time = "2026-08-28T10:01:28.947Z" },
|
|
214
|
+
]
|
|
215
|
+
|
|
216
|
+
[[package]]
|
|
217
|
+
name = "smmap"
|
|
218
|
+
version = "5.0.3"
|
|
219
|
+
source = { registry = "https://pypi.org/simple" }
|
|
220
|
+
sdist = { url = "https://files.pythonhosted.org/packages/1f/ea/49c993d6dfdd7338c9b1000a0f36817ed7ec84577ae2e52f890d1a4ff909/smmap-5.0.3.tar.gz", hash = "sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c", size = 22506, upload-time = "2026-03-09T03:43:26.1Z" }
|
|
221
|
+
wheels = [
|
|
222
|
+
{ url = "https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl", hash = "sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f", size = 24390, upload-time = "2026-03-09T03:43:24.361Z" },
|
|
223
|
+
]
|
|
224
|
+
|
|
225
|
+
[[package]]
|
|
226
|
+
name = "typing-extensions"
|
|
227
|
+
version = "4.16.0"
|
|
228
|
+
source = { registry = "https://pypi.org/simple" }
|
|
229
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
|
|
230
|
+
wheels = [
|
|
231
|
+
{ url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
[[package]]
|
|
235
|
+
name = "typing-inspection"
|
|
236
|
+
version = "0.4.4"
|
|
237
|
+
source = { registry = "https://pypi.org/simple" }
|
|
238
|
+
dependencies = [
|
|
239
|
+
{ name = "typing-extensions" },
|
|
240
|
+
]
|
|
241
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" }
|
|
242
|
+
wheels = [
|
|
243
|
+
{ url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" },
|
|
244
|
+
]
|
|
245
|
+
|
|
246
|
+
[[package]]
|
|
247
|
+
name = "win32-setctime"
|
|
248
|
+
version = "1.2.0"
|
|
249
|
+
source = { registry = "https://pypi.org/simple" }
|
|
250
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" }
|
|
251
|
+
wheels = [
|
|
252
|
+
{ url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" },
|
|
253
|
+
]
|