Commit graph

319 commits

Author SHA1 Message Date
Alex Garcia
90b727db73
Add OpenTelemetry metrics for SQL thread pool saturation and query latency
Spans describe requests that have finished. They structurally cannot answer
"am I saturating my 3 SQL threads right now", because that is a level rather
than an event - and with num_sql_threads defaulting to 3, it is usually the
first thing worth knowing about a busy Datasette. This adds the metrics that
answer it.

Five observable gauges, computed only when something is collecting, so an
instance with no MeterProvider installed does no work for them at all:

  datasette.sql.threads.limit         num_sql_threads
  datasette.sql.threads.queue_depth   queries waiting for a free thread
  datasette.sql.queries.pending       in-flight reads, by db.namespace
  datasette.write.queue_depth         writes behind the single write thread
  datasette.connections.open          tracked file connections

Three instruments recorded inline, which matters because metrics survive
trace sampling and spans do not - an operator sampling 1% of traces still
gets 100% of the latency distribution:

  db.client.operation.duration        semconv histogram, with error.type
  datasette.write.queue_wait          the metric twin of the existing span
  datasette.sql.queries.interrupted   sql_time_limit_ms kills

The interrupted counter closes a gap the plan called out as unanswerable:
"how often are we killing queries at the limit" is a rate, and a rate cannot
be recovered from sampled spans.

Core still creates no provider of any kind, so the architecture is unchanged;
`grep -rn 'opentelemetry.sdk' datasette/` stays empty. One real difference
from tracing is worth recording: _ProxyMeter and its instruments forward to a
provider installed after they were created, whereas ProxyTracer permanently
caches the first concrete tracer it resolves. Module-level instruments are
therefore safe and the test fixture has no ordering constraint.

Live instances are tracked in a lock-guarded WeakSet so instrumenting an
instance never keeps it alive. The pool gauges carry no attribute saying
which Datasette produced them: production runs one instance per process, and
adding an id to disambiguate the test suite's hundreds of instances would buy
unbounded attribute cardinality to fix a case that does not occur. The
collision is documented instead, and the gauge callbacks are plain generator
functions so tests can assert exact values by calling them directly rather
than through the SDK's last-value aggregation.

demos/otel/metrics_demo.py fires 12 concurrent 40ms queries at a 3-thread
pool and samples the gauges mid-flight: queue_depth peaks at exactly 9, and
the duration histogram reads max=0.1695s for a query whose work is 40ms. That
gap is the queue, and it is the thing traces alone will not show you.

Also corrects the demo README's privacy section, which still claimed
parameter values are never recorded - that stopped being unconditionally true
when trace_sql_parameters landed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

