uploadserver plus an in-browser previewer for developer files (Markdown, JSON, code, CSV, diffs, images). No build step; works offline on a LAN.
Project description
uploadserver-preview
An in-browser file explorer and previewer bolted onto
uploadserver. Browse a directory
over HTTP in a persistent file-tree, click a file, and see it rendered
instead of downloaded: Markdown as prose, JSON as a collapsible tree, source
code with syntax highlighting, CSV/TSV as tables, unified diffs GitHub-style,
and images inline.
It shines on a remote box you're SSH'd into: start it there, forward the port, and read files in a real browser instead of paging through the terminal.
Everything renders client-side with vendored JavaScript — no build step, no
CDN, no outbound network. It also works on an air-gapped LAN, which is where a
file server like this usually lives. Uploads and every other uploadserver
feature (basic auth, TLS/mTLS, --directory, --theme, …) are untouched.
Install
Published on PyPI as uploadserver-preview.
With uv (no separate install step):
uvx uploadserver-preview # run once, in an ephemeral environment
uvx uploadserver-preview 9000 -d /srv
Or install it properly, with uv or pip:
uv tool install uploadserver-preview
pip install uploadserver-preview
This pulls in uploadserver as a dependency. Python 3.9+.
Use
Exactly like uploadserver — same arguments, same behaviour, plus the explorer:
uploadserver-preview # serve ./ on :8000
uploadserver-preview 9000 -d /srv # port 9000, serve /srv
uploadserver-preview --theme dark
uploadserver-preview --basic-auth me:secret
python -m uploadserver_preview 8080 # module form also works
Open http://<host>:8000/ and you get a two-pane explorer: a file-tree on the
left (folders expand in place, a coloured glyph marks each file's kind, an eye
toggle reveals hidden and git-ignored files) and a preview pane on the right.
Previewable files open in the pane; anything else downloads. Every file has a
download link, and the pane's toggle switches between Rendered and
Raw.
Navigating a browser straight to a file's URL opens it in the explorer too;
curl/wget, fetch(), and any URL with ?raw still get the raw bytes, so
scripted downloads behave like stock uploadserver.
Uploads. Drag files anywhere onto the page (or use the Upload button) and they land in the folder you're browsing, not just the served root.
Git. When you browse inside a git work tree, a branch chip appears and you can compare the working tree against a base branch: changed files are marked in the tree, and any file with changes gains a Diff view. Read-only git commands only; outside a repo these surfaces simply don't show.
Flags
All of uploadserver's flags are accepted (port, --directory/-d,
--bind/-b, --theme, --allow-replace, --server-certificate/-c,
--client-certificate, --basic-auth, --basic-auth-upload, --cgi), plus:
| Flag | Effect |
|---|---|
--no-preview |
Disable the previewer; behave like plain uploadserver. |
--cgi also disables the previewer (CGI mode is left to stock uploadserver).
What it renders
| Type | Extensions | Rendered as |
|---|---|---|
| Markdown | .md .markdown .mdown .mkd |
Sanitized HTML prose; fenced code highlighted; ```mermaid fences rendered as diagrams |
| JSON | .json .geojson .ipynb |
Collapsible tree (falls back to highlighted source if invalid) |
| Config | .yaml .yml .toml .ini .cfg .conf |
Highlighted source |
| Code | .py .js .ts .tsx .rs .go .java .c .cpp .rb .php .lua .sql .sh and more |
Highlighted, line-numbered |
| Tables | .csv .tsv |
HTML table with row numbers |
| Diffs | .diff .patch |
Line-by-line diff view |
| Images | .png .jpg .jpeg .gif .webp .bmp .ico .avif .svg |
Inline, with dimensions |
| Markup | .html .htm .xml .xhtml |
Source only — never executed |
Unrecognized extensions are shown as text when they look textual, and flagged as binary otherwise. Text rendering is capped at 3 MB and tables at 5,000 rows to keep the browser responsive; the raw link always serves the full file.
Security notes
- Uploaded content is untrusted. Markdown is sanitized with DOMPurify before
it touches the DOM. Code, JSON, YAML, CSV, and diffs are escaped or inserted as
text. HTML/SVG/XML files are shown as source and never executed; images are
loaded via
<img>, where scripts do not run. - A strict Content-Security-Policy is sent on preview pages (
default-src 'self',script-src 'self'— all JS is external, no inline scripts —object-src 'none'). Inline styles are permitted because the JSON component and the highlight/diff themes rely on them. - Preview routes, assets, and uploads are behind the same basic auth as the rest of the server, so nothing is exposed before authentication.
- Git integration runs read-only git commands only, scoped to the served directory; the compare base is validated against the repo's real branch list.
- This is still a simple file server. Don't expose it to the public internet
without auth + TLS, exactly as with stock
uploadserver.
Offline / vendored assets
All rendering libraries live under uploadserver_preview/assets/ and are served
locally, so the previewer needs no internet access. Bundled: highlight.js,
marked, DOMPurify, PapaParse, diff2html, mermaid, and @andypf/json-viewer. See
LICENSE for their licenses. mermaid (~3.5 MB) is loaded on demand — only the
first markdown file that actually contains a diagram pulls it in.
Limitations
- No preview for PDF or Office documents (they open via the raw link; modern browsers render PDFs natively).
- Diffs are colored by line; intra-line syntax highlighting is omitted.
- CGI mode (
--cgi) is served by stockuploadserverwithout previews.
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 Distribution
Built Distribution
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 uploadserver_preview-0.1.19.tar.gz.
File metadata
- Download URL: uploadserver_preview-0.1.19.tar.gz
- Upload date:
- Size: 1.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
840ebccc3f85a9d09378d816f27c0ca1f74c1c69711c7c9cbff6aad1f4aaa456
|
|
| MD5 |
519853979acc115e640e7c8510d43747
|
|
| BLAKE2b-256 |
97cd06ac688ce03b5bc57211434724e09f79559e91b8ccb38da47beafdecd308
|
File details
Details for the file uploadserver_preview-0.1.19-py3-none-any.whl.
File metadata
- Download URL: uploadserver_preview-0.1.19-py3-none-any.whl
- Upload date:
- Size: 1.1 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1378aa8e55b505cc7e17bf763bcf9d047089995ff967d64c96a895417aa37aa7
|
|
| MD5 |
f1a8372f759c153903ea3765d2a4c023
|
|
| BLAKE2b-256 |
ae9d3d7838f88489470c48528c70110bef262dae1561d9440fabeb3552bc2f08
|