From 61b351041b0cf7d82377e87e014f571a7f5970ba Mon Sep 17 00:00:00 2001 From: Ronaldo Duarte Date: Mon, 7 Oct 2019 13:58:18 -0300 Subject: [PATCH] Make boto3 dependency optional (#30) * Add boto3 to local requirements * Add optional feature "aws" that depends on boto3 * Raise runtime error if boto3 is not installed * Add instructions to install optional aws feature * Test runtime error when boto3 is missing * Rename fixture * Add instructions to install aws feature --- docs/source/installation.rst | 6 ++++++ prettyconf/loaders.py | 12 ++++++++++-- requirements.txt | 3 ++- setup.py | 2 +- tests/test_parameterstore.py | 16 ++++++++++++++++ 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 8e7a7b1..c8587ec 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -12,3 +12,9 @@ First you need to install ``prettyconf`` library: .. code-block:: sh pip install prettyconf + +The ``AwsParameterStore`` configuration loader depends on the ``boto3`` package. +If you need to use it, install ``prettyconf`` with the optional feature ``aws``: + +.. code-block:: sh + pip install prettyconf[aws] diff --git a/prettyconf/loaders.py b/prettyconf/loaders.py index 589a718..09f8834 100644 --- a/prettyconf/loaders.py +++ b/prettyconf/loaders.py @@ -2,8 +2,11 @@ from configparser import ConfigParser, MissingSectionHeaderError, NoOptionError from glob import glob -import boto3 -import botocore +try: + import boto3 + import botocore +except ImportError: + boto3 = None from .exceptions import InvalidConfigurationFile, InvalidPath, MissingSettingsSection from .parsers import EnvFileParser @@ -308,6 +311,11 @@ def __getitem__(self, item): class AwsParameterStore(AbstractConfigurationLoader): def __init__(self, path="/", aws_access_key_id=None, aws_secret_access_key=None, region_name="us-east-1"): + if not boto3: + raise RuntimeError( + 'AwsParameterStore requires [aws] feature. Please install it: "pip install prettyconf[aws]"' + ) + self.path = path self.aws_access_key_id = aws_access_key_id self.aws_secret_access_key = aws_secret_access_key diff --git a/requirements.txt b/requirements.txt index 3495395..6979749 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ +boto3 +coveralls pytest pytest-cov pytest-runner Sphinx sphinx-rtd-theme twine -coveralls diff --git a/setup.py b/setup.py index f99e11f..d1a940e 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ def run(self): author="Osvaldo Santana Neto", author_email="prettyconf@osantana.me", license="MIT", packages=['prettyconf'], - install_requires=['boto3'], + extras_require={'aws': ['boto3']}, platforms='any', classifiers=[ 'Development Status :: 5 - Production/Stable', diff --git a/tests/test_parameterstore.py b/tests/test_parameterstore.py index 28f8a5d..f0792ec 100644 --- a/tests/test_parameterstore.py +++ b/tests/test_parameterstore.py @@ -1,3 +1,5 @@ +import importlib +import sys from unittest import mock import pytest @@ -43,6 +45,20 @@ } +@pytest.fixture +def boto_not_installed(): + sys.modules['boto3'] = None + importlib.reload(sys.modules['prettyconf.loaders']) + yield + sys.modules.pop('boto3') + importlib.reload(sys.modules['prettyconf.loaders']) + + +def test_create_loader_boto_not_installed(boto_not_installed): + with pytest.raises(RuntimeError): + AwsParameterStore() + + @mock.patch("prettyconf.loaders.boto3") def test_basic_config(mock_boto): mock_boto.client.return_value.get_parameters_by_path.return_value = PARAMETER_RESPONSE