Routing¶
spangle provides simple and flexible routing powered by parse .
Static routing¶
# routing.py
from spangle import Api
api = Api()
@api.route("/path/to/page")
class StaticRoute:
    async def on_request(self, req, resp):
        pass
Dynamic routing¶
You can get values from URL by using f-string style routing. To get params in a method, call use_params .
# routing.py
@api.route("/path/to/{name}")
class DynamicRoute(object):
    async def on_request(self, req, resp):
        name = use_params()["name"]
        # `spangle` tries to get a view from static routes first.
        assert name != "page"
@api.route("/use/{multiple}/{allowed}")
class Multiple:
    async def on_request(self, req, resp):
        params = use_params()
        assert "multiple" in params
        assert "allowed" in params
Convert values¶
View methods accept URL arguments as str by default. You can change this behavior to set converters.
# routing.py
# `default`, `int` and `float` are built-in converters.
# `str` is an alias of `default`.
@api.route("/use/{dynamic:int}")
class IntArg:
    async def on_request(self, req, resp):
        dynamic = use_params()["dynamic"]
        assert isinstance(dynamic, int)
# `default` match does not contain slash(`/`).
# `*rest_string` converter matches any characters including slash.
@api.route("/{for_spa:*rest_string}")
@api.route("/")
class SpaView:
    async def on_get(self, req, resp):
        ...
# You can define custom converters as `Dict[str,Callable]` .
def month(v:str) -> int:
    m = int(v)
    if not (1<=m<=12):
        raise ValueError
@api.route("/articles-in-{m:month}", converters={"month":month})
class CustomConverter:
    async def on_request(self, req, resp):
        m = use_params()["m"]
        assert 1<=m<=12
# You can use regular expression to set pattern to `converter.pattern` .
def regex(x):
    return x
regex.pattern = r"[A-Za-z]+(/[A-Za-z]+)+"
# convert must start with `*` to include slash for its pattern.
@api.route("/accept/custom-pattern/{path:*regex}", converters={"*regex":regex})
class SlashRequired:
    async def on_request(self, req, resp):
        path = use_params()["path"]
        assert "/" in path
See parse for more details.
Routing Strategies¶
spangle has 4 strategies about trailing slash.
- "no_slash"(default): always redirect from- /route/to- /routewith- 308 PERMANENT_REDIRECT.
- "slash": always redirect from- /routeto- /route/with- 308 PERMANENT_REDIRECT.
- "strict": distinct- /routefrom- /route/.
- "clone": return same view between- /routeand- /route/.
To change default strategy, create Api instance with an argument like Api(routing="clone") .
If you need to set different strategy against views, use route(view, routing="{strategy}") .
@api.route("/flexible/rules", routing="clone")
class Strategy:
    ...