sweatstack-cli 0.4.1__tar.gz → 0.6.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.
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/PKG-INFO +3 -3
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/pyproject.toml +3 -3
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/__init__.py +1 -1
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/commands/app.py +82 -5
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/commands/auth.py +1 -1
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/commands/page.py +31 -11
- sweatstack_cli-0.6.0/src/sweatstack_cli/project.py +111 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/version_check.py +2 -2
- sweatstack_cli-0.6.0/sweatstack.toml +3 -0
- sweatstack_cli-0.6.0/tests/test_project.py +110 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_version_check.py +1 -1
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/uv.lock +2 -102
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/.claude/settings.local.json +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/.gitignore +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/.python-version +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/CREATE_PRIVATE_APP.md +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/DEVELOPMENT.md +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/Makefile +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/PLAN.md +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/README.md +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/api/__init__.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/api/client.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/auth/__init__.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/auth/callback_server.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/auth/jwt.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/auth/pkce.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/auth/tokens.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/commands/__init__.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/config.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/console.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/exceptions.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/main.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/src/sweatstack_cli/py.typed +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/__init__.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/conftest.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_api/__init__.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_api/test_client.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_auth/__init__.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_auth/test_callback_server.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_auth/test_jwt.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_auth/test_pkce.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_auth/test_tokens.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_commands/__init__.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_commands/test_app.py +0 -0
- {sweatstack_cli-0.4.1 → sweatstack_cli-0.6.0}/tests/test_commands/test_cli.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sweatstack-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Command-line interface for SweatStack — the sports data platform for developers
|
|
5
5
|
Project-URL: Homepage, https://sweatstack.no
|
|
6
6
|
Project-URL: Documentation, https://docs.sweatstack.no
|
|
7
7
|
Project-URL: Repository, https://github.com/sweatstack/sweatstack-cli
|
|
8
|
-
Author-email: Aart Goossens <aart@
|
|
8
|
+
Author-email: Aart Goossens <aart@sweatstack.no>
|
|
9
9
|
License: MIT
|
|
10
10
|
Keywords: api,cli,fitness,sports,sweatstack
|
|
11
11
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -16,7 +16,7 @@ Classifier: Operating System :: OS Independent
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
17
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
18
|
Classifier: Typing :: Typed
|
|
19
|
-
Requires-Python: >=3.
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
20
|
Requires-Dist: httpx>=0.28.0
|
|
21
21
|
Requires-Dist: platformdirs>=4.0
|
|
22
22
|
Requires-Dist: typer>=0.15.0
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sweatstack-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.0"
|
|
4
4
|
description = "Command-line interface for SweatStack — the sports data platform for developers"
|
|
5
5
|
readme = "README.md"
|
|
6
|
-
authors = [{ name = "Aart Goossens", email = "aart@
|
|
7
|
-
requires-python = ">=3.
|
|
6
|
+
authors = [{ name = "Aart Goossens", email = "aart@sweatstack.no" }]
|
|
7
|
+
requires-python = ">=3.11"
|
|
8
8
|
license = { text = "MIT" }
|
|
9
9
|
keywords = ["sweatstack", "cli", "sports", "fitness", "api"]
|
|
10
10
|
classifiers = [
|
|
@@ -4,12 +4,14 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import json as json_lib
|
|
6
6
|
from pathlib import Path
|
|
7
|
+
from typing import Any, cast
|
|
7
8
|
|
|
8
9
|
import typer
|
|
9
10
|
|
|
10
11
|
from sweatstack_cli.api import APIClient
|
|
11
12
|
from sweatstack_cli.console import console, stderr_console
|
|
12
13
|
from sweatstack_cli.exceptions import APIError, AuthenticationError
|
|
14
|
+
from sweatstack_cli.project import CONFIG_FILENAME, write_config
|
|
13
15
|
|
|
14
16
|
app = typer.Typer(name="app", help="Manage OAuth2 applications.")
|
|
15
17
|
|
|
@@ -75,13 +77,20 @@ def create(
|
|
|
75
77
|
if env_path:
|
|
76
78
|
_write_env_file(env_path, result)
|
|
77
79
|
|
|
80
|
+
# Write sweatstack.toml
|
|
81
|
+
config_path = write_config(
|
|
82
|
+
app_name=result["name"],
|
|
83
|
+
client_id=result["client_id"],
|
|
84
|
+
page_slug=page,
|
|
85
|
+
)
|
|
86
|
+
|
|
78
87
|
if json_output:
|
|
79
88
|
console.print(json_lib.dumps(result, indent=2))
|
|
80
89
|
else:
|
|
81
|
-
_print_app_created(result, env_path)
|
|
90
|
+
_print_app_created(result, env_path, config_path)
|
|
82
91
|
|
|
83
92
|
|
|
84
|
-
def _write_env_file(path: Path, result: dict) -> None:
|
|
93
|
+
def _write_env_file(path: Path, result: dict[str, str]) -> None:
|
|
85
94
|
"""Append credentials to an env file."""
|
|
86
95
|
lines_to_add: list[str] = []
|
|
87
96
|
existing_content = ""
|
|
@@ -116,7 +125,7 @@ def _write_env_file(path: Path, result: dict) -> None:
|
|
|
116
125
|
f.write("\n".join(lines_to_add) + "\n")
|
|
117
126
|
|
|
118
127
|
|
|
119
|
-
def _print_app_created(result: dict, env_path: Path | None) -> None:
|
|
128
|
+
def _print_app_created(result: dict[str, str], env_path: Path | None, config_path: Path) -> None:
|
|
120
129
|
"""Pretty-print the created application details."""
|
|
121
130
|
console.print(f"[green]✓[/green] Created application [bold]{result['name']}[/bold]")
|
|
122
131
|
console.print()
|
|
@@ -131,9 +140,77 @@ def _print_app_created(result: dict, env_path: Path | None) -> None:
|
|
|
131
140
|
for uri in result["redirect_uris"]:
|
|
132
141
|
console.print(f" - {uri}")
|
|
133
142
|
|
|
143
|
+
console.print()
|
|
144
|
+
console.print(f"[green]✓[/green] Config written to [bold]{config_path}[/bold]")
|
|
145
|
+
|
|
134
146
|
if env_path:
|
|
135
|
-
console.print()
|
|
136
147
|
console.print(f"[green]✓[/green] Credentials written to [bold]{env_path}[/bold]")
|
|
137
|
-
|
|
148
|
+
|
|
149
|
+
if "client_secret" in result and not env_path:
|
|
138
150
|
console.print()
|
|
139
151
|
console.print("[yellow]Save the secret now — it won't be shown again.[/yellow]")
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@app.command()
|
|
155
|
+
def link(
|
|
156
|
+
force: bool = typer.Option(
|
|
157
|
+
False,
|
|
158
|
+
"--force",
|
|
159
|
+
"-f",
|
|
160
|
+
help="Overwrite existing sweatstack.toml.",
|
|
161
|
+
),
|
|
162
|
+
) -> None:
|
|
163
|
+
"""Link this directory to an existing application."""
|
|
164
|
+
config_path = Path(CONFIG_FILENAME)
|
|
165
|
+
|
|
166
|
+
# Check if config already exists
|
|
167
|
+
if config_path.exists() and not force:
|
|
168
|
+
console.print(f"[yellow]Already linked.[/yellow] {CONFIG_FILENAME} exists.")
|
|
169
|
+
console.print("Use [cyan]--force[/cyan] to overwrite.")
|
|
170
|
+
raise typer.Exit(1)
|
|
171
|
+
|
|
172
|
+
# Fetch user's apps
|
|
173
|
+
try:
|
|
174
|
+
client = APIClient()
|
|
175
|
+
except AuthenticationError as e:
|
|
176
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
177
|
+
console.print("[dim]Run 'sweatstack login' to authenticate.[/dim]")
|
|
178
|
+
raise typer.Exit(2)
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
# API returns a list, but client.get is typed as returning dict
|
|
182
|
+
apps = cast(list[dict[str, Any]], client.get("/api/v1/applications"))
|
|
183
|
+
except APIError as e:
|
|
184
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
185
|
+
raise typer.Exit(3)
|
|
186
|
+
|
|
187
|
+
if not apps:
|
|
188
|
+
console.print("[yellow]No applications found.[/yellow]")
|
|
189
|
+
console.print("Create one with [cyan]sweatstack app create <name>[/cyan]")
|
|
190
|
+
raise typer.Exit(1)
|
|
191
|
+
|
|
192
|
+
# Show apps and let user select
|
|
193
|
+
console.print("Link this directory to an existing application.\n")
|
|
194
|
+
console.print("Your applications:")
|
|
195
|
+
for i, app_info in enumerate(apps, 1):
|
|
196
|
+
page_info = f" [dim](page: {app_info['page_slug']})[/dim]" if app_info.get("page_slug") else ""
|
|
197
|
+
console.print(f" [cyan][{i}][/cyan] {app_info['name']}{page_info}")
|
|
198
|
+
|
|
199
|
+
console.print()
|
|
200
|
+
selection = typer.prompt("Select application", type=int)
|
|
201
|
+
|
|
202
|
+
if selection < 1 or selection > len(apps):
|
|
203
|
+
console.print("[red]Invalid selection.[/red]")
|
|
204
|
+
raise typer.Exit(1)
|
|
205
|
+
|
|
206
|
+
selected = apps[selection - 1]
|
|
207
|
+
|
|
208
|
+
# Write config
|
|
209
|
+
write_config(
|
|
210
|
+
app_name=selected["name"],
|
|
211
|
+
client_id=selected["id"],
|
|
212
|
+
page_slug=selected.get("page_slug"),
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
console.print()
|
|
216
|
+
console.print(f"[green]✓[/green] Linked to [bold]{selected['name']}[/bold]")
|
|
@@ -87,7 +87,7 @@ def status() -> None:
|
|
|
87
87
|
if update_available and latest:
|
|
88
88
|
console.print(
|
|
89
89
|
f"[yellow]⚠[/yellow] Update available: {latest} (current: {__version__})\n"
|
|
90
|
-
f" Run: [cyan]
|
|
90
|
+
f" Run: [cyan]uv tool upgrade sweatstack-cli[/cyan] [dim](or pip/pipx)[/dim]"
|
|
91
91
|
)
|
|
92
92
|
elif latest:
|
|
93
93
|
console.print(f"[green]✓[/green] Up to date ({__version__})")
|
|
@@ -11,6 +11,7 @@ from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
|
11
11
|
from sweatstack_cli.api import APIClient
|
|
12
12
|
from sweatstack_cli.console import console
|
|
13
13
|
from sweatstack_cli.exceptions import APIError, AuthenticationError
|
|
14
|
+
from sweatstack_cli.project import CONFIG_FILENAME, ProjectConfig
|
|
14
15
|
|
|
15
16
|
# URL where users can create pages for their applications
|
|
16
17
|
SETTINGS_URL = "https://app.sweatstack.no/settings/api"
|
|
@@ -53,21 +54,40 @@ def _collect_files(directory: Path) -> list[tuple[str, tuple[str, bytes, str]]]:
|
|
|
53
54
|
|
|
54
55
|
@app.command()
|
|
55
56
|
def deploy(
|
|
56
|
-
slug: str = typer.Argument(
|
|
57
|
-
|
|
58
|
-
help="Page slug
|
|
57
|
+
slug: str | None = typer.Argument(
|
|
58
|
+
None,
|
|
59
|
+
help="Page slug. Reads from sweatstack.toml if not provided.",
|
|
59
60
|
),
|
|
60
|
-
directory: Path = typer.Argument(
|
|
61
|
-
|
|
62
|
-
help="Directory
|
|
63
|
-
exists=True,
|
|
64
|
-
file_okay=False,
|
|
65
|
-
dir_okay=True,
|
|
66
|
-
resolve_path=True,
|
|
61
|
+
directory: Path | None = typer.Argument(
|
|
62
|
+
None,
|
|
63
|
+
help="Directory to deploy. Reads from sweatstack.toml or defaults to current dir.",
|
|
67
64
|
),
|
|
68
65
|
) -> None:
|
|
69
66
|
"""Deploy a static site to SweatStack Pages."""
|
|
70
|
-
|
|
67
|
+
# Load config for defaults
|
|
68
|
+
config = ProjectConfig.load()
|
|
69
|
+
|
|
70
|
+
# Resolve slug
|
|
71
|
+
page_slug = slug or (config.page.slug if config else None)
|
|
72
|
+
if not page_slug:
|
|
73
|
+
console.print("[red]Error:[/red] No page slug provided.")
|
|
74
|
+
console.print(f"Specify a slug or add it to [bold]{CONFIG_FILENAME}[/bold]")
|
|
75
|
+
raise typer.Exit(1)
|
|
76
|
+
|
|
77
|
+
# Resolve directory
|
|
78
|
+
if directory is None:
|
|
79
|
+
dir_from_config = config.page.directory if config else None
|
|
80
|
+
directory = Path(dir_from_config) if dir_from_config else Path(".")
|
|
81
|
+
|
|
82
|
+
if not directory.exists():
|
|
83
|
+
console.print(f"[red]Error:[/red] Directory '{directory}' does not exist.")
|
|
84
|
+
raise typer.Exit(1)
|
|
85
|
+
|
|
86
|
+
if not directory.is_dir():
|
|
87
|
+
console.print(f"[red]Error:[/red] '{directory}' is not a directory.")
|
|
88
|
+
raise typer.Exit(1)
|
|
89
|
+
|
|
90
|
+
directory = directory.resolve()
|
|
71
91
|
|
|
72
92
|
# Collect files
|
|
73
93
|
files = _collect_files(directory)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""Project configuration via sweatstack.toml."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import tomllib
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
CONFIG_FILENAME = "sweatstack.toml"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class PageConfig:
|
|
14
|
+
"""Page configuration."""
|
|
15
|
+
|
|
16
|
+
slug: str | None = None
|
|
17
|
+
directory: str | None = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class AppConfig:
|
|
22
|
+
"""Application configuration."""
|
|
23
|
+
|
|
24
|
+
name: str | None = None
|
|
25
|
+
client_id: str | None = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class ProjectConfig:
|
|
30
|
+
"""Project configuration from sweatstack.toml."""
|
|
31
|
+
|
|
32
|
+
app: AppConfig
|
|
33
|
+
page: PageConfig
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def load(cls, path: Path | None = None) -> ProjectConfig | None:
|
|
37
|
+
"""
|
|
38
|
+
Load config from sweatstack.toml in current directory.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
path: Optional path to config file. Defaults to ./sweatstack.toml.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
ProjectConfig if file exists and is valid, None otherwise.
|
|
45
|
+
"""
|
|
46
|
+
config_path = path or Path(CONFIG_FILENAME)
|
|
47
|
+
|
|
48
|
+
if not config_path.exists():
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
data = tomllib.loads(config_path.read_text(encoding="utf-8"))
|
|
53
|
+
except tomllib.TOMLDecodeError:
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
app_data = data.get("app", {})
|
|
57
|
+
page_data = data.get("page", {})
|
|
58
|
+
|
|
59
|
+
return cls(
|
|
60
|
+
app=AppConfig(
|
|
61
|
+
name=app_data.get("name"),
|
|
62
|
+
client_id=app_data.get("client_id"),
|
|
63
|
+
),
|
|
64
|
+
page=PageConfig(
|
|
65
|
+
slug=page_data.get("slug"),
|
|
66
|
+
directory=page_data.get("directory"),
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def write_config(
|
|
72
|
+
path: Path | None = None,
|
|
73
|
+
*,
|
|
74
|
+
app_name: str | None = None,
|
|
75
|
+
client_id: str | None = None,
|
|
76
|
+
page_slug: str | None = None,
|
|
77
|
+
page_directory: str | None = None,
|
|
78
|
+
) -> Path:
|
|
79
|
+
"""
|
|
80
|
+
Write sweatstack.toml file.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
path: Optional path to config file. Defaults to ./sweatstack.toml.
|
|
84
|
+
app_name: Application name.
|
|
85
|
+
client_id: OAuth2 client ID.
|
|
86
|
+
page_slug: Page slug.
|
|
87
|
+
page_directory: Page directory.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Path to the written config file.
|
|
91
|
+
"""
|
|
92
|
+
config_path = path or Path(CONFIG_FILENAME)
|
|
93
|
+
|
|
94
|
+
lines = ["[app]"]
|
|
95
|
+
if app_name:
|
|
96
|
+
lines.append(f'name = "{app_name}"')
|
|
97
|
+
if client_id:
|
|
98
|
+
lines.append(f'client_id = "{client_id}"')
|
|
99
|
+
|
|
100
|
+
if page_slug or page_directory:
|
|
101
|
+
lines.append("")
|
|
102
|
+
lines.append("[page]")
|
|
103
|
+
if page_slug:
|
|
104
|
+
lines.append(f'slug = "{page_slug}"')
|
|
105
|
+
if page_directory:
|
|
106
|
+
lines.append(f'directory = "{page_directory}"')
|
|
107
|
+
|
|
108
|
+
lines.append("") # Trailing newline
|
|
109
|
+
config_path.write_text("\n".join(lines), encoding="utf-8")
|
|
110
|
+
|
|
111
|
+
return config_path
|
|
@@ -70,6 +70,6 @@ def get_update_message() -> str | None:
|
|
|
70
70
|
return None
|
|
71
71
|
|
|
72
72
|
return (
|
|
73
|
-
f"
|
|
74
|
-
f"
|
|
73
|
+
f"Update available: {latest} (current: {__version__})\n"
|
|
74
|
+
f"Run: [cyan]uv tool upgrade sweatstack-cli[/cyan] [dim](or pip/pipx)[/dim]"
|
|
75
75
|
)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Tests for project configuration."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from sweatstack_cli.project import ProjectConfig, write_config
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestWriteConfig:
|
|
11
|
+
"""Tests for write_config function."""
|
|
12
|
+
|
|
13
|
+
def test_writes_app_only(self, tmp_path: Path) -> None:
|
|
14
|
+
"""Should write config with app section only."""
|
|
15
|
+
config_path = tmp_path / "sweatstack.toml"
|
|
16
|
+
|
|
17
|
+
write_config(
|
|
18
|
+
path=config_path,
|
|
19
|
+
app_name="My App",
|
|
20
|
+
client_id="abc123",
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
content = config_path.read_text()
|
|
24
|
+
assert '[app]' in content
|
|
25
|
+
assert 'name = "My App"' in content
|
|
26
|
+
assert 'client_id = "abc123"' in content
|
|
27
|
+
assert '[page]' not in content
|
|
28
|
+
|
|
29
|
+
def test_writes_app_and_page(self, tmp_path: Path) -> None:
|
|
30
|
+
"""Should write config with both sections."""
|
|
31
|
+
config_path = tmp_path / "sweatstack.toml"
|
|
32
|
+
|
|
33
|
+
write_config(
|
|
34
|
+
path=config_path,
|
|
35
|
+
app_name="My App",
|
|
36
|
+
client_id="abc123",
|
|
37
|
+
page_slug="my-page",
|
|
38
|
+
page_directory="dist",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
content = config_path.read_text()
|
|
42
|
+
assert '[app]' in content
|
|
43
|
+
assert '[page]' in content
|
|
44
|
+
assert 'slug = "my-page"' in content
|
|
45
|
+
assert 'directory = "dist"' in content
|
|
46
|
+
|
|
47
|
+
def test_returns_path(self, tmp_path: Path) -> None:
|
|
48
|
+
"""Should return the path to the config file."""
|
|
49
|
+
config_path = tmp_path / "sweatstack.toml"
|
|
50
|
+
|
|
51
|
+
result = write_config(path=config_path, app_name="Test")
|
|
52
|
+
|
|
53
|
+
assert result == config_path
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class TestProjectConfigLoad:
|
|
57
|
+
"""Tests for ProjectConfig.load method."""
|
|
58
|
+
|
|
59
|
+
def test_loads_full_config(self, tmp_path: Path) -> None:
|
|
60
|
+
"""Should load all fields from config file."""
|
|
61
|
+
config_path = tmp_path / "sweatstack.toml"
|
|
62
|
+
config_path.write_text('''
|
|
63
|
+
[app]
|
|
64
|
+
name = "My App"
|
|
65
|
+
client_id = "abc123"
|
|
66
|
+
|
|
67
|
+
[page]
|
|
68
|
+
slug = "my-page"
|
|
69
|
+
directory = "dist"
|
|
70
|
+
''')
|
|
71
|
+
|
|
72
|
+
config = ProjectConfig.load(config_path)
|
|
73
|
+
|
|
74
|
+
assert config is not None
|
|
75
|
+
assert config.app.name == "My App"
|
|
76
|
+
assert config.app.client_id == "abc123"
|
|
77
|
+
assert config.page.slug == "my-page"
|
|
78
|
+
assert config.page.directory == "dist"
|
|
79
|
+
|
|
80
|
+
def test_loads_partial_config(self, tmp_path: Path) -> None:
|
|
81
|
+
"""Should handle missing optional fields."""
|
|
82
|
+
config_path = tmp_path / "sweatstack.toml"
|
|
83
|
+
config_path.write_text('''
|
|
84
|
+
[app]
|
|
85
|
+
client_id = "abc123"
|
|
86
|
+
''')
|
|
87
|
+
|
|
88
|
+
config = ProjectConfig.load(config_path)
|
|
89
|
+
|
|
90
|
+
assert config is not None
|
|
91
|
+
assert config.app.name is None
|
|
92
|
+
assert config.app.client_id == "abc123"
|
|
93
|
+
assert config.page.slug is None
|
|
94
|
+
|
|
95
|
+
def test_returns_none_for_missing_file(self, tmp_path: Path) -> None:
|
|
96
|
+
"""Should return None if file doesn't exist."""
|
|
97
|
+
config_path = tmp_path / "nonexistent.toml"
|
|
98
|
+
|
|
99
|
+
config = ProjectConfig.load(config_path)
|
|
100
|
+
|
|
101
|
+
assert config is None
|
|
102
|
+
|
|
103
|
+
def test_returns_none_for_invalid_toml(self, tmp_path: Path) -> None:
|
|
104
|
+
"""Should return None for invalid TOML."""
|
|
105
|
+
config_path = tmp_path / "sweatstack.toml"
|
|
106
|
+
config_path.write_text("not valid toml [[[")
|
|
107
|
+
|
|
108
|
+
config = ProjectConfig.load(config_path)
|
|
109
|
+
|
|
110
|
+
assert config is None
|
|
@@ -103,7 +103,7 @@ class TestGetUpdateMessage:
|
|
|
103
103
|
|
|
104
104
|
assert msg is not None
|
|
105
105
|
assert "99.0.0" in msg
|
|
106
|
-
assert "
|
|
106
|
+
assert "sweatstack-cli" in msg
|
|
107
107
|
|
|
108
108
|
def test_returns_none_when_up_to_date(self, httpx_mock: HTTPXMock) -> None:
|
|
109
109
|
"""Should return None when on latest version."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
version = 1
|
|
2
2
|
revision = 3
|
|
3
|
-
requires-python = ">=3.
|
|
3
|
+
requires-python = ">=3.11"
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "annotated-doc"
|
|
@@ -16,7 +16,6 @@ name = "anyio"
|
|
|
16
16
|
version = "4.12.1"
|
|
17
17
|
source = { registry = "https://pypi.org/simple" }
|
|
18
18
|
dependencies = [
|
|
19
|
-
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
|
|
20
19
|
{ name = "idna" },
|
|
21
20
|
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
|
22
21
|
]
|
|
@@ -61,20 +60,6 @@ version = "7.13.4"
|
|
|
61
60
|
source = { registry = "https://pypi.org/simple" }
|
|
62
61
|
sdist = { url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91", size = 827239, upload-time = "2026-02-09T12:59:03.86Z" }
|
|
63
62
|
wheels = [
|
|
64
|
-
{ url = "https://files.pythonhosted.org/packages/44/d4/7827d9ffa34d5d4d752eec907022aa417120936282fc488306f5da08c292/coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415", size = 219152, upload-time = "2026-02-09T12:56:11.974Z" },
|
|
65
|
-
{ url = "https://files.pythonhosted.org/packages/35/b0/d69df26607c64043292644dbb9dc54b0856fabaa2cbb1eeee3331cc9e280/coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b", size = 219667, upload-time = "2026-02-09T12:56:13.33Z" },
|
|
66
|
-
{ url = "https://files.pythonhosted.org/packages/82/a4/c1523f7c9e47b2271dbf8c2a097e7a1f89ef0d66f5840bb59b7e8814157b/coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a", size = 246425, upload-time = "2026-02-09T12:56:14.552Z" },
|
|
67
|
-
{ url = "https://files.pythonhosted.org/packages/f8/02/aa7ec01d1a5023c4b680ab7257f9bfde9defe8fdddfe40be096ac19e8177/coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f", size = 248229, upload-time = "2026-02-09T12:56:16.31Z" },
|
|
68
|
-
{ url = "https://files.pythonhosted.org/packages/35/98/85aba0aed5126d896162087ef3f0e789a225697245256fc6181b95f47207/coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012", size = 250106, upload-time = "2026-02-09T12:56:18.024Z" },
|
|
69
|
-
{ url = "https://files.pythonhosted.org/packages/96/72/1db59bd67494bc162e3e4cd5fbc7edba2c7026b22f7c8ef1496d58c2b94c/coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def", size = 252021, upload-time = "2026-02-09T12:56:19.272Z" },
|
|
70
|
-
{ url = "https://files.pythonhosted.org/packages/9d/97/72899c59c7066961de6e3daa142d459d47d104956db43e057e034f015c8a/coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256", size = 247114, upload-time = "2026-02-09T12:56:21.051Z" },
|
|
71
|
-
{ url = "https://files.pythonhosted.org/packages/39/1f/f1885573b5970235e908da4389176936c8933e86cb316b9620aab1585fa2/coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda", size = 248143, upload-time = "2026-02-09T12:56:22.585Z" },
|
|
72
|
-
{ url = "https://files.pythonhosted.org/packages/a8/cf/e80390c5b7480b722fa3e994f8202807799b85bc562aa4f1dde209fbb7be/coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92", size = 246152, upload-time = "2026-02-09T12:56:23.748Z" },
|
|
73
|
-
{ url = "https://files.pythonhosted.org/packages/44/bf/f89a8350d85572f95412debb0fb9bb4795b1d5b5232bd652923c759e787b/coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c", size = 249959, upload-time = "2026-02-09T12:56:25.209Z" },
|
|
74
|
-
{ url = "https://files.pythonhosted.org/packages/f7/6e/612a02aece8178c818df273e8d1642190c4875402ca2ba74514394b27aba/coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58", size = 246416, upload-time = "2026-02-09T12:56:26.475Z" },
|
|
75
|
-
{ url = "https://files.pythonhosted.org/packages/cb/98/b5afc39af67c2fa6786b03c3a7091fc300947387ce8914b096db8a73d67a/coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9", size = 247025, upload-time = "2026-02-09T12:56:27.727Z" },
|
|
76
|
-
{ url = "https://files.pythonhosted.org/packages/51/30/2bba8ef0682d5bd210c38fe497e12a06c9f8d663f7025e9f5c2c31ce847d/coverage-7.13.4-cp310-cp310-win32.whl", hash = "sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf", size = 221758, upload-time = "2026-02-09T12:56:29.051Z" },
|
|
77
|
-
{ url = "https://files.pythonhosted.org/packages/78/13/331f94934cf6c092b8ea59ff868eb587bc8fe0893f02c55bc6c0183a192e/coverage-7.13.4-cp310-cp310-win_amd64.whl", hash = "sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95", size = 222693, upload-time = "2026-02-09T12:56:30.366Z" },
|
|
78
63
|
{ url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053", size = 219278, upload-time = "2026-02-09T12:56:31.673Z" },
|
|
79
64
|
{ url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11", size = 219783, upload-time = "2026-02-09T12:56:33.104Z" },
|
|
80
65
|
{ url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa", size = 250200, upload-time = "2026-02-09T12:56:34.474Z" },
|
|
@@ -168,18 +153,6 @@ wheels = [
|
|
|
168
153
|
{ url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0", size = 211242, upload-time = "2026-02-09T12:59:02.032Z" },
|
|
169
154
|
]
|
|
170
155
|
|
|
171
|
-
[[package]]
|
|
172
|
-
name = "exceptiongroup"
|
|
173
|
-
version = "1.3.1"
|
|
174
|
-
source = { registry = "https://pypi.org/simple" }
|
|
175
|
-
dependencies = [
|
|
176
|
-
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
|
177
|
-
]
|
|
178
|
-
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" }
|
|
179
|
-
wheels = [
|
|
180
|
-
{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" },
|
|
181
|
-
]
|
|
182
|
-
|
|
183
156
|
[[package]]
|
|
184
157
|
name = "h11"
|
|
185
158
|
version = "0.16.0"
|
|
@@ -241,16 +214,6 @@ version = "0.7.8"
|
|
|
241
214
|
source = { registry = "https://pypi.org/simple" }
|
|
242
215
|
sdist = { url = "https://files.pythonhosted.org/packages/e7/24/5f3646ff414285e0f7708fa4e946b9bf538345a41d1c375c439467721a5e/librt-0.7.8.tar.gz", hash = "sha256:1a4ede613941d9c3470b0368be851df6bb78ab218635512d0370b27a277a0862", size = 148323, upload-time = "2026-01-14T12:56:16.876Z" }
|
|
243
216
|
wheels = [
|
|
244
|
-
{ url = "https://files.pythonhosted.org/packages/44/13/57b06758a13550c5f09563893b004f98e9537ee6ec67b7df85c3571c8832/librt-0.7.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b45306a1fc5f53c9330fbee134d8b3227fe5da2ab09813b892790400aa49352d", size = 56521, upload-time = "2026-01-14T12:54:40.066Z" },
|
|
245
|
-
{ url = "https://files.pythonhosted.org/packages/c2/24/bbea34d1452a10612fb45ac8356f95351ba40c2517e429602160a49d1fd0/librt-0.7.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:864c4b7083eeee250ed55135d2127b260d7eb4b5e953a9e5df09c852e327961b", size = 58456, upload-time = "2026-01-14T12:54:41.471Z" },
|
|
246
|
-
{ url = "https://files.pythonhosted.org/packages/04/72/a168808f92253ec3a810beb1eceebc465701197dbc7e865a1c9ceb3c22c7/librt-0.7.8-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6938cc2de153bc927ed8d71c7d2f2ae01b4e96359126c602721340eb7ce1a92d", size = 164392, upload-time = "2026-01-14T12:54:42.843Z" },
|
|
247
|
-
{ url = "https://files.pythonhosted.org/packages/14/5c/4c0d406f1b02735c2e7af8ff1ff03a6577b1369b91aa934a9fa2cc42c7ce/librt-0.7.8-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:66daa6ac5de4288a5bbfbe55b4caa7bf0cd26b3269c7a476ffe8ce45f837f87d", size = 172959, upload-time = "2026-01-14T12:54:44.602Z" },
|
|
248
|
-
{ url = "https://files.pythonhosted.org/packages/82/5f/3e85351c523f73ad8d938989e9a58c7f59fb9c17f761b9981b43f0025ce7/librt-0.7.8-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4864045f49dc9c974dadb942ac56a74cd0479a2aafa51ce272c490a82322ea3c", size = 186717, upload-time = "2026-01-14T12:54:45.986Z" },
|
|
249
|
-
{ url = "https://files.pythonhosted.org/packages/08/f8/18bfe092e402d00fe00d33aa1e01dda1bd583ca100b393b4373847eade6d/librt-0.7.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a36515b1328dc5b3ffce79fe204985ca8572525452eacabee2166f44bb387b2c", size = 184585, upload-time = "2026-01-14T12:54:47.139Z" },
|
|
250
|
-
{ url = "https://files.pythonhosted.org/packages/4e/fc/f43972ff56fd790a9fa55028a52ccea1875100edbb856b705bd393b601e3/librt-0.7.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b7e7f140c5169798f90b80d6e607ed2ba5059784968a004107c88ad61fb3641d", size = 180497, upload-time = "2026-01-14T12:54:48.946Z" },
|
|
251
|
-
{ url = "https://files.pythonhosted.org/packages/e1/3a/25e36030315a410d3ad0b7d0f19f5f188e88d1613d7d3fd8150523ea1093/librt-0.7.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff71447cb778a4f772ddc4ce360e6ba9c95527ed84a52096bd1bbf9fee2ec7c0", size = 200052, upload-time = "2026-01-14T12:54:50.382Z" },
|
|
252
|
-
{ url = "https://files.pythonhosted.org/packages/fc/b8/f3a5a1931ae2a6ad92bf6893b9ef44325b88641d58723529e2c2935e8abe/librt-0.7.8-cp310-cp310-win32.whl", hash = "sha256:047164e5f68b7a8ebdf9fae91a3c2161d3192418aadd61ddd3a86a56cbe3dc85", size = 43477, upload-time = "2026-01-14T12:54:51.815Z" },
|
|
253
|
-
{ url = "https://files.pythonhosted.org/packages/fe/91/c4202779366bc19f871b4ad25db10fcfa1e313c7893feb942f32668e8597/librt-0.7.8-cp310-cp310-win_amd64.whl", hash = "sha256:d6f254d096d84156a46a84861183c183d30734e52383602443292644d895047c", size = 49806, upload-time = "2026-01-14T12:54:53.149Z" },
|
|
254
217
|
{ url = "https://files.pythonhosted.org/packages/1b/a3/87ea9c1049f2c781177496ebee29430e4631f439b8553a4969c88747d5d8/librt-0.7.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ff3e9c11aa260c31493d4b3197d1e28dd07768594a4f92bec4506849d736248f", size = 56507, upload-time = "2026-01-14T12:54:54.156Z" },
|
|
255
218
|
{ url = "https://files.pythonhosted.org/packages/5e/4a/23bcef149f37f771ad30203d561fcfd45b02bc54947b91f7a9ac34815747/librt-0.7.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ddb52499d0b3ed4aa88746aaf6f36a08314677d5c346234c3987ddc506404eac", size = 58455, upload-time = "2026-01-14T12:54:55.978Z" },
|
|
256
219
|
{ url = "https://files.pythonhosted.org/packages/22/6e/46eb9b85c1b9761e0f42b6e6311e1cc544843ac897457062b9d5d0b21df4/librt-0.7.8-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e9c0afebbe6ce177ae8edba0c7c4d626f2a0fc12c33bb993d163817c41a7a05c", size = 164956, upload-time = "2026-01-14T12:54:57.311Z" },
|
|
@@ -337,17 +300,10 @@ dependencies = [
|
|
|
337
300
|
{ name = "librt", marker = "platform_python_implementation != 'PyPy'" },
|
|
338
301
|
{ name = "mypy-extensions" },
|
|
339
302
|
{ name = "pathspec" },
|
|
340
|
-
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
|
341
303
|
{ name = "typing-extensions" },
|
|
342
304
|
]
|
|
343
305
|
sdist = { url = "https://files.pythonhosted.org/packages/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size = 3582404, upload-time = "2025-12-15T05:03:48.42Z" }
|
|
344
306
|
wheels = [
|
|
345
|
-
{ url = "https://files.pythonhosted.org/packages/2f/63/e499890d8e39b1ff2df4c0c6ce5d371b6844ee22b8250687a99fd2f657a8/mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec", size = 13101333, upload-time = "2025-12-15T05:03:03.28Z" },
|
|
346
|
-
{ url = "https://files.pythonhosted.org/packages/72/4b/095626fc136fba96effc4fd4a82b41d688ab92124f8c4f7564bffe5cf1b0/mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b", size = 12164102, upload-time = "2025-12-15T05:02:33.611Z" },
|
|
347
|
-
{ url = "https://files.pythonhosted.org/packages/0c/5b/952928dd081bf88a83a5ccd49aaecfcd18fd0d2710c7ff07b8fb6f7032b9/mypy-1.19.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6", size = 12765799, upload-time = "2025-12-15T05:03:28.44Z" },
|
|
348
|
-
{ url = "https://files.pythonhosted.org/packages/2a/0d/93c2e4a287f74ef11a66fb6d49c7a9f05e47b0a4399040e6719b57f500d2/mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74", size = 13522149, upload-time = "2025-12-15T05:02:36.011Z" },
|
|
349
|
-
{ url = "https://files.pythonhosted.org/packages/7b/0e/33a294b56aaad2b338d203e3a1d8b453637ac36cb278b45005e0901cf148/mypy-1.19.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1", size = 13810105, upload-time = "2025-12-15T05:02:40.327Z" },
|
|
350
|
-
{ url = "https://files.pythonhosted.org/packages/0e/fd/3e82603a0cb66b67c5e7abababce6bf1a929ddf67bf445e652684af5c5a0/mypy-1.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac", size = 10057200, upload-time = "2025-12-15T05:02:51.012Z" },
|
|
351
307
|
{ url = "https://files.pythonhosted.org/packages/ef/47/6b3ebabd5474d9cdc170d1342fbf9dddc1b0ec13ec90bf9004ee6f391c31/mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288", size = 13028539, upload-time = "2025-12-15T05:03:44.129Z" },
|
|
352
308
|
{ url = "https://files.pythonhosted.org/packages/5c/a6/ac7c7a88a3c9c54334f53a941b765e6ec6c4ebd65d3fe8cdcfbe0d0fd7db/mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab", size = 12083163, upload-time = "2025-12-15T05:03:37.679Z" },
|
|
353
309
|
{ url = "https://files.pythonhosted.org/packages/67/af/3afa9cf880aa4a2c803798ac24f1d11ef72a0c8079689fac5cfd815e2830/mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6", size = 12687629, upload-time = "2025-12-15T05:02:31.526Z" },
|
|
@@ -435,12 +391,10 @@ version = "9.0.2"
|
|
|
435
391
|
source = { registry = "https://pypi.org/simple" }
|
|
436
392
|
dependencies = [
|
|
437
393
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
438
|
-
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
|
|
439
394
|
{ name = "iniconfig" },
|
|
440
395
|
{ name = "packaging" },
|
|
441
396
|
{ name = "pluggy" },
|
|
442
397
|
{ name = "pygments" },
|
|
443
|
-
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
|
444
398
|
]
|
|
445
399
|
sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" }
|
|
446
400
|
wheels = [
|
|
@@ -509,7 +463,7 @@ wheels = [
|
|
|
509
463
|
|
|
510
464
|
[[package]]
|
|
511
465
|
name = "sweatstack-cli"
|
|
512
|
-
version = "0.
|
|
466
|
+
version = "0.5.0"
|
|
513
467
|
source = { editable = "." }
|
|
514
468
|
dependencies = [
|
|
515
469
|
{ name = "httpx" },
|
|
@@ -539,60 +493,6 @@ requires-dist = [
|
|
|
539
493
|
]
|
|
540
494
|
provides-extras = ["dev"]
|
|
541
495
|
|
|
542
|
-
[[package]]
|
|
543
|
-
name = "tomli"
|
|
544
|
-
version = "2.4.0"
|
|
545
|
-
source = { registry = "https://pypi.org/simple" }
|
|
546
|
-
sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" }
|
|
547
|
-
wheels = [
|
|
548
|
-
{ url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" },
|
|
549
|
-
{ url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" },
|
|
550
|
-
{ url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" },
|
|
551
|
-
{ url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" },
|
|
552
|
-
{ url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" },
|
|
553
|
-
{ url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" },
|
|
554
|
-
{ url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" },
|
|
555
|
-
{ url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" },
|
|
556
|
-
{ url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" },
|
|
557
|
-
{ url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" },
|
|
558
|
-
{ url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" },
|
|
559
|
-
{ url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" },
|
|
560
|
-
{ url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size = 251720, upload-time = "2026-01-11T11:22:00.178Z" },
|
|
561
|
-
{ url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size = 247014, upload-time = "2026-01-11T11:22:01.238Z" },
|
|
562
|
-
{ url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size = 251820, upload-time = "2026-01-11T11:22:02.727Z" },
|
|
563
|
-
{ url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size = 97712, upload-time = "2026-01-11T11:22:03.777Z" },
|
|
564
|
-
{ url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size = 108296, upload-time = "2026-01-11T11:22:04.86Z" },
|
|
565
|
-
{ url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size = 94553, upload-time = "2026-01-11T11:22:05.854Z" },
|
|
566
|
-
{ url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size = 154915, upload-time = "2026-01-11T11:22:06.703Z" },
|
|
567
|
-
{ url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size = 149038, upload-time = "2026-01-11T11:22:07.56Z" },
|
|
568
|
-
{ url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size = 242245, upload-time = "2026-01-11T11:22:08.344Z" },
|
|
569
|
-
{ url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size = 250335, upload-time = "2026-01-11T11:22:09.951Z" },
|
|
570
|
-
{ url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size = 245962, upload-time = "2026-01-11T11:22:11.27Z" },
|
|
571
|
-
{ url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size = 250396, upload-time = "2026-01-11T11:22:12.325Z" },
|
|
572
|
-
{ url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size = 97530, upload-time = "2026-01-11T11:22:13.865Z" },
|
|
573
|
-
{ url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size = 108227, upload-time = "2026-01-11T11:22:15.224Z" },
|
|
574
|
-
{ url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size = 94748, upload-time = "2026-01-11T11:22:16.009Z" },
|
|
575
|
-
{ url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size = 154725, upload-time = "2026-01-11T11:22:17.269Z" },
|
|
576
|
-
{ url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size = 148901, upload-time = "2026-01-11T11:22:18.287Z" },
|
|
577
|
-
{ url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size = 243375, upload-time = "2026-01-11T11:22:19.154Z" },
|
|
578
|
-
{ url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size = 250639, upload-time = "2026-01-11T11:22:20.168Z" },
|
|
579
|
-
{ url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size = 246897, upload-time = "2026-01-11T11:22:21.544Z" },
|
|
580
|
-
{ url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size = 254697, upload-time = "2026-01-11T11:22:23.058Z" },
|
|
581
|
-
{ url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size = 98567, upload-time = "2026-01-11T11:22:24.033Z" },
|
|
582
|
-
{ url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size = 108556, upload-time = "2026-01-11T11:22:25.378Z" },
|
|
583
|
-
{ url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size = 96014, upload-time = "2026-01-11T11:22:26.138Z" },
|
|
584
|
-
{ url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size = 163339, upload-time = "2026-01-11T11:22:27.143Z" },
|
|
585
|
-
{ url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size = 159490, upload-time = "2026-01-11T11:22:28.399Z" },
|
|
586
|
-
{ url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size = 269398, upload-time = "2026-01-11T11:22:29.345Z" },
|
|
587
|
-
{ url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size = 276515, upload-time = "2026-01-11T11:22:30.327Z" },
|
|
588
|
-
{ url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size = 273806, upload-time = "2026-01-11T11:22:32.56Z" },
|
|
589
|
-
{ url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size = 281340, upload-time = "2026-01-11T11:22:33.505Z" },
|
|
590
|
-
{ url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size = 108106, upload-time = "2026-01-11T11:22:34.451Z" },
|
|
591
|
-
{ url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size = 120504, upload-time = "2026-01-11T11:22:35.764Z" },
|
|
592
|
-
{ url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size = 99561, upload-time = "2026-01-11T11:22:36.624Z" },
|
|
593
|
-
{ url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" },
|
|
594
|
-
]
|
|
595
|
-
|
|
596
496
|
[[package]]
|
|
597
497
|
name = "typer"
|
|
598
498
|
version = "0.21.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|