Framework-agnostic Python package for shareable resource access control
Project description
Linkified
Framework-agnostic Python package for shareable resource access control.
Linkified provides a complete system for creating, managing, validating, and revoking shareable links for application resources — with pluggable storage backends and first-class integrations for FastAPI, Django, and Flask.
from linkified import LinkifiedManager, MemoryBackend
share = LinkifiedManager(backend=MemoryBackend())
token, link = share.create("document:123", permissions=["read"])
# → token is a URL-safe string to embed in a share URL
# → link.id is the stable identifier for lifecycle management
access = share.validate(token)
# → ShareAccess(resource="document:123", permissions=["read"], ...)
share.revoke(link.id)
Installation
pip install linkified
With optional extras:
pip install "linkified[fastapi]"
pip install "linkified[django]"
pip install "linkified[flask]"
pip install "linkified[redis]"
pip install "linkified[sqlalchemy]"
pip install "linkified[all]"
Quickstart
FastAPI
from fastapi import FastAPI, Depends
from linkified import LinkifiedManager
from linkified.backends import MemoryBackend
from linkified.frameworks.fastapi import require_share
app = FastAPI()
share = LinkifiedManager(backend=MemoryBackend())
app.state.linkified = share
@app.get("/documents/{id}")
async def view_document(id: int, access=Depends(require_share("read", manager=share))):
return {"resource": access.resource}
Django
# settings.py
from linkified import LinkifiedManager
from linkified.backends import SQLAlchemyBackend
LINKIFIED_MANAGER = LinkifiedManager(backend=SQLAlchemyBackend(url="postgresql+psycopg://..."))
# views.py
from linkified.frameworks.django import share_only
@share_only("read")
def view_document(request, doc_id, share_access=None):
return JsonResponse({"resource": share_access.resource})
Flask
from flask import Flask, g, jsonify
from linkified import LinkifiedManager
from linkified.backends import MemoryBackend
from linkified.frameworks.flask import Linkified, share_only
app = Flask(__name__)
ext = Linkified(manager=LinkifiedManager(backend=MemoryBackend()))
ext.init_app(app)
@app.get("/documents/<int:doc_id>")
@share_only("read")
def view_document(doc_id):
return jsonify({"resource": g.share_access.resource})
Storage Backends
| Backend | Use case |
|---|---|
MemoryBackend |
Testing / development |
SQLAlchemyBackend |
Persistent storage, auditing |
RedisBackend |
High-performance, TTL expiry |
HybridBackend |
PostgreSQL + Redis (recommended for production) |
JWTBackend |
Stateless, no storage required (no revocation) |
from linkified.backends import SQLAlchemyBackend, HybridBackend
from linkified.backends.redis import RedisBackend
# Recommended production setup
share = LinkifiedManager(
backend=HybridBackend(
storage=SQLAlchemyBackend(url="postgresql+psycopg://..."),
cache=RedisBackend(url="redis://localhost:6379/0"),
)
)
Core API
# Create
token, link = share.create(
resource="document:123", # string or registered model instance
permissions=["read"],
actor=user, # optional; enforces policy
expires_in=timedelta(days=7),
single_use=True,
password="s3cret",
access_mode="authenticated",
allowed_users=["user_a", "user_b"],
)
# Validate
access = share.validate(token, actor="user_a", password="s3cret")
# Lifecycle
link = share.get(link_id)
links = share.list(resource="document:123")
share.update(link_id, permissions=["read", "write"])
share.revoke(link_id)
share.restore(link_id)
share.extend(link_id, expires_in=timedelta(days=30))
share.delete(link_id)
# Audit + stats
share.access_log(link_id)
share.stats()
share.list_expiring(days=7)
share.list_by_permission("write")
Resource Registration
from linkified import shareable_resource
from linkified.policies import OwnerPolicy
@shareable_resource(
resource_type="document",
owner_field="owner",
policy=OwnerPolicy,
allow_anonymous=True,
)
class Document:
...
Authorization Decorators
| Decorator | Behavior |
|---|---|
@share_only("read") |
Share link is the only access mechanism |
@share_or_permission("docs.view") |
Share link OR app permission |
@share_and_permission("docs.view") |
Both share link AND app permission required |
License
MIT
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 linkified-0.1.0.tar.gz.
File metadata
- Download URL: linkified-0.1.0.tar.gz
- Upload date:
- Size: 107.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70b66cbe62ced0b0a69488295f724e390311bf6cb3e73e963dbc71b5728a7c66
|
|
| MD5 |
19a6ecc46bfb8c0c78c044a8d3effd60
|
|
| BLAKE2b-256 |
c8e6bc31e661c882195d2611b9e05d34297eaf20fe44960728858281e0a850ed
|
File details
Details for the file linkified-0.1.0-py3-none-any.whl.
File metadata
- Download URL: linkified-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2137c966c2c8202d256c774786c041998d640ba8cf479d360bbde039c879686
|
|
| MD5 |
57f85fc9956403e7db4e6391ccf1c0b5
|
|
| BLAKE2b-256 |
b4789697d7cb5126d4a8589335ca964df2231a6faebf7ecdc4af7d43bb7b1615
|