Build and Push Docker Container / build-and-push (push) Successful in 4m43s
- 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.
78 lines
3.8 KiB
Markdown
78 lines
3.8 KiB
Markdown
# NanoShare
|
|
Quart-based file sharing service with a desktop CLI and folder sync client.
|
|
|
|
## Python versions
|
|
- **Server: Python 3.15+**, matching the `quart_common` submodule's minimum.
|
|
`.python-version` and 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 annotations` in application and CLI modules.
|
|
- The CLI uses Python 3.14's `argparse` command 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):
|
|
```dotenv
|
|
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
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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.
|