├── LICENSE ├── README.md ├── examples └── example.py └── zadarma ├── __init__.py └── api.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Evgeniy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zadarma-py-api 2 | Class which help you work with API Zadarma (v1) 3 | 4 | ## Requirements: 5 | - Python 3.X or Python 2.X 6 | 7 | ## How to use? 8 | An official documentation on Zadarma API is [here](https://zadarma.com/support/api/). 9 | 10 | Keys for authorization are in [personal account](https://my.zadarma.com/api/). 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from zadarma import api 4 | 5 | if __name__ == '__main__': 6 | z_api = api.ZadarmaAPI(key='YOU_KEY', secret='YOUR_SECRET') 7 | # get tariff information 8 | z_api.call('/v1/tariff/') 9 | # set callerid for your sip number 10 | z_api.call('/v1/sip/callerid/', {'id': '1234567', 'number': '71234567890'}, 'PUT') 11 | # get information about coast 12 | z_api.call('/v1/info/price/', {'number': '71234567891', 'caller_id': '71234567890'}) 13 | -------------------------------------------------------------------------------- /zadarma/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __version__ = '1.0.0' -------------------------------------------------------------------------------- /zadarma/api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __version__ = '1.1.0' 3 | import sys 4 | from hashlib import sha1, md5 5 | from collections import OrderedDict 6 | if sys.version_info.major > 2: 7 | from urllib.parse import urlencode 8 | else: 9 | from urllib import urlencode 10 | import hmac 11 | import requests 12 | import base64 13 | 14 | 15 | class ZadarmaAPI(object): 16 | 17 | def __init__(self, key, secret, is_sandbox=False): 18 | """ 19 | Constructor 20 | :param key: key from personal 21 | :param secret: secret from personal 22 | :param is_sandbox: (True|False) 23 | """ 24 | self.key = key 25 | self.secret = secret 26 | self.is_sandbox = is_sandbox 27 | self.__url_api = 'https://api.zadarma.com' 28 | if is_sandbox: 29 | self.__url_api = 'https://api-sandbox.zadarma.com' 30 | 31 | def call(self, method, params={}, request_type='GET', format='json', is_auth=True): 32 | """ 33 | Function for send API request 34 | :param method: API method, including version number 35 | :param params: Query params 36 | :param request_type: (get|post|put|delete) 37 | :param format: (json|xml) 38 | :param is_auth: (True|False) 39 | :return: response 40 | """ 41 | request_type = request_type.upper() 42 | if request_type not in ['GET', 'POST', 'PUT', 'DELETE']: 43 | request_type = 'GET' 44 | params['format'] = format 45 | auth_str = None 46 | is_nested_data = False 47 | for k in params.values(): 48 | if not isinstance(k, str): 49 | is_nested_data = True 50 | break 51 | if is_nested_data: 52 | params_string = self.__http_build_query(OrderedDict(sorted(params.items()))) 53 | params = params_string 54 | else: 55 | params_string = urlencode(OrderedDict(sorted(params.items()))) 56 | 57 | if is_auth: 58 | auth_str = self.__get_auth_string_for_header(method, params_string) 59 | 60 | if request_type == 'GET': 61 | result = requests.get(self.__url_api + method + '?' + params_string, headers={'Authorization': auth_str}) 62 | elif request_type == 'POST': 63 | result = requests.post(self.__url_api + method, headers={'Authorization': auth_str}, data=params) 64 | elif request_type == 'PUT': 65 | result = requests.put(self.__url_api + method, headers={'Authorization': auth_str}, data=params) 66 | elif request_type == 'DELETE': 67 | result = requests.delete(self.__url_api + method, headers={'Authorization': auth_str}, data=params) 68 | return result.text 69 | 70 | def __http_build_query(self, data): 71 | parents = list() 72 | pairs = dict() 73 | 74 | def renderKey(parents): 75 | depth, outStr = 0, '' 76 | for x in parents: 77 | s = "[%s]" if depth > 0 or isinstance(x, int) else "%s" 78 | outStr += s % str(x) 79 | depth += 1 80 | return outStr 81 | 82 | def r_urlencode(data): 83 | if isinstance(data, list) or isinstance(data, tuple): 84 | for i in range(len(data)): 85 | parents.append(i) 86 | r_urlencode(data[i]) 87 | parents.pop() 88 | elif isinstance(data, dict): 89 | for key, value in data.items(): 90 | parents.append(key) 91 | r_urlencode(value) 92 | parents.pop() 93 | else: 94 | pairs[renderKey(parents)] = str(data) 95 | 96 | return pairs 97 | return urlencode(r_urlencode(data)) 98 | 99 | def __get_auth_string_for_header(self, method, params_string): 100 | """ 101 | :param method: API method, including version number 102 | :param params: Query params dict 103 | :return: auth header 104 | """ 105 | data = method + params_string + md5(params_string.encode('utf8')).hexdigest() 106 | hmac_h = hmac.new(self.secret.encode('utf8'), data.encode('utf8'), sha1) 107 | if sys.version_info.major > 2: 108 | bts = bytes(hmac_h.hexdigest(), 'utf8') 109 | else: 110 | bts = bytes(hmac_h.hexdigest()).encode('utf8') 111 | auth = self.key + ':' + base64.b64encode(bts).decode() 112 | return auth 113 | --------------------------------------------------------------------------------