Skip to main content

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


Download files

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

Source Distribution

linkified-0.1.0.tar.gz (107.5 kB view details)

Uploaded Source

Built Distribution

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

linkified-0.1.0-py3-none-any.whl (26.4 kB view details)

Uploaded Python 3

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

Hashes for linkified-0.1.0.tar.gz
Algorithm Hash digest
SHA256 70b66cbe62ced0b0a69488295f724e390311bf6cb3e73e963dbc71b5728a7c66
MD5 19a6ecc46bfb8c0c78c044a8d3effd60
BLAKE2b-256 c8e6bc31e661c882195d2611b9e05d34297eaf20fe44960728858281e0a850ed

See more details on using hashes here.

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

Hashes for linkified-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d2137c966c2c8202d256c774786c041998d640ba8cf479d360bbde039c879686
MD5 57f85fc9956403e7db4e6391ccf1c0b5
BLAKE2b-256 b4789697d7cb5126d4a8589335ca964df2231a6faebf7ecdc4af7d43bb7b1615

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