diff --git a/pipedrive/client.py b/pipedrive/client.py index 856db91..0a0ef16 100644 --- a/pipedrive/client.py +++ b/pipedrive/client.py @@ -1,3 +1,4 @@ +import time from urllib.parse import urlencode import requests @@ -5,6 +6,7 @@ from pipedrive import exceptions from pipedrive.activities import Activities from pipedrive.deals import Deals +from pipedrive.projects import Projects from pipedrive.filters import Filters from pipedrive.leads import Leads from pipedrive.items import Items @@ -31,6 +33,7 @@ def __init__(self, client_id=None, client_secret=None, domain=None): self.api_token = None self.activities = Activities(self) self.deals = Deals(self) + self.projects = Projects(self) self.filters = Filters(self) self.leads = Leads(self) self.items = Items(self) @@ -44,11 +47,15 @@ def __init__(self, client_id=None, client_secret=None, domain=None): self.stages = Stages(self) self.users = Users(self) self.webhooks = Webhooks(self) + self.requests_session = requests.Session() if domain: if not domain.endswith("/"): domain += "/" self.BASE_URL = domain + "v1/" + else: + self.BASE_URL = self.BASE_URL + "v1/" + def authorization_url(self, redirect_uri, state=None): params = { @@ -116,7 +123,34 @@ 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', 5) + intervaltime = kwargs.get('intervaltime', 2500) + + # 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(self.requests_session.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) as e: + # Do not retry, just return the response. + raise e + except (exceptions.ForbiddenError, exceptions.InternalServerError, exceptions.ServiceUnavailableError, + exceptions.UnknownError, exceptions.TooManyRequestsError): + # Retry! There is hope. + number_of_retries -= 1 + time.sleep(intervaltime / 1000.0) + else: + return self._parse(self.requests_session.request(method, url, headers=_headers, params=_params, **kwargs)) def _parse(self, response): status_code = response.status_code diff --git a/pipedrive/projects.py b/pipedrive/projects.py new file mode 100644 index 0000000..8d2e9e7 --- /dev/null +++ b/pipedrive/projects.py @@ -0,0 +1,77 @@ +class Projects(object): + def __init__(self, client): + self._client = client + + def get_project(self, project_id, **kwargs): + url = "projects/{}".format(project_id) + return self._client._get(self._client.BASE_URL + url, **kwargs) + + def get_all_projects(self, params=None, **kwargs): + url = "projects" + return self._client._get(self._client.BASE_URL + url, params=params, **kwargs) + + def get_all_projects_with_filter(self, filter_id, params=None, **kwargs): + url = "projects?filter_id={}".format(filter_id) + return self._client._get(self._client.BASE_URL + url, params=params, **kwargs) + + def create_project(self, data, **kwargs): + url = "projects" + return self._client._post(self._client.BASE_URL + url, json=data, **kwargs) + + def update_project(self, project_id, data, **kwargs): + url = "projects/{}".format(project_id) + return self._client._put(self._client.BASE_URL + url, json=data, **kwargs) + + def delete_project(self, project_id, **kwargs): + url = "projects/{}".format(project_id) + return self._client._delete(self._client.BASE_URL + url, **kwargs) + + def duplicate_project(self, project_id, **kwargs): + url = "projects/{}/duplicate".format(project_id) + return self._client._post(self._client.BASE_URL + url, **kwargs) + + def get_project_details(self, project_id, **kwargs): + url = "projects/{}".format(project_id) + return self._client._get(self._client.BASE_URL + url, **kwargs) + + def search_projects(self, params=None, **kwargs): + url = "projects/search" + return self._client._get(self._client.BASE_URL + url, params=params, **kwargs) + + def get_project_plan(self, project_id, **kwargs): + url = "projects/{}/plan".format(project_id) + return self._client._get(self._client.BASE_URL + url, **kwargs) + + def get_project_groups(self, project_id, **kwargs): + url = "projects/{}/groups".format(project_id) + return self._client._get(self._client.BASE_URL + url, **kwargs) + + def get_project_tasks(self, project_id, **kwargs): + url = "projects/{}/tasks".format(project_id) + return self._client._get(self._client.BASE_URL + url, **kwargs) + + def get_project_activities(self, project_id, **kwargs): + url = "projects/{}/activities".format(project_id) + return self._client._get(self._client.BASE_URL + url, **kwargs) + + def get_project_fields(self, params=None, **kwargs): + url = "projectFields" + return self._client._get(self._client.BASE_URL + url, params=params, **kwargs) + + def get_all_projects_boards(self, params=None, **kwargs): + url = "projects/boards" + return self._client._get(self._client.BASE_URL + url, params=params, **kwargs) + + def get_board(self, board_id, **kwargs): + url = "projects/boards/{}".format(board_id) + return self._client._get(self._client.BASE_URL + url, **kwargs) + + def get_project_phases(self, board_id, **kwargs): + url = "projects/phases?board_id={}".format(board_id) + return self._client._get(self._client.BASE_URL + url, **kwargs) + + def get_phase(self, phase_id, **kwargs): + url = "projects/phases/{}".format(phase_id) + return self._client._get(self._client.BASE_URL + url, **kwargs) + + diff --git a/pyproject.toml b/pyproject.toml index 0eab7cd..8f12aef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pipedrive-python-lib" -version = "1.2.3" +version = "1.2.5" description = "API wrapper for Pipedrive written in Python" authors = ["Miguel Ferrer "] license = "MIT"