caplinks
Capability links: hand someone a link to one thing, with no account. The token is the permission; a password may gate it; it expires; it can be revoked; password attempts are limited. Standard library only, no web framework.
pip install caplinks
from caplinks import CapabilityLinks
links = CapabilityLinks() # records in a dict; pass any MutableMapping to persist them
rec = links.create({"doc": "report-1"}, password="open sesame", expires="7d")
url = f"https://example.com/s/{rec['token']}/"
state, stored = links.status(rec["token"]) # "ok", "expired" or "missing"
links.check_password(stored, "open sesame") # True
cookie = links.unlock_value(stored) # what a correct password earns
links.unlocked(stored, cookie, max_age_s=3600) # True, until the password changes or the link is revoked
links.revoke(rec["token"]) # now "missing"
What is in it
CapabilityLinks: create, read, list and revoke links, and gate them on a password. Records are plain dicts in anyMutableMappingkeyed by token: the generic fields aretoken,created,expires,password(a hash) andrevoked; your own fields (what the link reaches) sit beside them.ScryptHasher(stdlib scrypt) behind thePasswordHasherprotocol (hash,verify -> bool): passhasher=for argon2 or anything else.parse_expiresreads what people write (30m,12h,7d,2w,2026-11-01meaning the end of that day UTC, an ISO timestamp,never) and refuses the past;is_expiredfails closed.SlidingWindowLimiterbehind theRateLimiterprotocol (allow(key) -> bool): count password attempts per client, per link, or both. It is per process; a shared limiter of the same shape (Redis, say) fits where several workers serve the links.
The unlock value is an HMAC keyed by the stored password hash, so changing the password or revoking the link (which clears the hash) ends every open session at once.
What stays with your app
What a link reaches (its scope), how it is served (routes, cookie name, headers), and the attempt policy. annals (share links) is the first host.
Seams
| keyword | default | for |
|---|---|---|
store |
dict |
persistence: a dol store, a file-backed mapping, S3 |
hasher |
ScryptHasher() |
argon2id or another scheme |
clock |
now_utc |
tests that pin the time |
min_password_len |
8 | a stricter or laxer gate |
A store that cannot vouch for a record raises KeyError, ValueError or OSError when it is read, and the link is then missing; so is a record whose generic fields have the wrong types. Every failure closes the link.
Metadata
Release files for caplinks 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| caplinks-0.0.2.tar.gz | 13.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| caplinks-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.1 kB
Release files / caplinks-0.0.2.tar.gz
| Download URL | caplinks-0.0.2.tar.gz |
|---|---|
| Size | 13.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
be06c3615b2ef88f18af10aea1304f5ad58654f33aea834672488de323c5c408
|
|
BLAKE2b-256 checksum How to use checksums |
38e4a032bbc0ca36d54c9368a7b13b20f4eeec88f2a13d376b96ff8c948d50fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","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}
|
Release files / caplinks-0.0.2-py3-none-any.whl
| Download URL | caplinks-0.0.2-py3-none-any.whl |
|---|---|
| Size | 12.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0a687053a945f0336a1fa2c67f5a9d842c8439b91be1884a7f4538925b4db9a4
|
|
BLAKE2b-256 checksum How to use checksums |
889cd75501eee16194ab02310e1d82079df5ada31a55c641c8b55b84812dae86
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","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}
|
Security for caplinks 0.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.