Skip to main content

An embedded server wrapped with nanobind

Project description

nanosrv

Python bindings for the nanosrv embedded HTTP/WebSocket server library, built with nanobind and scikit-build-core.

nanosrv is a lightweight, single-file C++ server library (based on Mongoose) that provides HTTP and WebSocket support with both single-threaded and multi-threaded (sharded) event loops. The Python bindings wrap this as a native extension, giving Python code direct access to the C++ event loop with minimal overhead.

Features

  • HTTP server with typed request/response handlers
  • WebSocket support (text, binary, ping/pong, upgrade)
  • Single-threaded (Manager) and multi-threaded (ShardedManager) event loops
  • URL parsing, Base64 encode/decode, URL encode/decode
  • JSON path-based extraction (string, number, integer, boolean)
  • Configurable logging levels
  • Connection hardening: idle timeout (set_idle_timeout), request-receive deadline (set_request_timeout), and request-body cap with 413 (set_max_body_size)
  • GIL-releasing poll() and run() for responsive Python integration

Server Implementations

The project provides six server implementations: five built on the nanosrv networking core, plus the upstream Mongoose 7.21 library (from which nanosrv was extracted) as a reference baseline. They differ in language, threading model, and abstraction level.

Overview

Implementation Language Threading Event loop Source
mongoose 7.21 C Single-threaded mg_mgr_poll() loop thirdparty/mongoose/main.c
mungo-server C Single-threaded mg_mgr_poll() loop projects/mungo/main.c
nanosrv-server C++ Single-threaded Manager::poll() loop projects/nanosrv-exe/main.cpp
nanosrv-sharded C++ Multi-threaded (accept-and-hand-off) 1 acceptor + N worker Manager loops projects/nanosrv-sharded/main_sharded.cpp
nanosrv Python Manager Python (nanobind) Single-threaded Manager.poll() from Python nanosrv.Manager
nanosrv Python ShardedManager Python (nanobind) Multi-threaded ShardedManager.run() from Python nanosrv.ShardedManager

Architecture

mongoose 7.21 is the upstream reference. Mongoose is a widely-used, battle-tested embedded networking library with HTTP, WebSocket, MQTT, and TLS support in a single mongoose.c/mongoose.h pair (~33K lines). It uses the same callback-based event loop as nanosrv. The server included here uses the identical API pattern as mungo-server, providing a baseline to verify that nanosrv's extraction from Mongoose introduces no performance regression.

mungo-server links against mungo.c/mungo.h -- a minimal subset extracted from Mongoose 7.21, stripped down to HTTP and WebSocket only (~5.5K lines vs ~33K). The API is identical: plain C function pointer callbacks receiving (mg_connection*, int ev, void* ev_data). No abstraction layer -- you check the event code, cast ev_data, and call mg_http_reply(). The reduced code size means faster compilation and a smaller binary, at the cost of features removed during extraction (MQTT, TLS, multipart, SSI, etc.).

nanosrv-server wraps the C core in a C++ RAII layer. Manager owns the mg_mgr and provides http_listen() with typed std::function<void(Connection&, HttpMessage&)> callbacks -- no manual event code checks or void pointer casts. The cost is one virtual call through std::function per request. The C++ layer also adds ConnectionRef, typed enums (Event, WsOpcode, LogLevel), and convenience methods on Connection and HttpMessage.

nanosrv-sharded uses a single acceptor thread that listens for connections and distributes accepted socket FDs round-robin to N worker threads. Each worker runs its own independent Manager event loop. On accept, the FD is detached from the acceptor's kqueue/epoll (via detach_fd()), pushed to a per-worker lock-protected queue, and adopted by the worker using wrapfd() with the HTTP protocol handler installed. This avoids the macOS SO_REUSEPORT limitation (which does not load-balance across listeners) and provides true connection-level parallelism.

nanosrv Python Manager exposes the C++ Manager class to Python via nanobind. The GIL is released during poll() so the event loop can process I/O without blocking Python threads. When a request arrives, the C++ trampoline acquires the GIL, calls the Python handler, and releases it again. The overhead per request is one GIL acquire/release cycle plus the Python-to-C++ marshalling (~100us at the scale we measured).

