Skip to content

Commit

Permalink
Merge pull request #162 from datmo/environment
Browse files Browse the repository at this point in the history
environment update and addition of cli environment command
  • Loading branch information
asampat3090 committed Jun 2, 2018
2 parents ff7b1e2 + f11ac97 commit 211fc15
Show file tree
Hide file tree
Showing 42 changed files with 1,362 additions and 836 deletions.
1 change: 0 additions & 1 deletion datmo/cli/command/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ def execute(self):
ClassMethodNotFound
If the Class method is not found
"""

# Sometimes eg(--help) the parser automagically handles the entire response
# and calls exit. If this happens, self.args is set to True
# in base.parse. Simply return True
Expand Down
54 changes: 54 additions & 0 deletions datmo/cli/command/environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from __future__ import print_function

import prettytable

from datmo.core.util.i18n import get as __
from datmo.core.controller.environment.environment import EnvironmentController
from datmo.core.util.misc_functions import printable_string
from datmo.cli.command.project import ProjectCommand


class EnvironmentCommand(ProjectCommand):
def __init__(self, home, cli_helper):
super(EnvironmentCommand, self).__init__(home, cli_helper)
# dest="subcommand" argument will populate a "subcommand" property with the subparsers name
# example "subcommand"="create" or "subcommand"="ls"
self.environment_controller = EnvironmentController(home=home)

def environment(self):
self.parse(["--help"])
return True

def create(self, **kwargs):
self.cli_helper.echo(__("info", "cli.environment.create"))
environment_obj = self.environment_controller.create(kwargs)
created_environment_id = environment_obj.id
environments = self.environment_controller.list()
for environment_obj in environments:
if created_environment_id == environment_obj.id:
self.cli_helper.echo(__("info", "cli.environment.create.alreadyexist", created_environment_id))
return created_environment_id
self.cli_helper.echo(__("info", "cli.environment.create.success", environment_obj.id))
return created_environment_id

def delete(self, **kwargs):
environment_id = kwargs.get('environment_id')
if self.environment_controller.delete(environment_id):
self.cli_helper.echo(__("info", "cli.environment.delete.success", environment_id))
return True

def ls(self):
environments = self.environment_controller.list()
header_list = ["id", "created at", "message"]
t = prettytable.PrettyTable(header_list)
environment_ids = []
for environment_obj in environments:
environment_ids.append(environment_obj.id)
environment_created_at = printable_string(
environment_obj.created_at.strftime("%Y-%m-%d %H:%M:%S"))
environment_message = printable_string(environment_obj.description) \
if environment_obj.description is not None else ''
t.add_row([environment_obj.id, environment_created_at, environment_message])

self.cli_helper.echo(t)
return environment_ids
29 changes: 18 additions & 11 deletions datmo/cli/command/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ def create(self, **kwargs):
if task_id is not None:
excluded_args = [
"code_id", "commit_id", "environment_id",
"environment_definition_filepath", "file_collection_id",
"filepaths", "config_filepath", "config_filename",
"stats_filepath", "stats_filename"
"environment_definition_paths", "file_collection_id", "paths",
"config_filepath", "config_filename", "stats_filepath",
"stats_filename"
]
for arg in excluded_args:
if arg in kwargs and kwargs[arg] is not None:
Expand All @@ -60,17 +60,17 @@ def create(self, **kwargs):

# Environment
if kwargs.get("environment_id", None) or kwargs.get(
"environment_definition_filepath", None):
"environment_definition_paths", None):
mutually_exclusive_args = [
"environment_id", "environment_definition_filepath"
"environment_id", "environment_definition_paths"
]
mutually_exclusive(mutually_exclusive_args, kwargs,
snapshot_dict)

# File
if kwargs.get("file_collection_id", None) or kwargs.get(
"filepaths", None):
mutually_exclusive_args = ["file_collection_id", "filepaths"]
"paths", None):
mutually_exclusive_args = ["file_collection_id", "paths"]
mutually_exclusive(mutually_exclusive_args, kwargs,
snapshot_dict)

Expand All @@ -94,7 +94,9 @@ def create(self, **kwargs):
# Stats
if kwargs.get("stats_filepath", None) or kwargs.get(
"stats_filename", None) or kwargs.get("config", None):
mutually_exclusive_args = ["stats_filepath", "stats_filename", "stats"]
mutually_exclusive_args = [
"stats_filepath", "stats_filename", "stats"
]
mutually_exclusive(mutually_exclusive_args, kwargs,
snapshot_dict)
# parsing stats
Expand Down Expand Up @@ -159,7 +161,11 @@ def update(self, **kwargs):
label = kwargs.get("label", None)

result = self.snapshot_controller.update(
snapshot_id, config=config, stats=stats, message=message, label=label)
snapshot_id,
config=config,
stats=stats,
message=message,
label=label)
self.cli_helper.echo(
__("info", "cli.snapshot.update.success", snapshot_id))
return result
Expand Down Expand Up @@ -189,7 +195,8 @@ def ls(self, **kwargs):
str(snapshot_obj.stats))
snapshot_message = printable_string(snapshot_obj.message)
t.add_row([
snapshot_obj.id, prettify_datetime(snapshot_obj.created_at),
snapshot_obj.id,
prettify_datetime(snapshot_obj.created_at),
snapshot_config_printable, snapshot_stats_printable,
snapshot_message, snapshot_obj.label, snapshot_obj.code_id,
snapshot_obj.environment_id,
Expand Down Expand Up @@ -255,4 +262,4 @@ def inspect(self, **kwargs):
snapshot_id = kwargs.get("id", None)
snapshot_obj = self.snapshot_controller.get(snapshot_id)
self.cli_helper.echo(str(snapshot_obj))
return True
return True
6 changes: 3 additions & 3 deletions datmo/cli/command/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ def run(self, **kwargs):

# Create input dictionaries
snapshot_dict = {}
if kwargs['environment_definition_filepath']:
snapshot_dict["environment_definition_filepath"] =\
kwargs['environment_definition_filepath']
if kwargs['environment_definition_paths']:
snapshot_dict["environment_definition_paths"] =\
kwargs['environment_definition_paths']
task_dict = {
"ports": kwargs['ports'],
"interactive": kwargs['interactive']
Expand Down
146 changes: 146 additions & 0 deletions datmo/cli/command/tests/test_environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
"""
Tests for EnvironmentCommand
"""
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import uuid
import tempfile
import shutil
import platform
try:
to_unicode = unicode
except NameError:
to_unicode = str

import os
from datmo.cli.driver.helper import Helper
from datmo.cli.command.environment import EnvironmentCommand
from datmo.cli.command.project import ProjectCommand
from datmo.core.util.misc_functions import pytest_docker_environment_failed_instantiation

# provide mountable tmp directory for docker
tempfile.tempdir = "/tmp" if not platform.system() == "Windows" else None
test_datmo_dir = os.environ.get('TEST_DATMO_DIR', tempfile.gettempdir())


class TestEnvironment():
def setup_class(self):
self.temp_dir = tempfile.mkdtemp(dir=test_datmo_dir)
self.cli_helper = Helper()

def teardown_class(self):
pass

def __set_variables(self):
self.project = ProjectCommand(self.temp_dir, self.cli_helper)
self.project.parse(
["init", "--name", "foobar", "--description", "test model"])
self.project.execute()
self.environment_command = EnvironmentCommand(self.temp_dir,
self.cli_helper)

def test_environment_create(self):
# 1) Environment definition file in `datmo_environment` folder
# 2) Environment definition file passed as an option
# 3) Environment definition file in root project folder
# 4) Environment definition file in root project folder (should return the same environment)
# 5) No environment definition file present
# 6) No environment definition file present (should return the same environment)
self.__set_variables()
# Test option 1
# Create environment definition in `datmo_environment` folder
datmo_environment_folder = os.path.join(self.temp_dir,
"datmo_environment")
os.makedirs(datmo_environment_folder)

definition_filepath = os.path.join(datmo_environment_folder,
"Dockerfile")
random_text = str(uuid.uuid1())
with open(definition_filepath, "w") as f:
f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
f.write(to_unicode(str("RUN echo " + random_text)))

self.environment_command.parse(["environment", "create"])
result = self.environment_command.execute()

assert result

# remove datmo_environment directory
shutil.rmtree(datmo_environment_folder)

# Test option 2
random_datmo_environment_folder = os.path.join(self.temp_dir,
"random_datmo_dir")
os.makedirs(random_datmo_environment_folder)

definition_filepath = os.path.join(random_datmo_environment_folder,
"Dockerfile")
random_text = str(uuid.uuid1())
with open(definition_filepath, "w") as f:
f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
f.write(to_unicode(str("RUN echo " + random_text)))

self.environment_command.parse([
"environment", "create", "--environment-def", definition_filepath
])
result = self.environment_command.execute()

assert result

# remove datmo environment directory
shutil.rmtree(random_datmo_environment_folder)

# Test option 3
definition_filepath = os.path.join(self.temp_dir, "Dockerfile")
random_text = str(uuid.uuid1())
with open(definition_filepath, "w") as f:
f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
f.write(to_unicode(str("RUN echo " + random_text)))

self.environment_command.parse(["environment", "create"])
result = self.environment_command.execute()

assert result

# Test option 4
self.environment_command.parse(["environment", "create"])
result_2 = self.environment_command.execute()
assert result == result_2

os.remove(definition_filepath)

# Test option 5
self.environment_command.parse(["environment", "create"])
result = self.environment_command.execute()

assert result

# Test option 6
self.environment_command.parse(["environment", "create"])
result_2 = self.environment_command.execute()

assert result == result_2

@pytest_docker_environment_failed_instantiation(test_datmo_dir)
def test_environment_delete(self):
self.__set_variables()
self.environment_command.parse(["environment", "create"])
environment_id = self.environment_command.execute()

self.environment_command.parse(
["environment", "delete", "--id", environment_id])
result = self.environment_command.execute()

assert result

def test_environment_ls(self):
self.__set_variables()
self.environment_command.parse(["environment", "create"])
environment_id = self.environment_command.execute()

self.environment_command.parse(["environment", "ls"])
environment_ids = self.environment_command.execute()

assert environment_id in environment_ids
2 changes: 1 addition & 1 deletion datmo/cli/command/tests/test_session.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Tests for SessopmCommand
Tests for SessionCommand
"""
from __future__ import division
from __future__ import print_function
Expand Down

0 comments on commit 211fc15

Please sign in to comment.