Skip to content

Implement datasette-files core features#7

Merged
simonw merged 12 commits intomainfrom
claude/datasette-file-plugin-design-jUQhp
Feb 19, 2026
Merged

Implement datasette-files core features#7
simonw merged 12 commits intomainfrom
claude/datasette-file-plugin-design-jUQhp

Conversation

@simonw
Copy link
Contributor

@simonw simonw commented Feb 16, 2026

Covers: terminology, data model, Storage ABC interface, filesystem storage,
permission model, upload flow, file serving, render_cell integration,
runtime column configuration, and API design.

https://claude.ai/code/session_016xxhVYZgWByonNJju2Zmuh

claude and others added 12 commits February 16, 2026 03:53
Covers: terminology, data model, Storage ABC interface, filesystem storage,
permission model, upload flow, file serving, render_cell integration,
runtime column configuration, and API design.

https://claude.ai/code/session_016xxhVYZgWByonNJju2Zmuh
- base.py: Storage ABC, FileMetadata, UploadInstructions, StorageCapabilities
- hookspecs.py: register_files_storage_types hook for plugin registration
- filesystem.py: Built-in FilesystemStorage with upload, read, list, delete
- __init__.py: Startup (schema + source instantiation), upload/serve/download
  routes, sources API, file info page, CSRF skip for uploads
- templates/file_info.html: HTML page showing file metadata
- pyproject.toml: Remove boto3, update to datasette>=1.0a24
- 16 passing tests covering base classes, filesystem storage, upload flow,
  file info/download/metadata endpoints, and sources API

https://claude.ai/code/session_016xxhVYZgWByonNJju2Zmuh
Demonstrates the complete datasette-files filesystem workflow:
sources API, file upload via curl, metadata retrieval, download,
HTML file info pages (with image preview), error handling, and
on-disk storage layout.

https://claude.ai/code/session_016xxhVYZgWByonNJju2Zmuh
- render_cell hook detects df-* file IDs in any table cell and emits
  <datasette-file> custom element with a fallback <a> link for no-JS
- Batch JSON endpoint (/-/files/batch.json?id=...) fetches metadata
  for all file IDs on a page in a single SQL query
- <datasette-file> web component collects all instances on page load,
  batch-fetches via single HTTP request, then hydrates each cell with
  filename links (non-images) or inline thumbnail previews (images)
- extra_js_urls hook injects the JS module on table/row/database views

https://claude.ai/code/session_016xxhVYZgWByonNJju2Zmuh
Showboat demo walking through the batch.json endpoint, render_cell hook,
web component hydration, and browser rendering with inline thumbnails.

https://claude.ai/code/session_016xxhVYZgWByonNJju2Zmuh
…search

- Define FileSourceResource as a top-level Resource for Datasette's SQL
  permissions system, with register_actions for files-browse, files-upload,
  and files-delete (all default deny)

- Add FTS5 virtual table (datasette_files_fts) with triggers to keep the
  index in sync on insert/update/delete, plus backfill at startup

- Implement permission_resources_sql hook to process files-browse config
  from datasette.yaml permissions block (global and per-source)

- Add /-/files/search endpoint (HTML + JSON) that uses
  allowed_resources_sql() to get browsable sources, then filters FTS and
  listing queries to only those sources

- Enforce files-browse permission on file_info, file_json, file_download,
  and batch_json endpoints

- 35 tests covering FTS indexing, search with/without query, source
  filtering, default deny, multi-source permission isolation, and
  actor-specific access control

https://claude.ai/code/session_016xxhVYZgWByonNJju2Zmuh
Showboat demo document showing:
- Per-source permission config (public-docs: everyone, team-docs: alice only)
- Anonymous vs authenticated search results (4 vs 6 files)
- FTS5 search by filename
- Permission enforcement on individual file pages (403 vs 200)
- Browser screenshots of the search UI for both actors

https://claude.ai/code/session_016xxhVYZgWByonNJju2Zmuh
- Add `search_text` TEXT column to datasette_files table, included in the
  FTS5 index so users can attach searchable descriptions to files

- Register `files-edit` action (abbr: fe) scoped to FileSourceResource,
  default deny like all other file actions

- File info page (/-/files/{id}) now handles POST to update search_text,
  gated by files-edit permission. Shows textarea form for actors with
  edit permission, read-only text or "No search text set" for others

- Startup migrates existing databases: adds search_text column if missing,
  drops and recreates FTS table + triggers to match new schema, backfills
  FTS index

- 43 tests: 8 new tests covering search_text column existence, FTS
  indexing of search_text, files-edit action registration, POST with/without
  permission, form visibility, and non-editor denial

https://claude.ai/code/session_016xxhVYZgWByonNJju2Zmuh
python-ulid imports typing_extensions but doesn't declare it as a
dependency. On Python 3.13 it isn't pulled in transitively, causing
an ImportError.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@simonw simonw changed the title Add comprehensive plugin system design document Implement datasette-files core features Feb 19, 2026
@simonw simonw merged commit d4b73c8 into main Feb 19, 2026
10 checks passed
simonw added a commit that referenced this pull request Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants