trainml 0.5.13__py3-none-any.whl → 0.5.15__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.
- tests/integration/cloudbender/conftest.py +28 -0
- tests/integration/cloudbender/test_providers_integration.py +3 -8
- tests/integration/cloudbender/test_regions_integration.py +42 -0
- tests/integration/cloudbender/test_services_integration.py +87 -0
- tests/integration/conftest.py +1 -1
- tests/integration/projects/conftest.py +2 -1
- tests/integration/projects/test_projects_credentials_integration.py +1 -0
- tests/integration/projects/test_projects_data_connectors_integration.py +1 -0
- tests/integration/projects/test_projects_datastores_integration.py +1 -0
- tests/integration/projects/test_projects_integration.py +1 -0
- tests/integration/projects/test_projects_members_integration.py +50 -0
- tests/integration/projects/test_projects_secrets_integration.py +1 -0
- tests/integration/projects/test_projects_services_integration.py +1 -0
- tests/integration/test_checkpoints_integration.py +1 -0
- tests/integration/test_datasets_integration.py +1 -0
- tests/integration/test_jobs_integration.py +13 -8
- tests/integration/test_models_integration.py +1 -0
- tests/integration/test_volumes_integration.py +1 -0
- tests/unit/projects/test_project_members_unit.py +107 -0
- trainml/__init__.py +1 -1
- trainml/auth.py +1 -1
- trainml/cli/job/create.py +32 -2
- trainml/cloudbender/services.py +19 -1
- trainml/jobs.py +9 -0
- trainml/projects/members.py +98 -0
- trainml/projects/projects.py +2 -0
- trainml/projects/services.py +17 -0
- trainml/trainml.py +37 -20
- {trainml-0.5.13.dist-info → trainml-0.5.15.dist-info}/METADATA +1 -1
- {trainml-0.5.13.dist-info → trainml-0.5.15.dist-info}/RECORD +34 -33
- tests/integration/projects/test_projects_keys_integration.py +0 -43
- tests/unit/cli/projects/test_cli_project_key_unit.py +0 -26
- tests/unit/projects/test_project_keys_unit.py +0 -96
- trainml/cli/project/key.py +0 -124
- trainml/projects/keys.py +0 -71
- {trainml-0.5.13.dist-info → trainml-0.5.15.dist-info}/LICENSE +0 -0
- {trainml-0.5.13.dist-info → trainml-0.5.15.dist-info}/WHEEL +0 -0
- {trainml-0.5.13.dist-info → trainml-0.5.15.dist-info}/entry_points.txt +0 -0
- {trainml-0.5.13.dist-info → trainml-0.5.15.dist-info}/top_level.txt +0 -0
trainml/cli/project/key.py
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
import os
|
|
3
|
-
import json
|
|
4
|
-
import base64
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from trainml.cli import pass_config
|
|
7
|
-
from trainml.cli.project import project
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@project.group()
|
|
11
|
-
@pass_config
|
|
12
|
-
def key(config):
|
|
13
|
-
"""trainML project key commands."""
|
|
14
|
-
pass
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@key.command()
|
|
18
|
-
@pass_config
|
|
19
|
-
def list(config):
|
|
20
|
-
"""List keys."""
|
|
21
|
-
data = [
|
|
22
|
-
["TYPE", "KEY ID", "UPDATED AT"],
|
|
23
|
-
[
|
|
24
|
-
"-" * 80,
|
|
25
|
-
"-" * 80,
|
|
26
|
-
"-" * 80,
|
|
27
|
-
],
|
|
28
|
-
]
|
|
29
|
-
project = config.trainml.run(config.trainml.client.projects.get_current())
|
|
30
|
-
keys = config.trainml.run(project.keys.list())
|
|
31
|
-
|
|
32
|
-
for key in keys:
|
|
33
|
-
data.append(
|
|
34
|
-
[
|
|
35
|
-
key.type,
|
|
36
|
-
key.key_id,
|
|
37
|
-
key.updated_at.isoformat(timespec="seconds"),
|
|
38
|
-
]
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
for row in data:
|
|
42
|
-
click.echo(
|
|
43
|
-
"{: >13.11} {: >37.35} {: >28.26}" "".format(*row),
|
|
44
|
-
file=config.stdout,
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@key.command()
|
|
49
|
-
@click.argument(
|
|
50
|
-
"type",
|
|
51
|
-
type=click.Choice(
|
|
52
|
-
[
|
|
53
|
-
"aws",
|
|
54
|
-
"azure",
|
|
55
|
-
"docker",
|
|
56
|
-
"gcp",
|
|
57
|
-
"huggingface",
|
|
58
|
-
"kaggle",
|
|
59
|
-
"ngc",
|
|
60
|
-
"wasabi",
|
|
61
|
-
],
|
|
62
|
-
case_sensitive=False,
|
|
63
|
-
),
|
|
64
|
-
)
|
|
65
|
-
@pass_config
|
|
66
|
-
def put(config, type):
|
|
67
|
-
"""
|
|
68
|
-
Set a key.
|
|
69
|
-
|
|
70
|
-
A key is uploaded.
|
|
71
|
-
"""
|
|
72
|
-
project = config.trainml.run(config.trainml.client.projects.get_current())
|
|
73
|
-
|
|
74
|
-
tenant = None
|
|
75
|
-
|
|
76
|
-
if type in ["aws", "wasabi"]:
|
|
77
|
-
key_id = click.prompt("Enter the key ID", type=str, hide_input=False)
|
|
78
|
-
secret = click.prompt("Enter the secret key", type=str, hide_input=True)
|
|
79
|
-
elif type == "azure":
|
|
80
|
-
key_id = click.prompt(
|
|
81
|
-
"Enter the Application (client) ID", type=str, hide_input=False
|
|
82
|
-
)
|
|
83
|
-
tenant = click.prompt(
|
|
84
|
-
"Enter the Directory (tenant) ley", type=str, hide_input=False
|
|
85
|
-
)
|
|
86
|
-
secret = click.prompt("Enter the client secret", type=str, hide_input=True)
|
|
87
|
-
elif type in ["docker", "huggingface"]:
|
|
88
|
-
key_id = click.prompt("Enter the username", type=str, hide_input=False)
|
|
89
|
-
secret = click.prompt("Enter the access token", type=str, hide_input=True)
|
|
90
|
-
elif type in ["gcp", "kaggle"]:
|
|
91
|
-
file_name = click.prompt(
|
|
92
|
-
"Enter the path of the credentials file",
|
|
93
|
-
type=click.Path(
|
|
94
|
-
exists=True, file_okay=True, dir_okay=False, resolve_path=True
|
|
95
|
-
),
|
|
96
|
-
hide_input=False,
|
|
97
|
-
)
|
|
98
|
-
key_id = os.path.basename(file_name)
|
|
99
|
-
with open(file_name) as f:
|
|
100
|
-
secret = json.load(f)
|
|
101
|
-
secret = json.dumps(secret)
|
|
102
|
-
elif type == "ngc":
|
|
103
|
-
key_id = "$oauthtoken"
|
|
104
|
-
secret = click.prompt("Enter the access token", type=str, hide_input=True)
|
|
105
|
-
else:
|
|
106
|
-
raise click.UsageError("Unsupported key type")
|
|
107
|
-
|
|
108
|
-
return config.trainml.run(
|
|
109
|
-
project.keys.put(type=type, key_id=key_id, secret=secret, tenant=tenant)
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
@key.command()
|
|
114
|
-
@click.argument("name", type=click.STRING)
|
|
115
|
-
@pass_config
|
|
116
|
-
def remove(config, name):
|
|
117
|
-
"""
|
|
118
|
-
Remove a key.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"""
|
|
122
|
-
project = config.trainml.run(config.trainml.client.projects.get_current())
|
|
123
|
-
|
|
124
|
-
return config.trainml.run(project.key.remove(name))
|
trainml/projects/keys.py
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
from dateutil import parser, tz
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class ProjectKeys(object):
|
|
8
|
-
def __init__(self, trainml, project_id):
|
|
9
|
-
self.trainml = trainml
|
|
10
|
-
self.project_id = project_id
|
|
11
|
-
|
|
12
|
-
async def list(self, **kwargs):
|
|
13
|
-
resp = await self.trainml._query(
|
|
14
|
-
f"/project/{self.project_id}/keys", "GET", kwargs
|
|
15
|
-
)
|
|
16
|
-
keys = [ProjectKey(self.trainml, **service) for service in resp]
|
|
17
|
-
return keys
|
|
18
|
-
|
|
19
|
-
async def put(self, type, key_id, secret, tenant=None, **kwargs):
|
|
20
|
-
data = dict(key_id=key_id, secret=secret, tenant=tenant)
|
|
21
|
-
payload = {k: v for k, v in data.items() if v is not None}
|
|
22
|
-
logging.info(f"Creating Project Key {type}")
|
|
23
|
-
resp = await self.trainml._query(
|
|
24
|
-
f"/project/{self.project_id}/key/{type}", "PUT", None, payload
|
|
25
|
-
)
|
|
26
|
-
key = ProjectKey(self.trainml, **resp)
|
|
27
|
-
logging.info(f"Created Project Key {type} in project {self.project_id}")
|
|
28
|
-
|
|
29
|
-
return key
|
|
30
|
-
|
|
31
|
-
async def remove(self, type, **kwargs):
|
|
32
|
-
await self.trainml._query(
|
|
33
|
-
f"/project/{self.project_id}/key/{type}", "DELETE", kwargs
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class ProjectKey:
|
|
38
|
-
def __init__(self, trainml, **kwargs):
|
|
39
|
-
self.trainml = trainml
|
|
40
|
-
self._entity = kwargs
|
|
41
|
-
self._type = self._entity.get("type")
|
|
42
|
-
self._project_uuid = self._entity.get("project_uuid")
|
|
43
|
-
self._key_id = self._entity.get("key_id")
|
|
44
|
-
self._updated_at = self._entity.get("updatedAt")
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def type(self) -> str:
|
|
48
|
-
return self._type
|
|
49
|
-
|
|
50
|
-
@property
|
|
51
|
-
def project_uuid(self) -> str:
|
|
52
|
-
return self._project_uuid
|
|
53
|
-
|
|
54
|
-
@property
|
|
55
|
-
def key_id(self) -> str:
|
|
56
|
-
return self._key_id
|
|
57
|
-
|
|
58
|
-
@property
|
|
59
|
-
def updated_at(self) -> datetime:
|
|
60
|
-
timestamp = parser.isoparse(self._updated_at)
|
|
61
|
-
timezone = tz.tzlocal()
|
|
62
|
-
return timestamp.astimezone(timezone)
|
|
63
|
-
|
|
64
|
-
def __str__(self):
|
|
65
|
-
return json.dumps({k: v for k, v in self._entity.items()})
|
|
66
|
-
|
|
67
|
-
def __repr__(self):
|
|
68
|
-
return f"ProjectKey( trainml , **{self._entity.__repr__()})"
|
|
69
|
-
|
|
70
|
-
def __bool__(self):
|
|
71
|
-
return bool(self._type)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|