An implementation of the URL Pattern Standard for Python written in Rust.
The URL Pattern Standard is a web standard for URL pattern matching. It is useful on the server side when serving different pages based on the URL (a.k.a. routing). It provides pattern matching syntax like /users/:id, similar to route parameters in Express or Path-to-RegExp. You can use it as a foundation to build your own web server or framework.
It's a thin wrapper of denoland/rust-urlpattern with PyO3 + Maturin.
The naming conventions follow the standard as closely as possible, similar to xml.dom.
On Linux/UNIX or macOS:
pip install urlpatternOn Windows:
py -m pip install urlpatternCheck urlpattern.pyi or the examples below.
For various usage examples, you can also check Chrome for Developers or MDN (you need to convert JavaScript into Python).
from urlpattern import URLPattern
pattern = URLPattern("https://example.com/admin/*")
print(pattern.test("https://example.com/admin/main/")) # output: True
print(pattern.test("https://example.com/main/")) # output: Falsefrom urlpattern import URLPattern
pattern = URLPattern({"pathname": "/users/:id/"})
result = pattern.exec({"pathname": "/users/4163/"})
print(result["pathname"]["groups"]["id"]) # output: 4163from urlpattern import URLPattern
pattern = URLPattern("b", "https://example.com/a/")
print(pattern.test("a/b", "https://example.com/")) # output: True
print(pattern.test("b", "https://example.com/a/")) # output: True
print(
pattern.test({"pathname": "b", "baseURL": "https://example.com/a/"})
) # output: Truefrom urlpattern import URLPattern
pattern = URLPattern("https://example.com/test")
print(pattern.test("https://example.com/test")) # output: True
print(pattern.test("https://example.com/TeST")) # output: False
pattern = URLPattern("https://example.com/test", {"ignoreCase": True})
print(pattern.test("https://example.com/test")) # output: True
print(pattern.test("https://example.com/TeST")) # output: Truefrom wsgiref.simple_server import make_server
from urlpattern import URLPattern
user_id_pattern = URLPattern({"pathname": "/users/:id"})
def get_user_id(environ, start_response):
user_id = environ["result"]["pathname"]["groups"]["id"]
status = "200 OK"
response_headers = [("Content-type", "text/plain; charset=utf-8")]
start_response(status, response_headers)
return [f"{user_id=}".encode()]
def app(environ, start_response):
path = environ["PATH_INFO"]
method = environ["REQUEST_METHOD"]
if result := user_id_pattern.exec({"pathname": path}):
if method == "GET":
return get_user_id(environ | {"result": result}, start_response)
status = "404 Not Found"
response_headers = [("Content-type", "text/plain; charset=utf-8")]
start_response(status, response_headers)
return [b"Not Found"]
with make_server("", 8000, app) as httpd:
httpd.serve_forever()Due to limitations in the dependency denoland/rust-urlpattern, it may not support all features specified in the standard.
Check pytest.skip in tests/test_lib.py.
In this library, some names such as baseURL and hasRegExpGroups do not use snake_case.
Like xml.dom, Python wrappers around web standards typically preserve the original camelCase rather than converting names to snake_case. This library follows that convention as well.