Skip to content

urlpattern/python-urlpattern

Repository files navigation

URL Pattern

PyPI - Version PyPI - Python Version Ruff CI

An implementation of the URL Pattern Standard for Python written in Rust.

Introduction

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.

Installation

On Linux/UNIX or macOS:

pip install urlpattern

On Windows:

py -m pip install urlpattern

Usage

Check 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).

Examples

test

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: False

exec

from urlpattern import URLPattern

pattern = URLPattern({"pathname": "/users/:id/"})
result = pattern.exec({"pathname": "/users/4163/"})
print(result["pathname"]["groups"]["id"])  # output: 4163

ignoreCase

from 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: True

Simple WSGI app

from 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()

Limitations

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.

About

An implementation of the URL Pattern Standard for Python written in Rust.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •