Repository: Stranger6667/postmarker
Pull request #142 (2017-05-14 07:15:40)

Instantiation helper


Patch:
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 41100f8..4cfdda0 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -6,6 +6,12 @@ Changelog
 `Unreleased`_
 -------------
 
+Added
+~~~~~
+
+- Alternative instantiation method - ``from_config``.
+
+
 `0.11.1`_ - 2017-05-10
 ----------------------
 
diff --git a/docs/usage.rst b/docs/usage.rst
index f901781..8d96890 100644
--- a/docs/usage.rst
+++ b/docs/usage.rst
@@ -25,3 +25,21 @@ With ``verbosity=3`` every request and response will be logged to the console.
 For timeouts and max_retries handling there are two parameters - ``max_retries`` and ``timeout``.
 The ``timeout`` value is passed to `requests.Session.request <http://docs.python-requests.org/en/master/api/#requests.Session.request>`_.
 ``max_retries`` is passed to `requests.adapters.HTTPAdapter <http://docs.python-requests.org/en/master/api/#requests.adapters.HTTPAdapter>`_.
+
+Alternatively you could use ``PostmarkClient.from_config`` method, which is helpful to instantiate ``PostmarkClient``
+from dict-like object, like Tornado or Flask configurations.
+
+.. code-block:: python
+
+    >>> config = {'POSTMARK_SERVER_TOKEN': 'foo', 'POSTMARK_TIMEOUT': 1}
+    >>> postmark = PostmarkClient.from_config(config, is_uppercase=True)
+
+With ``is_uppercase`` set to ``True`` keys will be converted to upper case before lookup in the config object.
+The default value for ``is_uppercase`` is ``False``.
+All arguments names from ``PostmarkClient.__init__`` will be looked up in the config object with default prefix `postmark_`.
+To use different prefix, just pass ``prefix='my_prefix_'`` to ``PostmarkClient.from_config`` method.
+
+.. code-block:: python
+
+    >>> config = {'my_prefix_server_token': 'foo', 'my_prefix_timeout': 1}
+    >>> postmark = PostmarkClient.from_config(config, prefix='my_prefix_')
diff --git a/postmarker/core.py b/postmarker/core.py
index 5d56837..3c38902 100644
--- a/postmarker/core.py
+++ b/postmarker/core.py
@@ -2,7 +2,7 @@
 import requests
 
 from . import __version__
-from ._compat import urljoin
+from ._compat import get_args, urljoin
 from .exceptions import ClientError, SpamAssassinError
 from .logging import get_logger
 from .models.bounces import BounceManager
@@ -50,6 +50,22 @@ class PostmarkClient(object):
         self.logger = get_logger('Postmarker', verbosity)
         self._setup_managers()
 
+    @classmethod
+    def from_config(cls, config, prefix='postmark_', is_uppercase=False):
+        """
+        Helper method for instantiating PostmarkClient from dict-like objects.
+        """
+        kwargs = {}
+        for arg in get_args(cls):
+            key = prefix + arg
+            if is_uppercase:
+                key = key.upper()
+            else:
+                key = key.lower()
+            if key in config:
+                kwargs[arg] = config[key]
+        return cls(**kwargs)
+
     def __repr__(self):
         return '<%s: %s>' % (self.__class__.__name__, self.server_token)
 
diff --git a/postmarker/tornado.py b/postmarker/tornado.py
index 044cda9..f8b81dc 100644
--- a/postmarker/tornado.py
+++ b/postmarker/tornado.py
@@ -1,5 +1,4 @@
 # coding: utf-8
-from ._compat import get_args
 from .core import PostmarkClient
 
 
@@ -12,16 +11,9 @@ class PostmarkMixin(object):
     def postmark_client(self):
         self.require_setting(POSTMARK_SERVER_TOKEN, 'Postmark client')
         if not hasattr(self, '_postmark_client'):
-            self._postmark_client = PostmarkClient(**self.get_postmark_kwargs())
+            self._postmark_client = PostmarkClient.from_config(self.settings)
         return self._postmark_client
 
-    def get_postmark_kwargs(self):
-        return dict(
-            (arg, self.settings['postmark_' + arg])
-            for arg in get_args(PostmarkClient)
-            if 'postmark_' + arg in self.settings
-        )
-
     def send(self, *args, **kwargs):
         return self.postmark_client.emails.send(*args, **kwargs)
 


Test patch:
diff --git a/tests/test_core.py b/tests/test_core.py
index 7f20aaa..fe28b5f 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -25,6 +25,16 @@ class TestClient:
     def test_repr(self, postmark, server_token):
         assert repr(postmark) == '<PostmarkClient: %s>' % server_token
 
+    @pytest.mark.parametrize('config, kwargs', (
+        ({'POSTMARK_SERVER_TOKEN': 'foo', 'POSTMARK_TIMEOUT': 1}, {'is_uppercase': True}),
+        ({'postmark_server_token': 'foo', 'postmark_timeout': 1}, {'is_uppercase': False}),
+    ))
+    def test_from_config(self, config, kwargs):
+        instance = PostmarkClient.from_config(config, **kwargs)
+        assert instance.server_token == 'foo'
+        assert instance.timeout == 1
+        assert instance.account_token is None
+
 
 @pytest.mark.parametrize('klass', (PostmarkClient, OutboundMessageManager, MessageManager, TriggersManager))
 class TestManagersSetup: