Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tdl 24072 fix typecasting bug max api limit #84

Merged
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: 2
jobs:
build:
docker:
- image: 218546966473.dkr.ecr.us-east-1.amazonaws.com/circle-ci:tap-tester
- image: 218546966473.dkr.ecr.us-east-1.amazonaws.com/circle-ci:stitch-tap-tester
steps:
- checkout
- run:
Expand All @@ -16,12 +16,12 @@ jobs:
name: 'Pylint'
command: |
source ~/.virtualenvs/tap-marketo/bin/activate
pylint tap_marketo -d C,R
pylint tap_marketo -d C,R,W
- run:
name: 'JSON Validator'
command: |
source /usr/local/share/virtualenvs/tap-tester/bin/activate
stitch-validate-json ~/.virtualenvs/tap-marketo/lib/python3.5/site-packages/tap_marketo/schemas/*.json
stitch-validate-json tap_marketo/schemas/*.json
- run:
name: 'Unit Tests'
command: |
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 2.5.1
* Fixed Validation Error for `max_daily_calls` [#84](https://github.com/singer-io/tap-marketo/pull/84)

## 2.5.0
* Add campaignId field to activities streams [#82](https://github.com/singer-io/tap-marketo/pull/82)

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from setuptools import setup

setup(name='tap-marketo',
version='2.5.0',
version='2.5.1',
description='Singer.io tap for extracting data from the Marketo API',
author='Stitch',
url='http://singer.io',
Expand Down
13 changes: 10 additions & 3 deletions tap_marketo/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# Marketo limits REST requests to 50000 per day with a rate limit of 100
# calls per 20 seconds.
# http://developers.marketo.com/rest-api/
MAX_DAILY_CALLS = int(50000 * 0.8)
MAX_DAILY_CALLS = 50000 * 0.8
RATE_LIMIT_CALLS = 100
RATE_LIMIT_SECONDS = 20

Expand Down Expand Up @@ -80,7 +80,7 @@ def raise_for_rate_limit(data):
class Client:
# pylint: disable=unused-argument
def __init__(self, endpoint, client_id, client_secret,
max_daily_calls=MAX_DAILY_CALLS,
max_daily_calls=None,
user_agent=DEFAULT_USER_AGENT,
job_timeout=JOB_TIMEOUT,
poll_interval=POLL_INTERVAL,
Expand All @@ -89,7 +89,14 @@ def __init__(self, endpoint, client_id, client_secret,
self.domain = extract_domain(endpoint)
self.client_id = client_id
self.client_secret = client_secret
self.max_daily_calls = int(max_daily_calls)
try:
self.max_daily_calls = int(max_daily_calls or MAX_DAILY_CALLS)
if self.max_daily_calls <= 1:
raise ValueError("Limit Cannot be Negative or Zero")
except (ValueError, TypeError) as err:
singer.log_critical(f"Invalid Value passed for max_daily_calls: {max_daily_calls}")
raise err

self.user_agent = user_agent
self.job_timeout = job_timeout
self.poll_interval = poll_interval
Expand Down
113 changes: 113 additions & 0 deletions tests/test_client_max_api_limit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import unittest
from tap_marketo.client import Client, MAX_DAILY_CALLS

class TestmaxdailycallsConfig(unittest.TestCase):

def test_maxdailycalls_default_no_val(self):
"""
Verify that max_daily_calls is default if no value is passed
"""
# Initialize Client object
client = Client(**{'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT'})

self.assertEqual(client.max_daily_calls, MAX_DAILY_CALLS)

def test_maxdailycalls_default_empty_str(self):
"""
Verify that max_daily_calls is default if empty string value is passed
Verify no Exception is raised for typecasting error between str to num
"""
# Initialize Client object
client = Client(**{'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':''})

self.assertEqual(client.max_daily_calls, MAX_DAILY_CALLS)

def test_maxdailycalls_default_bool_false_val(self):
"""
Verify that max_daily_calls is default if bool value is passed
"""
# Initialize Client object
client = Client(**{'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':False})
self.assertEqual(client.max_daily_calls ,MAX_DAILY_CALLS)

def test_maxdailycalls_bool_true_val(self):
"""
Verify that max_daily_calls is default if bool value is passed
"""
# Initialize Client object
params = {'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':True}
with self.assertRaises(ValueError):
try:
Client(**params)
except Exception as err:
self.assertEqual(str(err),"Limit Cannot be Negative or Zero")
raise err

def test_maxdailycalls_default_zero_val(self):
"""
Verify that api_limit is default if 0 value is passed
"""
# Initialize Client object
client = Client(**{'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':0})
self.assertEqual(client.max_daily_calls, MAX_DAILY_CALLS)

def test_maxdailycalls_default_none_val(self):
"""
Verify that api_limit is default if None value is passed
"""
# Initialize Client object
client = Client(**{'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':None})
self.assertEqual(client.max_daily_calls, MAX_DAILY_CALLS)

def test_maxdailycalls_enabled_num_val(self):
"""
Verify that api_limit is set appropriately if num value is passed
"""
# Initialize Client object
client = Client(**{'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':3})

self.assertEqual(client.max_daily_calls, 3)

def test_maxdailycalls_failed_comma_val(self):
"""
Verify that exception is raised if invalid input value is passed
"""
params = {'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':'30,000'}
# Initialize Client object
with self.assertRaises(ValueError):
Client(**params)

def test_maxdailycalls_failed_decimal_val(self):
"""
Verify that api_limit is set appropriately if num value is passed
"""
# Initialize Client object
params = {'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':'3700.15'}
with self.assertRaises(ValueError):
Client(**params)

def test_maxdailycalls_failed_negative_val(self):
"""
Verify that api_limit is set appropriately if num value is passed
"""
# Initialize Client object
params = {'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':'-522'}
with self.assertRaises(ValueError):
try:
Client(**params)
except Exception as err:
self.assertEqual(str(err),"Limit Cannot be Negative or Zero")
raise err

def test_maxdailycalls_default_str_zero_val(self):
"""
Verify that api_limit is default if "0" value is passed
"""
# Initialize Client object
params = {'endpoint': '123-ABC-789','client_id':'ABC-123','client_secret':'123-QRT','max_daily_calls':'0'}
with self.assertRaises(ValueError):
try:
Client(**params)
except Exception as err:
self.assertEqual(str(err),"Limit Cannot be Negative or Zero")
raise err