88
88
"""
89
89
90
90
91
- def default_requirements (path_req : str = PATH_REQ_DEFAULT ) -> list :
91
+ def load_requirements (path_req : str = PATH_REQ_DEFAULT ) -> list :
92
+ """Load the requirements from a file."""
92
93
with open (path_req ) as fp :
93
94
req = fp .readlines ()
94
95
req = [r [: r .index ("#" )] if "#" in r else r for r in req ]
@@ -98,6 +99,7 @@ def default_requirements(path_req: str = PATH_REQ_DEFAULT) -> list:
98
99
99
100
100
101
def get_running_cuda_version () -> str :
102
+ """Extract the version of actual CUDA for this runtime."""
101
103
try :
102
104
import torch
103
105
@@ -107,6 +109,7 @@ def get_running_cuda_version() -> str:
107
109
108
110
109
111
def get_running_torch_version ():
112
+ """Extract the version of actual PyTorch for this runtime."""
110
113
try :
111
114
import torch
112
115
@@ -129,6 +132,7 @@ def get_running_torch_version():
129
132
130
133
131
134
class AssistantCLI :
135
+ """Collection of handy CLI commands."""
132
136
133
137
DEVICE_ACCELERATOR = os .environ .get ("ACCELERATOR" , "cpu" ).lower ()
134
138
DATASET_FOLDER = os .environ .get ("PATH_DATASETS" , "_datasets" ).lower ()
@@ -161,13 +165,24 @@ class AssistantCLI:
161
165
162
166
@staticmethod
163
167
def _find_meta (folder : str ) -> str :
168
+ """Search for a meta file in given folder and return its path.
169
+
170
+ Args:
171
+ folder: path to the folder with python script, meta and artefacts
172
+ """
164
173
files = glob .glob (os .path .join (folder , AssistantCLI ._META_FILE_REGEX ), flags = glob .BRACE )
165
174
if len (files ) == 1 :
166
175
return files [0 ]
167
176
return ""
168
177
169
178
@staticmethod
170
179
def _load_meta (folder : str , strict : bool = False ) -> Optional [dict ]:
180
+ """Loading meta data for a particular notebook with given folder path.
181
+
182
+ Args:
183
+ folder: path to the folder with python script, meta and artefacts
184
+ strict: raise error if meta is missing required feilds
185
+ """
171
186
fpath = AssistantCLI ._find_meta (folder )
172
187
assert fpath , f"Missing meta file in folder: { folder } "
173
188
meta = yaml .safe_load (open (fpath ))
@@ -180,6 +195,11 @@ def _load_meta(folder: str, strict: bool = False) -> Optional[dict]:
180
195
181
196
@staticmethod
182
197
def _valid_conf_folder (folder : str ) -> Tuple [str , str ]:
198
+ """Validate notebook folder if it has required meta file and optional thumb.
199
+
200
+ Args:
201
+ folder: path to the folder with python script, meta and artefacts
202
+ """
183
203
meta_files = [os .path .join (folder , f".meta.{ ext } " ) for ext in ("yml" , "yaml" )]
184
204
meta_files = [pf for pf in meta_files if os .path .isfile (pf )]
185
205
if len (meta_files ) != 1 :
@@ -193,6 +213,13 @@ def _valid_conf_folder(folder: str) -> Tuple[str, str]:
193
213
194
214
@staticmethod
195
215
def _valid_folder (folder : str , ext : str ) -> Tuple [str , str , str ]:
216
+ """Validate notebook folder if it has required meta file, python script or ipython notebook (depending on
217
+ the stage) and optional thumb.
218
+
219
+ Args:
220
+ folder: path to the folder with python script, meta and artefacts
221
+ ext: extension determining the stage - ".py" for python script nad ".ipynb" for notebook
222
+ """
196
223
files = glob .glob (os .path .join (folder , f"*{ ext } " ))
197
224
if len (files ) != 1 :
198
225
names = list (map (os .path .basename , files ))
@@ -202,9 +229,10 @@ def _valid_folder(folder: str, ext: str) -> Tuple[str, str, str]:
202
229
203
230
@staticmethod
204
231
def _valid_accelerator (folder : str ) -> bool :
205
- """Parse standard requirements from meta file
232
+ """Parse standard requirements from meta file.
233
+
206
234
Args:
207
- folder: path to the folder
235
+ folder: path to the folder with python script, meta and artefacts
208
236
"""
209
237
meta = AssistantCLI ._load_meta (folder )
210
238
meta_accels = [acc .lower () for acc in meta .get ("accelerator" , AssistantCLI ._META_ACCEL_DEFAULT )]
@@ -213,9 +241,10 @@ def _valid_accelerator(folder: str) -> bool:
213
241
214
242
@staticmethod
215
243
def _parse_requirements (folder : str ) -> Tuple [str , str ]:
216
- """Parse standard requirements from meta file
244
+ """Parse standard requirements from meta file.
245
+
217
246
Args:
218
- folder: path to the folder
247
+ folder: path to the folder with python script, meta and artefacts
219
248
"""
220
249
meta = AssistantCLI ._load_meta (folder )
221
250
req = meta .get ("requirements" , [])
@@ -237,6 +266,11 @@ def _parse_requirements(folder: str) -> Tuple[str, str]:
237
266
238
267
@staticmethod
239
268
def _bash_download_data (folder : str ) -> List [str ]:
269
+ """Generate sequence of commands fro optional downloading dataset specified in the meta file.
270
+
271
+ Args:
272
+ folder: path to the folder with python script, meta and artefacts
273
+ """
240
274
cmd = ["HERE=$PWD" , f"cd { AssistantCLI .DATASET_FOLDER } " ]
241
275
meta = AssistantCLI ._load_meta (folder )
242
276
datasets = meta .get ("datasets" , {})
@@ -260,6 +294,14 @@ def _bash_download_data(folder: str) -> List[str]:
260
294
261
295
@staticmethod
262
296
def bash_render (folder : str ) -> str :
297
+ """Prepare bash script for running rendering of a particular notebook.
298
+
299
+ Args:
300
+ folder: name/path to a folder with notebook files
301
+
302
+ Returns:
303
+ string with nash script content
304
+ """
263
305
cmd = list (AssistantCLI ._BASH_SCRIPT_BASE ) + [f"# Rendering: { folder } " ]
264
306
if not AssistantCLI .DRY_RUN :
265
307
cmd += AssistantCLI ._bash_download_data (folder )
@@ -295,6 +337,14 @@ def bash_render(folder: str) -> str:
295
337
296
338
@staticmethod
297
339
def bash_test (folder : str ) -> str :
340
+ """Prepare bash script for running tests of a particular notebook.
341
+
342
+ Args:
343
+ folder: name/path to a folder with notebook files
344
+
345
+ Returns:
346
+ string with nash script content
347
+ """
298
348
cmd = list (AssistantCLI ._BASH_SCRIPT_BASE ) + [f"# Testing: { folder } " ]
299
349
cmd += AssistantCLI ._bash_download_data (folder )
300
350
ipynb_file , _ , _ = AssistantCLI ._valid_folder (folder , ext = ".ipynb" )
@@ -337,7 +387,7 @@ def augment_script(folder: str) -> None:
337
387
meta ["description" ] = meta ["description" ].replace (os .linesep , f"{ os .linesep } # " )
338
388
339
389
header = TEMPLATE_HEADER % meta
340
- requires = set (default_requirements () + meta ["requirements" ])
390
+ requires = set (load_requirements () + meta ["requirements" ])
341
391
setup = TEMPLATE_SETUP % dict (requirements = " " .join ([f'"{ req } "' for req in requires ]))
342
392
py_script = [header + setup ] + py_script + [TEMPLATE_FOOTER ]
343
393
@@ -350,7 +400,8 @@ def augment_script(folder: str) -> None:
350
400
351
401
@staticmethod
352
402
def _replace_images (lines : list , local_dir : str ) -> list :
353
- """Update images by URL to GitHub raw source
403
+ """Update images by URL to GitHub raw source.
404
+
354
405
Args:
355
406
lines: string lines from python script
356
407
local_dir: relative path to the folder with script
@@ -381,6 +432,7 @@ def _replace_images(lines: list, local_dir: str) -> list:
381
432
382
433
@staticmethod
383
434
def _is_ipynb_parent_dir (dir_path : str ) -> bool :
435
+ """Determine in recursive fasion of a folder is valid notebook file or any of sub-folders is."""
384
436
if AssistantCLI ._find_meta (dir_path ):
385
437
return True
386
438
sub_dirs = [d for d in glob .glob (os .path .join (dir_path , "*" )) if os .path .isdir (d )]
@@ -395,7 +447,8 @@ def group_folders(
395
447
strict : bool = True ,
396
448
root_path : str = "" ,
397
449
) -> None :
398
- """Group changes by folders
450
+ """Group changes by folders.
451
+
399
452
Args:
400
453
fpath_gitdiff: raw git changes
401
454
@@ -557,7 +610,8 @@ def copy_notebooks(
557
610
558
611
@staticmethod
559
612
def update_env_details (dir_path : str ):
560
- """Export the actual packages used in runtime
613
+ """Export the actual packages used in runtime.
614
+
561
615
Args:
562
616
dir_path: path to the folder
563
617
"""
0 commit comments