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

Add 'get_all' request to handle paging. Add retries. Get all emails of person. #32

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
93 changes: 88 additions & 5 deletions pipedrive/client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
from urllib.parse import urlencode

import requests
Expand Down Expand Up @@ -79,6 +80,47 @@ def set_api_token(self, api_token):
def _get(self, url, params=None, **kwargs):
return self._request('get', url, params=params, **kwargs)

def _get_all(self, url, params=None, **kwargs):
more = True
start = 0
final_response = {}
data = []
while more:
if not params:
params = {"start": start}
else:
params['start'] = start
response = {}
try:
response = self._get(url, params, **kwargs)
except exceptions.BaseError:
# If something is already in final_response, return that, otherwise return the response.
if final_response:
return final_response
return response

try:
if response['data'] is None:
return response

data.extend(response['data'])
final_response = response
final_response['data'] = data
except KeyError: # No 'data' key found
if final_response:
return final_response
return response

try:
if response['additional_data']['pagination']['more_items_in_collection']:
start = response['additional_data']['pagination']['next_start']
else:
more = False
except KeyError:
more = False

return final_response

def _post(self, url, **kwargs):
return self._request('post', url, **kwargs)

Expand All @@ -99,18 +141,59 @@ def _request(self, method, url, headers=None, params=None, **kwargs):
_headers.update(headers)
if params:
_params.update(params)
return self._parse(requests.request(method, url, headers=_headers, params=_params, **kwargs))

number_of_retries = kwargs.get('number_of_retries', 3)
intervaltime = kwargs.get('intervaltime', 500)

# remove number of retries and intervaltime from kwargs, otherwise the requests call will fail.
if 'number_of_retries' in kwargs:
del kwargs['number_of_retries']
if 'intervaltime' in kwargs:
del kwargs['intervaltime']

if number_of_retries:
while number_of_retries > 0:
try:
response = self._parse(requests.request(method, url, headers=_headers, params=_params, **kwargs))
# No except, response is ok, return it.
return response
except (exceptions.BadRequestError, exceptions.UnauthorizedError, exceptions.NotFoundError,
exceptions.UnsupportedMediaTypeError, exceptions.UnprocessableEntityError,
exceptions.NotImplementedError, exceptions.TooManyRequestsError) as e:
# Do not retry, just return the response.
raise e
except (exceptions.ForbiddenError, exceptions.InternalServerError, exceptions.ServiceUnavailableError,
exceptions.UnknownError):
# Retry! There is hope.
number_of_retries -= 1
time.sleep(intervaltime / 1000.0)
else:
return self._parse(requests.request(method, url, headers=_headers, params=_params, **kwargs))

def _parse(self, response):
status_code = response.status_code
if 'Content-Type' in response.headers and 'application/json' in response.headers['Content-Type']:
r = response.json()

if 'Content-Type' in response.headers:
content_type = response.headers['Content-Type']
else:
content_type = None

is_json = False

if content_type:
if content_type == 'application/json':
r = response.json()
is_json = True
elif 'text' in content_type:
r = response.text
else:
r = response.content
else:
return response.text
r = response.text

if not response.ok:
error = None
if 'error' in r:
if is_json and 'error' in r:
error = r['error']
if status_code == 400:
raise exceptions.BadRequestError(error, response)
Expand Down
6 changes: 5 additions & 1 deletion pipedrive/persons.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def get_person(self, person_id, **kwargs):

def get_all_persons(self, params=None, **kwargs):
url = 'persons'
return self._client._get(self._client.BASE_URL + url, params=params, **kwargs)
return self._client._get_all(self._client.BASE_URL + url, params=params, **kwargs)

def get_persons_by_name(self, params=None, **kwargs):
url = 'persons/find'
Expand All @@ -33,3 +33,7 @@ def get_person_deals(self, person_id, **kwargs):
def get_person_fields(self, params=None, **kwargs):
url = 'personFields'
return self._client._get(self._client.BASE_URL + url, params=params, **kwargs)

def get_person_emails(self, person_id, params=None, **kwargs):
url = 'persons/{}/mailMessages'.format(person_id)
return self._client._get_all(self._client.BASE_URL + url, params=params, **kwargs)