Esempio n. 1
0
    def test_oneArg(self):

        request = request_class(url='/1234')
        router_instance = Router()
        router_instance.set_url('/<tag>', self.noop)

        handler, kw = router_instance.get_mapped_handle(request)
        self.assertEqual(kw, {'tag': '1234'})
        self.assertEqual(handler, self.noop)
Esempio n. 2
0
    def test_static_url(self):

        request = request_class(url='/1234')
        router_instance = Router()
        router_instance.set_url('/1234', self.noop)

        handler, kw = router_instance.get_mapped_handle(request)
        self.assertEqual(kw, {})
        self.assertEqual(handler, self.noop)
Esempio n. 3
0
    def __init__(self, name=None):
        '''init the LuyA instance'''

        self.loop = None
        self.router = Router()
        self.blueprint_name_bundle = {}
        self.blueprint_in_order = []
        self.request_middleware = []
        self.response_middleware = []
        self.exception_handler = {}
Esempio n. 4
0
    def __init__(self, name=None):
        '''init the LuyA instance'''

        self.loop = None
        self.router = Router()
        self.blueprint_name_bundle = {}
        self.blueprint_in_order = []
        self.request_middleware = []
        self.response_middleware = []
        self.exception_handler = {}
        self.before_server_start = []
        self.after_server_start = []
        self.has_stream = False
Esempio n. 5
0
    def test_one_Blueprint_with_type(self):

        request = request_class(url='/bp/1234-')
        router_instance = Router()
        router_instance.set_url('/<tag>', self.noop)
        router_instance.set_url('/bp/<tag:int>', self.noop)

        with self.assertRaises(LuyAException):
            router_instance.get_mapped_handle(request)

        request = request_class(url='/bp/1234')
        handler, kw = router_instance.get_mapped_handle(request)

        self.assertEqual(kw, {'tag': 1234})
        self.assertEqual(handler, self.noop)
Esempio n. 6
0
    def test_multArg(self):

        request = request_class(url='/1234/12323')
        router_instance = Router()
        router_instance.set_url('/<tag>/<tag2>', self.noop)

        handler, kw = router_instance.get_mapped_handle(request)
        self.assertEqual(kw, {'tag': '1234', 'tag2': '12323'})
        self.assertEqual(handler, self.noop)

        request2 = request_class(url='/1234/12323/123')
        router_instance.set_url('/<tag>/<tag2>/<b4>', self.noop)
        handler, kw = router_instance.get_mapped_handle(request2)
        self.assertEqual(kw, {'tag': '1234', 'tag2': '12323', 'b4': '123'})
        self.assertEqual(handler, self.noop)
Esempio n. 7
0
    def test_static_duplicate_url(self):

        request = request_class(url='/1234')
        request2 = request_class(url='/1234')
        router_instance = Router()
        router_instance.set_url('/1234', self.noop)

        with self.assertRaises(ValueError):
            router_instance.set_url('/1234', self.noop)
Esempio n. 8
0
    def test_int_url(self):

        request = request_class(url='/123')
        
        router_instance = Router()
        router_instance.set_url('/<tag:int>', self.noop)

        handler, kw = router_instance.get_mapped_handle(request)
        self.assertEqual(kw, {'tag': 123})
        self.assertEqual(handler, self.noop)

        request2 = request_class(url='/12hh3-22')
        
        with self.assertRaises(LuyAException):
            handler, kw = router_instance.get_mapped_handle(request2)
