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), client connect timeout (set_connect_timeout), request-body cap with 413 (set_max_body_size), max-connection cap (set_max_connections), and send-buffer watermark (set_max_send_buffer)
  • Observability: cumulative counters and a live connection gauge (Manager.metrics, ShardedManager.metrics)
  • 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.
Metrics Snapshot of a manager's counters. Properties: accepted, closed, errors, bytes_read, bytes_written, active. Read via Manager.metrics / ShardedManager.metrics.
Url URL parse result. Static method: Url.parse(url). Properties: host, port, path, is_ssl.

Callback object lifetime

The Connection, HttpMessage, and WsMessage objects handed to a handler are borrowed views valid only for the duration of that call. They point into buffers owned by the event loop, which reuses or frees them as soon as the handler returns. Do not stash one and touch it later (from another thread, a timer, or a subsequent event) -- read what you need during the call, and copy out any bytes you must keep (e.g. bytes(msg.body) / std::string(hm.body...)). The Python bindings enforce this: a stored Connection/HttpMessage raises if used after the callback returns (see tests/test_nanosrv.py, TestCallbackObjectLifetime). The long-lived exception is ConnectionRef, the non-owning handle returned by http_listen(), which stays valid until its listener closes.

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_connect_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. See SECURITY.md for the current threat-model posture and how to report a vulnerability.
  • Observability. Manager.metrics / ShardedManager.metrics expose cumulative counters (accepted, closed, errors, bytes read/written) plus a live connection gauge for health/metrics endpoints.

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

Uploaded CPython 3.13Windows x86-64

nanosrv-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (180.8 kB view details)

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

nanosrv-0.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (168.6 kB view details)

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

