Skip to content

Commit e72f5e8

Browse files
authored
2 parents 0918546 + 7511dee commit e72f5e8

File tree

12 files changed

+163
-41
lines changed

12 files changed

+163
-41
lines changed

CHANGELOG.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,47 @@
11
# Changelog
22

3+
## v1.44.3 (2019-11-26)
4+
5+
### Bug fixes and other changes
6+
7+
* move sagemaker config loading to LocalSession since it is only used for local code support.
8+
9+
### Documentation changes
10+
11+
* fix docstring wording.
12+
13+
## v1.44.2 (2019-11-25)
14+
15+
### Bug fixes and other changes
16+
17+
* add pyyaml dependencies to the required list.
18+
19+
### Documentation changes
20+
21+
* Correct info on code_location parameter
22+
23+
## v1.44.1 (2019-11-21)
24+
25+
### Bug fixes and other changes
26+
27+
* Remove local mode dependencies from required.
28+
29+
## v1.44.0 (2019-11-21)
30+
31+
### Features
32+
33+
* separating sagemaker dependencies into more use case specific installable components.
34+
35+
### Bug fixes and other changes
36+
37+
* remove docker-compose as a required dependency.
38+
39+
## v1.43.5 (2019-11-18)
40+
41+
### Bug fixes and other changes
42+
43+
* remove red from possible colors when streaming logs
44+
345
## v1.43.4.post1 (2019-10-29)
446

547
### Documentation changes

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.43.5.dev0
1+
1.44.4.dev0

doc/overview.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,12 @@ For example, the ``dataframe`` method gets a pandas dataframe summarizing the as
661661
# Look at summary of associated training jobs
662662
my_dataframe = my_tuner_analytics.dataframe()
663663
664+
You can install all necessary for this feature dependencies using pip:
665+
666+
::
667+
668+
pip install 'sagemaker[analytics]' --upgrade
669+
664670
For more detailed examples of running hyperparameter tuning jobs, see:
665671

666672
- `Using the TensorFlow estimator with hyperparameter tuning <https://github.com/awslabs/amazon-sagemaker-examples/blob/master/hyperparameter_tuning/tensorflow_mnist/hpo_tensorflow_mnist.ipynb>`__
@@ -718,6 +724,12 @@ The SageMaker Python SDK supports local mode, which allows you to create estimat
718724
This is a great way to test your deep learning scripts before running them in SageMaker's managed training or hosting environments.
719725
Local Mode is supported for frameworks images (TensorFlow, MXNet, Chainer, PyTorch, and Scikit-Learn) and images you supply yourself.
720726

727+
You can install all necessary for this feature dependencies using pip:
728+
729+
::
730+
731+
pip install 'sagemaker[local]' --upgrade
732+
721733
We can take the example in `Using Estimators <#using-estimators>`__ , and use either ``local`` or ``local_gpu`` as the instance type.
722734

723735
.. code:: python

setup.py

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,42 @@ def read_version():
3838
"numpy>=1.9.0",
3939
"protobuf>=3.1",
4040
"scipy>=0.19.0",
41-
"urllib3>=1.21, <1.25",
4241
"protobuf3-to-dict>=0.1.5",
43-
"docker-compose>=1.23.0",
4442
"requests>=2.20.0, <2.21",
45-
"fabric>=2.0",
4643
]
4744

45+
# Specific use case dependencies
46+
extras = {
47+
"analytics": ["pandas"],
48+
"local": [
49+
"urllib3>=1.21, <1.25",
50+
"docker-compose>=1.23.0",
51+
"PyYAML>=3.10, <5", # PyYAML version has to match docker-compose requirements
52+
],
53+
"tensorflow": ["tensorflow>=1.3.0"],
54+
}
55+
# Meta dependency groups
56+
extras["all"] = [item for group in extras.values() for item in group]
57+
# Tests specific dependencies (do not need to be included in 'all')
58+
extras["test"] = (
59+
[
60+
extras["all"],
61+
"tox==3.13.1",
62+
"flake8",
63+
"pytest==4.4.1",
64+
"pytest-cov",
65+
"pytest-rerunfailures",
66+
"pytest-xdist",
67+
"mock",
68+
"contextlib2",
69+
"awslogs",
70+
"black==19.3b0 ; python_version >= '3.6'",
71+
"stopit==1.1.2",
72+
"apache-airflow==1.10.5",
73+
"fabric>=2.0",
74+
],
75+
)
76+
4877
# enum is introduced in Python 3.4. Installing enum back port
4978
if sys.version_info < (3, 4):
5079
required_packages.append("enum34>=1.1.6")
@@ -71,23 +100,6 @@ def read_version():
71100
"Programming Language :: Python :: 3.6",
72101
],
73102
install_requires=required_packages,
74-
extras_require={
75-
"test": [
76-
"tox==3.13.1",
77-
"flake8",
78-
"pytest==4.4.1",
79-
"pytest-cov",
80-
"pytest-rerunfailures",
81-
"pytest-xdist",
82-
"mock",
83-
"tensorflow>=1.3.0",
84-
"contextlib2",
85-
"awslogs",
86-
"pandas",
87-
"black==19.3b0 ; python_version >= '3.6'",
88-
"stopit==1.1.2",
89-
"apache-airflow==1.10.5",
90-
]
91-
},
103+
extras_require=extras,
92104
entry_points={"console_scripts": ["sagemaker=sagemaker.cli.main:main"]},
93105
)

