Skip to content

router.py

Provides router class.

Router

Router for managing request handling.

Supports route, middleware and exception handler registration.

Parameters:

Name Type Description Default
prefix str

Optional URL prefix for all routes.

None
Source code in jetweb/routing/router.py
 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
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
class Router:
    """
    Router for managing request handling.

    Supports route, middleware and exception handler registration.

    :param prefix: Optional URL prefix for all routes.
    """

    def __init__(self, prefix: str = None):
        self.prefix = prefix or ""
        self.middlewares = []
        self.exception_handlers = {}
        self.route_table = RouteTable()

    def include(self, router: Router) -> None:
        """
        Include routes, middlewares, and handlers from another router.

        :param router: Router for including.
        """
        self.middlewares.extend(router.middlewares)
        self.exception_handlers.update(router.exception_handlers)
        self.route_table.include(self.prefix, router.route_table)

    def add_middleware(self, middleware: Callable) -> None:
        """
        Register a middleware.

        :param middleware: Middleware.
        :raises ValueError: If middleware is not callable.
        """
        if isclass(middleware):
            middleware = middleware()

        if not callable(middleware):
            raise ValueError("Middleware must be callable")

        self.middlewares.append(middleware)

    def middleware(self, middleware: Callable) -> Callable:
        """
        Decorator for registering middleware.
        """
        self.add_middleware(middleware)
        return middleware

    def add_exception_handler(self, status: int, exception_handler: Callable) -> None:
        """
        Register an exception handler for the status.

        :param status: Exception status.
        :param exception_handler: Exception handler.
        :raises ValueError: If exception handler is not callable.
        """
        if not callable(exception_handler):
            raise ValueError("Exception handler must be callable")

        self.exception_handlers[status] = exception_handler

    def exception_handler(self, status: int) -> Callable:
        """
        Decorator for registering exception handler.
        """
        def decorator(exception_handler: Callable) -> Callable:
            self.add_exception_handler(status, exception_handler)
            return exception_handler
        return decorator

    def add_route(self, endpoint: str, handler: Callable, methods: Iterable[str] = None) -> None:
        """
        Register a request handler for endpoint pattern and allowed methods.

        :param endpoint: Route endpoint.
        :param handler: Request handler.
        :param methods: Allowed request methods.
        :raises ValueError: If class-based handler is not subclass of BaseHandler or handler is not callable.
        """
        if isclass(handler):
            if not issubclass(handler, BaseHandler):
                raise ValueError("Class-based handler must be subclass of BaseHandler")

            handler = handler().dispatch
            methods = ["*"]

        if not callable(handler):
            raise ValueError("Handler must be callable")

        self.route_table.add_route(self.prefix, endpoint, handler, methods)

    def route(self, endpoint: str, methods: Iterable[str] = None) -> Callable:
        """
        Decorator for registering request handler.
        """
        def decorator(handler: Callable) -> Callable:
            self.add_route(endpoint, handler, methods)
            return handler
        return decorator

    def get(self, endpoint: str) -> Callable:
        """
        Shortcut for @app.route(methods=["GET"]).
        """
        return self.route(endpoint, ["GET"])

    def post(self, endpoint: str) -> Callable:
        """
        Shortcut for @app.route(methods=["POST"]).
        """
        return self.route(endpoint, ["POST"])

    def put(self, endpoint: str) -> Callable:
        """
        Shortcut for @app.route(methods=["PUT"]).
        """
        return self.route(endpoint, ["PUT"])

    def patch(self, endpoint: str) -> Callable:
        """
        Shortcut for @app.route(methods=["PATCH"]).
        """
        return self.route(endpoint, ["PATCH"])

    def delete(self, endpoint: str) -> Callable:
        """
        Shortcut for @app.route(methods=["DELETE"]).
        """
        return self.route(endpoint, ["DELETE"])

add_exception_handler(status, exception_handler)

Register an exception handler for the status.

Parameters:

Name Type Description Default
status int

Exception status.

required
exception_handler Callable

Exception handler.

required

Raises:

Type Description
ValueError

If exception handler is not callable.

Source code in jetweb/routing/router.py
61
62
63
64
65
66
67
68
69
70
71
72
def add_exception_handler(self, status: int, exception_handler: Callable) -> None:
    """
    Register an exception handler for the status.

    :param status: Exception status.
    :param exception_handler: Exception handler.
    :raises ValueError: If exception handler is not callable.
    """
    if not callable(exception_handler):
        raise ValueError("Exception handler must be callable")

    self.exception_handlers[status] = exception_handler

add_middleware(middleware)

Register a middleware.

Parameters:

Name Type Description Default
middleware Callable

Middleware.

required

