|
| 1 | +import requests |
| 2 | +from urllib.parse import urlencode, urlparse, quote_plus |
| 3 | +from base64 import b64encode |
| 4 | + |
| 5 | + |
| 6 | +class Client: |
| 7 | + flow_base_url = "https://oauth.pipedrive.com/oauth/" |
| 8 | + oauth_end = "authorize?" |
| 9 | + token_end = "token" |
| 10 | + api_base_url = "" |
| 11 | + example_url = "https://api-proxy.pipedrive.com" |
| 12 | + header = {"Accept": "application/json, */*", "content-type": "application/json"} |
| 13 | + |
| 14 | + def __init__(self, client_id=None, client_secret=None, token=None): |
| 15 | + self.client_id = client_id |
| 16 | + self.client_secret = client_secret |
| 17 | + self.token = token |
| 18 | + |
| 19 | + def make_request(self, method, endpoint, data=None, json=None, **kwargs): |
| 20 | + """ |
| 21 | + this method do the request petition, receive the different methods (post, delete, patch, get) that the api allow |
| 22 | + :param method: |
| 23 | + :param endpoint: |
| 24 | + :param data: |
| 25 | + :param kwargs: |
| 26 | + :return: |
| 27 | + """ |
| 28 | + if self.token: |
| 29 | + self.header["Authorization"] = "Bearer " + self.token |
| 30 | + url = '{0}{1}'.format(self.api_base_url, endpoint) |
| 31 | + |
| 32 | + if method == "get": |
| 33 | + response = requests.request(method, url, headers=self.header, params=kwargs) |
| 34 | + else: |
| 35 | + response = requests.request(method, url, headers=self.header, data=data, json=json) |
| 36 | + return self.parse_response(response) |
| 37 | + else: |
| 38 | + raise Exception("To make petitions the token is necessary") |
| 39 | + |
| 40 | + def _get(self, endpoint, data=None, **kwargs): |
| 41 | + return self.make_request('get', endpoint, data=data, **kwargs) |
| 42 | + |
| 43 | + def _post(self, endpoint, data=None, json=None, **kwargs): |
| 44 | + return self.make_request('post', endpoint, data=data, json=json, **kwargs) |
| 45 | + |
| 46 | + def _delete(self, endpoint, **kwargs): |
| 47 | + return self.make_request('delete', endpoint, **kwargs) |
| 48 | + |
| 49 | + def _patch(self, endpoint, data=None, json=None, **kwargs): |
| 50 | + return self.make_request('patch', endpoint, data=data, json=json, **kwargs) |
| 51 | + |
| 52 | + def _put(self, endpoint, json=None, **kwargs): |
| 53 | + return self.make_request('put', endpoint, json=json, **kwargs) |
| 54 | + |
| 55 | + def parse_response(self, response): |
| 56 | + """ |
| 57 | + This method get the response request and returns json data or raise exceptions |
| 58 | + :param response: |
| 59 | + :return: |
| 60 | + """ |
| 61 | + if response.status_code == 204 or response.status_code == 201: |
| 62 | + return True |
| 63 | + elif response.status_code == 400: |
| 64 | + raise Exception( |
| 65 | + "The URL {0} retrieved an {1} error. Please check your request body and try again.\nRaw message: {2}".format( |
| 66 | + response.url, response.status_code, response.text)) |
| 67 | + elif response.status_code == 401: |
| 68 | + raise Exception( |
| 69 | + "The URL {0} retrieved and {1} error. Please check your credentials, make sure you have permission to perform this action and try again.".format( |
| 70 | + response.url, response.status_code)) |
| 71 | + elif response.status_code == 403: |
| 72 | + raise Exception( |
| 73 | + "The URL {0} retrieved and {1} error. Please check your credentials, make sure you have permission to perform this action and try again.".format( |
| 74 | + response.url, response.status_code)) |
| 75 | + elif response.status_code == 404: |
| 76 | + raise Exception( |
| 77 | + "The URL {0} retrieved an {1} error. Please check the URL and try again.\nRaw message: {2}".format( |
| 78 | + response.url, response.status_code, response.text)) |
| 79 | + elif response.status_code == 410: |
| 80 | + raise Exception( |
| 81 | + "The URL {0} retrieved an {1} error. Please check the URL and try again.\nRaw message: {2}".format( |
| 82 | + response.url, response.status_code, response.text)) |
| 83 | + elif response.status_code == 422: |
| 84 | + raise Exception( |
| 85 | + "The URL {0} retrieved an {1} error. Please check the URL and try again.\nRaw message: {2}".format( |
| 86 | + response.url, response.status_code, response.text)) |
| 87 | + elif response.status_code == 429: |
| 88 | + raise Exception( |
| 89 | + "The URL {0} retrieved an {1} error. Please check the URL and try again.\nRaw message: {2}".format( |
| 90 | + response.url, response.status_code, response.text)) |
| 91 | + elif response.status_code == 500: |
| 92 | + raise Exception( |
| 93 | + "The URL {0} retrieved an {1} error. Please check the URL and try again.\nRaw message: {2}".format( |
| 94 | + response.url, response.status_code, response.text)) |
| 95 | + elif response.status_code == 501: |
| 96 | + raise Exception( |
| 97 | + "The URL {0} retrieved an {1} error. Please check the URL and try again.\nRaw message: {2}".format( |
| 98 | + response.url, response.status_code, response.text)) |
| 99 | + return response.json() |
| 100 | + |
| 101 | + def get_oauth_uri(self, redirect_uri, state=None): |
| 102 | + if redirect_uri is not None: |
| 103 | + params = { |
| 104 | + 'client_id': self.client_id, |
| 105 | + 'redirect_uri': redirect_uri, |
| 106 | + # 'scope': ' '.join(scope), |
| 107 | + } |
| 108 | + if state is not None: |
| 109 | + params['state'] = state |
| 110 | + url = self.flow_base_url + self.oauth_end + urlencode(params) |
| 111 | + print(url) |
| 112 | + return url |
| 113 | + else: |
| 114 | + raise Exception("The attributes necessary to get the url were not obtained.") |
| 115 | + |
| 116 | + def exchange_code(self, redirect_uri, code): |
| 117 | + if redirect_uri is not None and code is not None: |
| 118 | + url = self.flow_base_url + self.token_end |
| 119 | + authorization = '{0}:{1}'.format(self.client_id, self.client_secret) |
| 120 | + header = {'Authorization': 'Basic {0}'.format(b64encode(authorization.encode('UTF-8')).decode('UTF-8'))} |
| 121 | + args = {'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri} |
| 122 | + response = requests.post(url, headers=header, data=args) |
| 123 | + return self.parse_response(response) |
| 124 | + else: |
| 125 | + raise Exception("The attributes necessary to exchange the code were not obtained.") |
| 126 | + |
| 127 | + def refresh_token(self, refresh_token): |
| 128 | + if refresh_token is not None: |
| 129 | + url = self.flow_base_url + self.token_end |
| 130 | + data = { |
| 131 | + 'client_id': self.client_id, |
| 132 | + 'client_secret': self.client_secret, |
| 133 | + 'grant_type': "refresh_token", |
| 134 | + 'refresh_token': refresh_token, |
| 135 | + } |
| 136 | + response = requests.post(url, data=data) |
| 137 | + return self.parse_response(response) |
| 138 | + else: |
| 139 | + raise Exception("The attributes necessary to refresh the token were not obtained.") |
| 140 | + |
| 141 | + def set_token(self, token): |
| 142 | + """ |
| 143 | + Sets the Token for its use in this library. |
| 144 | + :param token: |
| 145 | + :return: |
| 146 | + """ |
| 147 | + if token: |
| 148 | + self.token = token |
| 149 | + |
| 150 | + def get_deals(self, **kwargs): |
| 151 | + url = "{0}/deals".format(self.api_base_url) |
| 152 | + return self._get(url, **kwargs) |
| 153 | + |
| 154 | + def create_deal(self, **kwargs): |
| 155 | + url = "{0}/deals".format(self.api_base_url) |
| 156 | + if kwargs is not None: |
| 157 | + params = {} |
| 158 | + params.update(kwargs) |
| 159 | + return self._post(url, json=params) |
| 160 | + |
| 161 | + def duplicate_deal(self, deal_id): |
| 162 | + if deal_id is not None: |
| 163 | + url = "{0}/deals/{1}/duplicate".format(self.api_base_url, deal_id) |
| 164 | + return self._post(url) |
0 commit comments