src/sagemaker/estimator.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,11 +1431,10 @@ def __init__(
14311431
(default: logging.INFO). Valid values are defined in the Python
14321432
logging module.
14331433
code_location (str): The S3 prefix URI where custom code will be
1434-
uploaded (default: None). The code file uploaded in S3 is
1435-
'code_location/source/sourcedir.tar.gz'. If not specified, the
1436-
default code location is s3://default_bucket/job-name/. And code
1437-
file uploaded to S3 is
1438-
s3://default_bucket/job-name/source/sourcedir.tar.gz
1434+
uploaded (default: None) - don't include a trailing slash since
1435+
a string prepended with a "/" is appended to ``code_location``. The code
1436+
file uploaded to S3 is 'code_location/job-name/source/sourcedir.tar.gz'.
1437+
If not specified, the default ``code location`` is s3://default_bucket/job-name/.
14391438
image_name (str): An alternate image name to use instead of the
14401439
official Sagemaker image for the framework. This is useful to
14411440
run one of the Sagemaker supported frameworks with an image

src/sagemaker/local/entities.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@
1919
import os
2020
import tempfile
2121
import time
22-
import urllib3
2322

2423
import sagemaker.local.data
2524
from sagemaker.local.image import _SageMakerContainer
2625
from sagemaker.local.utils import copy_directory_structure, move_to_destination
27-
from sagemaker.utils import get_config_value
26+
from sagemaker.utils import DeferredError, get_config_value
27+
28+
try:
29+
import urllib3
30+
except ImportError as e:
31+
logging.warning("urllib3 failed to import. Local mode features will be impaired or broken.")
32+
# Any subsequent attempt to use urllib3 will raise the ImportError
33+
urllib3 = DeferredError(e)
34+
2835

2936
logger = logging.getLogger(__name__)
3037

src/sagemaker/local/image.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@
2929
import tarfile
3030
import tempfile
3131

32+
from distutils.spawn import find_executable
3233
from threading import Thread
3334
from six.moves.urllib.parse import urlparse
3435

35-
import yaml
36-
3736
import sagemaker
3837
import sagemaker.local.data
3938
import sagemaker.local.utils
@@ -77,6 +76,15 @@ def __init__(self, instance_type, instance_count, image, sagemaker_session=None)
7776
"""
7877
from sagemaker.local.local_session import LocalSession
7978

79+
# check if docker-compose is installed
80+
if find_executable("docker-compose") is None:
81+
raise ImportError(
82+
"'docker-compose' is not installed. "
83+
"Local Mode features will not work without docker-compose. "
84+
"For more information on how to install 'docker-compose', please, see "
85+
"https://docs.docker.com/compose/install/"
86+
)
87+
8088
self.sagemaker_session = sagemaker_session or LocalSession()
8189
self.instance_type = instance_type
8290
self.instance_count = instance_count
@@ -451,6 +459,13 @@ def _generate_compose_file(self, command, additional_volumes=None, additional_en
451459
}
452460

453461
docker_compose_path = os.path.join(self.container_root, DOCKER_COMPOSE_FILENAME)
462+
463+
try:
464+
import yaml
465+
except ImportError as e:
466+
logging.error(sagemaker.utils._module_import_error("yaml", "Local mode", "local"))
467+
raise e
468+
454469
yaml_content = yaml.dump(content, default_flow_style=False)
455470
logger.info("docker compose file: \n%s", yaml_content)
456471
with open(docker_compose_path, "w") as f:

src/sagemaker/local/local_session.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
from __future__ import absolute_import
1515

1616
import logging
17+
import os
1718
import platform
1819

1920
import boto3
20-
import urllib3
2121
from botocore.exceptions import ClientError
2222

2323
from sagemaker.local.image import _SageMakerContainer
@@ -29,7 +29,7 @@
2929
_LocalTransformJob,
3030
)
3131
from sagemaker.session import Session
32-
from sagemaker.utils import get_config_value
32+
from sagemaker.utils import get_config_value, _module_import_error
3333

3434
logger = logging.getLogger(__name__)
3535

@@ -323,6 +323,12 @@ def __init__(self, config=None):
323323
config (dict): Optional configuration for this client. In particular only
324324
the local port is read.
325325
"""
326+
try:
327+
import urllib3
328+
except ImportError as e:
329+
logging.error(_module_import_error("urllib3", "Local mode", "local"))
330+
raise e
331+
326332
self.http = urllib3.PoolManager()
327333
self.serving_port = 8080
328334
self.config = config
@@ -397,6 +403,16 @@ def _initialize(self, boto_session, sagemaker_client, sagemaker_runtime_client):
397403
self.sagemaker_runtime_client = LocalSagemakerRuntimeClient(self.config)
398404
self.local_mode = True
399405

406+
sagemaker_config_file = os.path.join(os.path.expanduser("~"), ".sagemaker", "config.yaml")
407+
if os.path.exists(sagemaker_config_file):
408+
try:
409+
import yaml
410+
except ImportError as e:
411+
logging.error(_module_import_error("yaml", "Local mode", "local"))
412+
raise e
413+
414+
self.config = yaml.load(open(sagemaker_config_file, "r"))
415+
400416
def logs_for_job(self, job_name, wait=False, poll=5, log_type="All"):
401417
"""
402418

src/sagemaker/logs.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
1+
# Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License"). You
44
# may not use this file except in compliance with the License. A copy of
@@ -31,7 +31,9 @@ class ColorWrap(object):
3131
cell).
3232
"""
3333

34-
_stream_colors = [31, 32, 33, 34, 35, 36]
34+
# For what color each number represents, see
35+
# https://misc.flogisoft.com/bash/tip_colors_and_formatting#colors
36+
_stream_colors = [34, 35, 32, 36, 33]
3537

3638
def __init__(self, force=False):
3739
"""Initialize the class.

src/sagemaker/session.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import boto3
2626
import botocore.config
2727
from botocore.exceptions import ClientError
28-
import yaml
2928

3029
import sagemaker.logs
3130
from sagemaker import vpc_utils
@@ -95,11 +94,8 @@ def __init__(self, boto_session=None, sagemaker_client=None, sagemaker_runtime_c
9594
"""
9695
self._default_bucket = None
9796

98-
sagemaker_config_file = os.path.join(os.path.expanduser("~"), ".sagemaker", "config.yaml")
99-
if os.path.exists(sagemaker_config_file):
100-
self.config = yaml.load(open(sagemaker_config_file, "r"))
101-
else:
102-
self.config = None
97+
# currently is used for local_code in local mode
98+
self.config = None
10399

104100
self._initialize(boto_session, sagemaker_client, sagemaker_runtime_client)
105101

src/sagemaker/utils.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,3 +684,23 @@ def __getattr__(self, name):
684684
name:
685685
"""
686686
raise self.exc
687+
688+
689+
def _module_import_error(py_module, feature, extras):
690+
"""Return error message for module import errors, provide
691+
installation details.
692+
693+
Args:
694+
py_module (str): Module that failed to be imported
695+
feature (str): Affected SageMaker feature
696+
extras (str): Name of the `extras_require` to install the relevant dependencies
697+
698+
Returns:
699+
str: Error message with installation instructions.
700+
"""
701+
error_msg = (
702+
"Failed to import {}. {} features will be impaired or broken. "
703+
"Please run \"pip install 'sagemaker[{}]'\" "
704+
"to install all required dependencies."
705+
)
706+
return error_msg.format(py_module, feature, extras)

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ deps =
119119
# pip install requirements.txt is separate as RTD does it in separate steps
120120
# having the requirements.txt installed in deps above results in Double Requirement exception
121121
# https://github.com/pypa/pip/issues/988
122+
# TODO: Remove pip install python-dateutil==2.8.0 once botocore no longer requires a pinned version
122123
commands =
123124
pip install python-dateutil==2.8.0
124125
pip install ../tests/data/smdebug_rulesconfig-0.4a0-py2.py3-none-any.whl

0 commit comments

Comments
 (0)