Esempio n. 9
0
class Luya:
    def __init__(self, name=None):
        '''init the LuyA instance'''

        self.loop = None
        self.router = Router()
        self.blueprint_name_bundle = {}
        self.blueprint_in_order = []
        self.request_middleware = []
        self.response_middleware = []
        self.exception_handler = {}

    def run(self, host='127.0.0.1', port=8000, workers=1):

        _print_logo()
        server_args = {
            'host': host,
            'port': port,
            'workers': workers
        }

        if workers == 1:
            serve(self, **server_args)
        else:
            multiple_serve(self, server_args)

    def register_blueprint(self, blueprint):
        '''
        register a blueprint
        '''

        if blueprint.name in self.blueprint_name_bundle:
            raise KeyError(
                'the name {} for blueprint has already registered, please choose another name instead')
        else:
            self.blueprint_in_order.append(blueprint)
            blueprint.register(self)

    def register_middleware(self, middleware, before=None):
        if before == 'request':
            self.request_middleware.append(middleware)
        if before == 'response':
            self.response_middleware.append(middleware)

        # decorator
    def middleware(self, middleware_or_string):
        ''' a decorator for registing middleware,which will be invoked
            before request or after request in order.
            example:
            default @app.middleware is for registing 'request'
            middleware_or_string = 'request', it will fire before request
            middleware_or_string = 'response', it will fire before response

            if middleware return a response object, it will response directly
            without calling any other method
        '''

        # if the way is @app.middleware
        if callable(middleware_or_string):
            return self.register_middleware(middleware_or_string, before='request')
        else:
            return functools.partial(
                self.register_middleware,
                before=middleware_or_string)

            # decorator
    def exception(self, exception):

        def decorator(func):
            print('yes')
            status_code = exception.status_code
            self.exception_handler[status_code] = func

        return decorator

        # decorator
    def route(self, url, methods=None):
        '''
        if user decorate their function with this method,
        it will fire when a method is being decorated
        '''
        def response(func):
            # todo to using dict directly is not good for reading
            # has to encapsulate into a class
            self.router.set_url(url, func, methods)

        return response

    def add_route(self, handler_or_class, url):

        is_class = hasattr(handler_or_class, 'view_class')
        methods = []
        if is_class:
            for method in HTTP_METHODS:
                handler = getattr(handler_or_class, method.lower(), None)
                if handler:
                    methods.append(method)

        self.route(url, methods=methods)(handler_or_class)

    async def request_handler(self, request, write_callback, stream_callback):
        '''
        this method will fire when the request has been parsed,
        the user has to make sure every single function is a coroutine
        function and super fast.

        this is a coroutine function

        :param write_callback: the callback for writing response back
        :param stream_callback: for stream request,normally it is a download request
        '''
        #----------------
        # handling request middleware
        #----------------
        try:
            for middleware in self.request_middleware:
                response = middleware(request)

                if isinstance(response, HTTPResponse):
                    if isawaitable(response):
                        response = await response
                    write_callback(response)
                    return
        except Exception as e:
            response = response_html(
                '''<h3>unable to perform the request middleware and router function</h3>
                    <p>{}</p>
                    <p>{}</p>
                '''.format(e, format_exc()), status=500)

        #----------------
        # handling request
        #----------------

        try:
            handler, kw = self.router.get_mapped_handle(request)

            # users may define a non-awaitable function
            response = handler(request, **kw)
            if isawaitable(response):
                response = await response
            else:
                logging.warning('url %s for %s is not isawaitable' %
                                (request.url, handler))
        except LuyAException as e:
            try:
                handler = self.exception_handler.get(e.status_code, None)

                if handler is not None:
                    response = handler(request, exception=e)
                    if isawaitable(response):
                        response = await response

                    # setting a status code for return
                    if response.status == 200:
                        response.status = e.status_code
                else:
                    response = response_html(
                        '<h3>{}<h3>'.format(e), status=e.status_code
                    )

            except Exception as err:
                response = response_html(
                    '<h1>{}</h1>{}'.format(err, format_exc()), status=500)

        except Exception as e:
            response = response_html(
                '''<h3>unable to perform the request middleware and router function</h3>
                    <p>{}</p>
                    <p>{}</p>
                '''.format(e, format_exc()), status=500)

        finally:
            #----------------
            # handling response middleware
            #----------------
            try:
                response = await self.run_response_middleware(request, response)
            except Exception as e:
                response = response_html(
                    '''<h3>unable to perform the request middleware and router function</h3>
                        <p>{}</p>
                        <p>{}</p>
                    '''.format(e, format_exc()), status=500)

        # todo stream call_back
        try:
            write_callback(response)
        except Exception as e:
            print('write_callback fail', e)

    async def run_response_middleware(self, request, response):
        for middleware in self.response_middleware:
            _response = middleware(request, response)

            if isinstance(_response, HTTPResponse):
                if isawaitable(_response):
                    _response = await _response
                if _response:
                    response = _response
                break

        return response