def _load(self) -> UnindexedData: logger.debug('loading from %s', self._file_path) try: # If the file is accessible but empty, consider data loaded and return empty dictionary if os.stat(self._file_path).st_size == 0: logger.debug('file %s is empty', self._file_path) return {} except FileNotFoundError: # If the file does not exist, consider data loaded and return empty dictionary logger.debug('file %s does not exist', self._file_path) return {} try: with open(self._file_path, 'rb') as f: data = f.read() return json_utils.loads(data, allow_extended_types=True) except Exception as e: if not self._use_backup: raise # Upon failure, if using a backup, simply log the error and attempt to load from backup file logger.error('failed to load from %s: %s', self._file_path, e, exc_info=True) backup_file_path = self._get_backup_file_path() logger.warning('loading from backup %s', backup_file_path) with open(backup_file_path, 'rb') as f: return json_utils.loads(f.read(), allow_extended_types=True)
async def request(self, method: str, path: str, body: Any = None, admin_password: Optional[str] = None, no_log: bool = False) -> Any: http_client = httpclient.AsyncHTTPClient() if admin_password: password_hash = hashlib.sha256(admin_password.encode()).hexdigest() else: password_hash = core_api_auth.EMPTY_PASSWORD_HASH headers = { 'Content-Type': json_utils.JSON_CONTENT_TYPE, 'Authorization': core_api_auth.make_auth_header(core_api_auth.ORIGIN_CONSUMER, username='******', password_hash=password_hash) } # TODO: this only tries standard port 80; ideally it should try connecting on a list of known ports timeout = settings.slaves.discover.request_timeout url = f'http://{self.ip_address}:80{path}' body_str = None if body is not None: body_str = json_utils.dumps(body) request = httpclient.HTTPRequest(url=url, method=method, headers=headers, body=body_str, connect_timeout=timeout, request_timeout=timeout) if not no_log: self.debug('requesting %s %s', method, path) try: response = await http_client.fetch(request, raise_error=True) except Exception as e: if not no_log: self.error('request %s %s failed: %s', method, path, e, exc_info=True) raise if response.body: return json_utils.loads(response.body)
def get_request_json(self) -> Any: if self._json is self._UNDEFINED: try: self._json = json_utils.loads(self.request.body) except ValueError as e: logger.error('could not decode json from request body: %s', e) raise core_api.APIError(400, 'malformed-body') from e return self._json
def parse(response: HTTPResponse, decode_json: bool = True, resolve_refs: bool = True) -> Any: if 100 <= response.code < 599: if response.code == 204: return # Happy case - no content if decode_json and response.body: try: body = json_utils.loads(response.body, resolve_refs=resolve_refs) except Exception as e: raise InvalidJson() from e else: body = response.body if response.code == 200: return body # Happy case with content if response.code == 202: raise Accepted(body) if response.code == 301: raise MovedPermanently(response.headers.get('Location', '')) if response.code in [302, 303]: raise Redirect(response.headers.get('Location', '')) if decode_json: raise HTTPError(response.code, body.pop('error', ''), **body) raise HTTPError(response.code, response.reason) elif response.error or response.code == 599: if str(response.error).lower().count('timeout'): raise Timeout() eno = getattr(response.error, 'errno', None) if eno: raise _response_error_errno(eno) raise OtherError(str(response.error)) raise OtherError( f'Unknown HTTP error ({response.code}: {str(response.error)})')
def _value_from_db(value: str) -> Any: return json_utils.loads(value, allow_extended_types=True)
def _value_from_db(value: str) -> Any: return json_utils.loads(value)