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()andrun()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://andwss://are not supported:tls_available()returnsFalse, and callinghttp_listen/http_listen_eventwith a TLS URL raisesRuntimeErrorimmediately 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 whichtls_available()isTrueand 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd688ee842fb512607aa2d0e53e92e55f2a37419da4421696a2a6485456c7594
|
|
| MD5 |
5b11e7807b1f188388ad8d7a3a98dfe2
|
|
| BLAKE2b-256 |
d425b1c93232f63308bae4dfc23173a6cb74d8138121949ef190a364d3e96503
|
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
- Download URL: nanosrv-0.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 175.6 kB
- Tags: CPython 3.13, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd5bb722ae34733614b28f71cdf73f9eb01ea888de7386f32a5a925f17564907
|
|
| MD5 |
0f738b5e679d0d666c0660a1adec8266
|
|
| BLAKE2b-256 |
fb5579ff608e95c46d256bcd0425bc01cdb5d9362a00b69d7dbf26cf31c2b3e2
|
File details
Details for the file nanosrv-0.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 162.6 kB
- Tags: CPython 3.13, manylinux: glibc 2.27+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50fcf1d7f51e4817c88c55e10d31e12d0a2bd0e9fac542cf3daea517c55afa7b
|
|
| MD5 |
96664f87f7552d7d31793eed27ca8b05
|
|
| BLAKE2b-256 |
b933e9547fab6a720efdc4e34fabd1055f5643b0b49c805617adb9917a7da306
|
File details
Details for the file nanosrv-0.1.1-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 140.3 kB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf77bc2910ad482d437a095ca466c0231517e03ec73139f4a8932eb03d6bbe1e
|
|
| MD5 |
e97854ace01834dcd445fce9635dc9a2
|
|
| BLAKE2b-256 |
8dac03fdd56913454afeabd210dd54379c6877c1be6726ebc7d8cb349c1fc4bc
|
File details
Details for the file nanosrv-0.1.1-cp313-cp313-macosx_10_14_x86_64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp313-cp313-macosx_10_14_x86_64.whl
- Upload date:
- Size: 150.8 kB
- Tags: CPython 3.13, macOS 10.14+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d27588467ea8c000e6a1174c2c94d47a37efd94025fbd3ba6dfebe52d58f9994
|
|
| MD5 |
28b7a4b9882cfcd1789e24b518afb280
|
|
| BLAKE2b-256 |
99eb4021abe83905c484b20b22de76c5fa64d0e23a36e44507de78dde19cbf05
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ade8a2d04655c865944df5448af6c9f2432c9151e2fe1aabb5375f682fc2810a
|
|
| MD5 |
4edf35034682571bf48fc3f3ad9081af
|
|
| BLAKE2b-256 |
d9ce669ad914b7ba88099e8fa78a2c38f185f0a5b525297b4ca09ec2893c327f
|
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
- Download URL: nanosrv-0.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 175.7 kB
- Tags: CPython 3.12, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5a1c4234939ddd4d13f1e25f7a2e9affb6ef48327e0b7e197f429cc258ca09c
|
|
| MD5 |
a65ba1b821ca02339e4c61b903bc6fd2
|
|
| BLAKE2b-256 |
c3eeae75f40e0eb9a35929679f5e67bc3231108ad9c092b5288e1b499c34d2f7
|
File details
Details for the file nanosrv-0.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 162.9 kB
- Tags: CPython 3.12, manylinux: glibc 2.27+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea130f029313ca9d59cbdb3da216d3ecc0490b2d495811a737346f9c2f7bcce5
|
|
| MD5 |
7d1489489a930e14f41b54df22fa7afd
|
|
| BLAKE2b-256 |
3da58ba6d0d873659ae140f71663da266f0d08afb68900d90ab9c48bc3f579c3
|
File details
Details for the file nanosrv-0.1.1-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 140.4 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5cb556320f5244d95b31bfb1c1002d121903bb82c3ed9b3343faae59b67ff099
|
|
| MD5 |
e349cb7457101248cf7691431b484b54
|
|
| BLAKE2b-256 |
07b69e0a0e5d4f7bb8df46c557c95ceae25f5c5aa8fb46621850e09ce4904c50
|
File details
Details for the file nanosrv-0.1.1-cp312-cp312-macosx_10_14_x86_64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp312-cp312-macosx_10_14_x86_64.whl
- Upload date:
- Size: 150.9 kB
- Tags: CPython 3.12, macOS 10.14+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df7399195a9c17dc3543bf4c86aacb21b7828f72c39a1590236fbea6e18e81f9
|
|
| MD5 |
7cc06a61ef36afe0338814e72400b5ed
|
|
| BLAKE2b-256 |
ac68c8fd93b7f828d56ea887b478ce127f4ce6ab45ac6db57f9df28c845f36b3
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1de9cfce504eb86acbee0ad5d2c30f2f511e4e354959c927662e9ffca3dc4fc
|
|
| MD5 |
af39723975c5c92b4fe77b3aa4ed8f50
|
|
| BLAKE2b-256 |
5ec207d9e695b813cfc663e120306e3726a1b80b931665bbd17a90aff19d913f
|
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
- Download URL: nanosrv-0.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 176.6 kB
- Tags: CPython 3.11, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75f8d18d6c359642e36ec21d7470eca11319f09c1c9257b444d7dc49d727f8f8
|
|
| MD5 |
168e797373e6b9f23b05ed36dda34a95
|
|
| BLAKE2b-256 |
3560475e654267abaf60e76adb7b67a13415243ad25615b07ff9bc6a8e3b6948
|
File details
Details for the file nanosrv-0.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 163.5 kB
- Tags: CPython 3.11, manylinux: glibc 2.27+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
528cee44ef556a6cf553de9fb3c3f4576b52a55715ccffe9c3fc2f54a8412e64
|
|
| MD5 |
99b26e97521b4249561dae73bd608ae0
|
|
| BLAKE2b-256 |
bf0c77050abaf499a11febccf97e64e2158107670db34ddd6b91717871863e29
|
File details
Details for the file nanosrv-0.1.1-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 141.2 kB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93d186aa80ac96bfbf96ffa3b1cc456231dea4c56a1ef7bcac3eef29b85914d6
|
|
| MD5 |
b5520207a5d5f3dd6c80764beb1c50c6
|
|
| BLAKE2b-256 |
8c6a1b96b70232842ba0a423f23eca15d242a1da8f68d83085bd9c5b3ec4fa26
|
File details
Details for the file nanosrv-0.1.1-cp311-cp311-macosx_10_14_x86_64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp311-cp311-macosx_10_14_x86_64.whl
- Upload date:
- Size: 151.1 kB
- Tags: CPython 3.11, macOS 10.14+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2390e0142ee29476b381887754b5c5964a4ab7c6580a1cf895df2148e83b5d35
|
|
| MD5 |
f54a444131e9d6607f54851f0a84e142
|
|
| BLAKE2b-256 |
e428db13b5298892615f66a3faca76712401689ba7e948978e9cd8b529d07ee3
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13fb64058a72a7805a643a579911236999888d923f524d5004afd0a68ee6cbf4
|
|
| MD5 |
22976d3dfe98d721cce3db2489815539
|
|
| BLAKE2b-256 |
45cc1e843f5c4787972c7602fe9286b44cb7b18d20306402f6d0c8c40fc3a8eb
|
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
- Download URL: nanosrv-0.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 176.4 kB
- Tags: CPython 3.10, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
186550692d764b42274820db9ffd8e61c7a4352a56af5e1c56f6e401ca7e7a87
|
|
| MD5 |
935faa0d26abf498035c12d75b723828
|
|
| BLAKE2b-256 |
bc3e49e5e83b2d543f0e6ec1fc7d52f0cac684ed8b515af94f52b3c4ef3a17f6
|
File details
Details for the file nanosrv-0.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 163.2 kB
- Tags: CPython 3.10, manylinux: glibc 2.27+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f5b149d9a00f9c06931672956d5fdf77069276425906fb93184fd6fedd9d6475
|
|
| MD5 |
24252fe303df536bcf4d4ae61968cb0f
|
|
| BLAKE2b-256 |
784ae8a0b901f6d827e88220ac69a5c7e25b4906ce93b2f9df8ae188e8959eb3
|
File details
Details for the file nanosrv-0.1.1-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 140.8 kB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
509fa93fcf87be6c7894c10ded0be839249f4ded6c5043cfbf0384f0ece48254
|
|
| MD5 |
7a9f57b400b3260e2751de6b7d30a318
|
|
| BLAKE2b-256 |
eab562e3356ab68b0eed42b5f5a17b14bf4def89a64573c3689de04015f33f92
|
File details
Details for the file nanosrv-0.1.1-cp310-cp310-macosx_10_14_x86_64.whl.
File metadata
- Download URL: nanosrv-0.1.1-cp310-cp310-macosx_10_14_x86_64.whl
- Upload date:
- Size: 150.7 kB
- Tags: CPython 3.10, macOS 10.14+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6162ce98983eb00cdec101193a0cea3896f8e16aab7111db6a2f7fdc562eaa86
|
|
| MD5 |
42fc5221dbc14deb14dc948cfed14d54
|
|
| BLAKE2b-256 |
f5da8591f1a67027d385e52ce5aad4083b84df0f3a495c9bcf682054f73ef70b
|