|
| 1 | +""" |
| 2 | +Mango Python Library Client |
| 3 | +""" |
| 4 | +import json |
| 5 | + |
| 6 | +import requests |
| 7 | +from requests.exceptions import ConnectionError |
| 8 | + |
| 9 | +from .error import UnableToConnect, AuthenticationError, NotFound, \ |
| 10 | + InputValidationError, InputValidationGenericError, \ |
| 11 | + UnhandledError, MethodNotAllowed |
| 12 | + |
| 13 | + |
| 14 | +BASE_URL = "https://api.getmango.com" |
| 15 | +HEADERS = {"content-type": "application/json"} |
| 16 | + |
| 17 | + |
| 18 | +def req(api_key, method, endpoint, data=None, params=None): |
| 19 | + """ |
| 20 | + Make request and return a Python object from the JSON response. If |
| 21 | + HTTP method is DELETE return True for 204 response, false otherwise. |
| 22 | +
|
| 23 | + :param api_key: String with the API key |
| 24 | + :param method: String with the HTTP method |
| 25 | + :param endpoint: String with the URL |
| 26 | + :param data: Dictionary with data that will be sent |
| 27 | + :param params: Dictionary with query strings |
| 28 | + :return: Native python object resulting of the JSON deserialization of the API response |
| 29 | + """ |
| 30 | + if data: |
| 31 | + data = json.dumps(data) |
| 32 | + |
| 33 | + try: |
| 34 | + response = requests.request( |
| 35 | + method, |
| 36 | + build_url(endpoint), |
| 37 | + data=data, |
| 38 | + params=params, |
| 39 | + auth=(api_key, ""), |
| 40 | + headers=HEADERS |
| 41 | + ) |
| 42 | + except ConnectionError: |
| 43 | + raise UnableToConnect |
| 44 | + |
| 45 | + # Success |
| 46 | + if 200 <= response.status_code <= 206: |
| 47 | + if response.request.method == "DELETE": |
| 48 | + return response.status_code == 204 or response.status_code == 200 |
| 49 | + |
| 50 | + return response.json() |
| 51 | + |
| 52 | + # Error handling |
| 53 | + if response.status_code == 400: |
| 54 | + try: |
| 55 | + input_validation_error = response.json() |
| 56 | + errors = input_validation_error.get("errors")[0] |
| 57 | + error_code, error_message = errors.items()[0] |
| 58 | + except: |
| 59 | + raise InputValidationGenericError("{status_code}: {text}".format( |
| 60 | + status_code=response.status_code, |
| 61 | + text=response.text |
| 62 | + )) |
| 63 | + raise InputValidationError(error_code, error_message) |
| 64 | + elif response.status_code == 404: |
| 65 | + raise NotFound |
| 66 | + elif response.status_code == 401: |
| 67 | + raise AuthenticationError |
| 68 | + elif response.status_code == 404: |
| 69 | + raise NotFound |
| 70 | + elif response.status_code == 405: |
| 71 | + raise MethodNotAllowed |
| 72 | + |
| 73 | + raise UnhandledError("{status_code}: {text}".format( |
| 74 | + status_code=response.status_code, |
| 75 | + text=response.text |
| 76 | + )) |
| 77 | + |
| 78 | + |
| 79 | +def build_url(endpoint): |
| 80 | + """ |
| 81 | + Build complete URL from API endpoint |
| 82 | +
|
| 83 | + :param endpoint: String with the endpoint, ex: /v1/charges/ |
| 84 | + :return: String with complete URL, ex: https://api.getmango.com/v1/charges/ |
| 85 | + """ |
| 86 | + return "{base_url}/{endpoint}".format( |
| 87 | + base_url=BASE_URL, |
| 88 | + endpoint=endpoint |
| 89 | + ) |
0 commit comments