nanosrv Python ShardedManager exposes the C++ ShardedManager to Python. Worker threads each run their own event loop (GIL released), acquiring the GIL only to execute the Python callback. Since CPython's GIL serializes all Python execution, multiple workers contend for the GIL -- the parallelism benefits I/O and C++-side work but not Python handler code. This makes the sharded Python variant slower than the single-threaded one for trivial Python handlers, but beneficial when the handler triggers significant C/C++ work (e.g., computation or I/O that releases the GIL).

Feature Comparison

Feature mongoose 7.21 mungo-server nanosrv-server nanosrv-sharded nanosrv Python Manager nanosrv Python ShardedManager
HTTP request/response yes yes yes yes yes yes
WebSocket yes yes yes yes yes yes
MQTT yes -- -- -- -- --
TLS (mbedTLS) yes -- opt-in opt-in -- --
Multipart / SSI / OTA yes -- -- -- -- --
Typed callbacks (no void*) -- -- yes yes yes yes
RAII resource management -- -- yes yes yes yes
Multi-threaded I/O -- -- -- yes -- yes
Signal handling manual manual manual manual Python signal Python signal + threading.Event
Dependencies libc only libc only libc + libstdc++ libc + libstdc++ Python + nanobind Python + nanobind
Library size (lines) ~33K ~5.5K ~5.5K + C++ wrappers ~5.5K + C++ wrappers ~5.5K + bindings ~5.5K + bindings

Quickstart

Install and build

uv sync                # install dependencies + build extension
uv run pytest          # run tests

Minimal HTTP server

import nanosrv

mgr = nanosrv.Manager()
mgr.http_listen("http://0.0.0.0:8080", lambda conn, msg: (
    conn.http_reply(200, "Content-Type: text/plain\r\n",
                    f"Hello! You requested {msg.uri}")
))

while True:
    mgr.poll(1000)

Sharded (multi-threaded) server

import nanosrv
import threading

mgr = nanosrv.ShardedManager(0)  # 0 = use all CPU cores
mgr.http_listen("http://0.0.0.0:8080", lambda conn, msg: (
    conn.http_reply(200, "", "OK\n")
))

runner = threading.Thread(target=mgr.run, daemon=True)
runner.start()

# mgr.stop() to shut down

WebSocket upgrade

def handler(conn, event, data):
    if event == nanosrv.Event.HttpMessage:
        conn.ws_upgrade(data, "")
    elif event == nanosrv.Event.WsMessage:
        conn.ws_send_text(f"echo: {data.data}")

mgr = nanosrv.Manager()
mgr.http_listen_event("http://0.0.0.0:8080", handler)

Utilities

import nanosrv

# Base64
nanosrv.base64_encode("hello")   # "aGVsbG8="
nanosrv.base64_decode("aGVsbG8=") # "hello"

# URL encode/decode
nanosrv.url_encode("hello world") # "hello%20world"
nanosrv.url_decode("hello%20world") # "hello world"

# URL parsing
u = nanosrv.Url.parse("https://example.com:8443/path")
# u.host="example.com", u.port=8443, u.path="/path", u.is_ssl=True

# JSON path extraction
nanosrv.json.string('{"name": "nanosrv"}', "$.name")  # "nanosrv"
nanosrv.json.integer('{"n": 42}', "$.n")             # 42
nanosrv.json.number('{"x": 3.14}', "$.x")            # 3.14
nanosrv.json.boolean('{"ok": true}', "$.ok")          # True

API Reference

Classes

Class Description
Manager Single-threaded event loop. Call poll(timeout_ms) in a loop.
ShardedManager(n) Multi-threaded event loop. n=0 uses hardware concurrency. Call run() to block, stop() to shut down.
Connection Passed to handlers. Methods: http_reply(), ws_send_text(), ws_send_binary(), ws_upgrade(), send_bytes(), close().
ConnectionRef Non-owning handle returned by http_listen(). Methods: http_reply(), send_bytes(), close().
HttpMessage Read-only incoming HTTP message. Properties: method, uri, query, body, status_code. Methods: header(name), credentials().
WsMessage Read-only WebSocket frame. Properties: data, flags, opcode.
Url URL parse result. Static method: Url.parse(url). Properties: host, port, path, is_ssl.

Enums

Enum Values
Event Error, Open, Poll, Resolve, Connect, Accept, TlsHandshake, Read, Write, Close, HttpHeaders, HttpMessage, WsOpen, WsMessage, WsControl, Wakeup, User
WsOpcode Continue, Text, Binary, Close, Ping, Pong
LogLevel None, Error, Info, Debug, Verbose

