You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
5.7 KiB
203 lines
5.7 KiB
# coding: utf8
|
|
|
|
"""
|
|
Yandex.Connect Base API module
|
|
:author: Alexeev Nick
|
|
:email: n@akolka.ru
|
|
:version: 0.01b
|
|
"""
|
|
|
|
import json
|
|
import requests
|
|
import datetime
|
|
import inspect
|
|
|
|
|
|
def json_prepare_dump(obj):
|
|
"""
|
|
Подготовка к json.dumps
|
|
:param obj: объект
|
|
:return: подготовленный объект
|
|
"""
|
|
if isinstance(obj, list):
|
|
for i, item in enumerate(obj):
|
|
obj[i] = json_prepare_dump(item)
|
|
elif isinstance(obj, dict):
|
|
for key in obj:
|
|
obj[key] = json_prepare_dump(obj[key])
|
|
elif type(obj) is datetime.date:
|
|
return obj.isoformat()
|
|
elif isinstance(obj, datetime.datetime):
|
|
return obj.isoformat()
|
|
return obj
|
|
|
|
|
|
def inspect_args_func(frame):
|
|
"""
|
|
Inspect current def arguments
|
|
:param frame: inspect.currentframe()
|
|
:return: dict
|
|
"""
|
|
args, _, _, values = inspect.getargvalues(frame)
|
|
return {key: values[key] for key in args if key != 'self'}
|
|
|
|
|
|
class YandexConnectException(Exception):
|
|
"""
|
|
Exception of module
|
|
"""
|
|
pass
|
|
|
|
|
|
class YandexConnectExceptionY(Exception):
|
|
"""
|
|
Exception by yandex request
|
|
"""
|
|
pass
|
|
|
|
|
|
class YandexConnectRequest(object):
|
|
""" Yandex Connect request API object """
|
|
|
|
_version = None # API version
|
|
_oauth_token = None # OAuth Token
|
|
_org_id = None # Org ID
|
|
_domain = None # Domain
|
|
|
|
def __init__(self, domain, oauth_token, org_id=None, version=6):
|
|
"""
|
|
Init
|
|
:param domain: yandex domain
|
|
:param oauth_token: OAuth Token — https://oauth.yandex.ru/
|
|
:param org_id: Organization id
|
|
:param version: API version
|
|
"""
|
|
self._domain = domain
|
|
self._oauth_token = oauth_token
|
|
self._org_id = org_id
|
|
if version:
|
|
self._version = version
|
|
|
|
def __call__(self, name, data=None, method='post'):
|
|
"""
|
|
Base request method
|
|
:param name: url path
|
|
:param data: data / args of request
|
|
:param method: request method - get/post
|
|
:raise YandexConnectException: bad request, jsonify failed
|
|
:raise YandexConnectExceptionY: yandex exception
|
|
:return: dict
|
|
"""
|
|
url = '%(domain)s/v%(version)s/%(name)s' % {
|
|
'domain': self._domain,
|
|
'version': self._version,
|
|
'name': name
|
|
}
|
|
if not url.endswith('/'):
|
|
url = '%s/' % url
|
|
|
|
if data:
|
|
for key in data.keys():
|
|
if data[key] is None or (isinstance(data[key], dict) and not data[key]):
|
|
del data[key]
|
|
continue
|
|
method = method.lower()
|
|
if method not in ['get', 'post', 'patch', 'delete']:
|
|
raise ValueError('Not right method')
|
|
kwargs = {
|
|
'headers': {
|
|
'Authorization': 'OAuth %s' % self._oauth_token,
|
|
'X-Org-ID': self._org_id if self._org_id else None
|
|
}
|
|
}
|
|
if method in ['post', 'patch']:
|
|
if data:
|
|
module = name.split('/')[0]
|
|
if module.endswith('s'):
|
|
module = module[:-1]
|
|
key_id = '%s_id' % module
|
|
if key_id in data:
|
|
del data[key_id]
|
|
kwargs['data'] = json.dumps(json_prepare_dump(data))
|
|
kwargs['headers']['Content-Type'] = 'application/json'
|
|
else:
|
|
kwargs['params'] = data
|
|
|
|
if not kwargs['headers']['X-Org-ID']:
|
|
del kwargs['headers']['X-Org-ID']
|
|
|
|
try:
|
|
r = getattr(requests, method)(url, **kwargs)
|
|
except Exception:
|
|
raise YandexConnectException(u'Request error: send', name, data)
|
|
if r.status_code > 299:
|
|
try:
|
|
msg = r.json()
|
|
except Exception:
|
|
msg = r.text
|
|
raise YandexConnectExceptionY(r.status_code, msg)
|
|
if method == 'delete':
|
|
return True
|
|
try:
|
|
ret = r.json()
|
|
except Exception:
|
|
return True
|
|
return ret
|
|
|
|
|
|
class YandexConnectBase(object):
|
|
""" Yandex connect API base class"""
|
|
|
|
DOMAIN = None # Request Domain
|
|
|
|
request = None # Request object
|
|
|
|
def __init__(self, oauth_token, org_id=None, version=6):
|
|
"""
|
|
:param oauth_token: OAuth token
|
|
:param org_id: ID org
|
|
:param version: API version
|
|
"""
|
|
self.request = YandexConnectRequest(self.DOMAIN, oauth_token, org_id=org_id, version=version)
|
|
|
|
@staticmethod
|
|
def prepare_fields(fields, title_field, only_title_field=False):
|
|
"""
|
|
Prepare fields data key
|
|
:param fields: obj
|
|
:param title_field: second field
|
|
:param only_title_field: return only title field
|
|
:return:
|
|
"""
|
|
if not fields:
|
|
if not only_title_field:
|
|
fields = ['id', title_field]
|
|
else:
|
|
fields = [title_field]
|
|
if isinstance(fields, list):
|
|
fields = u','.join(fields)
|
|
return fields
|
|
|
|
def list_full(self, callback, default_field, **kwargs):
|
|
"""
|
|
List full
|
|
:param callback: callback function
|
|
:param default_field: default field
|
|
:param kwargs: params
|
|
:return: list
|
|
"""
|
|
kwargs['fields'] = self.prepare_fields(kwargs['fields'], default_field)
|
|
kwargs['per_page'] = 100
|
|
pages = None
|
|
page = 1
|
|
ret = []
|
|
while True:
|
|
kwargs['page'] = page
|
|
r = callback(**kwargs)
|
|
if pages is None:
|
|
pages = r['pages']
|
|
ret += r['result']
|
|
if page >= pages:
|
|
break
|
|
page += 1
|
|
return ret
|
|
|