Skip to content

Commit

Permalink
Allow for priorities on routes defs (#76)
Browse files Browse the repository at this point in the history
* Allow for priorities on routes defs

* Format

* Make pretty and add ruff
  • Loading branch information
ahopkins authored Dec 7, 2023
1 parent 8893c4a commit 41b5cd2
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 17 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package

on:
Expand Down
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ test:
test-cov:
${PYTEST} --cov sanic_routing

.PHONY: fix
fix:
ruff check sanic_routing --fix

.PHONY: format
format:
ruff format sanic_routing

.PHONY: pretty
pretty:
black --line-length 79 sanic_routing tests
isort --line-length 79 sanic_routing tests --profile=black
pretty: fix format
29 changes: 29 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[tool.ruff]
target-version = "py38"
line-length = 79

[tool.ruff.lint]
select = [
"E", # pycodestyle
"F", # pyflakes
"I", # isort
"W", # pycodestyle warnings
]
ignore = [
"E203",
]

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

[tool.ruff.isort]
known-first-party = ["sanic_routing"]
known-third-party = ["pytest"]
lines-after-imports = 2
lines-between-types = 1
1 change: 1 addition & 0 deletions sanic_routing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
from .route import Route
from .router import BaseRouter


__version__ = "23.6.0"
__all__ = ("BaseRouter", "Route", "RouteGroup")
2 changes: 2 additions & 0 deletions sanic_routing/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ def __init__(
message: str = "Method does not exist",
method: Optional[str] = None,
allowed_methods: Optional[Set[str]] = None,
path: Optional[str] = None,
):
super().__init__(message)
self.method = method
self.allowed_methods = allowed_methods
self.path = path


class FinalizationError(BaseException):
Expand Down
13 changes: 13 additions & 0 deletions sanic_routing/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ def finalize(self):
}
)

def prioritize_routes(self) -> None:
"""
Sorts the routes in the group by priority
"""
self._routes = tuple(
sorted(
self._routes, key=lambda route: route.priority, reverse=True
)
)

def reset(self):
self.methods_index = dict(self.methods_index)

Expand Down Expand Up @@ -163,6 +173,9 @@ def handler2(...):
)
else:
_routes.append(other_route)
_routes.sort(
key=lambda route: route.priority, reverse=True
)
self._routes = tuple(_routes)

@property
Expand Down
1 change: 1 addition & 0 deletions sanic_routing/patterns.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
import typing as t
import uuid

from datetime import date, datetime
from types import SimpleNamespace
from typing import Any, Callable, Dict, Pattern, Tuple, Type
Expand Down
14 changes: 10 additions & 4 deletions sanic_routing/route.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re
import typing as t

from types import SimpleNamespace
from warnings import warn

Expand Down Expand Up @@ -28,6 +29,7 @@ class Route:
"parts",
"path",
"pattern",
"priority",
"regex",
"requirements",
"router",
Expand Down Expand Up @@ -80,12 +82,15 @@ def __init__(
static: bool = False,
regex: bool = False,
overloaded: bool = False,
*,
priority: int = 0,
):
self.router = router
self.name = name
self.handler = handler # type: ignore
self.methods = frozenset(methods)
self.requirements = Requirements(requirements or {})
self.priority = priority

self.ctx = SimpleNamespace()
self.extra = SimpleNamespace()
Expand Down Expand Up @@ -326,15 +331,16 @@ def parse_parameter_string(self, parameter_string: str):
"""Parse a parameter string into its constituent name, type, and
pattern
For example::
For example:
parse_parameter_string('<param_one:[A-z]>')` ->
('param_one', '[A-z]', <class 'str'>, '[A-z]')
```text
parse_parameter_string('<param_one:[A-z]>')` -> ('param_one', '[A-z]', <class 'str'>, '[A-z]')
```
:param parameter_string: String to parse
:return: tuple containing
(parameter_name, parameter_type, parameter_pattern)
"""
""" # noqa: E501
# We could receive NAME or NAME:PATTERN
parameter_string = parameter_string.strip("<>")
name = parameter_string
Expand Down
12 changes: 11 additions & 1 deletion sanic_routing/router.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ast
import sys
import typing as t

from abc import ABC, abstractmethod
from types import SimpleNamespace
from warnings import warn
Expand All @@ -21,6 +22,7 @@
from .tree import Node, Tree
from .utils import parts_to_path, path_to_parts


# The below functions might be called by the compiled source code, and
# therefore should be made available here by import
import re # noqa isort:skip
Expand Down Expand Up @@ -96,7 +98,7 @@ def resolve(
orig=path,
extra=extra,
)
raise self.exception(str(e), path=path)
raise e.__class__(str(e), path=path)

if isinstance(route, RouteGroup):
try:
Expand Down Expand Up @@ -157,6 +159,8 @@ def add(
unquote: bool = False, # noqa
overwrite: bool = False,
append: bool = False,
*,
priority: int = 0,
) -> Route:
# Can add a route with overwrite, or append, not both.
# - overwrite: if matching path exists, replace it
Expand All @@ -166,6 +170,10 @@ def add(
"Cannot add a route with both overwrite and append equal "
"to True"
)
if priority and not append:
raise FinalizationError(
"Cannot add a route with priority if append is False"
)
if not methods:
methods = [self.DEFAULT_METHOD]

Expand Down Expand Up @@ -223,6 +231,7 @@ def add(
unquote=unquote,
static=static,
regex=regex,
priority=priority,
)
group = self.group_class(route)

Expand Down Expand Up @@ -327,6 +336,7 @@ def finalize(self, do_compile: bool = True, do_optimize: bool = False):
group.finalize()
for route in group.routes:
route.finalize()
group.prioritize_routes()

# Evaluates all of the paths and arranges them into a hierarchichal
# tree of nodes
Expand Down
2 changes: 2 additions & 0 deletions sanic_routing/tree.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import typing as t

from logging import getLogger

from .group import RouteGroup
from .line import Line
from .patterns import REGEX_PARAM_NAME, REGEX_PARAM_NAME_EXT, alpha, ext, slug


logger = getLogger("sanic.root")


Expand Down
1 change: 1 addition & 0 deletions sanic_routing/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re

from urllib.parse import quote, unquote

from sanic_routing.exceptions import InvalidUsage
Expand Down
9 changes: 3 additions & 6 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@ commands =

[testenv:lint]
deps =
flake8
black
isort
ruff
mypy

commands =
flake8 sanic_routing
black --line-length 79 --check sanic_routing
isort --line-length 79 --check sanic_routing --profile=black
ruff check sanic_routing
ruff format sanic_routing --check
mypy sanic_routing

[pytest]
Expand Down

0 comments on commit 41b5cd2

Please sign in to comment.