{"id":16693594,"url":"https://github.com/nickelpro/nanoroute","last_synced_at":"2025-08-29T13:09:16.912Z","repository":{"id":257821291,"uuid":"871001733","full_name":"nickelpro/nanoroute","owner":"nickelpro","description":"Small, fast, Python HTTP URL router","archived":false,"fork":false,"pushed_at":"2025-05-28T21:22:48.000Z","size":107,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-29T12:03:28.698Z","etag":null,"topics":["http","python","url-router","wsgi-framework"],"latest_commit_sha":null,"homepage":"https://nanoroute.dev/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nickelpro.png","metadata":{"files":{"readme":"ReadMe.md","changelog":null,"contributing":null,"funding":null,"license":"License","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-11T04:30:00.000Z","updated_at":"2025-05-28T21:22:52.000Z","dependencies_parsed_at":"2024-10-11T05:41:10.882Z","dependency_job_id":"75aa916b-42c5-4d33-acb8-31eff5136b62","html_url":"https://github.com/nickelpro/nanoroute","commit_stats":null,"previous_names":["nickelpro/nanoroute"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/nickelpro/nanoroute","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickelpro%2Fnanoroute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickelpro%2Fnanoroute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickelpro%2Fnanoroute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickelpro%2Fnanoroute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickelpro","download_url":"https://codeload.github.com/nickelpro/nanoroute/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickelpro%2Fnanoroute/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266465051,"owners_count":23933049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http","python","url-router","wsgi-framework"],"created_at":"2024-10-12T16:31:39.768Z","updated_at":"2025-07-22T09:31:39.433Z","avatar_url":"https://github.com/nickelpro.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/nickelpro/nanoroute/test.yaml?style=for-the-badge)](https://github.com/nickelpro/nanoroute/actions/workflows/test.yaml)\n\n# nanoroute\n\nA small Python HTTP URL routing facility capable of sub-microsecond routing,\ntypically \u003c200ns.\n\nNanoroute is a C++ implementation of a modified version of the priority\nradix-tree algorithm pioneered by Julien Schmidt's\n[httprouter](https://github.com/julienschmidt/httprouter). Like httprouter,\nnanorouter's underlying implementation performs no allocations in the common\ncase, although some allocations are necessary to create the PyObjects necessary\nfor the CPython bindings.\n\nThe nanoroute package is suitable as a building block for more fully featured\nHTTP frameworks. It also provides a simple WSGI interface for integration\ndirectly into WSGI application stacks.\n\nThe intended use cases are high-performance message brokers, dispatchers, and\ningestion endpoints. The performance improvements of a high-speed router are\nunlikely to be very significant in a typical database-backed Python REST API.\n\n## Quickstart\n\nFor complete documentation, see the [docs](https://nanoroute.dev).\n\n#### Installation\n\nNanoroute only supports Python 3.13+. It is available via PyPI, any mechanism\nof installing Python packages from PyPI will work:\n\n```\npip install nanoroute\n```\n\n#### Registering Routes\n\nNanoroute provides a single class, the `router`, which can be used to register\nhandlers for common HTTP verbs.\n\n```python\nimport nanoroute\n\napp = nanoroute.router()\n\n@app.get('/')\ndef root(*args, **kwargs):\n  ...\n\n@app.post('/endpoint')\ndef endpoint(*args, **kwargs):\n  ...\n```\n\nThe verbs supported via these convenience methods are `GET`, `POST`, `PUT`, and\n`DELETE`. Arbitrary sets of any ***valid*** HTTP verbs can be registered\nusing `router.route()`.\n\n```python\n# Register for a single HTTP verb\n@app.route('PATCH', '/object')\ndef handle_patch(*args, **kwargs):\n  ...\n\n# Register for a multiple HTTP verbs\n@app.route(['POST', 'PUT'], '/multi-meth')\ndef handle_multi(*args, **kwargs):\n  ...\n```\n\nFinally, any arbitrary object can be registered with nanoroute. The decorator\nsyntax is merely convenient for typical usage.\n\n```python\n# Register arbitrary object for GET '/'\napp.get('/')(object())\n```\n\n#### Capturing Parameters\n\nTwo forms of parameter capture are available, segment capture and catchall.\nSegment captures are delimited by `:` and capture from the appearance of the\ndelimiter until the following `/` or the end of the URL. Catchalls are delimited\nby `*` and capture the entire URL following their appearance.\n\nBoth types of parameter capture may be followed by a name, which will used as\nthe key associated with the parameter during route lookup. Anonymous parameters\nact as wildcards, they have the same behavior as named parameters but the\ncaptured data is not reported during lookup.\n\n```python\n# Captures the middle segment with the name \"id\"\n@app.get('/user/:id/profile')\ndef get_profile(*args, **kwargs):\n  ...\n\n# Captures the article ID into \"id\", and then everything after the final \"/\"\n# is captured as \"slug\" which might contain multiple path segments\n@app.get('/article/:id/*slug')\ndef article(*args, **kwargs):\n  ...\n\n# The first path segment is a wildcard, anything may appear, but nothing is\n# captured during route lookup\n@app.get('/:/anonymous')\ndef anon(*args, **kwargs):\n  ...\n```\n\nCaptures are allowed to appear at arbtirary points in a given segment, so\nlong as multiple captures do not appear in the same segment.\n\n```python\n# Captures an \"id\" in the middle of a segment\n@app.get('/user_:id/profile')\ndef get_profile(*args, **kwargs):\n  ...\n\n# Error: Invalid wildcard construction. Only one capture is allowed to appear\n# in a given path segment\n@app.get('/user_:id_:name')\ndef this_is_an_error(*args, **kwargs):\n  ...\n```\n\nCaptures that appear in the same place for different paths may have different\nnames, which will be recorded appropriately.\n\n```python\n# Captures the first segment as \"foo\"\n@app.get('/:foo/alpha')\ndef alpha(*args, **kwargs):\n  ...\n\n# Captures the first segment as \"bar\"\n@app.get('/:bar/beta')\ndef beta(*args, **kwargs):\n  ...\n```\n\n#### Lookup\n\nThe base lookup facility is `router.lookup()`, which is intended for other\nframeworks to use as a building block. It takes a method and path as arguments\nand returns the registered handler and a parameter capture dictionary.\n\n```python\n@app.get('/user/:name')\ndef say_hello(params):\n  print(f'Hello {params['name']}!')\n\nhandler, params = app.lookup('GET', '/user/Jane')\nhandler(params)\n\n# \u003e\u003e\u003e Hello Jane!\n```\n\nAs a convenience, a WSGI application is also provided. It is directly equivalent\nto the following code:\n```python\ndef wsgi_app(environ, start_response):\n  handler, params = app.lookup(environ['REQUEST_METHOD'], environ['PATH_INFO'])\n  environ['nanoroute.params'] = params\n  return handler(environ, start_response)\n\napp.wsgi_app = wsgi_app\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickelpro%2Fnanoroute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickelpro%2Fnanoroute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickelpro%2Fnanoroute/lists"}