Functions

Function Description
base64_encode(s) / base64_decode(s) Base64 encode/decode
url_encode(s) / url_decode(s) URL percent-encoding
set_log_level(level) / get_log_level() Control log verbosity
millis() Current time in milliseconds
tls_available() Whether the build has a TLS backend (False in the default build; True when built with the mbedTLS backend -- see Build Targets)
json.string(json, path) Extract string at JSON path
json.number(json, path) Extract float at JSON path
json.integer(json, path) Extract int at JSON path
json.boolean(json, path) Extract bool at JSON path

Limitations & security notes

  • TLS is opt-in (C++ build). The default build links a no-op TLS stub, so https:// and wss:// are not supported: tls_available() returns False, and calling http_listen / http_listen_event with a TLS URL raises RuntimeError immediately rather than failing later at the handshake. An mbedTLS backend can be enabled when building the C++ library/server with -DNANOSRV_TLS=mbed (see Build Targets), after which tls_available() is True and TLS listeners/clients work. The Python wheel currently ships with the stub (no TLS); terminate TLS in front of nanosrv (e.g. a reverse proxy) when using the bindings.
  • IP ACLs are not enforced automatically. The library provides check_ip_acl() (C++), which now matches both IPv4 and IPv6 with bitwise prefix comparison -- a previous version returned early for IPv6, so a restrictive ACL silently failed open for IPv6 peers. It is a building block: no listener applies an ACL on its own yet, so wire it into your handler if you need address filtering.
  • Not yet hardened for hostile networks. See the connection-hardening knobs (set_idle_timeout, set_request_timeout, set_max_body_size, set_max_connections, set_max_send_buffer) and the graceful-drain support, but treat exposure to untrusted clients as experimental.

Performance

Benchmarked with wrk -t4 -c100 -d10s on Apple Silicon (M2, 8 cores).

Trivial handler (no CPU work)

Server Req/sec Avg Latency p99 Latency vs mongoose
mongoose 7.21 (C) 205,744 466us 779us --
mungo-server (C) 208,152 461us 860us +1%
nanosrv-server (C++) 200,851 486us 817us -2%
nanosrv-sharded (C++, 8 workers) 183,784 683us 8.5ms -11%
nanosrv Python Manager (Python) 161,698 610us 1.24ms -21%
nanosrv Python ShardedManager (Python, 8 workers) 86,769 1.15ms 2.67ms -58%

With a trivial handler, the single-threaded C servers dominate. Mongoose 7.21 and mungo-server are within noise of each other (~206K vs ~208K req/s), confirming that nanosrv's extraction from Mongoose introduces no performance regression despite removing ~27K lines of code. The C++ wrapper costs ~2% for std::function dispatch. The sharded server pays an accept-and-hand-off tax (mutex, queue, FD re-registration in kqueue) that exceeds the benefit when there is no CPU work to parallelize. The nanosrv Python Manager retains ~79% of native C throughput -- the remaining cost is GIL acquire/release per request. The nanosrv Python ShardedManager is slowest here because multiple worker threads contend for the GIL to run a trivial Python callback.

CPU-bound handler (busy spin)

The --busy <us> flag on the C++ servers adds a CPU spin loop to the handler, simulating real work (JSON serialization, computation, etc.):

Busy (us) Single req/s Sharded req/s Speedup
0 200,315 186,308 0.93x
10 66,181 145,511 2.2x
50 18,284 88,111 4.8x
100 9,542 51,804 5.4x
500 1,958 12,062 6.2x

With just 10us of handler work the sharded server already doubles throughput. At 500us (realistic for a database query or large JSON response) it delivers 6.2x speedup across 8 workers -- near-linear scaling. The crossover point is around 5-10us of handler CPU time.

Run benchmarks

make bench    # builds everything, runs all benchmarks, generates HTML report

This produces terminal output and an HTML report at build/bench-report.html with SVG charts and tables.

When to Use Which

mongoose 7.21 -- Use when you need the full Mongoose feature set: MQTT, TLS, multipart uploads, SSI, OTA updates, or any of the many protocols and utilities that Mongoose provides out of the box. It is battle-tested, widely deployed, and commercially supported. The performance is identical to mungo-server. Choose this over nanosrv when you need features that were stripped during extraction.