(cherry picked from 6ef0dd8c and adapted to the rebuilt phase-1 stack:
attribute names now come from telemetry_registry where entries exist, the
meter carries the instrumentation-scope version and schema URL, and the
interrupted-queries counter skips expected timeouts - callers that opted
into a deliberately short budget, like facet suggestion - matching how
those are excluded from span error status. The internals.rst reference
lands with the registry commit that follows.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F2h9ANGZ7paWSpqs5DUAcG
2026-09-24 09:14:06 -07:00
Alex Garcia
9bce2eec7c
Emit an OpenTelemetry span for each HTTP request
PR #2863
2026-09-24 09:14:03 -07:00
Alex Garcia
daf1989ebe
OpenTelemetry tracing for the database layer (#2862)
PR #2862
2026-09-24 09:11:08 -07:00
Simon Willison
1dbbacedda Add intro sentence to 1.0a40 release notes 2026-09-16 16:55:01 -07:00
Simon Willison
2eb2571fee Release 1.0a40
Refs #1681, #1695, #1861, #2005, #2129, #2639, #2876, #2902, #2903, #2914, #2924, #2925, GHSA-h547-rmjf-5m2m
2026-09-16 16:46:51 -07:00
Simon Willison
caf238aac8 Fix for GHSA-h547-rmjf-5m2m 2026-09-16 16:43:34 -07:00
Simon Willison
d2098e9f84
Fix facet selection for explicit exact filters
`colname__exact=value` is now treated the same as `colname=value` when determining which facets are selected.

Closes #1695
2026-09-16 14:56:09 -07:00
Simon Willison
0d0bb5dd8c
Merge branch 'main' into codex/test-write-wrapper-alter-rollback 2026-09-16 14:42:20 -07:00
Simon Willison
6c119323d0 Keep alter-table changes rollbackable by write wrappers 2026-09-16 14:40:50 -07:00
Simon Willison
6dd5297b34
Allow extra_template_vars to resolve to None
Closes #2005
2026-09-16 10:30:11 -07:00
Simon Willison
df4c0fde0f
Make request header lookups case-insensitive
Closes #1861
2026-09-16 10:27:35 -07:00
Simon Willison
faff4c8820 Return CSV errors as plain text, closes #2129 2026-09-15 15:53:10 -07:00
Simon Willison
27b7240f30 Fix for render_cell() pks for SQL views, refs #2639 2026-09-15 15:30:51 -07:00
Simon Willison
7c8ed1015e Changelog for #1681, #2876 2026-09-15 13:35:51 -07:00
Simon Willison
f40d838429 Changelog entry for #2902 and #2903 2026-09-15 12:58:41 -07:00
Simon Willison
5827feff74 Fix old broken link in Changelog
Refs #2912
2026-09-15 12:20:47 -07:00
Aurora
d60d88488f
docs: fix dead Starlette, Uvicorn and Docker Hub links (#2912)
www.starlette.io and www.uvicorn.org no longer resolve (NXDOMAIN); both
projects now publish their documentation at starlette.dev and uvicorn.dev
respectively. The Docker Hub link was missing the /r/ path segment, which
returns a 404.

- docs/plugin_hooks.rst: www.starlette.io/middleware/ -> starlette.dev/middleware/
- docs/changelog.rst (x3): www.uvicorn.org/ -> uvicorn.dev/
- docs/changelog.rst: hub.docker.com/datasetteproject/... -> hub.docker.com/r/datasetteproject/...

All four replacement URLs verified to return HTTP 200.
2026-09-15 11:57:39 -07:00
Alex Garcia
374b194ff5
Add /-/tasks introspection endpoint for supervised background tasks (#2892)
Co-authored-by: Simon Willison <swillison@gmail.com>
2026-09-15 11:56:53 -07:00
Simon Willison
1538832830 /db/table/-/count? endpoint, fixed 'count all' button
Closes #2914
2026-09-15 10:03:17 -07:00
Simon Willison
b338c6f5f6
Migrate from httpx to httpx2, closes #2879
https://claude.ai/code/session_01Xdqoneq8ddvruVZETo6rFf
2026-09-10 19:44:49 -07:00
Simon Willison
5e7cdaabbd Release 1.0a39 2026-09-10 16:52:52 -07:00
Simon Willison
12b25affb5 Release 1.0a38
Refs #2868
2026-08-06 11:20:25 -07:00
Simon Willison
481df7ff6d Shorten link text in changelog 2026-07-14 09:31:28 -07:00
Simon Willison
2ffd8a860e Release 1.0a37
Refs #2831, #2832, #2841, #2842, #2843, #2846
2026-07-14 09:28:29 -07:00
Simon Willison
52ae7d1b6d Release 1.0a36
Refs
#1983, #1996, #2783, #2806, #2809, #2811, #2812, #2813, #2815, #2818, #2819, #2822, #2823, #2827
2026-07-07 14:32:25 -07:00
Simon Willison
a31673c90b Changelog for #2811, #2815, #2783 2026-07-07 14:26:48 -07:00
Simon Willison
617acedd38 Remove readthedocs/actions/preview
Closes #2828
2026-07-07 14:18:10 -07:00
Claude
b7bbde04be
Link the consistency review release note to PR #2824
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
2026-07-07 05:18:54 +00:00
Claude
57ce1a059f
Tighten unstable marker release note
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
2026-07-07 01:13:33 +00:00
Claude
b83b12dd7a
Remove params input alias from the query create and update APIs
The alias existed so API payloads could mirror the params key used by
queries defined in datasette.yaml, but it was undocumented and untested,
and the create endpoint is not part of the stable API. The API now only
accepts parameters - sending params is a 400 Invalid keys error. The
documented params key for queries in configuration is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
2026-07-07 01:13:33 +00:00
Claude
b23fc4ec48
Unreleased release notes for the JSON API consistency review
Documents the canonical error format, the ok/envelope changes, the
array-to-object endpoint conversions, 401s for invalid tokens, the
pagination and page-size unification, removed legacy keys and formats,
and the new Response.error(), TokenInvalid, count_truncated and
unstable-marker APIs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
2026-07-07 00:32:29 +00:00
Simon Willison
58c07cc264 max_post_body_bytes setting, enforced for reuest.post_body()
Closes #2823
2026-07-03 17:42:39 -07:00
Simon Willison
7ab8b644a7 Merge remote-tracking branch 'origin/main' into edit-blobs
# Conflicts:
#	docs/changelog.rst
#	tests/test_playwright.py
2026-07-03 17:25:41 -07:00
Simon Willison
19dde1c860 Support BLOB values in row edit UI 2026-07-03 16:09:27 -07:00
Simon Willison
8856914be8 Add column_details JSON extra 2026-07-03 14:45:38 -07:00
Simon Willison
b1d990ceba Wording tweak 2026-07-03 12:37:07 -07:00
Simon Willison
3d67168ee5 Docs and unreleased release notes for bulk insert/create table from data 2026-07-03 12:35:59 -07:00
Simon Willison
488c9cf3d3 Small tweaks to 1.0a35 release notes prior to release 2026-06-23 14:33:20 -07:00
Simon Willison
753fa3b316 Release 1.0a35
Refs #1477, #1510, #1975, #2002, #2127, #2787, #2788, #2794, #2796, #2798, #2803
2026-06-23 14:30:08 -07:00
Simon Willison
85be50ac71 Changelog entry for #1975
Plus fixed broken rst link
2026-06-23 14:22:14 -07:00
Simon Willison
a913ba372a Changelog note for #2002
Refs #2792
2026-06-23 14:09:31 -07:00
Simon Willison
5eca46a4bc
Add cache-busted static asset helper (#2804)
* Add cache-busted static asset helper

Add a static() helper for Datasette, plugin, and mounted static assets that appends content-based hashes, caches hashes in production, and serves matching hashed asset URLs with immutable far-future cache headers.

Closes #2800
2026-06-23 13:44:58 -07:00
Simon Willison
a4f74d1d2b More unreleased changes in changelog 2026-06-23 12:50:23 -07:00
Simon Willison
b3b5c25df8 Draft changelog for create/alter table UI, refs #2787, #2788 2026-06-22 13:51:32 -07:00
Simon Willison
1ae55007f2 Release 1.0a34
Refs #2767, #2775, #2776, #2779, #2780, #2782
2026-06-16 14:27:26 -07:00
Simon Willison
dc6f207d37 Update unreleased release notes section
Refs #2780 and many more.
2026-06-14 20:29:59 -07:00
Simon Willison
1d4212122e Add release date for 1.0a33 2026-06-11 10:36:16 -07:00
Simon Willison
993169ae49 Release 1.0a33
Refs #2735, #2677, #2680, #2711, #2756, #2761, #2768, #2754
2026-06-11 08:24:37 -07:00
Simon Willison
bbf0424c45 Changelog for row/query extras and related fixes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 22:51:25 -07:00
Simon Willison
6eaa9e3199
Web UI to edit and delete stored queries (#2764)
* Add web UI to edit and delete stored queries

Stored query pages now offer Edit and Delete actions in the query
actions menu, gated by the update-query and delete-query permissions.

- New QueryEditView (GET/POST at /<db>/<query>/-/edit) renders a
  pre-filled form for editing a query's title, description, SQL and
  privacy, reusing the create-query analysis UI. Changing the SQL still
  requires execute-sql; metadata-only edits do not.
- QueryDeleteView gains a GET confirmation page and HTML form POST that
  redirects to the query list, while keeping the existing JSON API.
- New default query_actions hook adds the Edit/Delete links for stored
  (non-config, non-trusted) queries the actor is allowed to manage.

Permission semantics (already enforced by default_query_permissions_sql)
are surfaced in the UI: owners can always edit/delete their queries;
non-private queries can be edited/deleted by any actor with the relevant
permission; private queries remain owner-only.

Shared the create-query form styles into _query_form_styles.html so the
edit form can reuse them.

Animated demo: https://github.com/simonw/datasette/pull/2764#issuecomment-4655694668

Closes #2760

https://claude.ai/code/session_019GU9g3pZAERukLKYNa4uAL
2026-06-08 20:19:47 -07:00