예제 #1
0
 def autoroutes_add_routes(routes):
     router = Routes()
     for url, controller, methods, method_dict in routes:
         router.add(url, methods=method_dict)
     return router
예제 #2
0
from timeit import timeit
from autoroutes import Routes

PATHS = [
    'user/', 'user/{id}', 'user/{id}/subpath', 'user/{id}/subpath2', 'boat/',
    'boat/{id}', 'boat/{id}/subpath', 'boat/{id}/subpath2', 'horse/',
    'horse/{id}', 'horse/{id}/subpath', 'horse/{id}/subpath2', 'bicycle/',
    'bicycle/{id}', 'bicycle/{id}/subpath2', 'bicycle/{id}/subpath'
]

routes = Routes()
for i, path in enumerate(PATHS):
    routes.add(path, GET=i)

node = routes.match('user/')
print('user/', node)
node = routes.match('horse/22/subpath')
print('horse/22/subpath', node)
node = routes.match('plane/')
print(node)

total = timeit("routes.match('user/')", globals=globals(), number=100000)
print(f'First flat path:\n> {total}')

total = timeit("routes.match('horse/22/subpath')",
               globals=globals(),
               number=100000)
print(f'Middle path with placeholder:\n> {total}')

total = timeit("routes.match('plane/')", globals=globals(), number=100000)
print(f'Not found path:\n> {total}')
예제 #3
0
# Named profile_.py not to clash with cProfile doing bad absolute imports.
# Add "# cython: profile=True, linetrace=True, binding=True" directive in
# autoroutes.pyx to profile, remove autoroutes.c and autoroutes.xxx.so

from cProfile import runctx
import pstats

import pyximport

pyximport.install()

from autoroutes import Routes  # noqa (we need pyximport.install)

PATHS = [
    '/user/', '/user/{id}', '/user/{id}/subpath', '/user/{id}/subpath2',
    '/boat/', '/boat/{id}', '/boat/{id}/subpath', '/boat/{id}/subpath2',
    '/horse/', '/horse/{id}', '/horse/{id}/subpath', '/horse/{id}/subpath2',
    '/bicycle/', '/bicycle/{id}', '/bicycle/{id}/subpath2',
    '/bicycle/{id}/subpath'
]

routes = Routes()
for path in PATHS:
    routes.add(path, data='data')

runctx('for i in range(100000):\n routes.match("/horse/22/subpath")',
       globals(), locals(), 'Profile.prof')

s = pstats.Stats('Profile.prof')
s.strip_dirs().sort_stats('time').print_stats()
예제 #4
0
class Trinket(Application, dict):

    __slots__ = ('hooks', 'routes', 'websockets', 'server')

    handle_request = request_handler

    def __init__(self):
        self.routes = Routes()
        self.websockets = set()
        self.hooks = defaultdict(list)

    async def lookup(self, request: Request):
        payload, params = self.routes.match(request.path)

        if not payload:
            raise HTTPError(HTTPStatus.NOT_FOUND, request.path)

        # Uppercased in order to only consider HTTP verbs.
        handler = payload.get(request.method.upper(), None)
        if handler is None:
            raise HTTPError(HTTPStatus.METHOD_NOT_ALLOWED)

        # We check if the route is for a websocket handler.
        # If it is, we make sure we were asked for an upgrade.
        if payload.get('websocket', False) and not request.upgrade:
            raise HTTPError(HTTPStatus.UPGRADE_REQUIRED,
                            'This is a websocket endpoint, please upgrade.')

        return handler, params

    @handler_events
    async def __call__(self, request: Request):
        handler, params = await self.lookup(request)
        return await handler(request, **params)

    def route(self, path: str, methods: list = None, **extras: dict):
        if methods is None:
            methods = ['GET']

        def wrapper(func):
            payload = {method: func for method in methods}
            payload.update(extras)
            self.routes.add(path, **payload)
            return func

        return wrapper

    def websocket(self, path: str, **extras: dict):
        def wrapper(func):
            @wraps(func)
            async def websocket_handler(request, **params):
                websocket = Websocket(request.socket)
                try:
                    await websocket.upgrade(request)
                    self.websockets.add(websocket)
                    task = await spawn(func, request, websocket, **params)
                    await websocket.flow(task)
                finally:
                    self.websockets.discard(websocket)

            payload = {'GET': websocket_handler, 'websocket': True}
            payload.update(extras)
            self.routes.add(path, **payload)
            return func

        return wrapper

    def listen(self, name: str):
        def wrapper(func):
            self.hooks[name].append(func)

        return wrapper

    async def notify(self, name: str, *args, **kwargs):
        if name in self.hooks:
            for hook in self.hooks[name]:
                result = await hook(*args, **kwargs)
                if result is not None:
                    # Allows to shortcut the chain.
                    return result
        return None

    def start(self, host='127.0.0.1', port=5000, debug=True):
        Server.start(self, host, port, debug)