tetra-rp 0.12.0__py3-none-any.whl → 0.13.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tetra-rp might be problematic. Click here for more details.
- tetra_rp/cli/__init__.py +0 -0
- tetra_rp/cli/commands/__init__.py +1 -0
- tetra_rp/cli/commands/deploy.py +336 -0
- tetra_rp/cli/commands/init.py +86 -0
- tetra_rp/cli/commands/resource.py +191 -0
- tetra_rp/cli/commands/run.py +122 -0
- tetra_rp/cli/main.py +81 -0
- tetra_rp/cli/templates/advanced/main.py +58 -0
- tetra_rp/cli/templates/advanced/utils.py +24 -0
- tetra_rp/cli/templates/basic/main.py +32 -0
- tetra_rp/cli/templates/gpu-compute/main.py +64 -0
- tetra_rp/cli/templates/web-api/api.py +67 -0
- tetra_rp/cli/templates/web-api/main.py +42 -0
- tetra_rp/cli/utils/__init__.py +1 -0
- tetra_rp/cli/utils/deployment.py +172 -0
- tetra_rp/cli/utils/skeleton.py +101 -0
- tetra_rp/client.py +0 -6
- tetra_rp/config.py +29 -0
- tetra_rp/execute_class.py +0 -3
- tetra_rp/protos/remote_execution.py +0 -4
- tetra_rp/stubs/live_serverless.py +1 -3
- tetra_rp/stubs/registry.py +0 -4
- {tetra_rp-0.12.0.dist-info → tetra_rp-0.13.0.dist-info}/METADATA +5 -1
- {tetra_rp-0.12.0.dist-info → tetra_rp-0.13.0.dist-info}/RECORD +27 -9
- tetra_rp-0.13.0.dist-info/entry_points.txt +2 -0
- {tetra_rp-0.12.0.dist-info → tetra_rp-0.13.0.dist-info}/WHEEL +0 -0
- {tetra_rp-0.12.0.dist-info → tetra_rp-0.13.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Project skeleton creation utilities."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Dict, List, Any
|
|
5
|
+
|
|
6
|
+
from tetra_rp.config import get_paths
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_template_directory() -> Path:
|
|
10
|
+
"""Get the path to the templates directory."""
|
|
11
|
+
return Path(__file__).parent.parent / "templates"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def load_template_files(template_name: str) -> Dict[str, Any]:
|
|
15
|
+
"""Load template files from filesystem."""
|
|
16
|
+
template_dir = get_template_directory() / template_name
|
|
17
|
+
|
|
18
|
+
if not template_dir.exists():
|
|
19
|
+
raise ValueError(f"Template '{template_name}' not found in {template_dir}")
|
|
20
|
+
|
|
21
|
+
files = {}
|
|
22
|
+
|
|
23
|
+
# Load all files from the template directory
|
|
24
|
+
for file_path in template_dir.iterdir():
|
|
25
|
+
if file_path.is_file():
|
|
26
|
+
relative_path = file_path.name
|
|
27
|
+
|
|
28
|
+
# Special handling for config.json - return as callable that generates tetra config
|
|
29
|
+
if file_path.name == "config.json":
|
|
30
|
+
config_content = file_path.read_text()
|
|
31
|
+
files[".tetra/config.json"] = lambda content=config_content: content
|
|
32
|
+
else:
|
|
33
|
+
files[relative_path] = file_path.read_text()
|
|
34
|
+
|
|
35
|
+
return files
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_available_templates() -> Dict[str, Dict[str, Any]]:
|
|
39
|
+
"""Get available project templates from filesystem."""
|
|
40
|
+
template_dir = get_template_directory()
|
|
41
|
+
templates = {}
|
|
42
|
+
|
|
43
|
+
# Template descriptions
|
|
44
|
+
descriptions = {
|
|
45
|
+
"basic": "Simple remote function example",
|
|
46
|
+
"advanced": "Multi-function project with dependencies",
|
|
47
|
+
"gpu-compute": "GPU-optimized compute workload",
|
|
48
|
+
"web-api": "FastAPI web service deployment",
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Discover templates from filesystem
|
|
52
|
+
for template_path in template_dir.iterdir():
|
|
53
|
+
if template_path.is_dir():
|
|
54
|
+
template_name = template_path.name
|
|
55
|
+
try:
|
|
56
|
+
templates[template_name] = {
|
|
57
|
+
"description": descriptions.get(
|
|
58
|
+
template_name, f"{template_name} template"
|
|
59
|
+
),
|
|
60
|
+
"files": load_template_files(template_name),
|
|
61
|
+
}
|
|
62
|
+
except Exception as e:
|
|
63
|
+
print(f"Warning: Failed to load template '{template_name}': {e}")
|
|
64
|
+
|
|
65
|
+
return templates
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def create_project_skeleton(
|
|
69
|
+
template_name: str, template_info: Dict[str, Any], force: bool = False
|
|
70
|
+
) -> List[str]:
|
|
71
|
+
"""Create project skeleton from template."""
|
|
72
|
+
created_files = []
|
|
73
|
+
|
|
74
|
+
# Create .tetra directory using centralized config
|
|
75
|
+
paths = get_paths()
|
|
76
|
+
paths.ensure_tetra_dir()
|
|
77
|
+
|
|
78
|
+
# Create files from template
|
|
79
|
+
for file_path, content in template_info["files"].items():
|
|
80
|
+
path = Path(file_path)
|
|
81
|
+
|
|
82
|
+
# Create parent directories if needed
|
|
83
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
84
|
+
|
|
85
|
+
# Skip existing files unless force is True
|
|
86
|
+
if path.exists() and not force:
|
|
87
|
+
continue
|
|
88
|
+
|
|
89
|
+
# Get content (could be string or callable)
|
|
90
|
+
if callable(content):
|
|
91
|
+
file_content = content()
|
|
92
|
+
else:
|
|
93
|
+
file_content = content
|
|
94
|
+
|
|
95
|
+
# Write file
|
|
96
|
+
with open(path, "w") as f:
|
|
97
|
+
f.write(file_content)
|
|
98
|
+
|
|
99
|
+
created_files.append(str(path))
|
|
100
|
+
|
|
101
|
+
return created_files
|
tetra_rp/client.py
CHANGED
|
@@ -15,7 +15,6 @@ def remote(
|
|
|
15
15
|
dependencies: Optional[List[str]] = None,
|
|
16
16
|
system_dependencies: Optional[List[str]] = None,
|
|
17
17
|
accelerate_downloads: bool = True,
|
|
18
|
-
hf_models_to_cache: Optional[List[str]] = None,
|
|
19
18
|
**extra,
|
|
20
19
|
):
|
|
21
20
|
"""
|
|
@@ -33,8 +32,6 @@ def remote(
|
|
|
33
32
|
environment before executing the function. Defaults to None.
|
|
34
33
|
accelerate_downloads (bool, optional): Enable download acceleration for dependencies and models.
|
|
35
34
|
Defaults to True.
|
|
36
|
-
hf_models_to_cache (List[str], optional): List of HuggingFace model IDs to pre-cache using
|
|
37
|
-
download acceleration. Defaults to None.
|
|
38
35
|
extra (dict, optional): Additional parameters for the execution of the resource. Defaults to an empty dict.
|
|
39
36
|
|
|
40
37
|
Returns:
|
|
@@ -47,7 +44,6 @@ def remote(
|
|
|
47
44
|
resource_config=my_resource_config,
|
|
48
45
|
dependencies=["numpy", "pandas"],
|
|
49
46
|
accelerate_downloads=True,
|
|
50
|
-
hf_models_to_cache=["gpt2", "bert-base-uncased"]
|
|
51
47
|
)
|
|
52
48
|
async def my_function(data):
|
|
53
49
|
# Function logic here
|
|
@@ -64,7 +60,6 @@ def remote(
|
|
|
64
60
|
dependencies,
|
|
65
61
|
system_dependencies,
|
|
66
62
|
accelerate_downloads,
|
|
67
|
-
hf_models_to_cache,
|
|
68
63
|
extra,
|
|
69
64
|
)
|
|
70
65
|
else:
|
|
@@ -82,7 +77,6 @@ def remote(
|
|
|
82
77
|
dependencies,
|
|
83
78
|
system_dependencies,
|
|
84
79
|
accelerate_downloads,
|
|
85
|
-
hf_models_to_cache,
|
|
86
80
|
*args,
|
|
87
81
|
**kwargs,
|
|
88
82
|
)
|
tetra_rp/config.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Configuration management for tetra-rp CLI."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import NamedTuple
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TetraPaths(NamedTuple):
|
|
8
|
+
"""Paths for tetra-rp configuration and data."""
|
|
9
|
+
|
|
10
|
+
tetra_dir: Path
|
|
11
|
+
config_file: Path
|
|
12
|
+
deployments_file: Path
|
|
13
|
+
|
|
14
|
+
def ensure_tetra_dir(self) -> None:
|
|
15
|
+
"""Ensure the .tetra directory exists."""
|
|
16
|
+
self.tetra_dir.mkdir(exist_ok=True)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_paths() -> TetraPaths:
|
|
20
|
+
"""Get standardized paths for tetra-rp configuration."""
|
|
21
|
+
tetra_dir = Path.cwd() / ".tetra"
|
|
22
|
+
config_file = tetra_dir / "config.json"
|
|
23
|
+
deployments_file = tetra_dir / "deployments.json"
|
|
24
|
+
|
|
25
|
+
return TetraPaths(
|
|
26
|
+
tetra_dir=tetra_dir,
|
|
27
|
+
config_file=config_file,
|
|
28
|
+
deployments_file=deployments_file,
|
|
29
|
+
)
|
tetra_rp/execute_class.py
CHANGED
|
@@ -203,7 +203,6 @@ def create_remote_class(
|
|
|
203
203
|
dependencies: Optional[List[str]],
|
|
204
204
|
system_dependencies: Optional[List[str]],
|
|
205
205
|
accelerate_downloads: bool,
|
|
206
|
-
hf_models_to_cache: Optional[List[str]],
|
|
207
206
|
extra: dict,
|
|
208
207
|
):
|
|
209
208
|
"""
|
|
@@ -222,7 +221,6 @@ def create_remote_class(
|
|
|
222
221
|
self._dependencies = dependencies or []
|
|
223
222
|
self._system_dependencies = system_dependencies or []
|
|
224
223
|
self._accelerate_downloads = accelerate_downloads
|
|
225
|
-
self._hf_models_to_cache = hf_models_to_cache
|
|
226
224
|
self._extra = extra
|
|
227
225
|
self._constructor_args = args
|
|
228
226
|
self._constructor_kwargs = kwargs
|
|
@@ -307,7 +305,6 @@ def create_remote_class(
|
|
|
307
305
|
dependencies=self._dependencies,
|
|
308
306
|
system_dependencies=self._system_dependencies,
|
|
309
307
|
accelerate_downloads=self._accelerate_downloads,
|
|
310
|
-
hf_models_to_cache=self._hf_models_to_cache,
|
|
311
308
|
instance_id=self._instance_id,
|
|
312
309
|
create_new_instance=not hasattr(
|
|
313
310
|
self, "_stub"
|
|
@@ -81,10 +81,6 @@ class FunctionRequest(BaseModel):
|
|
|
81
81
|
default=True,
|
|
82
82
|
description="Enable download acceleration for dependencies and models",
|
|
83
83
|
)
|
|
84
|
-
hf_models_to_cache: Optional[List[str]] = Field(
|
|
85
|
-
default=None,
|
|
86
|
-
description="List of HuggingFace model IDs to pre-cache using acceleration",
|
|
87
|
-
)
|
|
88
84
|
|
|
89
85
|
@model_validator(mode="after")
|
|
90
86
|
def validate_execution_requirements(self) -> "FunctionRequest":
|
|
@@ -68,7 +68,6 @@ class LiveServerlessStub(RemoteExecutorStub):
|
|
|
68
68
|
dependencies,
|
|
69
69
|
system_dependencies,
|
|
70
70
|
accelerate_downloads,
|
|
71
|
-
hf_models_to_cache,
|
|
72
71
|
*args,
|
|
73
72
|
**kwargs,
|
|
74
73
|
):
|
|
@@ -79,7 +78,6 @@ class LiveServerlessStub(RemoteExecutorStub):
|
|
|
79
78
|
"dependencies": dependencies,
|
|
80
79
|
"system_dependencies": system_dependencies,
|
|
81
80
|
"accelerate_downloads": accelerate_downloads,
|
|
82
|
-
"hf_models_to_cache": hf_models_to_cache,
|
|
83
81
|
}
|
|
84
82
|
|
|
85
83
|
# Thread-safe cache access
|
|
@@ -110,7 +108,7 @@ class LiveServerlessStub(RemoteExecutorStub):
|
|
|
110
108
|
|
|
111
109
|
if response.stdout:
|
|
112
110
|
for line in response.stdout.splitlines():
|
|
113
|
-
|
|
111
|
+
print(line)
|
|
114
112
|
|
|
115
113
|
if response.success:
|
|
116
114
|
if response.result is None:
|
tetra_rp/stubs/registry.py
CHANGED
|
@@ -31,7 +31,6 @@ def _create_live_serverless_stub(resource, **extra):
|
|
|
31
31
|
dependencies,
|
|
32
32
|
system_dependencies,
|
|
33
33
|
accelerate_downloads,
|
|
34
|
-
hf_models_to_cache,
|
|
35
34
|
*args,
|
|
36
35
|
**kwargs,
|
|
37
36
|
) -> dict:
|
|
@@ -43,7 +42,6 @@ def _create_live_serverless_stub(resource, **extra):
|
|
|
43
42
|
dependencies,
|
|
44
43
|
system_dependencies,
|
|
45
44
|
accelerate_downloads,
|
|
46
|
-
hf_models_to_cache,
|
|
47
45
|
*args,
|
|
48
46
|
**kwargs,
|
|
49
47
|
)
|
|
@@ -78,7 +76,6 @@ def _(resource, **extra):
|
|
|
78
76
|
dependencies,
|
|
79
77
|
system_dependencies,
|
|
80
78
|
accelerate_downloads,
|
|
81
|
-
hf_models_to_cache,
|
|
82
79
|
*args,
|
|
83
80
|
**kwargs,
|
|
84
81
|
) -> dict:
|
|
@@ -103,7 +100,6 @@ def _(resource, **extra):
|
|
|
103
100
|
dependencies,
|
|
104
101
|
system_dependencies,
|
|
105
102
|
accelerate_downloads,
|
|
106
|
-
hf_models_to_cache,
|
|
107
103
|
*args,
|
|
108
104
|
**kwargs,
|
|
109
105
|
) -> dict:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tetra_rp
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Summary: A Python library for distributed inference and serving of machine learning models
|
|
5
5
|
Author-email: Marut Pandya <pandyamarut@gmail.com>, Patrick Rachford <prachford@icloud.com>, Dean Quinanola <dean.quinanola@runpod.io>
|
|
6
6
|
License: MIT
|
|
@@ -14,6 +14,9 @@ Requires-Dist: cloudpickle>=3.1.1
|
|
|
14
14
|
Requires-Dist: runpod
|
|
15
15
|
Requires-Dist: python-dotenv>=1.0.0
|
|
16
16
|
Requires-Dist: pydantic>=2.0.0
|
|
17
|
+
Requires-Dist: rich>=14.0.0
|
|
18
|
+
Requires-Dist: typer>=0.12.0
|
|
19
|
+
Requires-Dist: questionary>=2.0.0
|
|
17
20
|
|
|
18
21
|
# Tetra: Serverless computing for AI workloads
|
|
19
22
|
|
|
@@ -359,6 +362,7 @@ if __name__ == "__main__":
|
|
|
359
362
|
```python
|
|
360
363
|
import asyncio
|
|
361
364
|
from tetra_rp import remote, LiveServerless, GpuGroup, PodTemplate
|
|
365
|
+
import base64
|
|
362
366
|
|
|
363
367
|
# Advanced GPU configuration with consolidated template overrides
|
|
364
368
|
sd_config = LiveServerless(
|
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
tetra_rp/__init__.py,sha256=_D3Wbtv9tBh_WGS4Si5uQbsefL63GqqjoGTN3R8P6fA,769
|
|
2
|
-
tetra_rp/client.py,sha256=
|
|
3
|
-
tetra_rp/
|
|
2
|
+
tetra_rp/client.py,sha256=cJRDCzMcU7OMwvlFSV5thjOBMysRWnzHFGko-ebYHBI,3073
|
|
3
|
+
tetra_rp/config.py,sha256=9FYzouOam0PVoBIITpwHu1N5dGd1ueLHjWMaZYmdquI,760
|
|
4
|
+
tetra_rp/execute_class.py,sha256=pm-wupP_rGwlmS_3B5O2g8a5qINlVSWuGUc1E7pveUw,12075
|
|
4
5
|
tetra_rp/logger.py,sha256=gk5-PWp3k_GQ5DxndsRkBCX0jarp_3lgZ1oiTFuThQg,1125
|
|
6
|
+
tetra_rp/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
tetra_rp/cli/main.py,sha256=89rSSHWG9fxXFmCR0QzRIQUd9N_nvlEy3ImzQdGs8jw,2090
|
|
8
|
+
tetra_rp/cli/commands/__init__.py,sha256=gQ6tnU0Rvm0-ESWFUBU-KDl5dpNOpUTG509hXOQQjwY,27
|
|
9
|
+
tetra_rp/cli/commands/deploy.py,sha256=dznG7NI04ihfccn5YIjBbIxMRM19h-B60jTTWazGppc,10609
|
|
10
|
+
tetra_rp/cli/commands/init.py,sha256=smRqSrxSzW_Rh-HBOLDdxOw-SDVC6uNOWTJAjF078c4,3020
|
|
11
|
+
tetra_rp/cli/commands/resource.py,sha256=XMsSAYaCtw42tUz7vJsK53lZRrKX51fMMfQv8sdExlc,5679
|
|
12
|
+
tetra_rp/cli/commands/run.py,sha256=XHbsTqzgz48qA_I1rc9MiZAh2H2OKRMNr6JPOGVaoXI,3781
|
|
13
|
+
tetra_rp/cli/templates/advanced/main.py,sha256=gfPETln1Re0R7Ysd8WlMon1myFmCtpJk6k6a1AGnK0Q,1221
|
|
14
|
+
tetra_rp/cli/templates/advanced/utils.py,sha256=8BfZW2_qXS7bYyiO62KhEib_TqUfIxer2jqXoIctK1c,647
|
|
15
|
+
tetra_rp/cli/templates/basic/main.py,sha256=fItaje-ahvQKsvVcA_HNVCy0grw9fLb1kd07eU5jvAQ,677
|
|
16
|
+
tetra_rp/cli/templates/gpu-compute/main.py,sha256=x-8W2ciT_bnLACcdKrMPwX4HqkLCeX-RKC1E6IzXnAI,1602
|
|
17
|
+
tetra_rp/cli/templates/web-api/api.py,sha256=7ucd6Mg9Y3aVNuG21Jh_ToiBWe0R3NaYIN-dExaRN_U,2009
|
|
18
|
+
tetra_rp/cli/templates/web-api/main.py,sha256=lRu0CVbPuCfvVQrp5IQf4KlR1dpC70fd7J008GXmtvs,846
|
|
19
|
+
tetra_rp/cli/utils/__init__.py,sha256=Ytcdqe_Kzy37LSnsBj1Drkrx0Uo7TWExjQZ2mwW_nMg,27
|
|
20
|
+
tetra_rp/cli/utils/deployment.py,sha256=2hskoGEnZYTJMR2on37X4kaQEtBDCKoWK_7RQr1VEY0,5123
|
|
21
|
+
tetra_rp/cli/utils/skeleton.py,sha256=zOo1sudIPA8sJa3tToV-XpkJMdsMtYzYAqSv-QH9nq4,3184
|
|
5
22
|
tetra_rp/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
23
|
tetra_rp/core/api/__init__.py,sha256=oldrEKMwxYoBPLvPfVlaFS3wfUtTTxCN6-HzlpTh6vE,124
|
|
7
24
|
tetra_rp/core/api/runpod.py,sha256=3TTx1fkXMLZ2R5JCrQYPEn8dhdUsBt8i5OEwAfaKQ_k,10451
|
|
@@ -27,12 +44,13 @@ tetra_rp/core/utils/json.py,sha256=q0r7aEdfh8kKVeHGeh9fBDfuhHYNopSreislAMB6HhM,1
|
|
|
27
44
|
tetra_rp/core/utils/lru_cache.py,sha256=drwKg-DfLbeBRGTzuxKqNKMQq0EuZV15LMTZIOyZuVk,2618
|
|
28
45
|
tetra_rp/core/utils/singleton.py,sha256=lSXgEQGX9nzhrc05GMpThn9SHKG45iajBbSEtwCcNyI,632
|
|
29
46
|
tetra_rp/protos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
-
tetra_rp/protos/remote_execution.py,sha256=
|
|
47
|
+
tetra_rp/protos/remote_execution.py,sha256=InVGKgkShi-muoNjGz-l7-cBwOZzaTnBdFr6LhVE9JE,5482
|
|
31
48
|
tetra_rp/stubs/__init__.py,sha256=ozKsHs8q0T7o2qhQEquub9hqomh1Htys53mMraaRu2E,72
|
|
32
|
-
tetra_rp/stubs/live_serverless.py,sha256=
|
|
33
|
-
tetra_rp/stubs/registry.py,sha256=
|
|
49
|
+
tetra_rp/stubs/live_serverless.py,sha256=gIjhizgX5MDifxXo5JBONS3fmGipwRAgv9_sydc_cxU,4451
|
|
50
|
+
tetra_rp/stubs/registry.py,sha256=OdqAHFJIhPBAaR-S_spJNgRwpO96xEqhfAENhomqmI4,3235
|
|
34
51
|
tetra_rp/stubs/serverless.py,sha256=BM_a5Ml5VADBYu2WRNmo9qnicP8NnXDGl5ywifulbD0,947
|
|
35
|
-
tetra_rp-0.
|
|
36
|
-
tetra_rp-0.
|
|
37
|
-
tetra_rp-0.
|
|
38
|
-
tetra_rp-0.
|
|
52
|
+
tetra_rp-0.13.0.dist-info/METADATA,sha256=9IiJ4LYhMcTUkf2Qgp2U_rh8y8XdAK0WDGe8tWSFXpE,28182
|
|
53
|
+
tetra_rp-0.13.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
54
|
+
tetra_rp-0.13.0.dist-info/entry_points.txt,sha256=FJi3ytBLKCcyz4tXJhOM3XNKzTxpnl3AauiPH2lHvWY,48
|
|
55
|
+
tetra_rp-0.13.0.dist-info/top_level.txt,sha256=bBay7JTDwJXsTYvVjrwno9hnF-j0q272lk65f2AcPjU,9
|
|
56
|
+
tetra_rp-0.13.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|