diff --git a/.gitignore b/.gitignore index 9325160..dc1ff5a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.swp *.pyc - +/*.egg-info +/dist/ diff --git a/Intaro.py b/Intaro.py deleted file mode 100644 index a423e14..0000000 --- a/Intaro.py +++ /dev/null @@ -1,217 +0,0 @@ -import requests, json - -class IntaroApy: - """Intaro Api wrapper""" - - apiVersion = '3' - - def __init__(self, crmUrl, apiKey): - self.apiUrl = crmUrl + '/api/v' + IntaroApy.apiVersion + '/' - self.apiKey = apiKey - self.parameters = { 'apiKey': apiKey } - - def requestApi(self, url, method='GET', format='json'): - - #TODO: catch http exceptions - if method == 'GET': - result = requests.get(url, params=self.parameters) - elif method == 'POST': - result = requests.post(url, data=self.parameters) - - statusCode = result.status_code - r = result.json() - - # reset params dict - self.parameters = { 'apiKey': self.apiKey } - - if statusCode > 400 or r.has_key('success') and r['success'] == False : - #TODO: raise ApiException - pass - - if r.has_key('generatedAt') : - self.generatedAt = r['generatedAt'] - del r['generatedAt'] - - del r['success'] - - return r - - def getErrorMessage(self, response) : - if type(response) is not dict : return '' - err = '' - - if response.has_key('message'): - err = response['message'] - elif response.has_key('error') : - err = response['error']['message'] - elif response.has_key('errorMsg') : - err = response['errorMsg'] - - if len(err) == 0 : return 'Application Error' - - return err - - def orderGet(self, id, by='externalId') : - url = self.apiUrl + 'orders/' + str(id) - - if by != 'externalId' : - self.parameters['by'] = by - - return self.requestApi(url) - - def orderCreate(self, order) : - dataJson = json.dumps(order) - self.parameters['order'] = dataJson - - url = self.apiUrl + 'orders/create' - return self.requestApi(url, 'POST') - - def orderEdit(self, order) : - dataJson = json.dumps(order) - self.parameters['order'] = dataJson - - url = self.apiUrl + 'orders/' + str(order['externalId']) + '/edit' - return self.requestApi(url, 'POST') - - def orderUpload(self, orders) : - dataJson = json.dumps(orders) - self.parameters['orders'] = dataJson - - url = self.apiUrl + 'orders/' + str(order['externalId']) + '/edit' - result = self.requestApi(url, 'POST') - - if type(result) is dict and result.has_key('uploadedOrders') : - return result['uploadedOrders'] - else : - return result - - def orderFixExternalIds(self, orders) : - dataJson = json.dumps(orders) - self.parameters['orders'] = dataJson - - url = self.apiUrl + 'orders/fix-external-ids' - return self.requestApi(url, 'POST') - - def orderHistory(self, startDate='', endDate='', limit=100, offset=0) : - url = self.apiUrl + 'orders/history' - self.parameters['startDate'] = startDate - self.parameters['endDate'] = endDate - self.parameters['limit'] = limit - self.parameters['offset'] = offset - - return self.requestApi(url) - - def customerGet(self, id, by='externalId') : - url = self.apiUrl + 'customers/' + str(id) - - if by != 'externalId' : - self.parameters['by'] = by - - return self.requestApi(url) - - def customers(self, phone=None, email=None, fio=None, limit=200, offset=0) : - url = self.apiUrl + 'customers' - - if email : - self.parameters['email'] = email - if phone : - self.parameters['phone'] = phone - if fio : - self.parameters['fio'] = fio - - self.parameters['limit'] = limit - self.parameters['offset'] = offset - - return self.requestApi(url) - - def customerCreate(self, customer) : - dataJson = json.dumps(customer) - self.parameters['customer'] = dataJson - - url = self.apiUrl + 'customers/create' - return self.requestApi(url, 'POST') - - def customerEdit(self, customer) : - dataJson = json.dumps(customer) - self.parameters['customer'] = dataJson - - url = self.apiUrl + 'customers/' + customer['externalId'] + '/edit' - return self.requestApi(url, 'POST') - - def customerUpload(self, customers) : - dataJson = json.dumps(customers) - self.parameters['customers'] = dataJson - - url = self.apiUrl + 'customers/upload' - result = self.requestApi(url, 'POST') - - if type(result) is dict and result.has_key('uploaded') : - return result['uploaded'] - else : - return result - - def deliveryTypesList(self) : - url = self.apiUrl + 'reference/delivery-types' - return self.requestApi(url) - - def deliveryTypeEdit(self, deliveryType) : - dataJson = json.dumps(deliveryType) - self.parameters['deliveryType'] = dataJson - - url = self.apiUrl + 'reference/delivery-types/' + deliveryType['code'] + '/edit' - return self.requestApi(url, 'POST') - - def deliveryServicesList(self) : - url = self.apiUrl + 'reference/delivery-services' - return self.requestApi(url) - - def deliveryServiceEdit(self, deliveryService) : - dataJson = json.dumps(deliveryService) - self.parameters['deliveryService'] = dataJson - - url = self.apiUrl + 'reference/delivery-services/' + deliveryService['code'] + '/edit' - return self.requestApi(url, 'POST') - - def paymentTypesList(self) : - url = self.apiUrl + 'reference/payment-types' - return self.requestApi(url) - - def paymentTypesEdit(self, paymentType) : - dataJson = json.dumps(paymentType) - self.parameters['paymentType'] = dataJson - - url = self.apiUrl + 'reference/payment-types/' + paymentType['code'] + '/edit' - return self.requestApi(url, 'POST') - - def orderTypesList(self) : - url = self.apiUrl + 'reference/order-types' - return self.requestApi(url) - - def orderTypesEdit(self, orderType) : - dataJson = json.dumps(orderType) - self.parameters['orderType'] = dataJson - - url = self.apiUrl + 'reference/order-types/' + orderType['code'] + '/edit' - return self.requestApi(url, 'POST') - - def orderMethodsList(self) : - url = self.apiUrl + 'reference/order-methods' - return self.requestApi(url) - - def orderMethodsEdit(self, orderMethod) : - dataJson = json.dumps(orderMethod) - self.parameters['orderMethod'] = dataJson - - url = self.apiUrl + 'reference/order-methods/' + orderMethod['code'] + '/edit' - return self.requestApi(url, 'POST') - - def orderStatusesList(self) : - url = self.apiUrl + 'reference/statuses' - return self.requestApi(url) - - def orderStatusEdit(self, status) : - dataJson = json.dumps(orderStatuse) - self.parameters['status'] = dataJson - - url = self.apiUrl + 'reference/statuses/' + status['code'] + '/edit' - return self.requestApi(url, 'POST') diff --git a/README.md b/README.md index 67390d0..27d3c97 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,31 @@ -api-client-python -================= +retailCRM API python client +=========================== -REST API client for Python +### Install + +``` +pip install retailcrm +``` + +### Usage + +```python +import retailcrm + + +client = retailcrm.Client('https://demo.intarocrm.ru', 'uLxXKBwjQteE9NkO3cJAqTXNwvKktaTc') + +order = { + 'firstName': 'Ivan', + 'lastName': 'Ivanov', + 'phone': '+79000000000', + 'email': 'ivan@example.com', + 'orderMethod': 'call-request', +} + +result = crm.orders_create(order) +``` + +### Documentation + +* http://www.retailcrm.pro/docs/Developers/ApiVersion3 diff --git a/retailcrm/__init__.py b/retailcrm/__init__.py new file mode 100644 index 0000000..e84d0e5 --- /dev/null +++ b/retailcrm/__init__.py @@ -0,0 +1,2 @@ +from client import Client +from response import Response diff --git a/retailcrm/client.py b/retailcrm/client.py new file mode 100644 index 0000000..5eb68a8 --- /dev/null +++ b/retailcrm/client.py @@ -0,0 +1,642 @@ +# coding=utf-8 +import requests +import json +from response import Response + + +class Client(object): + """retailCRM API client""" + + apiVersion = '3' + + def __init__(self, crm_url, api_key): + self.apiUrl = crm_url + '/api/v' + self.apiVersion + '/' + self.apiKey = api_key + self.parameters = {'apiKey': api_key} + + def make_request(self, url, method='GET'): + """ + :param url: string + :param method: string + :return: Response + """ + global result + if method == 'GET': + result = requests.get(url, params=self.parameters) + elif method == 'POST': + result = requests.post(url, data=self.parameters) + + response_code = result.status_code + response_body = result.json() + + return Response(response_code, response_body) + + def orders(self, filters, limit=20, page=1): + """ + :param filters: array + :param limit: integer + :param page: integer + :return: Response + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + url = self.apiUrl + 'orders' + + return self.make_request(url) + + def orders_get(self, uid, by='externalId', site=None): + """ + :param uid: string + :param by: string + :param site: string + :return: Response + """ + url = self.apiUrl + 'orders/' + str(uid) + + if site is not None: + self.parameters['site'] = site + + if by != 'externalId': + self.parameters['by'] = by + + return self.make_request(url) + + def orders_create(self, order, site=None): + """ + + :param order: + :param site: + :return: + """ + data_json = json.dumps(order) + self.parameters['order'] = data_json + + if site is not None: + self.parameters['site'] = site + + url = self.apiUrl + 'orders/create' + + return self.make_request(url, 'POST') + + def orders_edit(self, order, site=None): + """ + + :param order: + :param site: + :return: + """ + data_json = json.dumps(order) + self.parameters['order'] = data_json + + if site is not None: + self.parameters['site'] = site + + url = self.apiUrl + 'orders/' + str(order['externalId']) + '/edit' + + return self.make_request(url, 'POST') + + def orders_upload(self, orders, site=None): + """ + + :param orders: + :param site: + :return: + """ + data_json = json.dumps(orders) + self.parameters['orders'] = data_json + + if site is not None: + self.parameters['site'] = site + + url = self.apiUrl + 'orders/upload' + + return self.make_request(url, 'POST') + + def orders_fix_external_ids(self, orders, site=None): + """ + + :param orders: + :param site: + :return: + """ + data_json = json.dumps(orders) + self.parameters['orders'] = data_json + + if site is not None: + self.parameters['site'] = site + + url = self.apiUrl + 'orders/fix-external-ids' + + return self.make_request(url, 'POST') + + def orders_statuses(self, ids, external_ids): + """ + + :param ids: + :param external_ids: + :return: + """ + self.parameters['ids'] = ids + self.parameters['externalIds'] = external_ids + url = self.apiUrl + 'orders/statuses' + + return self.make_request(url) + + def orders_history(self, start_date=None, end_date=None, limit=100, offset=0, skip_my_changes=True): + """ + + :param start_date: + :param end_date: + :param limit: + :param offset: + :param skip_my_changes: + :return: + """ + self.parameters['startDate'] = start_date + self.parameters['endDate'] = end_date + self.parameters['limit'] = limit + self.parameters['offset'] = offset + self.parameters['skipMyChanges'] = skip_my_changes + url = self.apiUrl + 'orders/history' + + return self.make_request(url) + + def customers(self, filters, limit=20, page=0): + """ + + :param filters: + :param limit: + :param page: + :return: + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + url = self.apiUrl + 'customers' + + return self.make_request(url) + + def customers_get(self, uid, by='externalId', site=None): + """ + + :param uid: + :param by: + :param site: + :return: + """ + url = self.apiUrl + 'customers/' + str(uid) + + if by != 'externalId': + self.parameters['by'] = by + + if site is not None: + self.parameters['site'] = site + + return self.make_request(url) + + def customers_create(self, customer, site=None): + """ + + :param customer: + :param site: + :return: + """ + data_json = json.dumps(customer) + self.parameters['customer'] = data_json + + if site is not None: + self.parameters['site'] = site + + url = self.apiUrl + 'customers/create' + + return self.make_request(url, 'POST') + + def customers_edit(self, customer, site=None): + """ + + :param customer: + :param site: + :return: + """ + data_json = json.dumps(customer) + self.parameters['customer'] = data_json + + if site is not None: + self.parameters['site'] = site + + url = self.apiUrl + 'customers/' + customer['externalId'] + '/edit' + return self.make_request(url, 'POST') + + def customers_upload(self, customers, site=None): + """ + + :param customers: + :param site: + :return: + """ + data_json = json.dumps(customers) + self.parameters['customers'] = data_json + + if site is not None: + self.parameters['site'] = site + + url = self.apiUrl + 'customers/upload' + + return self.make_request(url, 'POST') + + def customers_fix_external_ids(self, customers, site=None): + """ + + :param customers: + :param site: + :return: + """ + data_json = json.dumps(customers) + self.parameters['customers'] = data_json + + if site is not None: + self.parameters['site'] = site + + url = self.apiUrl + 'customers/fix-external-ids' + + return self.make_request(url, 'POST') + + def inventories(self, filters, limit=20, page=1): + """ + + :param filters: + :param limit: + :param page: + :return: + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + url = self.apiUrl + 'store/inventories' + + return self.make_request(url) + + def inventories_upload(self, offers): + """ + + :param offers: + :return: + """ + data_json = json.dumps(offers) + self.parameters['offers'] = data_json + url = self.apiUrl + 'store/inventories/upload' + + return self.make_request(url, 'POST') + + def packs(self, filters, limit=20, page=1): + """ + + :param filters: + :param limit: + :param page: + :return: + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + url = self.apiUrl + 'orders/packs' + + return self.make_request(url) + + def packs_get(self, uid): + """ + + :param uid: + :return: + """ + url = self.apiUrl + 'orders/packs/' + str(uid) + + return self.make_request(url) + + def packs_create(self, pack): + """ + + :param pack: + :return: + """ + data_json = json.dumps(pack) + self.parameters['pack'] = data_json + url = self.apiUrl + 'orders/packs/create' + + return self.make_request(url, 'POST') + + def packs_edit(self, pack, uid): + """ + + :param pack: + :param uid: + :return: + """ + data_json = json.dumps(pack) + self.parameters['pack'] = data_json + url = self.apiUrl + 'orders/packs/' + str(uid) + '/edit' + + return self.make_request(url, 'POST') + + def packs_delete(self, uid): + """ + + :param uid: + :return: + """ + url = self.apiUrl + 'orders/packs/' + str(uid) + '/delete' + + return self.make_request(url, 'POST') + + def packs_history(self, filters, limit=20, page=1): + """ + + :param filters: + :param limit: + :param page: + :return: + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + url = self.apiUrl + 'orders/packs/history' + + return self.make_request(url) + + def countries(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/countries' + + return self.make_request(url) + + def delivery_types(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/delivery-types' + + return self.make_request(url) + + def delivery_types_edit(self, delivery_type): + """ + + :param delivery_type: + :return: + """ + data_json = json.dumps(delivery_type) + self.parameters['deliveryType'] = data_json + url = self.apiUrl + 'reference/delivery-types/' + delivery_type['code'] + '/edit' + + return self.make_request(url, 'POST') + + def delivery_services(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/delivery-services' + + return self.make_request(url) + + def delivery_services_edit(self, delivery_service): + """ + + :param delivery_service: + :return: + """ + data_json = json.dumps(delivery_service) + self.parameters['deliveryService'] = data_json + url = self.apiUrl + 'reference/delivery-services/' + delivery_service['code'] + '/edit' + + return self.make_request(url, 'POST') + + def payment_types(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/payment-types' + + return self.make_request(url) + + def payment_types_edit(self, payment_type): + """ + + :param payment_type: + :return: + """ + data_json = json.dumps(payment_type) + self.parameters['paymentType'] = data_json + url = self.apiUrl + 'reference/payment-types/' + payment_type['code'] + '/edit' + + return self.make_request(url, 'POST') + + def payment_statuses(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/payment-statuses' + + return self.make_request(url) + + def payment_statuses_edit(self, payment_status): + """ + + :param payment_status: + :return: + """ + data_json = json.dumps(payment_status) + self.parameters['paymentStatus'] = data_json + url = self.apiUrl + 'reference/payment-statuses/' + payment_status['code'] + '/edit' + + return self.make_request(url, 'POST') + + def product_statuses(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/product-statuses' + + return self.make_request(url) + + def product_statuses_edit(self, product_status): + """ + + :param product_status: + :return: + """ + data_json = json.dumps(product_status) + self.parameters['productStatus'] = data_json + url = self.apiUrl + 'reference/product-statuses/' + product_status['code'] + '/edit' + + return self.make_request(url, 'POST') + + def order_types(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/order-types' + + return self.make_request(url) + + def order_types_edit(self, order_type): + """ + + :param order_type: + :return: + """ + data_json = json.dumps(order_type) + self.parameters['orderType'] = data_json + url = self.apiUrl + 'reference/order-types/' + order_type['code'] + '/edit' + + return self.make_request(url, 'POST') + + def order_methods(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/order-methods' + + return self.make_request(url) + + def order_methods_edit(self, order_method): + """ + + :param order_method: + :return: + """ + data_json = json.dumps(order_method) + self.parameters['orderMethod'] = data_json + url = self.apiUrl + 'reference/order-methods/' + order_method['code'] + '/edit' + + return self.make_request(url, 'POST') + + def status_groups(self): + """ + :return + """ + url = self.apiUrl + 'reference/status-groups' + + return self.make_request(url) + + def statuses(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/statuses' + + return self.make_request(url) + + def statuses_edit(self, status): + """ + + :param status: + :return: + """ + data_json = json.dumps(status) + self.parameters['status'] = data_json + url = self.apiUrl + 'reference/statuses/' + status['code'] + '/edit' + + return self.make_request(url, 'POST') + + def stores(self): + """ + + :return: + """ + url = self.apiUrl + 'reference/stores' + + return self.make_request(url) + + def stores_edit(self, store): + """ + + :param store: + :return: + """ + data_json = json.dumps(store) + self.parameters['status'] = data_json + url = self.apiUrl + 'reference/stores/' + store['code'] + '/edit' + + return self.make_request(url, 'POST') + + def statistic_update(self): + """ + :return + """ + url = self.apiUrl + 'statistic/update' + + return self.make_request(url) + + def telephony_call_event(self, phone, call_type, code, status): + """ + + :param phone: + :param call_type: + :param code: + :param status: + :return: + """ + self.parameters['hangupStatus'] = status + self.parameters['phone'] = phone + self.parameters['code'] = code + self.parameters['type'] = call_type + url = self.apiUrl + 'telephony/call/event' + + return self.make_request(url, 'POST') + + def telephony_calls_upload(self, calls): + """ + + :param calls: + :return: + """ + data_json = json.dumps(calls) + self.parameters['calls'] = data_json + url = self.apiUrl + 'telephony/calls/upload' + + return self.make_request(url, 'POST') + + def telephony_settings(self, code, client_id, make_call_url, active, name, image): + """ + + :param code: + :param client_id: + :param make_call_url: + :param active: + :param name: + :param image: + :return: + """ + self.parameters['code'] = code + self.parameters['clientId'] = client_id + self.parameters['makeCallUrl'] = make_call_url + self.parameters['active'] = active + self.parameters['name'] = name + self.parameters['image'] = image + url = self.apiUrl + 'telephony/settings/' + str(code) + + return self.make_request(url, 'POST') + + def telephony_manager(self, phone, details=True): + """ + + :param phone: + :param details: + :return: + """ + self.parameters['phone'] = phone + self.parameters['details'] = details + url = self.apiUrl + 'telephony/manager' + + return self.make_request(url) diff --git a/retailcrm/response.py b/retailcrm/response.py new file mode 100644 index 0000000..8ca3e35 --- /dev/null +++ b/retailcrm/response.py @@ -0,0 +1,29 @@ +# coding=utf-8 + + +class Response(object): + """ + API response class + """ + + def __init__(self, code, body): + self.response_body = body + self.status_code = code + + def get_status_code(self): + """ + :return: integer + """ + return self.status_code + + def get_response(self): + """ + :return: dict + """ + return self.response_body + + def is_successfull(self): + """ + :return: boolean + """ + return int(self.status_code) < 400 diff --git a/setup.py b/setup.py index 6b62553..61990d0 100644 --- a/setup.py +++ b/setup.py @@ -1,14 +1,16 @@ -from os.path import join, dirname - +# coding=utf-8 from setuptools import setup - setup( - name='api-client-python', - version=0.1, - long_description=open(join(dirname(__file__), 'README.md')).read(), - author='Intarocrm', - package_data={}, - install_requires=[u'requests', ], - url='https://github.com/intarocrm/api-client-python.git' -) \ No newline at end of file + name='retailcrm', + version='3.0.5', + description='Client for retailCRM API', + url='https://github.com/retailcrm/api-client-python', + author='retailCRM', + author_email='integration@retailcrm.ru', + keywords='crm, saas, rest, e-commerce', + license='MIT', + packages=['retailcrm'], + package_data={}, + install_requires=['requests'] +)