Raises:

Type Description
ValueError

If middleware is not callable.

Source code in jetweb/routing/router.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
def add_middleware(self, middleware: Callable) -> None:
    """
    Register a middleware.

    :param middleware: Middleware.
    :raises ValueError: If middleware is not callable.
    """
    if isclass(middleware):
        middleware = middleware()

    if not callable(middleware):
        raise ValueError("Middleware must be callable")

    self.middlewares.append(middleware)

add_route(endpoint, handler, methods=None)

Register a request handler for endpoint pattern and allowed methods.

Parameters:

Name Type Description Default
endpoint str

Route endpoint.

required
handler Callable

Request handler.

required
methods Iterable[str]

Allowed request methods.

None

Raises:

Type Description
ValueError

If class-based handler is not subclass of BaseHandler or handler is not callable.

Source code in jetweb/routing/router.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
def add_route(self, endpoint: str, handler: Callable, methods: Iterable[str] = None) -> None:
    """
    Register a request handler for endpoint pattern and allowed methods.

    :param endpoint: Route endpoint.
    :param handler: Request handler.
    :param methods: Allowed request methods.
    :raises ValueError: If class-based handler is not subclass of BaseHandler or handler is not callable.
    """
    if isclass(handler):
        if not issubclass(handler, BaseHandler):
            raise ValueError("Class-based handler must be subclass of BaseHandler")

        handler = handler().dispatch
        methods = ["*"]

    if not callable(handler):
        raise ValueError("Handler must be callable")

    self.route_table.add_route(self.prefix, endpoint, handler, methods)

delete(endpoint)

Shortcut for @app.route(methods=["DELETE"]).

Source code in jetweb/routing/router.py
137
138
139
140
141
def delete(self, endpoint: str) -> Callable:
    """
    Shortcut for @app.route(methods=["DELETE"]).
    """
    return self.route(endpoint, ["DELETE"])

exception_handler(status)

Decorator for registering exception handler.

Source code in jetweb/routing/router.py
74
75
76
77
78
79
80
81
def exception_handler(self, status: int) -> Callable:
    """
    Decorator for registering exception handler.
    """
    def decorator(exception_handler: Callable) -> Callable:
        self.add_exception_handler(status, exception_handler)
        return exception_handler
    return decorator

get(endpoint)

Shortcut for @app.route(methods=["GET"]).

Source code in jetweb/routing/router.py
113
114
115
116
117
def get(self, endpoint: str) -> Callable:
    """
    Shortcut for @app.route(methods=["GET"]).
    """
    return self.route(endpoint, ["GET"])

include(router)

Include routes, middlewares, and handlers from another router.

Parameters:

Name Type Description Default
router Router

Router for including.

required
Source code in jetweb/routing/router.py
29
30
31
32
33
34
35
36
37
def include(self, router: Router) -> None:
    """
    Include routes, middlewares, and handlers from another router.

    :param router: Router for including.
    """
    self.middlewares.extend(router.middlewares)
    self.exception_handlers.update(router.exception_handlers)
    self.route_table.include(self.prefix, router.route_table)

middleware(middleware)

Decorator for registering middleware.

Source code in jetweb/routing/router.py
54
55
56
57
58
59
def middleware(self, middleware: Callable) -> Callable:
    """
    Decorator for registering middleware.
    """
    self.add_middleware(middleware)
    return middleware

patch(endpoint)

Shortcut for @app.route(methods=["PATCH"]).

Source code in jetweb/routing/router.py
131
132
133
134
135
def patch(self, endpoint: str) -> Callable:
    """
    Shortcut for @app.route(methods=["PATCH"]).
    """
    return self.route(endpoint, ["PATCH"])

post(endpoint)

Shortcut for @app.route(methods=["POST"]).

Source code in jetweb/routing/router.py
119
120
121
122
123
def post(self, endpoint: str) -> Callable:
    """
    Shortcut for @app.route(methods=["POST"]).
    """
    return self.route(endpoint, ["POST"])

put(endpoint)

Shortcut for @app.route(methods=["PUT"]).

Source code in jetweb/routing/router.py
125
126
127
128
129
def put(self, endpoint: str) -> Callable:
    """
    Shortcut for @app.route(methods=["PUT"]).
    """
    return self.route(endpoint, ["PUT"])

route(endpoint, methods=None)

Decorator for registering request handler.

Source code in jetweb/routing/router.py
104
105
106
107
108
109
110
111
def route(self, endpoint: str, methods: Iterable[str] = None) -> Callable:
    """
    Decorator for registering request handler.
    """
    def decorator(handler: Callable) -> Callable:
        self.add_route(endpoint, handler, methods)
        return handler
    return decorator