accli 0.5__tar.gz → 0.5.2__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.
- {accli-0.5 → accli-0.5.2}/PKG-INFO +1 -3
- {accli-0.5 → accli-0.5.2}/README.md +0 -2
- {accli-0.5 → accli-0.5.2}/accli/AcceleratorJobProjectService.py +57 -30
- {accli-0.5 → accli-0.5.2}/accli/AcceleratorTaskDispatcher.py +63 -39
- {accli-0.5 → accli-0.5.2}/accli/AcceleratorTerminalCliProjectService.py +22 -9
- {accli-0.5 → accli-0.5.2}/accli/_version.py +1 -1
- {accli-0.5 → accli-0.5.2}/accli/cli.py +2 -2
- accli-0.5.2/accli/common.py +6 -0
- {accli-0.5 → accli-0.5.2}/accli/token.py +19 -0
- {accli-0.5 → accli-0.5.2}/accli.egg-info/PKG-INFO +1 -3
- {accli-0.5 → accli-0.5.2}/accli.egg-info/SOURCES.txt +1 -0
- {accli-0.5 → accli-0.5.2}/LICENSE +0 -0
- {accli-0.5 → accli-0.5.2}/accli/CsvRegionalTimeseriesValidator.py +0 -0
- {accli-0.5 → accli-0.5.2}/accli/__init__.py +0 -0
- {accli-0.5 → accli-0.5.2}/accli/__main__.py +0 -0
- {accli-0.5 → accli-0.5.2}/accli.egg-info/dependency_links.txt +0 -0
- {accli-0.5 → accli-0.5.2}/accli.egg-info/entry_points.txt +0 -0
- {accli-0.5 → accli-0.5.2}/accli.egg-info/requires.txt +0 -0
- {accli-0.5 → accli-0.5.2}/accli.egg-info/top_level.txt +0 -0
- {accli-0.5 → accli-0.5.2}/pyproject.toml +0 -0
- {accli-0.5 → accli-0.5.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: accli
|
|
3
|
-
Version: 0.5
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: IIASA Accelerator Client
|
|
5
5
|
Author-email: Wrufesh S <wrufesh@gmail.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -83,5 +83,3 @@ Please follow [this link.](https://packaging.python.org/en/latest/tutorials/pack
|
|
|
83
83
|
2. Run 'python scripts/tag.py'
|
|
84
84
|
3. `python -m build`
|
|
85
85
|
4. `twine upload -r pypi -u __token__ -p <password-or-token> ./dist/*`
|
|
86
|
-
|
|
87
|
-
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import io
|
|
3
|
+
import sys
|
|
3
4
|
import typing
|
|
4
5
|
import requests
|
|
5
6
|
import json
|
|
@@ -8,6 +9,8 @@ import urllib3
|
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
from typing import List, Tuple
|
|
10
11
|
|
|
12
|
+
from accli.common import todict
|
|
13
|
+
|
|
11
14
|
class AccAPIError(Exception):
|
|
12
15
|
pass
|
|
13
16
|
|
|
@@ -16,6 +19,9 @@ class AccAPIError(Exception):
|
|
|
16
19
|
# self.response_data = kwargs.pop('response_data')
|
|
17
20
|
# super().__init__(*args, **kwargs)
|
|
18
21
|
|
|
22
|
+
class UnhealthyControlServerError(Exception):
|
|
23
|
+
pass
|
|
24
|
+
|
|
19
25
|
retries = urllib3.util.Retry(total=10, backoff_factor=1)
|
|
20
26
|
|
|
21
27
|
http_client = urllib3.poolmanager.PoolManager(
|
|
@@ -47,15 +53,13 @@ class AcceleratorJobProjectService:
|
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
def http_client_request(self, *args, **kwargs):
|
|
56
|
+
|
|
50
57
|
res = self.http_client.request(*args, **kwargs)
|
|
51
58
|
|
|
52
59
|
if str(res.status)[0] in ['4', '5']:
|
|
53
60
|
raise AccAPIError(
|
|
54
61
|
f"Accelerator api error:: status_code={res.status} :: response_data={res.data}",
|
|
55
|
-
# status_code=res.status,
|
|
56
|
-
# response_data=res.data
|
|
57
62
|
)
|
|
58
|
-
|
|
59
63
|
return res
|
|
60
64
|
|
|
61
65
|
def get_file_stat(self, bucket_object_id):
|
|
@@ -64,7 +68,7 @@ class AcceleratorJobProjectService:
|
|
|
64
68
|
f"{self.cli_base_url}/file-stat/{bucket_object_id}",
|
|
65
69
|
headers=self.common_request_headers
|
|
66
70
|
)
|
|
67
|
-
return res.
|
|
71
|
+
return todict(res.data)
|
|
68
72
|
|
|
69
73
|
def get_file_url_from_repo(self, filename):
|
|
70
74
|
project_slug = filename.split('/')[0]
|
|
@@ -74,7 +78,7 @@ class AcceleratorJobProjectService:
|
|
|
74
78
|
headers=self.common_request_headers
|
|
75
79
|
)
|
|
76
80
|
if res.data:
|
|
77
|
-
return res.
|
|
81
|
+
return todict(res.data)
|
|
78
82
|
|
|
79
83
|
def get_dataset_type(self, *args, **kwargs):
|
|
80
84
|
return self.get_bucket_object_validation_type(*args, **kwargs)
|
|
@@ -86,7 +90,7 @@ class AcceleratorJobProjectService:
|
|
|
86
90
|
headers=self.common_request_headers
|
|
87
91
|
)
|
|
88
92
|
if res.data:
|
|
89
|
-
return res.
|
|
93
|
+
return todict(res.data)
|
|
90
94
|
|
|
91
95
|
def get_bucket_object_validation_details(self, bucket_object_id):
|
|
92
96
|
res = self.http_client_request(
|
|
@@ -95,7 +99,7 @@ class AcceleratorJobProjectService:
|
|
|
95
99
|
headers=self.common_request_headers
|
|
96
100
|
)
|
|
97
101
|
if res.data:
|
|
98
|
-
return res.
|
|
102
|
+
return todict(res.data)
|
|
99
103
|
|
|
100
104
|
|
|
101
105
|
def get_file_url(self, bucket_object_id):
|
|
@@ -106,7 +110,7 @@ class AcceleratorJobProjectService:
|
|
|
106
110
|
)
|
|
107
111
|
|
|
108
112
|
if res.data:
|
|
109
|
-
return res.
|
|
113
|
+
return todict(res.data)
|
|
110
114
|
|
|
111
115
|
|
|
112
116
|
def get_file_stream(self, bucket_object_id):
|
|
@@ -114,13 +118,33 @@ class AcceleratorJobProjectService:
|
|
|
114
118
|
if url:
|
|
115
119
|
resp = self.http_client_request("GET", url, preload_content=False)
|
|
116
120
|
return resp
|
|
121
|
+
|
|
122
|
+
def check_job_health(self):
|
|
123
|
+
try:
|
|
124
|
+
res = self.http_client_request(
|
|
125
|
+
"GET",
|
|
126
|
+
f"{self.cli_base_url}/is-healthy/",
|
|
127
|
+
headers=self.common_request_headers
|
|
128
|
+
)
|
|
129
|
+
if res.data:
|
|
130
|
+
res = todict(res.data)
|
|
131
|
+
except Exception as err:
|
|
132
|
+
raise UnhealthyControlServerError(str(err))
|
|
133
|
+
|
|
134
|
+
is_healthy = res['is_healthy']
|
|
135
|
+
return is_healthy
|
|
117
136
|
|
|
118
137
|
def add_log_file(self, data: bytes, filename):
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
138
|
+
try:
|
|
139
|
+
res = self.http_client_request(
|
|
140
|
+
"GET",
|
|
141
|
+
f"{self.cli_base_url}/presigned-log-upload-url/?filename={filename}",
|
|
142
|
+
headers=self.common_request_headers
|
|
143
|
+
)
|
|
144
|
+
if res.data:
|
|
145
|
+
res = todict(res.data)
|
|
146
|
+
except Exception as err:
|
|
147
|
+
raise UnhealthyControlServerError(str(err))
|
|
124
148
|
|
|
125
149
|
upload_url = res['upload_url']
|
|
126
150
|
app_bucket_id = res['app_bucket_id']
|
|
@@ -134,18 +158,21 @@ class AcceleratorJobProjectService:
|
|
|
134
158
|
verify=False,
|
|
135
159
|
)
|
|
136
160
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
161
|
+
try:
|
|
162
|
+
self.http_client_request(
|
|
163
|
+
"POST",
|
|
164
|
+
f"{self.cli_base_url}/register-log-file/",
|
|
165
|
+
json=dict(
|
|
166
|
+
filename=res_filename,
|
|
167
|
+
app_bucket_id=app_bucket_id
|
|
168
|
+
),
|
|
169
|
+
headers=self.common_request_headers
|
|
170
|
+
)
|
|
171
|
+
except Exception as err:
|
|
172
|
+
raise UnhealthyControlServerError(str(err))
|
|
146
173
|
|
|
147
174
|
if not is_healthy:
|
|
148
|
-
|
|
175
|
+
raise UnhealthyControlServerError('Unhealthy control server.')
|
|
149
176
|
|
|
150
177
|
|
|
151
178
|
|
|
@@ -168,7 +195,7 @@ class AcceleratorJobProjectService:
|
|
|
168
195
|
headers=self.common_request_headers
|
|
169
196
|
)
|
|
170
197
|
|
|
171
|
-
return res.
|
|
198
|
+
return todict(res.data)
|
|
172
199
|
|
|
173
200
|
def get_multipart_put_update_signed_url(
|
|
174
201
|
self,
|
|
@@ -187,7 +214,7 @@ class AcceleratorJobProjectService:
|
|
|
187
214
|
headers=self.common_request_headers
|
|
188
215
|
)
|
|
189
216
|
|
|
190
|
-
return res.
|
|
217
|
+
return todict(res.data)
|
|
191
218
|
|
|
192
219
|
def get_put_create_multipart_upload_id(self, filename):
|
|
193
220
|
res = self.http_client_request(
|
|
@@ -196,7 +223,7 @@ class AcceleratorJobProjectService:
|
|
|
196
223
|
headers=self.common_request_headers
|
|
197
224
|
)
|
|
198
225
|
|
|
199
|
-
data = res.
|
|
226
|
+
data = todict(res.data)
|
|
200
227
|
|
|
201
228
|
return data['upload_id'], data['app_bucket_id'], data['uniqified_filename']
|
|
202
229
|
|
|
@@ -207,7 +234,7 @@ class AcceleratorJobProjectService:
|
|
|
207
234
|
headers=self.common_request_headers
|
|
208
235
|
)
|
|
209
236
|
|
|
210
|
-
return res.
|
|
237
|
+
return todict(res.data)
|
|
211
238
|
|
|
212
239
|
def complete_job_multipart_upload(
|
|
213
240
|
self,
|
|
@@ -234,7 +261,7 @@ class AcceleratorJobProjectService:
|
|
|
234
261
|
headers=headers
|
|
235
262
|
)
|
|
236
263
|
|
|
237
|
-
return res.
|
|
264
|
+
return todict(res.data)
|
|
238
265
|
|
|
239
266
|
def complete_update_multipart_upload(
|
|
240
267
|
self, bucket_object_id, upload_id, parts: List[Tuple[str, str]]
|
|
@@ -344,7 +371,7 @@ class AcceleratorJobProjectService:
|
|
|
344
371
|
headers=headers
|
|
345
372
|
)
|
|
346
373
|
|
|
347
|
-
return res.
|
|
374
|
+
return todict(res.data)
|
|
348
375
|
|
|
349
376
|
|
|
350
377
|
|
|
@@ -555,7 +582,7 @@ class Fs:
|
|
|
555
582
|
|
|
556
583
|
@staticmethod
|
|
557
584
|
def get_file_url(remote_filepath):
|
|
558
|
-
user_token = os.environ.get("
|
|
585
|
+
user_token = os.environ.get("ACC_JOB_TOKEN", None)
|
|
559
586
|
server_url = os.environ.get("ACC_JOB_GATEWAY_SERVER", None)
|
|
560
587
|
|
|
561
588
|
if not (user_token and server_url):
|
|
@@ -1,37 +1,46 @@
|
|
|
1
1
|
import git
|
|
2
2
|
import os
|
|
3
|
+
import zipfile
|
|
3
4
|
import hashlib
|
|
4
5
|
import shutil
|
|
5
6
|
import tempfile
|
|
7
|
+
import requests
|
|
6
8
|
from typing import Optional, List, Dict
|
|
7
9
|
from pydantic.v1 import BaseModel, root_validator
|
|
8
|
-
|
|
9
|
-
from accli.token import get_github_app_token
|
|
10
|
+
from accli.AcceleratorTerminalCliProjectService import AcceleratorTerminalCliProjectService
|
|
11
|
+
from accli.token import get_github_app_token, get_token, get_server_url, get_project_slug
|
|
10
12
|
|
|
11
13
|
FOLDER_JOB_REPO_URL = 'https://github.com/IIASA-Accelerator/wkube-job.git'
|
|
12
14
|
|
|
13
|
-
def hash_folder(folder_path):
|
|
14
|
-
md5_hash = hashlib.md5()
|
|
15
|
-
sha256_hash = hashlib.sha256()
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
def compress_folder(folder_path, output_path):
|
|
17
|
+
# Fixed timestamp for normalization
|
|
18
|
+
fixed_time = (1980, 1, 1, 0, 0, 0)
|
|
19
|
+
|
|
20
|
+
with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
|
21
|
+
for root, dirs, files in os.walk(folder_path):
|
|
22
|
+
dirs.sort()
|
|
23
|
+
files.sort()
|
|
24
|
+
for file in files:
|
|
25
|
+
file_path = os.path.join(root, file)
|
|
26
|
+
arcname = os.path.relpath(file_path, start=folder_path)
|
|
27
|
+
# Add file to zip with fixed timestamp
|
|
28
|
+
info = zipfile.ZipInfo(arcname)
|
|
29
|
+
info.date_time = fixed_time
|
|
30
|
+
info.external_attr = 0o600 << 16 # Set file permissions
|
|
21
31
|
with open(file_path, 'rb') as f:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
md5_hash.update(chunk)
|
|
25
|
-
sha256_hash.update(chunk)
|
|
26
|
-
except IOError:
|
|
27
|
-
# Handle read error (if any)
|
|
28
|
-
print(f"Error reading file: {file_path}")
|
|
32
|
+
|
|
33
|
+
zipf.writestr(info, f.read(), zipfile.ZIP_DEFLATED)
|
|
29
34
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
def get_file_sha1(file_path):
|
|
36
|
+
sha1_hash = hashlib.sha1()
|
|
37
|
+
with open(file_path, "rb") as f:
|
|
38
|
+
chunk = f.read(8192)
|
|
39
|
+
while chunk:
|
|
40
|
+
sha1_hash.update(chunk)
|
|
41
|
+
chunk = f.read(8192)
|
|
42
|
+
return sha1_hash.hexdigest()
|
|
33
43
|
|
|
34
|
-
return md5_digest
|
|
35
44
|
|
|
36
45
|
def copy_tree(src, dst):
|
|
37
46
|
"""Recursively copy from src to dst, excluding .git folders."""
|
|
@@ -49,35 +58,50 @@ def copy_tree(src, dst):
|
|
|
49
58
|
|
|
50
59
|
def push_folder_job(dir):
|
|
51
60
|
|
|
61
|
+
access_token = get_token()
|
|
62
|
+
|
|
63
|
+
server_url = get_server_url()
|
|
64
|
+
|
|
65
|
+
project_slug = get_project_slug()
|
|
66
|
+
|
|
67
|
+
term_cli_project_service = AcceleratorTerminalCliProjectService(
|
|
68
|
+
user_token=access_token,
|
|
69
|
+
server_url=server_url,
|
|
70
|
+
verify_cert=False
|
|
71
|
+
)
|
|
72
|
+
|
|
52
73
|
repo_dir = tempfile.mkdtemp()
|
|
53
74
|
|
|
54
75
|
copy_tree(dir, repo_dir)
|
|
55
|
-
|
|
56
|
-
branch_name = hash_folder(repo_dir)
|
|
57
|
-
|
|
58
|
-
repo = git.Repo.init(repo_dir)
|
|
59
76
|
|
|
60
|
-
|
|
77
|
+
temp_zip_path = f"{repo_dir}/temp.zip"
|
|
61
78
|
|
|
62
|
-
|
|
63
|
-
|
|
79
|
+
compress_folder(repo_dir, temp_zip_path)
|
|
80
|
+
|
|
81
|
+
sha256_hash = get_file_sha1(temp_zip_path)
|
|
64
82
|
|
|
65
|
-
|
|
83
|
+
final_zip_path = f"{repo_dir}/{sha256_hash}.zip"
|
|
66
84
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
except git.exc.GitCommandError:
|
|
70
|
-
repo.git.checkout('-b', branch_name)
|
|
85
|
+
|
|
86
|
+
os.rename(temp_zip_path, final_zip_path)
|
|
71
87
|
|
|
72
|
-
|
|
88
|
+
presigned_push_url = term_cli_project_service.get_jobstore_push_url(
|
|
89
|
+
project_slug, f"{sha256_hash}.zip"
|
|
90
|
+
)
|
|
73
91
|
|
|
74
|
-
repo.index.commit(branch_name)
|
|
75
92
|
|
|
76
|
-
|
|
77
|
-
|
|
93
|
+
if presigned_push_url:
|
|
94
|
+
with open(final_zip_path, 'rb') as f:
|
|
95
|
+
requests.put(
|
|
96
|
+
presigned_push_url,
|
|
97
|
+
data=f,
|
|
98
|
+
verify=False,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
78
102
|
shutil.rmtree(repo_dir)
|
|
79
103
|
|
|
80
|
-
return
|
|
104
|
+
return f"s3accjobstore://{sha256_hash}.zip", sha256_hash
|
|
81
105
|
|
|
82
106
|
|
|
83
107
|
class JobDispatchModel(BaseModel):
|
|
@@ -204,7 +228,7 @@ class WKubeTask(GenericTask):
|
|
|
204
228
|
|
|
205
229
|
WKubeTaskPydantic(*t_args, **t_kwargs)
|
|
206
230
|
wkube_task_kwargs = WKubeTaskKwargs(*t_args, **t_kwargs)
|
|
207
|
-
wkube_task_meta.update(WKubeTaskMeta(*t_args, **t_kwargs).dict())
|
|
231
|
+
wkube_task_meta.update(WKubeTaskMeta(*t_args, **t_kwargs).dict(exclude_unset=True))
|
|
208
232
|
|
|
209
233
|
|
|
210
234
|
self.dispatch_model_task = JobDispatchModel(
|
|
@@ -212,7 +236,7 @@ class WKubeTask(GenericTask):
|
|
|
212
236
|
execute_cluster='WKUBE',
|
|
213
237
|
job_location='acc_native_jobs.dispatch_wkube_task',
|
|
214
238
|
job_args=[],
|
|
215
|
-
job_kwargs= wkube_task_kwargs.dict() if wkube_task_kwargs else dict(),
|
|
239
|
+
job_kwargs= wkube_task_kwargs.dict(exclude_unset=True) if wkube_task_kwargs else dict(),
|
|
216
240
|
**wkube_task_meta
|
|
217
241
|
)
|
|
218
242
|
|
|
@@ -7,7 +7,7 @@ import concurrent.futures
|
|
|
7
7
|
from typing import List, Tuple
|
|
8
8
|
from rich.progress import Progress
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
from accli.common import todict
|
|
11
11
|
|
|
12
12
|
class AccAPIError(Exception):
|
|
13
13
|
|
|
@@ -76,7 +76,7 @@ class AcceleratorTerminalCliProjectService:
|
|
|
76
76
|
else:
|
|
77
77
|
raise err
|
|
78
78
|
|
|
79
|
-
return res.
|
|
79
|
+
return todict(res.data)
|
|
80
80
|
|
|
81
81
|
def get_file_url_from_repo(self, filename):
|
|
82
82
|
project_slug = filename.split('/')[0]
|
|
@@ -86,7 +86,7 @@ class AcceleratorTerminalCliProjectService:
|
|
|
86
86
|
headers=self.common_request_headers
|
|
87
87
|
)
|
|
88
88
|
if res.data:
|
|
89
|
-
return res.
|
|
89
|
+
return todict(res.data)
|
|
90
90
|
|
|
91
91
|
def get_github_app_token(self, project_slug):
|
|
92
92
|
|
|
@@ -96,7 +96,20 @@ class AcceleratorTerminalCliProjectService:
|
|
|
96
96
|
headers=self.common_request_headers
|
|
97
97
|
)
|
|
98
98
|
|
|
99
|
-
return res.
|
|
99
|
+
return todict(res.data)
|
|
100
|
+
|
|
101
|
+
def get_jobstore_push_url(self, project_slug, filename):
|
|
102
|
+
|
|
103
|
+
res = self.http_client_request(
|
|
104
|
+
"GET",
|
|
105
|
+
f"{self.cli_base_url}/{project_slug}/jobstore-push-url/?filename={filename}",
|
|
106
|
+
headers=self.common_request_headers
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
if res.status == 409 or res.status == '409':
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
return todict(res.data)
|
|
100
113
|
|
|
101
114
|
def dispatch(self, project_slug, job_description):
|
|
102
115
|
|
|
@@ -110,7 +123,7 @@ class AcceleratorTerminalCliProjectService:
|
|
|
110
123
|
except AccAPIError as err:
|
|
111
124
|
raise err
|
|
112
125
|
|
|
113
|
-
return res.
|
|
126
|
+
return todict(res.data)['job_id']
|
|
114
127
|
|
|
115
128
|
def get_dataset_template_details(self, project_slug, template_slug):
|
|
116
129
|
|
|
@@ -125,7 +138,7 @@ class AcceleratorTerminalCliProjectService:
|
|
|
125
138
|
else:
|
|
126
139
|
raise err
|
|
127
140
|
|
|
128
|
-
return res.
|
|
141
|
+
return todict(res.data)
|
|
129
142
|
|
|
130
143
|
|
|
131
144
|
def get_multipart_put_create_signed_url(
|
|
@@ -148,7 +161,7 @@ class AcceleratorTerminalCliProjectService:
|
|
|
148
161
|
headers=self.common_request_headers
|
|
149
162
|
)
|
|
150
163
|
|
|
151
|
-
return res.
|
|
164
|
+
return todict(res.data)
|
|
152
165
|
|
|
153
166
|
|
|
154
167
|
|
|
@@ -162,7 +175,7 @@ class AcceleratorTerminalCliProjectService:
|
|
|
162
175
|
headers=self.common_request_headers
|
|
163
176
|
)
|
|
164
177
|
|
|
165
|
-
data = res.
|
|
178
|
+
data = todict(res.data)
|
|
166
179
|
|
|
167
180
|
return data['upload_id'], data['app_bucket_id'], data['uniqified_filename']
|
|
168
181
|
|
|
@@ -191,7 +204,7 @@ class AcceleratorTerminalCliProjectService:
|
|
|
191
204
|
headers=headers
|
|
192
205
|
)
|
|
193
206
|
|
|
194
|
-
return res.
|
|
207
|
+
return todict(res.data)
|
|
195
208
|
|
|
196
209
|
|
|
197
210
|
def abort_create_multipart_upload(self, project_slug, app_bucket_id, filename, upload_id):
|
|
@@ -9,7 +9,7 @@ import importlib.util
|
|
|
9
9
|
from rich import print
|
|
10
10
|
from typing_extensions import Annotated
|
|
11
11
|
|
|
12
|
-
from accli.token import save_token_details, get_token, get_server_url, set_github_app_token
|
|
12
|
+
from accli.token import save_token_details, get_token, get_server_url, set_github_app_token, set_project_slug
|
|
13
13
|
|
|
14
14
|
from accli.CsvRegionalTimeseriesValidator import CsvRegionalTimeseriesValidator
|
|
15
15
|
from ._version import VERSION
|
|
@@ -181,7 +181,7 @@ def dispatch(
|
|
|
181
181
|
root_task_variable: Annotated[str, typer.Argument(help="Root task variable in workflow_file.")],
|
|
182
182
|
server: Annotated[str, typer.Option(help="Accelerator server url.")] = "https://accelerator-api.iiasa.ac.at",
|
|
183
183
|
):
|
|
184
|
-
|
|
184
|
+
set_project_slug(project_slug)
|
|
185
185
|
access_token = get_token()
|
|
186
186
|
|
|
187
187
|
server_url = get_server_url()
|
|
@@ -61,6 +61,25 @@ def set_github_app_token(github_app_token):
|
|
|
61
61
|
db = TinyDB(db_path)
|
|
62
62
|
db.update({'github_app_token': github_app_token}, doc_ids=[1])
|
|
63
63
|
|
|
64
|
+
def set_project_slug(project_slug):
|
|
65
|
+
db_path = get_db_path()
|
|
66
|
+
db = TinyDB(db_path)
|
|
67
|
+
db.update({'project_slug': project_slug}, doc_ids=[1])
|
|
68
|
+
|
|
69
|
+
def get_project_slug():
|
|
70
|
+
db_path = get_db_path()
|
|
71
|
+
|
|
72
|
+
db = TinyDB(db_path)
|
|
73
|
+
|
|
74
|
+
for item in db:
|
|
75
|
+
project_slug = item.get('project_slug')
|
|
76
|
+
if project_slug:
|
|
77
|
+
break
|
|
78
|
+
|
|
79
|
+
if not project_slug:
|
|
80
|
+
print("project slug was not set.")
|
|
81
|
+
return project_slug
|
|
82
|
+
|
|
64
83
|
|
|
65
84
|
def get_server_url():
|
|
66
85
|
db_path = get_db_path()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: accli
|
|
3
|
-
Version: 0.5
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: IIASA Accelerator Client
|
|
5
5
|
Author-email: Wrufesh S <wrufesh@gmail.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -83,5 +83,3 @@ Please follow [this link.](https://packaging.python.org/en/latest/tutorials/pack
|
|
|
83
83
|
2. Run 'python scripts/tag.py'
|
|
84
84
|
3. `python -m build`
|
|
85
85
|
4. `twine upload -r pypi -u __token__ -p <password-or-token> ./dist/*`
|
|
86
|
-
|
|
87
|
-
|
|
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
|