From 343cdf55c1c2e5f7942cbaa0c145fd9d39f3dd72 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 25 Nov 2019 10:49:52 +0100 Subject: [PATCH] formatting fixes --- pype/services/rest_api/base_class.py | 30 ++++++++++++++------- pype/services/rest_api/lib/exceptions.py | 3 ++- pype/services/rest_api/lib/factory.py | 21 ++++++++++----- pype/services/rest_api/lib/handler.py | 19 +++++++++----- pype/services/rest_api/lib/lib.py | 33 +++++++++++++++++------- 5 files changed, 72 insertions(+), 34 deletions(-) diff --git a/pype/services/rest_api/base_class.py b/pype/services/rest_api/base_class.py index 8a3c9d3704..6f06e01fcf 100644 --- a/pype/services/rest_api/base_class.py +++ b/pype/services/rest_api/base_class.py @@ -1,4 +1,3 @@ -from functools import wraps from http import HTTPStatus from .lib import ( @@ -15,9 +14,12 @@ def route(path, url_prefix="", methods=[], strict_match=False): :type path: str :param url_prefix: Specify prefix of path, defaults to "/". :type url_prefix: str, list, optional - :param methods: Specify request method (GET, POST, PUT, etc.) when callback will be triggered, defaults to ["GET"] + :param methods: Specify request method (GET, POST, PUT, etc.) when + callback will be triggered, defaults to ["GET"] :type methods: list, str, optional - :param strict_match: Decides if callback can handle both single and multiple entities (~/projects/ && ~/projects/), defaults to False. + :param strict_match: Decides if callback can handle both single and + multiple entities (~/projects/ && ~/projects/), + defaults to False. :type strict_match: bool `path` may include dynamic keys that will be stored to object which can @@ -36,6 +38,7 @@ def route(path, url_prefix="", methods=[], strict_match=False): In this case request path must be "/avalon/projects" to trigger registered callback. """ + def decorator(callback): RestApiFactory.register_route( path, callback, url_prefix, methods, strict_match @@ -49,26 +52,32 @@ def register_statics(url_prefix, dir_path): """Decorator that register callback and all its attributes. Callback is registered to Singleton RestApiFactory. - :param url_prefix: Specify prefix of path, defaults to "/". (Example: "/resources") + :param url_prefix: Specify prefix of path, defaults to "/". + (Example: "/resources") :type url_prefix: str :param dir_path: Path to file folder where statics are located. :type dir_path: str """ + RestApiFactory.register_statics((url_prefix, dir_path)) def abort(status_code=HTTPStatus.NOT_FOUND, message=None): - """Should be used to stop registered callback + """Should be used to stop registered callback. `abort` raise AbortException that is handled with request Handler which returns entered status and may send optional message in body. - :param status_code: Status that will be send in reply of request, defaults to 404 + :param status_code: Status that will be send in reply of request, + defaults to 404 :type status_code: int - :param message: Message to send in body, default messages are based on statuc_code in Handler, defaults to None + :param message: Message to send in body, default messages are based on + statuc_code in Handler, defaults to None :type message: str, optional ... - :raises AbortException: This exception is handled in Handler to know about launched `abort` + :raises AbortException: This exception is handled in Handler to know + about launched `abort` """ + items = [] items.append(str(status_code)) if not message: @@ -85,9 +94,10 @@ class RestApi: Use this class is required when it is necessary to have class for handling requests and want to use decorators for registering callbacks. - It is possible to use decorators in another class only when object, of class - where decorators are, is registered to RestApiFactory. + It is possible to use decorators in another class only when object, + of class where decorators are, is registered to RestApiFactory. """ + def route(path, url_prefix="", methods=[], strict_match=False): return route(path, url_prefix, methods, strict_match) diff --git a/pype/services/rest_api/lib/exceptions.py b/pype/services/rest_api/lib/exceptions.py index 118fa4ffc8..b17e1ce012 100644 --- a/pype/services/rest_api/lib/exceptions.py +++ b/pype/services/rest_api/lib/exceptions.py @@ -8,4 +8,5 @@ class ObjAlreadyExist(Exception): super().__init__(message) -class AbortException(Exception): pass +class AbortException(Exception): + pass diff --git a/pype/services/rest_api/lib/factory.py b/pype/services/rest_api/lib/factory.py index a07a8262c1..2b94d498ff 100644 --- a/pype/services/rest_api/lib/factory.py +++ b/pype/services/rest_api/lib/factory.py @@ -116,7 +116,8 @@ def prepare_methods(methods, callback=None): :param methods: Contain rest api methods, when callback is called. :type methods: str, list - :param callback: Registered callback, helps to identify where is invalid method. + :param callback: Registered callback, helps to identify where is + invalid method. :type callback: function, method, optional :return: Valid methods :rtype: list @@ -138,7 +139,7 @@ def prepare_methods(methods, callback=None): for method in methods: found = False _method = RestMethods.get(method) - if _method == None: + if _method is None: invalid_methods[methods].append(callback) continue @@ -169,6 +170,7 @@ def prepare_methods(methods, callback=None): return _methods + def prepare_callback_info(callback): """Prepare data for callback handling when should be triggered.""" callback_info = inspect.getfullargspec(callback) @@ -228,7 +230,9 @@ class _RestApiFactory: self.unprocessed_statics.index(item) ) - def register_route(self, path, callback, url_prefix, methods, strict_match): + def register_route( + self, path, callback, url_prefix, methods, strict_match + ): log.debug("Registering callback for item \"{}\"".format( callback.__qualname__ )) @@ -242,7 +246,7 @@ class _RestApiFactory: self.unprocessed_routes.append(route) def register_obj(self, obj): - """Register object for decorated methods in class definition""" + """Register object for decorated methods in class definition.""" self.registered_objs.append(obj) def register_statics(self, item): @@ -255,7 +259,8 @@ class _RestApiFactory: Registration info are prepared to easy filter during handling of requests. - :param route: Contain all necessary info for filtering and handling callback for registered route. + :param route: Contain all necessary info for filtering and + handling callback for registered route. :type route: dict """ callback = route["callback"] @@ -278,7 +283,7 @@ class _RestApiFactory: }) def prepare_registered(self): - """Iterate through all registered callbacks and statics and prepare them + """Iter through all registered callbacks and statics to prepare them. First are processed callbacks registered with decorators in classes by registered objects. Remaining callbacks are filtered, it is checked if @@ -314,7 +319,9 @@ class _RestApiFactory: if not ( callback.__qualname__ == method.__qualname__ and callback.__module__ == method.__module__ and - callback.__globals__["__file__"] == method.__globals__["__file__"] + callback.__globals__["__file__"] == ( + method.__globals__["__file__"] + ) ): continue diff --git a/pype/services/rest_api/lib/handler.py b/pype/services/rest_api/lib/handler.py index 3f4ec8937d..6a19ce90be 100644 --- a/pype/services/rest_api/lib/handler.py +++ b/pype/services/rest_api/lib/handler.py @@ -32,6 +32,7 @@ class Handler(http.server.SimpleHTTPRequestHandler): "NO_CONTENT": 204 } } + def do_GET(self): return self._handle_request(RestMethods.GET) @@ -156,7 +157,6 @@ class Handler(http.server.SimpleHTTPRequestHandler): self.wfile.write(message.encode()) return message - def _handle_callback_result(self, result, rest_method): """Send response to request based on result of callback. :param result: Result returned by callback. @@ -232,7 +232,7 @@ class Handler(http.server.SimpleHTTPRequestHandler): :param item: Item stored during callback registration with all info. :type item: dict - :param parsed_url: Url parsed with urllib (separated path, query, etc.). + :param parsed_url: Url parsed with urllib (separated path, query, etc). :type parsed_url: ParseResult :param rest_method: Rest api method (GET, POST, etc.). :type rest_method: RestMethods @@ -284,7 +284,7 @@ class Handler(http.server.SimpleHTTPRequestHandler): return callback(*args, **kwargs) def _handle_statics(self, dirpath, path): - """Return static file in response when file exist in registered destination.""" + """Return static file in response when file exist in destination.""" path = os.path.normpath(dirpath + path) ctype = self.guess_type(path) @@ -327,12 +327,17 @@ class Handler(http.server.SimpleHTTPRequestHandler): self.send_response(HTTPStatus.OK) self.send_header("Content-type", ctype) self.send_header("Content-Length", str(file_stat[6])) - self.send_header("Last-Modified", - self.date_time_string(file_stat.st_mtime)) + self.send_header( + "Last-Modified", + self.date_time_string(file_stat.st_mtime) + ) self.end_headers() self.wfile.write(file_obj.read()) return file_obj - except: - self.log.error("Failed to read data from file \"{}\"".format(path)) + except Exception: + log.error( + "Failed to read data from file \"{}\"".format(path), + exc_info=True + ) finally: file_obj.close() diff --git a/pype/services/rest_api/lib/lib.py b/pype/services/rest_api/lib/lib.py index 4fab11469e..9fbefe4655 100644 --- a/pype/services/rest_api/lib/lib.py +++ b/pype/services/rest_api/lib/lib.py @@ -65,12 +65,22 @@ class HandlerDict(dict): def __repr__(self): return "<{}> {}".format(self.__class__.__name__, str(dict(self))) -class Params(HandlerDict): pass -class UrlData(HandlerDict): pass -class RequestData(HandlerDict): pass + +class Params(HandlerDict): + pass + + +class UrlData(HandlerDict): + pass + + +class RequestData(HandlerDict): + pass + class Query(HandlerDict): - """Class for url query convert to dict and string""" + """Class for url query convert to dict and string.""" + def __init__(self, query): if isinstance(query, dict): pass @@ -81,8 +91,10 @@ class Query(HandlerDict): def get_string(self): return urlencode(dict(self), doseq=True) + class Fragment(HandlerDict): - """Class for url fragment convert to dict and string""" + """Class for url fragment convert to dict and string.""" + def __init__(self, fragment): if isinstance(fragment, dict): _fragment = fragment @@ -112,13 +124,15 @@ class Fragment(HandlerDict): ) return "&".join(items) + class RequestInfo: """Object that can be passed to callback as argument. Contain necessary data for handling request. Object is created to single use and can be used similar to dict. - :param url_data: Data collected from path when path with dynamic keys is matching. + :param url_data: Data collected from path when path with dynamic keys + is matching. :type url_data: dict, None :param request_data: Data of body from request. :type request_data: dict, None @@ -166,14 +180,15 @@ class CallbackResult: """Can be used as return value of callback. It is possible to specify status code, success boolean, message and data - for specify head and body of request response. `abort` should be rather used - when result is error. + for specify head and body of request response. `abort` should be rather + used when result is error. :param status_code: Status code of result. :type status_code: int :param success: Success is key in body, may be used for handling response. :type success: bool - :param message: Similar to success, message is key in body and may be used for handling response. + :param message: Similar to success, message is key in body and may + be used for handling response. :type message: str, None :param data: Data is also key for body in response. :type data: dict, None