fbde4d6aca
Provide a zero-dependency Python tool that races multiple public paste providers and documents safe AI-tool usage through a project skill.
112 lines
4.3 KiB
Markdown
112 lines
4.3 KiB
Markdown
# 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:
|
|
|
|
```sh
|
|
python -m pip install .
|
|
```
|
|
|
|
## CLI
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
url=$(publicpaste --file notes.txt)
|
|
```
|
|
|
|
JSON output includes the provider name:
|
|
|
|
```sh
|
|
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`.
|
|
|
|
## Python API
|
|
|
|
```python
|
|
from publicpaste import paste_text
|
|
|
|
result = paste_text("hello", timeout=8.0, overall_timeout=12.0)
|
|
print(result.url)
|
|
print(result.provider)
|
|
```
|
|
|
|
Signature:
|
|
|
|
```python
|
|
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.rs` — `POST https://paste.rs/`, raw UTF-8 body; `GET /<id>` returns plain text.
|
|
- `dpaste.org` — `POST 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.org` — `POST 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:
|
|
|
|
```sh
|
|
python -m pytest
|
|
```
|