summaryrefslogtreecommitdiff
path: root/day9/task5/router.py
blob: 0827bb4537cc858e1e6e1c94e245d03e21d93be9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import re
from utils import NOT_FOUND_CODE, BAD_REQUEST_CODE
from core import Response, ErrorResponse


def route(url_format, methods=None):
    if methods is None:
        methods = ['GET']

    def wrapper(func):
        def inner(url, query, *args, **kwargs):
            pattern = re.compile(url_format)
            match = re.fullmatch(pattern, url)

            if match is None or len(match.groups()) != pattern.groups:
                return ErrorResponse(BAD_REQUEST_CODE)

            return func(query, *match.groups(), *args, **kwargs)

        _router_tree[url_format] = _router_tree.get(url_format, {})
        for method in methods:
            _router_tree[url_format][method] = inner

        return inner

    return wrapper


def run(request) -> Response:
    res = ErrorResponse(NOT_FOUND_CODE)

    method, url = request['method'], request['url']
    for url_pattern in _router_tree:
        if re.fullmatch(url_pattern, url) and method in _router_tree[url_pattern]:
            res = _router_tree[url_pattern][method](url, request['query'])
            break

    return res


_router_tree = {}