mungo-server -- Use when you only need HTTP and WebSocket and want the smallest possible footprint. At ~5.5K lines vs Mongoose's ~33K, it compiles faster, produces a smaller binary, and has less code surface to audit. The API is identical to Mongoose, so migrating between them is trivial. Best for embedded systems, microcontrollers, or any C project where you want a minimal HTTP server with no extras.

nanosrv-server -- The default choice for C++ projects. Typed callbacks, RAII, and std::function handlers make it safer and more ergonomic than the C API with negligible overhead (~2%). Use this for any single-threaded C++ server where the handler is fast (under ~5us) or where simplicity matters more than multi-core scaling.

nanosrv-sharded -- Use when your handler does real CPU work (>10us per request): computation, serialization, database query building, or any blocking operation. The accept-and-hand-off architecture distributes connections across workers for true parallelism. Not worth the overhead for trivial handlers -- the single-threaded server will be faster in that case.

nanosrv Python Manager -- The default choice for Python projects. You get 79% of native C throughput with a Pythonic API. The single-threaded event loop avoids GIL contention entirely. Use this for Python HTTP/WebSocket servers, prototyping, scripting, or any case where Python handler logic is the bottleneck (since the GIL already serializes it, multiple threads won't help).

nanosrv Python ShardedManager -- Use only when the Python handler triggers significant work that releases the GIL: calling into C extensions, doing I/O via libraries that release the GIL, or dispatching to native code. If your handler is pure Python, the single-threaded Manager will be faster. On Python 3.13+ with free-threading (PEP 703), the sharded variant would benefit from true parallel Python execution, but as of CPython 3.12 the GIL serializes all Python-level work.

Decision flowchart:

Is it a Python project?
  yes --> Is the handler pure Python?
            yes --> nanosrv Python Manager
            no  --> Does the handler release the GIL for heavy work?
                      yes --> nanosrv Python ShardedManager
                      no  --> nanosrv Python Manager
  no  --> Do you need MQTT, TLS, multipart, or other Mongoose features?
            yes --> mongoose 7.21
            no  --> Is it a C-only project or size-constrained?
                      yes --> mungo-server
                      no  --> Does the handler do >10us of CPU work per request?
                                yes --> nanosrv-sharded
                                no  --> nanosrv-server

Build Targets

Use make help for the full list. Key targets:

make build       # rebuild extension after code changes
make test        # run pytest suite
make lint        # ruff check + fix
make format      # ruff format
make typecheck   # mypy type checking
make qa          # all of the above
make wheel       # build wheel distribution
make dist        # build wheel + sdist + twine check
make clean       # remove build artifacts

C++ server targets:

make server-build   # build nanosrv-server and nanosrv-sharded via CMake
make server-run     # build and run nanosrv-server
make server-test    # build and run C++ tests via ctest
make server-clean   # remove CMake build directory
make bench          # run wrk benchmarks (builds everything first)

TLS backend (opt-in)

TLS is off by default. To build the C++ library and servers with TLS, configure the CMake project with the mbedTLS backend:

cmake -B build/cmake -S projects -DNANOSRV_TLS=mbed
cmake --build build/cmake

mbedTLS is not vendored. By default it is fetched at configure time via CMake FetchContent, pinned to the v3.6.6 release commit and cached under the build tree (so the first configure of the mbed backend needs network access; the default none build never fetches). NANOSRV_MBEDTLS_PROVIDER controls the source:

-DNANOSRV_MBEDTLS_PROVIDER=auto     # use an installed mbedTLS if found, else fetch (default)
-DNANOSRV_MBEDTLS_PROVIDER=system   # require an installed mbedTLS (error if absent)
-DNANOSRV_MBEDTLS_PROVIDER=fetch    # always fetch the pinned commit

An installed mbedTLS is accepted only in the range >= 3.6, < 4.0 (the backend targets the mbedTLS 3.x API; 4.x is an API break and is skipped). With the backend enabled, the C++ test suite adds end-to-end TLS handshake and mutual-TLS (client-certificate) tests.

License

GPL3

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

nanosrv-0.1.1-cp313-cp313-win_amd64.whl (137.5 kB view details)

Uploaded CPython 3.13Windows x86-64

nanosrv-0.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (175.6 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

nanosrv-0.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (162.6 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

nanosrv-0.1.1-cp313-cp313-macosx_11_0_arm64.whl (140.3 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

nanosrv-0.1.1-cp313-cp313-macosx_10_14_x86_64.whl (150.8 kB view details)

Uploaded CPython 3.13macOS 10.14+ x86-64

nanosrv-0.1.1-cp312-cp312-win_amd64.whl (137.5 kB view details)

Uploaded CPython 3.12Windows x86-64

nanosrv-0.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (175.7 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

nanosrv-0.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (162.9 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

nanosrv-0.1.1-cp312-cp312-macosx_11_0_arm64.whl (140.4 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

nanosrv-0.1.1-cp312-cp312-macosx_10_14_x86_64.whl (150.9 kB view details)

Uploaded CPython 3.12macOS 10.14+ x86-64

nanosrv-0.1.1-cp311-cp311-win_amd64.whl (138.1 kB view details)

Uploaded CPython 3.11Windows x86-64

nanosrv-0.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (176.6 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

nanosrv-0.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (163.5 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

nanosrv-0.1.1-cp311-cp311-macosx_11_0_arm64.whl (141.2 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

nanosrv-0.1.1-cp311-cp311-macosx_10_14_x86_64.whl (151.1 kB view details)

Uploaded CPython 3.11macOS 10.14+ x86-64

nanosrv-0.1.1-cp310-cp310-win_amd64.whl (137.9 kB view details)

Uploaded CPython 3.10Windows x86-64

nanosrv-0.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (176.4 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

nanosrv-0.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (163.2 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

nanosrv-0.1.1-cp310-cp310-macosx_11_0_arm64.whl (140.8 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

nanosrv-0.1.1-cp310-cp310-macosx_10_14_x86_64.whl (150.7 kB view details)

Uploaded CPython 3.10macOS 10.14+ x86-64

File details

Details for the file nanosrv-0.1.1-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: nanosrv-0.1.1-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 137.5 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanosrv-0.1.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 fd688ee842fb512607aa2d0e53e92e55f2a37419da4421696a2a6485456c7594
MD5 5b11e7807b1f188388ad8d7a3a98dfe2
BLAKE2b-256 d425b1c93232f63308bae4dfc23173a6cb74d8138121949ef190a364d3e96503

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 bd5bb722ae34733614b28f71cdf73f9eb01ea888de7386f32a5a925f17564907
MD5 0f738b5e679d0d666c0660a1adec8266
BLAKE2b-256 fb5579ff608e95c46d256bcd0425bc01cdb5d9362a00b69d7dbf26cf31c2b3e2

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 50fcf1d7f51e4817c88c55e10d31e12d0a2bd0e9fac542cf3daea517c55afa7b
MD5 96664f87f7552d7d31793eed27ca8b05
BLAKE2b-256 b933e9547fab6a720efdc4e34fabd1055f5643b0b49c805617adb9917a7da306

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cf77bc2910ad482d437a095ca466c0231517e03ec73139f4a8932eb03d6bbe1e
MD5 e97854ace01834dcd445fce9635dc9a2
BLAKE2b-256 8dac03fdd56913454afeabd210dd54379c6877c1be6726ebc7d8cb349c1fc4bc

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp313-cp313-macosx_10_14_x86_64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp313-cp313-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 d27588467ea8c000e6a1174c2c94d47a37efd94025fbd3ba6dfebe52d58f9994
MD5 28b7a4b9882cfcd1789e24b518afb280
BLAKE2b-256 99eb4021abe83905c484b20b22de76c5fa64d0e23a36e44507de78dde19cbf05

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: nanosrv-0.1.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 137.5 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanosrv-0.1.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 ade8a2d04655c865944df5448af6c9f2432c9151e2fe1aabb5375f682fc2810a
MD5 4edf35034682571bf48fc3f3ad9081af
BLAKE2b-256 d9ce669ad914b7ba88099e8fa78a2c38f185f0a5b525297b4ca09ec2893c327f

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a5a1c4234939ddd4d13f1e25f7a2e9affb6ef48327e0b7e197f429cc258ca09c
MD5 a65ba1b821ca02339e4c61b903bc6fd2
BLAKE2b-256 c3eeae75f40e0eb9a35929679f5e67bc3231108ad9c092b5288e1b499c34d2f7

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ea130f029313ca9d59cbdb3da216d3ecc0490b2d495811a737346f9c2f7bcce5
MD5 7d1489489a930e14f41b54df22fa7afd
BLAKE2b-256 3da58ba6d0d873659ae140f71663da266f0d08afb68900d90ab9c48bc3f579c3

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5cb556320f5244d95b31bfb1c1002d121903bb82c3ed9b3343faae59b67ff099
MD5 e349cb7457101248cf7691431b484b54
BLAKE2b-256 07b69e0a0e5d4f7bb8df46c557c95ceae25f5c5aa8fb46621850e09ce4904c50

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp312-cp312-macosx_10_14_x86_64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp312-cp312-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 df7399195a9c17dc3543bf4c86aacb21b7828f72c39a1590236fbea6e18e81f9
MD5 7cc06a61ef36afe0338814e72400b5ed
BLAKE2b-256 ac68c8fd93b7f828d56ea887b478ce127f4ce6ab45ac6db57f9df28c845f36b3

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: nanosrv-0.1.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 138.1 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanosrv-0.1.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 c1de9cfce504eb86acbee0ad5d2c30f2f511e4e354959c927662e9ffca3dc4fc
MD5 af39723975c5c92b4fe77b3aa4ed8f50
BLAKE2b-256 5ec207d9e695b813cfc663e120306e3726a1b80b931665bbd17a90aff19d913f

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 75f8d18d6c359642e36ec21d7470eca11319f09c1c9257b444d7dc49d727f8f8
MD5 168e797373e6b9f23b05ed36dda34a95
BLAKE2b-256 3560475e654267abaf60e76adb7b67a13415243ad25615b07ff9bc6a8e3b6948

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 528cee44ef556a6cf553de9fb3c3f4576b52a55715ccffe9c3fc2f54a8412e64
MD5 99b26e97521b4249561dae73bd608ae0
BLAKE2b-256 bf0c77050abaf499a11febccf97e64e2158107670db34ddd6b91717871863e29

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 93d186aa80ac96bfbf96ffa3b1cc456231dea4c56a1ef7bcac3eef29b85914d6
MD5 b5520207a5d5f3dd6c80764beb1c50c6
BLAKE2b-256 8c6a1b96b70232842ba0a423f23eca15d242a1da8f68d83085bd9c5b3ec4fa26

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp311-cp311-macosx_10_14_x86_64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp311-cp311-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 2390e0142ee29476b381887754b5c5964a4ab7c6580a1cf895df2148e83b5d35
MD5 f54a444131e9d6607f54851f0a84e142
BLAKE2b-256 e428db13b5298892615f66a3faca76712401689ba7e948978e9cd8b529d07ee3

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: nanosrv-0.1.1-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 137.9 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for nanosrv-0.1.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 13fb64058a72a7805a643a579911236999888d923f524d5004afd0a68ee6cbf4
MD5 22976d3dfe98d721cce3db2489815539
BLAKE2b-256 45cc1e843f5c4787972c7602fe9286b44cb7b18d20306402f6d0c8c40fc3a8eb

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 186550692d764b42274820db9ffd8e61c7a4352a56af5e1c56f6e401ca7e7a87
MD5 935faa0d26abf498035c12d75b723828
BLAKE2b-256 bc3e49e5e83b2d543f0e6ec1fc7d52f0cac684ed8b515af94f52b3c4ef3a17f6

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f5b149d9a00f9c06931672956d5fdf77069276425906fb93184fd6fedd9d6475
MD5 24252fe303df536bcf4d4ae61968cb0f
BLAKE2b-256 784ae8a0b901f6d827e88220ac69a5c7e25b4906ce93b2f9df8ae188e8959eb3

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 509fa93fcf87be6c7894c10ded0be839249f4ded6c5043cfbf0384f0ece48254
MD5 7a9f57b400b3260e2751de6b7d30a318
BLAKE2b-256 eab562e3356ab68b0eed42b5f5a17b14bf4def89a64573c3689de04015f33f92

See more details on using hashes here.

File details

Details for the file nanosrv-0.1.1-cp310-cp310-macosx_10_14_x86_64.whl.

File metadata

File hashes

Hashes for nanosrv-0.1.1-cp310-cp310-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 6162ce98983eb00cdec101193a0cea3896f8e16aab7111db6a2f7fdc562eaa86
MD5 42fc5221dbc14deb14dc948cfed14d54
BLAKE2b-256 f5da8591f1a67027d385e52ce5aad4083b84df0f3a495c9bcf682054f73ef70b

See more details on using hashes here.

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