Skip to main content

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.

demo

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
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, and @andypf/json-viewer. See LICENSE for their licenses.

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 stock uploadserver without previews.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uploadserver_preview-0.1.14.tar.gz (160.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uploadserver_preview-0.1.14-py3-none-any.whl (164.4 kB view details)

Uploaded Python 3

File details

Details for the file uploadserver_preview-0.1.14.tar.gz.

File metadata

  • Download URL: uploadserver_preview-0.1.14.tar.gz
  • Upload date:
  • Size: 160.8 kB
  • 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

Hashes for uploadserver_preview-0.1.14.tar.gz
Algorithm Hash digest
SHA256 affdcb6be41c637dd9cec072c0bd8553835f7023e841c17f0df6902d249b5e8c
MD5 84252721eca4b4bb9417cbffd18f9c08
BLAKE2b-256 48c9a358185a1f5b3b9a5ed9fc0c01340db927dfe4e090fc4658acf7897768ef

See more details on using hashes here.

File details

Details for the file uploadserver_preview-0.1.14-py3-none-any.whl.

File metadata

  • Download URL: uploadserver_preview-0.1.14-py3-none-any.whl
  • Upload date:
  • Size: 164.4 kB
  • 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

Hashes for uploadserver_preview-0.1.14-py3-none-any.whl
Algorithm Hash digest
SHA256 52f791ab327f53000d972778da23c77fd432babf50ead56bd06ea9239e4247d3
MD5 acda30fa2bf31c58c6c6a959798ad2ed
BLAKE2b-256 06531260a5479611191d276cc851b69c3564b18e7a1e7b1d51367dc016a611ff

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