Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

datasette-paper

PyPI Changelog Tests License

Collaborative document editor for Datasette. ProseMirror frontend, SQLite-backed storage in Datasette's internal database, real-time collaboration over SSE.

The paper editor: a rich-text document with headings, a table and a task list, a formatting toolbar, and a header showing the author, edit time and number of users online.

Rich text with tables and task lists, wiki-style links between papers, images (paste, drag-and-drop, or insert from the toolbar), and per-paper sharing:

A table in the editor with the floating action bar for adding/removing rows and columns and naming the table for the API. A task list with checkboxes; completed items are struck through.
Typing [[ opens an autocomplete popup listing other papers to link to. The share dialog showing people with access and their roles, plus general link access.
Hovering a link while editing reveals a tooltip with Edit, Open and Copy; Edit opens a small dialog with Text and URL fields to rewrite the link.

Insert an image by pasting, dropping a file, or using the toolbar's image button — which offers a paste area or a file upload with a live preview:

The insert-image dialog with the Upload tab active, showing a preview of the chosen image, an alt-text field, and an enabled Insert button.

And a paper index listing everyone's papers with author and last-edited time:

The paper index: a table of papers with name, creator and updated time, plus tabs for Active / Archive / Trash / Templates.

Drop inline #tags anywhere in a paper's body — type # for an autocomplete of existing tags. Clicking a tag opens a results page listing every paper whose body mentions it:

Inline #tag pills in a paper's body, distinct from the document-level metadata tags. The tag results page: every paper whose body contains #roadmap, each with a mention count.

Installation

Install in the same environment as Datasette:

datasette install datasette-paper

Quickstart

datasette --internal papers.db \
  -s permissions.datasette-paper-list true \
  -s permissions.datasette-paper-create true \
  -s permissions.datasette-paper-view true \
  -s permissions.datasette-paper-edit true

No user database is required — papers live in Datasette's internal database.

Pass --internal <path> to persist papers across restarts. Without it, Datasette uses an ephemeral tempfile for the internal DB that is deleted when the process exits. The plugin emits a startup warning when it detects this, so you don't lose your papers to a forgotten flag.

Permissions

Four actions gate access. The view/edit actions are per-paper; list/create are global.

Action Scope Gates
datasette-paper-list global The paper index page and the list endpoint.
datasette-paper-create global (also-requires list) Creating new papers.
datasette-paper-view per-paper (PaperResource) Reading a specific paper (bootstrap, SSE, document, tasks).
datasette-paper-edit per-paper (PaperResource, also-requires view) Modifying a specific paper (events, presence, rename, snapshot, share).

The plugin registers a permission_resources_sql hook that resolves per-paper view/edit grants from the _datasette_paper_doc.created_by column (owners) and the _datasette_paper_share table (explicit grants

  • link-visibility levels).

Sharing

Each paper has one of three visibility levels:

  • private — only the owner and explicitly-shared actors can access.
  • link-view — any authenticated actor with the link can view.
  • link-edit — any authenticated actor with the link can view and edit.

Plus per-actor share rows that grant a specific actor a viewer or editor role on a single paper.

The owner is whoever created the paper (created_by, captured from the actor cookie at create time). Only the owner can change visibility or mutate shares.

Papers as data

Paper data lives in Datasette's internal database under tables prefixed with _datasette_paper_:

  • _datasette_paper_doc — one row per paper (id, name, visibility, created_by).
  • _datasette_paper_step — append-only log of ProseMirror steps.
  • _datasette_paper_snapshot — periodic full-document snapshots.
  • _datasette_paper_share — per-actor view/edit grants.

Wire protocol

JSON API rooted at /-/paper/api/... — no per-database segment. List/create docs, bootstrap a paper, post step batches, stream updates over SSE, manage shares, render markdown / extract tasks. See CLAUDE.md for the full endpoint table.

Frontend stack

Vite + Svelte 5 + ProseMirror. Bundle outputs to datasette_paper/static/.

Development

npm install --prefix frontend
just frontend          # build the bundle
just dev               # run datasette with the plugin + permissions granted
just dev-with-hmr      # vite dev server + watchexec restart
just shots             # regenerate docs/screenshots/*.png (used in this README)

just shots is self-contained: it builds the bundle, boots a throwaway Datasette with seeded papers, drives Playwright to capture each surface, and tears the server down. The PNGs are committed, so re-run and commit when the UI changes (the diff shows what changed). Pass shot names to regenerate a subset, e.g. just shots editor tables.

Run the test layers:

just test              # backend pytest
just test-frontend     # vitest
just test-e2e          # playwright (requires built bundle)

Always invoke Python with uv run --prerelease=allow …datasette is on a >=1a23 pre-release pin.

Download files

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

Source Distribution

datasette_paper-0.0.2a9.tar.gz (657.7 kB view details)

Uploaded Source

Built Distribution

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

datasette_paper-0.0.2a9-py3-none-any.whl (585.4 kB view details)

Uploaded Python 3

File details

Details for the file datasette_paper-0.0.2a9.tar.gz.

File metadata

  • Download URL: datasette_paper-0.0.2a9.tar.gz
  • Upload date:
  • Size: 657.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","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}

File hashes

Hashes for datasette_paper-0.0.2a9.tar.gz
Algorithm Hash digest
SHA256 8f0c4c647de60e0075b6ddb3e61e1976bf0be926c71653b1bfdc8358fc78fa28
MD5 7323bf5bb84b45e919b58f3241a6102d
BLAKE2b-256 37ab308db93dbc7fc68a926d80698140963e6efb54fc7a381c89007fc9770289

See more details on using hashes here.

File details

Details for the file datasette_paper-0.0.2a9-py3-none-any.whl.

File metadata

  • Download URL: datasette_paper-0.0.2a9-py3-none-any.whl
  • Upload date:
  • Size: 585.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","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}

File hashes

Hashes for datasette_paper-0.0.2a9-py3-none-any.whl
Algorithm Hash digest
SHA256 d2378f0ab4858e227912cf0c4c23d9daa163c96d490c4cb3d77f54d06491420e
MD5 8583b6ebca08e444d81d578d58f8d9b2
BLAKE2b-256 e38949aa23d5d894095481e7f3e40e1a38b289ac4e76db11742c6e5b42178ad9

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 Sentry Error logging StatusPage Status page