nanosrv-0.2.0-cp313-cp313-macosx_11_0_arm64.whl (144.0 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

nanosrv-0.2.0-cp313-cp313-macosx_10_14_x86_64.whl (159.9 kB view details)

Uploaded CPython 3.13macOS 10.14+ x86-64

nanosrv-0.2.0-cp312-cp312-win_amd64.whl (141.4 kB view details)

Uploaded CPython 3.12Windows x86-64

nanosrv-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (180.9 kB view details)

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

nanosrv-0.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (168.7 kB view details)

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

nanosrv-0.2.0-cp312-cp312-macosx_11_0_arm64.whl (144.0 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

nanosrv-0.2.0-cp312-cp312-macosx_10_14_x86_64.whl (159.9 kB view details)

Uploaded CPython 3.12macOS 10.14+ x86-64

nanosrv-0.2.0-cp311-cp311-win_amd64.whl (142.0 kB view details)

Uploaded CPython 3.11Windows x86-64

nanosrv-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (181.9 kB view details)

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

nanosrv-0.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (169.3 kB view details)

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

nanosrv-0.2.0-cp311-cp311-macosx_11_0_arm64.whl (144.9 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

nanosrv-0.2.0-cp311-cp311-macosx_10_14_x86_64.whl (160.3 kB view details)

Uploaded CPython 3.11macOS 10.14+ x86-64

nanosrv-0.2.0-cp310-cp310-win_amd64.whl (142.0 kB view details)

Uploaded CPython 3.10Windows x86-64

nanosrv-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (181.8 kB view details)

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

nanosrv-0.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (169.4 kB view details)

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

nanosrv-0.2.0-cp310-cp310-macosx_11_0_arm64.whl (144.9 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

nanosrv-0.2.0-cp310-cp310-macosx_10_14_x86_64.whl (160.2 kB view details)

Uploaded CPython 3.10macOS 10.14+ x86-64

File details

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

File metadata

  • Download URL: nanosrv-0.2.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 141.3 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.2.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 c89fda514086fec5eebcbfe564f49b8a47e3ae34c9911edecc19dd0c8cd26e16
MD5 3aa792c1c9938372120d3ae975db1d6d
BLAKE2b-256 4ee33cfeb93152e1c4d4f3d07df5b763c5bee2bf7405eb7ac68bc37e404ca84e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6d34713a391139e06c285be922721439b77f91254acc5b2a501690e58f808aa4
MD5 c840ae7b059327d6547a2dfa336e2b9b
BLAKE2b-256 1894a27c1fa00590e1015be1350f938c9ba617de6c8ffdb37dac29f561788b30

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 dfb5e5b9ae83096ef86e25552f3c1c271ae506f1985d37df2433715fa17f27fb
MD5 b1cbfdc14b1904fe881adbe9799089f0
BLAKE2b-256 781a0a77c5beea6201e55ecdfceb1c3cb709b6b714c832838c65bb97cfc36cde

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c65fe5a3e4e00332bb6fceee02695e750cdfe762e11faab2ebd33cee59f06aa2
MD5 bd83607c4ea4af0dd98fb60ebf927d5e
BLAKE2b-256 8678cdd1d28266999e43bfdb225538a677ab3ba3efeb3044974f18d9294eaf67

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp313-cp313-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 fdcdaae41d4f3a172151bcebc8e22121805e5c63cb62a23243a26f4b5a1edc8f
MD5 5f8150c21f9d6734aa64b8a1fb02a334
BLAKE2b-256 aa6984a65849c3807d7ab0d987f34c009008ab71fa4d82bbe67a91af2501010c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nanosrv-0.2.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 141.4 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.2.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 b3fe78e994daf14310d80db0add12df43866b6a759a124ae2b92f6bb805f1c99
MD5 e8f72219223ea170fcd323b2ba5a67c5
BLAKE2b-256 e6fe0fa24463bc705be93b0f6765b8e265468d7a021d7c9b1dd7eb871584daa9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 49605ac056ef8c23b4d3b84c2e84b1fad63a927ee4a514cbf3dc88ee95c75ef3
MD5 8a5b6ce8e5141d6a85a49fbe8f746984
BLAKE2b-256 6c91950bcd8e7fad527c34b758a0e882b3b8cdcfcce58a3118baaa868c4443aa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 45a64abb8647ec41a8d4eb9478f2bd03f8cc0013e7881ad94e4c6445d4d5b65a
MD5 861d146536f9f5f19114cd4b40c79a57
BLAKE2b-256 416777dfb1dcb9d7d1c57fe3e1d3ff6b1790945e794628c0c565f9169705f570

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d1270f42c5150336ddfbf089fa5d187f2a12722f0ac8086b7470d8b041108389
MD5 4d890261d458d94dce7aa34ff932381e
BLAKE2b-256 dc54a0af2730ab8ad590347fa3ad701f6e8bcea6744fe04b13882f042ad2530a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp312-cp312-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 f8b99396f67c895977bc756b4446944d9a914d0ba3d7a3008c9caf6ecd7e41e6
MD5 3aa4e8f77cfdef872ee6d98e05eadd17
BLAKE2b-256 47487c43d861acbfd9f1bfb6c3b836c3974039450639daf0e157840ae838ac08

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nanosrv-0.2.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 142.0 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.2.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 8f278c6fa8c4e5e2106006f7206f7a716956e6e46f2009774baa3816eb2f6280
MD5 a8c6c355b150856cd4d59d3d631b89ad
BLAKE2b-256 21039c30a2ccb853f639c76e1860adc66b52b851133a0b8c2e1de3005c5d3de3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 007570eda80d7ed0fcfa67eba80af3ac67ad286d445ec7cd33f5469ddf0b44eb
MD5 dba633a247526268524614d71333a6e9
BLAKE2b-256 ba4737a5b4751a458e4a83bbf40ac58ede31162bedcbfb3a2681caae632373a6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0be935b7eb612be8f36715d5c88b42cccb21b314147584ff8a551fac845d02aa
MD5 3684631bb95ce9599137877f60f0c7cd
BLAKE2b-256 45cccb5bf5f6cb96456d4f0723e36d75e4457790285f880c529145890f2fab2f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a386ab95ae93c82124a8cee3fb2f4890032bdc54f1bb859406cd6b1e2e8bb5ea
MD5 4f1ef1c052e381a6f754e5264fd538e0
BLAKE2b-256 05b116f7a81c8d8784522d929a20cdaa2cb63c37fe01dd1c75003574bad70b4e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp311-cp311-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 8e142f71aade6c3b220c946e46824d4d9d7f87e128dc481b2e24240ee9c70adf
MD5 fba8599e2a2cff4f58916316fc43ab81
BLAKE2b-256 7cfb60c48107b5df0305b5a490463f5ff34a5fc9475cf79eeb961afd2baa3524

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nanosrv-0.2.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 142.0 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.2.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 7635c4231a7a52e116bd52f7baf6ae282f5f0d9f421fdc98cf70a8b80347bcb8
MD5 fd52ad0a5153ead2d7b428baf1098530
BLAKE2b-256 6f5ed1ac8a8f6e0a1f12bea8d841bbcac80532f1b1c751f090d24c41fe20d6ce

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 24786e9cf1b6c42210b92bb4445256674704e498c1f7eef008b8862597dbde3c
MD5 78daedcc3ce7be00746b8a4fcf594f2e
BLAKE2b-256 8f53bd85fe7def1b425aed994d98adcda4411a91830bf1f78e49c93289ff2699

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ba64af1aad20a574b9fe77c7cd38d619d1098bfa15069ab0c63b0dc0d41c0f46
MD5 2a4eb553a519879f71f9085b102cba05
BLAKE2b-256 240c1f7fd87ce687f10da189e956d2349a7f87c984fb0c92641cf813315922d5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7149104b4839bec69bc407d85e9513e7070a528eaa82c6d21b4a741e36f210f2
MD5 f6742cc402c85a9ccc362bd3c4a7d39f
BLAKE2b-256 0a9c21cea30c028d2fab821dddb57a2c94f2285e5aa55ebeceeeae4691967921

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nanosrv-0.2.0-cp310-cp310-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 352544471b2eba15eebf406672f469cea0ad4e4c0fac488f0fc68cc80bca713c
MD5 e89da4c9c9ee4d47dfa172bd54119a2f
BLAKE2b-256 4d22e9ebdae911d0987cbb9a5185b4bd8d95640dbf7f67a4dacb47d28f0ad18d

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