Skip to content

Commit 5ca297a

Browse files
committed
DOModelDeployer documentation and cleanup
1 parent 52b5e77 commit 5ca297a

File tree

1 file changed

+42
-22
lines changed

1 file changed

+42
-22
lines changed

dse_do_utils/domodeldeployer.py

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@
99
from dse_do_utils.scenariomanager import ScenarioManager
1010
import time
1111
import pathlib
12+
import tempfile
1213

1314

1415
class DOModelDeployer(object):
15-
"""Deploys a DO Model in WML. For use in WS Cloud. Retrieves the model from the DO Model Builder.
16+
"""Deploys a DO Model in WML. For use in CPD 4.0. Retrieves the model from the DO Model Builder.
1617
1718
Usage::
1819
19-
md = DOModelDeployer(wml_credentials, project, model_name, scenario_name, deployment_name, deployment_description)
20+
md = DOModelDeployer(wml_credentials, model_name, scenario_name, space_name,
21+
deployment_name, deployment_description)
2022
deployment_uid = md.deploy_model()
2123
print(deployment_uid)
2224
@@ -25,13 +27,19 @@ class DOModelDeployer(object):
2527
def __init__(self, wml_credentials: Dict, model_name: str, scenario_name: str, space_name: str,
2628
package_paths: List[str]=[],
2729
file_paths: List[str]=[],
28-
deployment_name: str = 'xxx', deployment_description: str = 'xxx', project=None):
30+
deployment_name: str = 'xxx', deployment_description: str = 'xxx', project=None,
31+
tmp_dir: str = None):
2932
"""
3033
34+
:param wml_credentials
35+
:param model_name (str): name of DO Experiment
36+
:param scenario_name (str): name of scenario with the Python model
37+
:param space_name (str): name of deployment space
3138
:param package_paths (List[str]): list paths to packages that will be included. The 'stem' of the path, with all included files and folders will be included in the root of the deployment archive. E.g. "/userfs/MyPackageDevFolder/my_package" will result in the folder 'my_package' in the root of the archive. Components can be imported using `from my_package.my_module import MyClass`. WARNING: this feature doesn't work yet due to failing import.
3239
:param file_paths (List[str]): list paths to files that will be included along side the model. Components can be imported using `from my_file import MyClass`
3340
:param space_name (str): name of deployment space
3441
:param project (project_lib.Project): for WS Cloud, not required for CP4D on-prem. See ScenarioManager(). Used to connect to DO Experiment.
42+
:param tmp_dir (str): path to directory where the intermediate files will be written. Make sure this exists. Can be used for debugging to inspect the files. If None, will use `tempfile` to generate a temporary folder that will be cleaned up automatically.
3543
"""
3644
self.wml_credentials = wml_credentials
3745
self.project = project
@@ -43,9 +51,9 @@ def __init__(self, wml_credentials: Dict, model_name: str, scenario_name: str, s
4351

4452
self.package_paths = package_paths
4553
self.file_paths = file_paths
54+
self.tmp_dir = tmp_dir
4655

4756
# Initialize clients
48-
# self.client = WatsonMachineLearningAPIClient(wml_credentials)
4957
self.client = APIClient(wml_credentials)
5058
space_id = self.guid_from_space_name(space_name) # TODO: catch error if space_name cannot be found?
5159
result = self.client.set.default_space(space_id)
@@ -127,31 +135,39 @@ def deploy_model(self) -> str:
127135
Returns:
128136
deployment_uid (str): Deployment UID necessary to call the deployment.
129137
"""
130-
model_archive_file_path = self.create_model_archive()
131-
yaml_file_path = self.write_yaml_file("./main.yml")
132-
deployment_uid = self.deploy_archive(model_archive_file_path, yaml_file_path)
138+
if self.tmp_dir is None:
139+
with tempfile.TemporaryDirectory() as path:
140+
model_archive_file_path = self.create_model_archive(path)
141+
yaml_file_path = self.write_yaml_file(os.path.join(path, "main.yml"))
142+
deployment_uid = self.deploy_archive(model_archive_file_path, yaml_file_path)
143+
else:
144+
model_archive_file_path = self.create_model_archive(self.tmp_dir)
145+
yaml_file_path = self.write_yaml_file(os.path.join(self.tmp_dir, "main.yml"))
146+
deployment_uid = self.deploy_archive(model_archive_file_path, yaml_file_path)
133147
return deployment_uid
134148

135149
############################################
136150
# Create model archive
137151
############################################
138-
def create_model_archive(self):
139-
"""Creates a model archive on the default path:
152+
def create_model_archive(self, path: str):
153+
"""Creates a model archive on the path:
140154
The archive contains one .py file: the do-model surrounded by boilerplate code to process
141155
the inputs and outputs dictionaries.
142156
Steps:
143-
1. Creates a directory `model`
144-
2. Write a file `model/main.py`
145-
3. Creates an archive file from the model directory
157+
1. Write a file `path/main.py`
158+
2. Creates an archive file in path
159+
3. Adds the main.py
160+
4. Adds packages
161+
5. Adds (module) files
146162
"""
147-
path = self.create_model_directory()
148-
file_path = os.path.join(path, 'main.py')
149-
self.write_main_file(file_path)
150-
file_path = self.create_archive()
163+
164+
main_file_path = os.path.join(path, 'main.py')
165+
self.write_main_file(main_file_path)
166+
file_path = self.create_archive(main_file_path, path)
151167
return file_path
152168

153169
def create_model_directory(self) -> str:
154-
"""Create a directory in the default path.
170+
"""Create a directory 'model' in the default path.
155171
Will remove/clear first if exists.
156172
157173
Return:
@@ -188,16 +204,21 @@ def get_scenario(self):
188204
scenario = self.scenario_manager.get_do_scenario(self.model_name, self.scenario_name)
189205
return scenario
190206

191-
def create_archive(self):
207+
def create_archive(self, main_file_path: str, path: str):
192208
"""Create archive.
193209
For now assume one folder `model` with one file `main.py`
210+
211+
:param main_file_path: file path of main.py file
212+
:param path: folder where archive will be written
194213
"""
195214
def reset(tarinfo):
196215
tarinfo.uid = tarinfo.gid = 0
197216
tarinfo.uname = tarinfo.gname = "root"
198217
return tarinfo
199-
tar = tarfile.open("model.tar.gz", "w:gz")
200-
tar.add("model/main.py", arcname="main.py", filter=reset)
218+
tar_file_path = os.path.join(path, "model.tar.gz")
219+
tar = tarfile.open(tar_file_path, "w:gz")
220+
# tar.add("model/main.py", arcname="main.py", filter=reset)
221+
tar.add(main_file_path, arcname="main.py", filter=reset)
201222

202223
def filter_package(tarinfo):
203224
tarinfo.uid = tarinfo.gid = 0
@@ -217,8 +238,7 @@ def filter_package(tarinfo):
217238
tar.add(file_path, arcname=file_name, filter=filter_package)
218239

219240
tar.close()
220-
file_path = "./model.tar.gz" # TODO: avoid hard-coding
221-
return file_path
241+
return tar_file_path
222242

223243
#########################################################
224244
# Deploy model

0 commit comments

Comments
 (0)