- Record url.path before routing so 404s and early responses retain their path. - Keep matched route templates as span names to limit cardinality. - Exclude query strings, full URLs, cookies and authorization headers. - Test decoded paths on 404 responses and path attributes on matched routes. - Document that paths may expose filenames, IDs or share tokens. - Validate NanoShare with 294 passing tests.
NanoShare
Quart-based file sharing service with a desktop CLI and folder sync client.
Python versions
- Server: Python 3.15+, matching the
quart_commonsubmodule's minimum..python-versionand the Docker image select Python 3.15. - Standalone CLI: Python 3.14+. Install with
uv tool install ./cli.
Modern Python features
- Native deferred annotations (Python 3.14, PEP 649/749) replace
from __future__ import annotationsin application and CLI modules. - The CLI uses Python 3.14's
argparsecommand typo suggestions. - Targeted
__lazy_modules__declarations (Python 3.15, PEP 810) defer command-specific CLI dependencies and QR/Pillow imports until needed. Python 3.14 imports these normally. Server registration imports remain eager; do not enable global lazy imports for the application.
OpenTelemetry request tracing
Tracing follows the setup in My Webside and API and is disabled unless an OTLP endpoint is configured. Export uses OTLP/HTTP protobuf with a bounded background queue (2-second export timeout), not network I/O on the request path.
Example environment variables (also usable with Docker):
OTEL_SERVICE_NAME=nanoshare
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
OTEL_TRACES_SAMPLER_ARG=0.1
| Variable | Purpose |
|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
Collector base URL; exporter appends /v1/traces. |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
Full trace URL; takes precedence over the base URL. |
OTEL_SERVICE_NAME |
Service resource name; falls back to SERVICE_NAME, then nanoshare. |
OTEL_TRACES_SAMPLER_ARG |
Root-request sampling ratio from 0 to 1, default 0.1. Valid parent sampling decisions are respected. |
OTEL_EXPORTER_OTLP_HEADERS |
Optional exporter authentication headers; use environment secrets, never commit credentials. |
OTEL_EXPORTER_OTLP_TRACES_HEADERS |
Optional trace-specific exporter headers. |
HTTP server spans accept W3C traceparent/tracestate, return X-Trace-ID, and
correlate existing wide-event logs through trace_id and request.id. Route
names use templates rather than actual file IDs or paths. The existing
my_helpers Convex worker instrumentation creates child client spans across
worker/thread boundaries, propagates W3C context, and sends native
convex-request-id: otel-<trace-id>-<span-id> headers without changing function
arguments. Retries get distinct span/request IDs.
HTTP spans include url.path for every request, including unmatched 404s.
Paths can contain filenames, IDs or share tokens; treat stored traces accordingly.
Span names still use route templates when available to avoid high cardinality.
Spans do not capture payloads, query strings, full URLs, cookies, authorization
headers or exception text. WebSockets and ASGI lifespan messages pass through unchanged.
This integration exports traces only, not OTel metrics or logs; existing
wide-event logging remains independent. The SDK shuts down its exporter off the
event loop during application shutdown. Configure the collector/network outside
this project; no collector container is added here.
Development and tests
uv sync --locked
uv run --locked python -m pytest -q
The dev dependency group includes pytest, pytest-asyncio, and watchdog.
The Docker build excludes this group with --no-dev.
The complete suite includes quart_common/tests and requires Python 3.15.
For standalone CLI checks on Python 3.14, use a separate environment:
uv venv --python 3.14 /tmp/nanoshare-cli-py314
uv pip install --python /tmp/nanoshare-cli-py314/bin/python ./cli pytest
/tmp/nanoshare-cli-py314/bin/python -m pytest -q tests/test_nanoshare_cli.py
Regression tests in tests/test_python_features.py cover deferred annotations,
command suggestions, lazy help/completion imports, and QR rendering. Lazy import
checks are skipped on Python 3.14.