Skip to content

Commit

Permalink
Refactoring. Closes #41 (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
Stranger6667 authored Oct 9, 2016
1 parent 701ff66 commit 2a904b7
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 133 deletions.
10 changes: 5 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ Send single email:

.. code-block:: python
>>> from postmarker.core import ServerClient
>>> server_client = ServerClient(token='API_TOKEN')
>>> server_client.emails.send(
>>> from postmarker.core import PostmarkClient
>>> postmark = PostmarkClient(token='API_TOKEN')
>>> postmark.emails.send(
From='[email protected]',
To='[email protected]',
Subject='Postmark test',
Expand All @@ -44,7 +44,7 @@ Send batch:

.. code-block:: python
>>> server_client.emails.send_batch(
>>> postmark.emails.send_batch(
{
From='[email protected]',
To='[email protected]',
Expand All @@ -63,7 +63,7 @@ Setup an email:

.. code-block:: python
>>> email = server_client.emails.Email(
>>> email = postmark.emails.Email(
From='[email protected]',
To='[email protected]',
Subject='Postmark test',
Expand Down
6 changes: 3 additions & 3 deletions docs/bounces.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ Bounces

.. code-block:: python
>>> server_client.bounces
>>> postmark.bounces
<BouncesManager>
You can get a list of bounces with :py:meth:`~postmarker.models.bounces.BounceManager.all` method:

.. code-block:: python
>>> server_client.bounces.all()
>>> postmark.bounces.all()
[<Bounce: 943247350>, <Bounce: 924829573>]
Every bounce instance is represented by its ID. You can directly get one.

.. code-block:: python
>>> bounce = server_client.bounces.get(943247350)
>>> bounce = postmark.bounces.get(943247350)
>>> bounce
<Bounce: 943247350>
Expand Down
16 changes: 8 additions & 8 deletions docs/emails.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Sending emails is super easy! Here is the most simple case:

.. code-block:: python
>>> server_client.emails.send(
>>> postmark.emails.send(
From='[email protected]',
To='[email protected]',
Subject='Postmark test',
Expand All @@ -31,13 +31,13 @@ Or send ``MIMEText``/``MIMEMultipart`` instances:
>>> message = MIMEText('Text')
>>> message['From'] = '[email protected]'
>>> message['To'] = '[email protected]'
>>> server_client.emails.send(message=message)
>>> postmark.emails.send(message=message)
To specify multiple recipients (or ``Cc`` / ``Bcc``) you could pass values as list or string with comma separated values:

.. code-block:: python
>>> server_client.emails.send(
>>> postmark.emails.send(
From='[email protected]',
To=['[email protected]', '[email protected]'], # The same as '[email protected], [email protected]'
Subject='Postmark test',
Expand All @@ -48,7 +48,7 @@ Headers could be specified as dict:

.. code-block:: python
>>> server_client.emails.send(
>>> postmark.emails.send(
From='[email protected]',
To='[email protected]',
Headers={'X-Accept-Language': 'en-us, en'},
Expand Down Expand Up @@ -76,7 +76,7 @@ Then pass them to :py:meth:`~postmarker.models.emails.EmailManager.send`:

.. code-block:: python
>>> server_client.emails.send(
>>> postmark.emails.send(
From='[email protected]',
To='[email protected]',
Subject='Postmark test',
Expand All @@ -88,7 +88,7 @@ To send email in batch there is :py:meth:`~postmarker.models.emails.EmailManager

.. code-block:: python
>>> server_client.emails.send_batch(
>>> postmark.emails.send_batch(
{
From='[email protected]',
To='[email protected]',
Expand All @@ -114,7 +114,7 @@ To get more flexibility it is possible to use :py:class:`Email` objects.

.. code-block:: python
>>> email = server_client.emails.Email(
>>> email = postmark.emails.Email(
From='[email protected]',
To='[email protected]',
Subject='Postmark test',
Expand Down Expand Up @@ -162,7 +162,7 @@ Batches are available via :py:meth:`~postmarker.models.emails.EmailManager.Email

.. code-block:: python
>>> batch = server_client.emails.EmailBatch(email)
>>> batch = postmark.emails.EmailBatch(email)
>>> len(batch)
1
>>> batch.send()
Expand Down
2 changes: 1 addition & 1 deletion docs/server.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ Server API is available via ``ServerManager``:

.. code-block:: python
>>> server = server_client.server.get()
>>> server = postmark.server.get()
>>> server.edit(TrackOpens=True)
18 changes: 5 additions & 13 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,20 @@ Usage
=====

At the first step you have to initialize the client with proper API token.
Postmarker provides two client classes - ``ServerClient`` for Server API and ``AccountClient`` for Account API.
Postmarker provides single ``PostmarkClient`` class for Server and Account APIs.

.. code-block:: python
from postmarker.core import ServerClient
from postmarker.core import PostmarkClient
>>> server_client = ServerClient(token='API_TOKEN')
>>> postmark = PostmarkClient(token='API_TOKEN')
.. code-block:: python
from postmarker.core import AccountClient
>>> account_client = AccountClient(token='API_TOKEN')
Variables ``server_client`` and ``account_client`` from the examples above will be used in next examples.
Variables ``postmark`` from the examples above will be used in next examples.
By default logging is configured to be silent. To enable it pass ``verbosity`` to client instantiation:

.. code-block:: python
>>> server_client = ServerClient(token='API_TOKEN', verbosity=3)
>>> postmark = PostmarkClient(token='API_TOKEN', verbosity=3)
With ``verbosity=3`` every request and response will be logged to console.
34 changes: 9 additions & 25 deletions postmarker/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@ def check_managers(new_class):
raise ConfigError('Defined managers names override client\'s members')


class BaseClient(with_metaclass(ClientMeta)):
class PostmarkClient(with_metaclass(ClientMeta)):
"""
Basic class for API clients. Provides basic functionality to make requests.
"""
root_url = 'https://api.postmarkapp.com/'
auth_header_name = None
_managers = ()
_managers = (
EmailManager,
BounceManager,
ServerManager,
)

def __init__(self, token=None, verbosity=0):
assert token, 'You have to provide token to use Postmark API'
Expand All @@ -55,8 +58,8 @@ def _setup_managers(self):
"""
Allows to access manager by model name.
>>> client = ServerClient(token='TEST')
>>> client.bounces
>>> postmark = PostmarkClient(token='TEST')
>>> postmark.bounces
<BounceManager>
"""
for manager_class in self._managers:
Expand All @@ -74,7 +77,7 @@ def _call(self, method, endpoint, data=None, **kwargs):
Low-level call to Postmark API.
"""
headers = {
self.auth_header_name: self.token,
'X-Postmark-Server-Token': self.token,
'Accept': 'application/json',
}
url = urljoin(self.root_url, endpoint)
Expand All @@ -83,22 +86,3 @@ def _call(self, method, endpoint, data=None, **kwargs):
self.logger.debug('Response: %s', response.text)
response.raise_for_status()
return response


class ServerClient(BaseClient):
"""
Provides an interface for actions, that require server level privileges.
"""
auth_header_name = 'X-Postmark-Server-Token'
_managers = (
EmailManager,
BounceManager,
ServerManager,
)


class AccountClient(BaseClient):
"""
Provides an interface for actions, that require account level privileges.
"""
auth_header_name = 'X-Postmark-Account-Token'
6 changes: 3 additions & 3 deletions postmarker/django.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.core.exceptions import ImproperlyConfigured
from django.core.mail.backends.base import BaseEmailBackend

from .core import TEST_TOKEN, ServerClient
from .core import TEST_TOKEN, PostmarkClient


DEFAULT_CONFIG = {
Expand Down Expand Up @@ -36,6 +36,6 @@ def get_option(self, key):
return self.config.get(key, DEFAULT_CONFIG.get(key))

def send_messages(self, email_messages):
server_client = ServerClient(token=self.token)
postmark = PostmarkClient(token=self.token)
prepared_messages = [message.message() for message in email_messages]
return len(server_client.emails.send_batch(*prepared_messages, TrackOpens=self.get_option('TRACK_OPENS')))
return len(postmark.emails.send_batch(*prepared_messages, TrackOpens=self.get_option('TRACK_OPENS')))
2 changes: 1 addition & 1 deletion postmarker/models/bounces.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# coding: utf-8
"""
Information about bounces is available via :py:class:`~postmarker.models.bounces.BounceManager`,
which is an attribute of ``server_client`` instance.
which is an attribute of ``postmark`` instance.
"""
from .base import Model, ModelManager

Expand Down
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# coding=utf-8
31 changes: 13 additions & 18 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from betamax import Betamax
from betamax_serializers import pretty_json
from postmarker.core import AccountClient, ServerClient
from postmarker.core import PostmarkClient

from ._compat import patch
from .helpers import replace_real_credentials
Expand All @@ -28,7 +28,7 @@ def pytest_unconfigure(config):


@pytest.yield_fixture(autouse=True, scope='module')
def betamax_recorder(request, server_client):
def betamax_recorder(request, postmark):
"""
Module level Betamax recorder.
"""
Expand All @@ -38,7 +38,7 @@ def betamax_recorder(request, server_client):
record_mode = 'none' if os.environ.get('TRAVIS') else 'once'
cassette_name = getattr(request.node._obj, 'CASSETTE_NAME', 'default')
vcr = Betamax(
server_client.session,
postmark.session,
cassette_library_dir=CASSETTE_DIR,
default_cassette_options={
'preserve_exact_body_bytes': True,
Expand Down Expand Up @@ -66,30 +66,25 @@ def api_token():


@pytest.fixture(scope='session')
def server_client(api_token):
return ServerClient(token=api_token)
def postmark(api_token):
return PostmarkClient(token=api_token)


@pytest.fixture(scope='session')
def account_client(api_token):
return AccountClient(token=api_token)
def bounce(postmark):
return postmark.bounces.get(723626745)


@pytest.fixture(scope='session')
def bounce(server_client):
return server_client.bounces.get(723626745)


@pytest.fixture(scope='session')
def server(server_client):
return server_client.server.get()
def server(postmark):
return postmark.server.get()


@pytest.fixture()
def email(server_client):
return server_client.emails.Email(From='[email protected]', To='[email protected]', TextBody='text')
def email(postmark):
return postmark.emails.Email(From='[email protected]', To='[email protected]', TextBody='text')


@pytest.fixture
def email_batch(server_client, email):
return server_client.emails.EmailBatch(email)
def email_batch(postmark, email):
return postmark.emails.EmailBatch(email)
12 changes: 6 additions & 6 deletions tests/models/test_bounces.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ def test_activate(self, bounce):

class TestManager:

def test_tags(self, server_client):
assert server_client.bounces.tags == []
def test_tags(self, postmark):
assert postmark.bounces.tags == []

def test_deliverystats(self, server_client):
assert server_client.bounces.deliverystats == {
def test_deliverystats(self, postmark):
assert postmark.bounces.deliverystats == {
'Bounces': [
{'Count': 141, 'Name': 'All'},
{'Count': 136, 'Name': 'Hard bounce', 'Type': 'HardBounce'},
Expand All @@ -41,7 +41,7 @@ def test_deliverystats(self, server_client):
'InactiveMails': 136
}

def test_all(self, server_client):
bounces = server_client.bounces.all(count=2)
def test_all(self, postmark):
bounces = postmark.bounces.all(count=2)
assert len(bounces) == 2
assert all(isinstance(bounce, Bounce) for bounce in bounces)
Loading

0 comments on commit 2a904b7

Please sign in to comment.