diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 1d062a5..2880a21 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -182,9 +182,9 @@ jobs: strategy: matrix: platform: - - runner: macos-13 + - runner: macos-15-intel target: x86_64 - - runner: macos-14 + - runner: macos-latest target: aarch64 steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index b8a2a95..287a1aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -105,9 +105,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -195,9 +195,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" [[package]] name = "potential_utf" @@ -210,9 +210,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] @@ -280,7 +280,7 @@ dependencies = [ [[package]] name = "python-urlpattern" -version = "0.1.5" +version = "0.1.6" dependencies = [ "pyo3", "urlpattern", @@ -396,9 +396,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" +checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba" [[package]] name = "tinystr" @@ -436,9 +436,9 @@ dependencies = [ [[package]] name = "urlpattern" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957a88ad1abd5d13336275adb17d4f9b6a2404f3baed2e075e0b026dc0b2b58d" +checksum = "0f805818f843b548bacc19609eb3619dd2850e54746f5cada37927393c2ef4ec" dependencies = [ "icu_properties", "regex", diff --git a/Cargo.toml b/Cargo.toml index d2fd6a4..278aec4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "python-urlpattern" -version = "0.1.5" +version = "0.1.6" authors = ["방성범 (Bang Seongbeom) "] edition = "2024" description = "An implementation of the URL Pattern Standard for Python written in Rust." @@ -15,4 +15,4 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.27.2" -deno_urlpattern = { package = "urlpattern", version = "0.4.1" } +deno_urlpattern = { package = "urlpattern", version = "0.4.2" } diff --git a/README.md b/README.md index 46f32f9..58cefd4 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ An implementation of [the URL Pattern Standard](https://urlpattern.spec.whatwg.o ## 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. It provides pattern matching syntax like `/users/:id`, similar to [route parameters in Express](https://expressjs.com/en/guide/routing.html#route-parameters) or [Path-to-RegExp](https://github.com/pillarjs/path-to-regexp). You can use it as a foundation to build your own web server or framework. +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](https://expressjs.com/en/guide/routing.html#route-parameters) or [Path-to-RegExp](https://github.com/pillarjs/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](https://github.com/denoland/rust-urlpattern) with [PyO3](https://github.com/PyO3/pyo3) + [Maturin](https://github.com/PyO3/maturin). @@ -29,11 +29,11 @@ py -m pip install urlpattern ## Usage -Check [urlpattern.pyi](urlpattern.pyi). +Check [urlpattern.pyi](https://github.com/urlpattern/python-urlpattern/blob/main/urlpattern.pyi) or the examples below. -## Examples +For various usage examples, you can also check [Chrome for Developers](https://developer.chrome.com/docs/web-platform/urlpattern) or [MDN](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API) (you need to convert JavaScript into Python). -For various usage examples, refer to [Chrome for Developers](https://developer.chrome.com/docs/web-platform/urlpattern) or [MDN](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) (you may need to convert JavaScript into Python). +## Examples ### `test` @@ -72,20 +72,33 @@ print(pattern.test("https://example.com/TeST")) # output: True ### Simple WSGI app ```py -from urlpattern import URLPattern 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}): - user_id = result["pathname"]["groups"]["id"] - start_response("200 OK", [("Content-Type", "text/plain; charset=utf-8")]) - return [f"{user_id=}".encode()] + 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: @@ -96,4 +109,4 @@ with make_server("", 8000, app) as httpd: Due to limitations in the dependency [denoland/rust-urlpattern](https://github.com/denoland/rust-urlpattern), it may not support all features specified in [the standard](https://urlpattern.spec.whatwg.org/). -Check the `pytest.skip` in [`tests/test_lib.py`](tests/test_lib.py). +Check `pytest.skip` in [`tests/test_lib.py`](https://github.com/urlpattern/python-urlpattern/blob/main/tests/test_lib.py).