Files
publicpaste/README.md
T
尘曲 73a6614118 Add web interface and Docker deployment
Expose the paste tool through a lightweight web UI/API and provide the container setup required for the publicpaste service.
2026-05-13 01:00:40 +08:00

5.3 KiB

publicpaste

publicpaste is a tiny Python package and CLI that posts text to multiple public paste providers concurrently and returns the first successful direct URL.

  • Python 3 standard library first
  • zero runtime dependencies
  • CLI and Python API
  • concurrent provider fan-out with first-success return
  • optional verification of the returned URL

Only paste text that is safe to publish. Returned links are public, and third-party services have their own retention and acceptable-use policies.

Install

From this repository:

python -m pip install .

CLI

publicpaste "hello from publicpaste"
echo "hello from stdin" | publicpaste
publicpaste --file a.txt

By default stdout contains only the URL, making the command easy to pipe:

url=$(publicpaste --file notes.txt)

JSON output includes the provider name:

publicpaste --json "hello"
# {"url":"https://...","provider":"paste.rs"}

Useful options:

  • --timeout SECONDS: per-provider timeout, default 8.0
  • --overall-timeout SECONDS: total wait budget, default 12.0
  • --json: print url and provider as JSON
  • --verbose: print provider diagnostics on failure
  • --verify: GET the returned URL and confirm a 2xx response containing a text fragment
  • --list-providers: list provider names
  • --provider NAME: use only a provider; repeat to select several
  • --disable-provider NAME: disable a provider; repeatable

Failures print a concise error to stderr and exit with status 1.

Web service

publicpaste also includes a zero-dependency web UI and JSON API:

python -m publicpaste.web
# or, after installation:
publicpaste-web

Open http://127.0.0.1:12072, enter text, and click “完成”. The page calls POST /api/paste, shows the returned URL/provider, and copies the URL to the clipboard.

Useful environment variables:

  • PUBLICPASTE_HOST: bind host, default 0.0.0.0
  • PUBLICPASTE_PORT: bind port, default 12072
  • PUBLICPASTE_DATA_DIR: data/log directory, default /data
  • PUBLICPASTE_TIMEOUT: per-provider timeout, default 8.0
  • PUBLICPASTE_OVERALL_TIMEOUT: total wait budget, default 12.0
  • PUBLICPASTE_VERIFY: verify returned URL when true, default false

Health check:

curl http://127.0.0.1:12072/health

Docker

Build and run with Compose:

docker compose up -d --build

The included compose.yml uses image/container name publicpaste, maps 12072:12072, and stores logs/data in /vol1/1000/docker/publicpaste/data mounted at /data.

Python API

from publicpaste import paste_text

result = paste_text("hello", timeout=8.0, overall_timeout=12.0)
print(result.url)
print(result.provider)

Signature:

paste_text(
    text,
    timeout=8.0,
    overall_timeout=12.0,
    providers=None,
    disabled_providers=None,
    verify=False,
)

providers may be a sequence of provider names or provider instances. disabled_providers removes providers by name. The function returns a PasteResult dataclass with at least url and provider. If every provider fails, it raises PasteError with aggregated per-provider errors.

Providers

Default enabled providers:

  • paste.rsPOST https://paste.rs/, raw UTF-8 body; GET /<id> returns plain text.
  • dpaste.orgPOST https://dpaste.org/api/, form fields content, lexer=plain, format=url, expires_on=2592000.
  • 0x0.st — multipart field file, filename paste.txt, text/plain; this is a public file host, so use only non-sensitive text.
  • snippet.host — form fields content, visibility=2, expires=1month, language=plain text; parses Location or HTML URL.
  • paste.centos.orgPOST https://paste.centos.org/, form fields code, lang=text, expire=1440; parses the final redirected view URL. Its documented /api/create endpoint currently requires an API key, so the browser-compatible form endpoint is used.
  • termbin.com — TCP port 9999; low priority but enabled by default.

Each provider has a response parsing method so parsing can be unit tested without network access.

Validation and verification

Provider responses are accepted only when the URL uses http or https and matches the expected provider host and path shape. By default publicpaste does not fetch the returned URL after creation, keeping the fastest provider path quick.

When verify=True or --verify is used, publicpaste performs a GET against the returned direct URL and checks that the response is 2xx and contains a fragment of the original text. HTML escaping is tolerated.

Why not PrivateBin, privydrop, clipboard-style services, or similar?

This project intentionally targets simple public paste endpoints with stable, scriptable APIs. It does not include PrivateBin, privydrop, clipboard-style services, or similar tools when they require browser JavaScript, P2P flows, access codes, encrypted URL fragments, unstable/undocumented APIs, or interaction patterns that do not reliably return a direct public URL from a simple request.

The initially reviewed services that are not enabled by default for those reasons include clipboard.im, clipboard.run, clipboardify.com, clipboardonline.com, privydrop.app, privatebin.net, paste.drhack.net, pasteme.cn, paste.sdjz.wiki, and myonlineclipboard.com.

Tests

Tests are unit-only and do not access the public internet:

python -m pytest