Skip to main content

Small, fast, HTTP URL router

Project description

GitHub Actions Workflow Status

nanoroute

A small Python HTTP URL routing facility capable of sub-microsecond routing, typically <200ns.

Nanoroute is a C++ implementation of a modified version of the priority radix-tree algorithm pioneered by Julien Schmidt's httprouter. Like httprouter, nanorouter's underlying implementation performs no allocations in the common case, although some allocations are necessary to create the PyObjects necessary for the CPython bindings.

The nanoroute package is suitable as a building block for more fully featured HTTP frameworks. It also provides a simple WSGI interface for integration directly into WSGI application stacks.

The intended use cases are high-performance message brokers, dispatchers, and ingestion endpoints. The performance improvements of a high-speed router are unlikely to be very significant in a typical database-backed Python REST API.

Quickstart

For complete documentation, see the docs.

Installation

Nanoroute only supports Python 3.13+. It is available via PyPI, any mechanism of installing Python packages from PyPI will work:

pip install nanoroute

Registering Routes

Nanoroute provides a single class, the router, which can be used to register handlers for common HTTP verbs.

import nanoroute

app = nanoroute.router()

@app.get('/')
def root(*args, **kwargs):
  ...

@app.post('/endpoint')
def endpoint(*args, **kwargs):
  ...

The verbs supported via these convenience methods are GET, POST, PUT, and DELETE. Arbitrary sets of any valid HTTP verbs can be registered using router.route().

# Register for a single HTTP verb
@app.route('PATCH', '/object')
def handle_patch(*args, **kwargs):
  ...

# Register for a multiple HTTP verbs
@app.route(['POST', 'PUT'], '/multi-meth')
def handle_multi(*args, **kwargs):
  ...

Finally, any arbitrary object can be registered with nanoroute. The decorator syntax is merely convenient for typical usage.

# Register arbitrary object for GET '/'
app.get('/')(object())

Capturing Parameters

Two forms of parameter capture are available, segment capture and catchall. Segment captures are delimited by : and capture from the appearance of the delimiter until the following / or the end of the URL. Catchalls are delimited by * and capture the entire URL following their appearance.

Both types of parameter capture may be followed by a name, which will used as the key associated with the parameter during route lookup. Anonymous parameters act as wildcards, they have the same behavior as named parameters but the captured data is not reported during lookup.

# Captures the middle segment with the name "id"
@app.get('/user/:id/profile')
def get_profile(*args, **kwargs):
  ...

# Captures the article ID into "id", and then everything after the final "/"
# is captured as "slug" which might contain multiple path segments
@app.get('/article/:id/*slug')
def article(*args, **kwargs):
  ...

# The first path segment is a wildcard, anything may appear, but nothing is
# captured during route lookup
@app.get('/:/anonymous')
def anon(*args, **kwargs):
  ...

Captures are allowed to appear at arbtirary points in a given segment, so long as multiple captures do not appear in the same segment.

# Captures an "id" in the middle of a segment
@app.get('/user_:id/profile')
def get_profile(*args, **kwargs):
  ...

# Error: Invalid wildcard construction. Only one capture is allowed to appear
# in a given path segment
@app.get('/user_:id_:name')
def this_is_an_error(*args, **kwargs):
  ...

Captures that appear in the same place for different paths may have different names, which will be recorded appropriately.

# Captures the first segment as "foo"
@app.get('/:foo/alpha')
def alpha(*args, **kwargs):
  ...

# Captures the first segment as "bar"
@app.get('/:bar/beta')
def beta(*args, **kwargs):
  ...

Lookup

The base lookup facility is router.lookup(), which is intended for other frameworks to use as a building block. It takes a method and path as arguments and returns the registered handler and a parameter capture dictionary.

@app.get('/user/:name')
def say_hello(params):
  print(f'Hello {params['name']}!')

handler, params = app.lookup('GET', '/user/Jane')
handler(params)

# >>> Hello Jane!

As a convenience, a WSGI application is also provided. It is directly equivalent to the following code:

def wsgi_app(environ, start_response):
  handler, params = app.lookup(environ['REQUEST_METHOD'], environ['PATH_INFO'])
  environ['nanoroute.params'] = params
  return handler(environ, start_response)

app.wsgi_app = wsgi_app

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nanoroute-2.0.2.tar.gz (22.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

nanoroute-2.0.2-cp313-cp313-win_amd64.whl (84.4 kB view details)

Uploaded CPython 3.13Windows x86-64

nanoroute-2.0.2-cp313-cp313-manylinux_2_39_x86_64.whl (34.7 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.39+ x86-64

nanoroute-2.0.2-cp313-cp313-macosx_13_0_arm64.whl (27.6 kB view details)

Uploaded CPython 3.13macOS 13.0+ ARM64

File details

Details for the file nanoroute-2.0.2.tar.gz.

File metadata

  • Download URL: nanoroute-2.0.2.tar.gz
  • Upload date:
  • Size: 22.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for nanoroute-2.0.2.tar.gz
Algorithm Hash digest
SHA256 3c1ce493dae8ebb6206d5e6449d00a4ed07410baa70c1b73eb93ba6dd18020a6
MD5 4a0ffaf6c40241f6682217fb20a16e45
BLAKE2b-256 d4cf6563647fe05167c08accc55adf0ccabbf20cd7e375bee1270799575744bb

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanoroute-2.0.2.tar.gz:

Publisher: publish.yaml on nickelpro/nanoroute

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nanoroute-2.0.2-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: nanoroute-2.0.2-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 84.4 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for nanoroute-2.0.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 96e9cce37819cf91948ba186f1a14c5682b1cc3fdf14326596e37b53838772c3
MD5 1fabda41b057d06b8ad99131594e027b
BLAKE2b-256 2709f6b24cbde6f415cdf4578f5da86491ca80488f8474962166e7e2edb9dc1f

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanoroute-2.0.2-cp313-cp313-win_amd64.whl:

Publisher: publish.yaml on nickelpro/nanoroute

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nanoroute-2.0.2-cp313-cp313-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for nanoroute-2.0.2-cp313-cp313-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 10954dbada7f8378bd6203a98981d53959b6b2d27f5dc9df6e0702ab6f94ba5b
MD5 a83fcfb9a0f15f4c1c8faabd4b9e89f4
BLAKE2b-256 b9aaedf2800d6cbbd1e6346ca2fbdfa77677674ac5decc3b692223ffbc1dc576

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanoroute-2.0.2-cp313-cp313-manylinux_2_39_x86_64.whl:

Publisher: publish.yaml on nickelpro/nanoroute

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nanoroute-2.0.2-cp313-cp313-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for nanoroute-2.0.2-cp313-cp313-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 6225c4c34b67277e6fee9001bb2dd7c2cc568ada409b868e747b57fdb41b6144
MD5 4e414a5d9d6dbbcaf6712f8743e164ff
BLAKE2b-256 8e4365d3d115e5ee00e3331e06fef3bd65bf6ab9f79ca877b9c52596cf260055

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanoroute-2.0.2-cp313-cp313-macosx_13_0_arm64.whl:

Publisher: publish.yaml on nickelpro/nanoroute

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page