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.1.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.1-cp313-cp313-win_amd64.whl (84.4 kB view details)

Uploaded CPython 3.13Windows x86-64

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

Uploaded CPython 3.13macOS 13.0+ ARM64

nanoroute-2.0.1-cp312-cp312-manylinux_2_39_x86_64.whl (34.7 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.39+ x86-64

File details

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

File metadata

  • Download URL: nanoroute-2.0.1.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.1.tar.gz
Algorithm Hash digest
SHA256 3035fed5837808f06197f4f60c52258ae190b6c8af52364b275dc92a302d0066
MD5 7d2410984b772e4edad7e47906ddca2d
BLAKE2b-256 208034523a6c606cacc7771414d5721a30883a62e2e9f3e679360470126f35db

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanoroute-2.0.1.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.1-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: nanoroute-2.0.1-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.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 1f6ad0398092d7f44e2db162ef83b94558a9f6fbfa40b22ff61108f3639106d9
MD5 c9f771bdb3dd033b9eac0f261131fbae
BLAKE2b-256 6e00fcad97fe9d7a1c70a394c3c0110f723c394e84d6983f63d7ca2bb2fe39f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanoroute-2.0.1-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.1-cp313-cp313-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for nanoroute-2.0.1-cp313-cp313-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 a3c576e0536dc30323e6d22478b416d077ba5c9d00b83f64ce3c55ed6c8e0e3d
MD5 e0e7d2f84e9fce5f27672c1f0dedf0ae
BLAKE2b-256 0a5006919e20324094718f0fa30b7b8e2706b10fa7c28f10a82f629824cd42a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanoroute-2.0.1-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.

File details

Details for the file nanoroute-2.0.1-cp312-cp312-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for nanoroute-2.0.1-cp312-cp312-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 4f4bdb7636476937eb00805d3ae6e5d40fd8c097ba203530b4cc268c25e3f0b6
MD5 36e855e4deaf94594815b7050bdb600d
BLAKE2b-256 3ff4321aced319cd31fe1cffd56b3800d0ccef42739dd2a79ac131e5ab78a388

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanoroute-2.0.1-cp312-cp312-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.

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