Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions README.md
Comment thread
eberquist marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,26 @@ pip install emailable

## Usage

The library needs to be configured with your account's API key which is available in your [Emailable Dashboard](https://app.emailable.com/api).
### Authentication

### Setup
The Emailable API requires either an API key or an access token for
authentication. API keys can be created and managed in the
[Emailable Dashboard](https://app.emailable.com/api).

An API key can be set globally for the Emailable client:

```python
client = emailable.Client('your_api_key')
```

Or, you can specify an `api_key` or an `access_token` with each request:

```python
import emailable
# set api_key at request time
client.verify(api_key='your_api_key')

client = emailable.Client('live_...')
# set access_token at request time
client.verify(access_token='your_access_token')
```

### Verification
Expand All @@ -36,7 +48,7 @@ response = client.verify('evan@emailable.com')
response.state
=> 'deliverable'

# additional parameters are available. see API docs for additional info.
# additional parameters are available. see API docs for more info.
client.verify('evan@emailable.com', smtp=False, accept_all=True, timeout=25)
```

Expand Down
38 changes: 27 additions & 11 deletions emailable/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@

class Client:

def __init__(self, api_key):
def __init__(self, api_key=None):
self.api_key = api_key
self.base_url = 'https://api.emailable.com/v1/'

def verify(self, email, smtp=True, accept_all=False, timeout=None):
def verify(self,
email,
smtp=True,
accept_all=False,
timeout=None,
api_key=None,
access_token=None):
options = {
'headers': {
'Authorization': f'Bearer {self.api_key or api_key or access_token}'
Comment thread
eberquist marked this conversation as resolved.
Outdated
},
'params': {
'api_key': self.api_key,
'email': email,
'smtp': str(smtp).lower(),
'accept_all': str(accept_all).lower(),
Expand All @@ -24,10 +32,12 @@ def verify(self, email, smtp=True, accept_all=False, timeout=None):
url = self.base_url + 'verify'
return self.__request('get', url, options)

def batch(self, emails, params={}):
def batch(self, emails, params={}, api_key=None, access_token=None):
options = {
'headers': {
'Authorization': f'Bearer {self.api_key or api_key or access_token}'
},
'params': {
**{'api_key': self.api_key},
**params
},
'json': {
Expand All @@ -37,10 +47,16 @@ def batch(self, emails, params={}):
url = self.base_url + 'batch'
return self.__request('post', url, options)

def batch_status(self, batch_id, simulate=None):
def batch_status(self,
batch_id,
simulate=None,
api_key=None,
access_token=None):
options = {
'headers': {
'Authorization': f'Bearer {self.api_key or api_key or access_token}'
},
'params': {
'api_key': self.api_key,
'id': batch_id,
'simulate': simulate
}
Expand All @@ -49,11 +65,11 @@ def batch_status(self, batch_id, simulate=None):
url = self.base_url + 'batch'
return self.__request('get', url, options)

def account(self):
def account(self, api_key=None, access_token=None):
options = {
'params': {
'api_key': self.api_key
}
'headers': {
'Authorization': f'Bearer {self.api_key or api_key or access_token}'
},
}

url = self.base_url + 'account'
Expand Down
41 changes: 41 additions & 0 deletions tests/test_authentication.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from unittest import TestCase
import emailable

class TestAuthentication(TestCase):

def setUp(self):
self.api_key = 'test_7aff7fc0142c65f86a00'
self.email = 'evan@emailable.com'
self.emails = ['evan@emailable.com', 'jarrett@emailable.com']

def test_invalid_api_key_authentication(self):
client = emailable.Client('test_7aff7fc0141c65f86a00')
self.assertRaises(
emailable.AuthError,
client.verify,
'evan@emailable.com'
)

def test_missing_api_key_authentication(self):
client = emailable.Client()
self.assertRaises(
emailable.AuthError,
client.verify,
'evan@emailable.com'
)

def test_global_api_key_authentication(self):
client = emailable.Client(self.api_key)
self.assertIsNotNone(client.verify(self.email).domain)
batch_id = client.batch(self.emails).id
self.assertIsNotNone(batch_id)
self.assertIsNotNone(client.batch_status(batch_id).id)
self.assertIsNotNone(client.account().available_credits)

def test_request_time_api_key_authentication(self):
client = emailable.Client()
self.assertIsNotNone(client.verify(self.email, api_key=self.api_key).domain)
batch_id = client.batch(self.emails, api_key=self.api_key).id
self.assertIsNotNone(batch_id)
self.assertIsNotNone(client.batch_status(batch_id, api_key=self.api_key).id)
self.assertIsNotNone(client.account(api_key=self.api_key).available_credits)
16 changes: 0 additions & 16 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,6 @@ def setUp(self):
self.client = emailable.Client('test_7aff7fc0142c65f86a00')
time.sleep(0.5)

def test_invalid_api_key(self):
client = emailable.Client('test_7aff7fc0141c65f86a00')
self.assertRaises(
emailable.AuthError,
client.verify,
'evan@emailable.com'
)
Comment thread
jclusso marked this conversation as resolved.

def test_missing_api_key(self):
self.client.api_key = None
self.assertRaises(
emailable.AuthError,
self.client.verify,
'evan@emailable.com'
)

def test_verify_returns_response(self):
response = self.client.verify('johndoe+tag@emailable.com')
self.assertIsInstance(response, emailable.Response)
Expand Down