def execute(cls, uri, http_verb, extra_headers=None, batch=False, _body=None, **kw): """ if batch == False, execute a command with the given parameters and return the response JSON. If batch == True, return the dictionary that would be used in a batch command. """ if batch: urlsplitter = urlparse(API_ROOT).netloc ret = {"method": http_verb, "path": uri.split(urlsplitter, 1)[1]} if kw: ret["body"] = kw return ret if not ('app_id' in ACCESS_KEYS and 'rest_key' in ACCESS_KEYS): raise core.ParseError('Missing connection credentials') app_id = ACCESS_KEYS.get('app_id') rest_key = ACCESS_KEYS.get('rest_key') master_key = ACCESS_KEYS.get('master_key') url = uri if uri.startswith(API_ROOT) else cls.ENDPOINT_ROOT + uri if _body is None: data = kw and json.dumps(kw, default=date_handler) or "{}" else: data = _body if http_verb == 'GET' and data and len(urlencode(kw)) > 0: url += '?%s' % urlencode(kw) data = None else: data = data.encode('utf-8') headers = { 'Content-type': 'application/json', 'X-Parse-Application-Id': app_id, 'X-Parse-REST-API-Key': rest_key } headers.update(extra_headers or {}) url = url.replace('classes/User', 'users') # Jarrel edit request = Request(url, data, headers) if ACCESS_KEYS.get('session_token'): request.add_header('X-Parse-Session-Token', ACCESS_KEYS.get('session_token')) elif master_key: request.add_header('X-Parse-Master-Key', master_key) request.get_method = lambda: http_verb try: response = urlopen(request, timeout=CONNECTION_TIMEOUT) except HTTPError as e: exc = { 400: core.ResourceRequestBadRequest, 401: core.ResourceRequestLoginRequired, 403: core.ResourceRequestForbidden, 404: core.ResourceRequestNotFound }.get(e.code, core.ParseError) raise exc(e.read()) return json.loads(response.read().decode('utf-8'))
def batch(self, methods): """ Given a list of create, update or delete methods to call, call all of them in a single batch operation. """ methods = list(methods) # methods can be iterator if not methods: #accepts also empty list (or generator) - it allows call batch directly with query result (eventually empty) return queries, callbacks = list(zip(*[m(batch=True) for m in methods])) # perform all the operations in one batch responses = self.execute("", "POST", requests=queries) # perform the callbacks with the response data (updating the existing # objets, etc) for callback, response in zip(callbacks, responses): if "success" in response: callback(response["success"]) else: raise core.ParseError(response["error"])
def ret(obj, *args, **kw): conn = ACCESS_KEYS if not (conn and conn.get('master_key')): message = '%s requires the master key' % func.__name__ raise core.ParseError(message) func(obj, *args, **kw)
def execute(cls, http_verb, extra_headers=None, batch=False, _body=None, **kw): """ if batch == False, execute a command with the given parameters and return the response JSON. If batch == True, return the dictionary that would be used in a batch command. """ api_root = CONNECTION['api_root'] url, kw = cls.get_url(api_root, **kw) if batch: urlsplitter = urlparse(api_root).netloc ret = {"method": http_verb, "path": url.split(urlsplitter, 1)[1]} if kw: ret["body"] = kw return ret if not (CONNECTION.get('app_id') and CONNECTION.get('rest_key')): raise core.ParseError('Missing connection credentials') if _body is None: data = kw and json.dumps(kw, default=date_handler) or "{}" else: data = _body if http_verb == 'GET' and data: url += '?%s' % urlencode(kw) data = None else: if cls.__name__ == 'File': data = data else: data = data.encode('utf-8') headers = { 'Content-type': 'application/json', 'X-Parse-Application-Id': CONNECTION['app_id'], 'X-Parse-REST-API-Key': CONNECTION['rest_key'] } headers.update(extra_headers or {}) if cls.__name__ == 'File': request = Request(url.encode('utf-8'), data, headers) else: request = Request(url, data, headers) if CONNECTION.get('session_token'): request.add_header('X-Parse-Session-Token', CONNECTION['session_token']) elif CONNECTION.get('master_key'): request.add_header('X-Parse-Master-Key', CONNECTION['master_key']) request.get_method = lambda: http_verb try: response = urlopen(request, timeout=CONNECTION_TIMEOUT) except HTTPError as e: exc = { 400: core.ResourceRequestBadRequest, 401: core.ResourceRequestLoginRequired, 403: core.ResourceRequestForbidden, 404: core.ResourceRequestNotFound }.get(e.code, core.ParseError) raise exc(e.read()) return json.loads(response.read().decode('utf-8'))