summaryrefslogtreecommitdiff
path: root/day9/task5_vue/backend/core/router.py
blob: 135b241797266fd2d00a2640dcd7a9ceed9e7844 (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
42
43
44
45
46
47
48
49
import re
from backend.core.response_types import *
from backend.core.utils import NOT_FOUND_CODE


class ResolutionError(Exception):
    pass


class Route:
    """
    Представляет из себя класс роута. При инициализации принимает допустимые
    методы и регулярное выражение. Содержит методы для работы роутинга.
    Чтобы созданный путь стал обрабатываться необходимо поместить объект Route в таблицу роутера.
    """

    def __init__(self, callback, url_format, methods=None):
        self.methods = ['GET'] if methods is None else methods
        self.url_pattern = re.compile(url_format)
        self.callback = callback

    def resolve(self, url, method, query):
        match = self.url_pattern.fullmatch(url)
        if match is not None:
            groups = match.groups()

            matched = len(groups) == self.url_pattern.groups and method in self.methods
            if not matched:
                raise ResolutionError()
        else:
            raise ResolutionError()

        return self.callback(query, *match.groups())


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

    method, url = request['method'], request['url']
    for route in router_table:
        try:
            response = route.resolve(url, method, request['query'])
        except ResolutionError:
            continue

    return response


router_table = []