EVEMISSTechnology

Repository guide · overview · v2

simonw / datasette

“An open source multi-tool for exploring and publishing data” — as described by its authors

  • Data and Databases
  • Python
  • Apache-2.0 · open-source license
Original repository
simonw/datasette
Source platform
GitHub
Repository owner / organization
simonw
License
Apache-2.0 · open-source license
Analyzed revision
b338c6f5f6b39dd3e0a341431f071d8cecb0d12b
Last verified

Newer revision observed; parts of this guide may be outdated. The default branch moved to cec5e6b2ef5d, checked 2026-10-03. The whole guide describes revision b338c6f5f6b3. A revision diff found changes in 4 code regions it cites (listed below); statements about those regions may not hold at the new revision and have not been rechecked yet.

  • datasette/app.py:394-3037 · lines changed
  • datasette/app.py:3040-3314 · lines changed
  • datasette/app.py:168 · call site on the execution path changed
  • datasette/utils/asgi.py:86-284 · lines changed

simonw/datasette repository overview: Python data exploration tool

Terms used on this page
Entrypoint record
A file the analyzer marks as a place where execution can start. When it carries a __main__ guard excerpt, the file contains an if __name__ == "__main__": block and the excerpt shows what that block calls; without an excerpt, the file was flagged by its name only.
Bounded static execution path
A call chain reconstructed from the source code without running it, stopped after a fixed number of steps. It shows how far the code can be followed on paper, not what happens at run time.
Unresolved boundary
Where a static path stops because the next call goes into an external library or cannot be resolved without running the code. It marks the edge of this analysis, not a defect in the repository.
Static relations
Calls and imports found in the source. "External or unresolved" relations point outside the analyzed files.
Module role
The analyzer's label for a file, inferred from how many calls go in and out (for example core, entry/orchestration, leaf). It describes a position in the call graph, not the authors' design.
Test-like files
Files whose names or locations look like tests. This analysis counts them; it does not run them.
Observed · inferred · author-claimed · unresolved
How each statement is supported: read directly from the analyzed files; derived by the analyzer from them; stated by the repository's authors (metadata, README); or not established by this analysis.
Verified
Two uses on these pages. In an analyzer record ("verified provenance", "a verified entrypoint") it means the record was read directly from the analyzed files, which these guides call observed; for an entrypoint, the __main__ guard text is present. Since the analyzer fix of 2026-10-04, a file that only has an entrypoint-like name such as cli.py or main.py is recorded as inferred; guides analyzed before that still call such a file verified, and it is still only a guess about how the file is used. It does not mean the code was run or tested. "Last verified" is the date the guide last passed the lab's checks against the analysis record of the stated revision; it is not a review of the repository itself.

Datasette is an open-source Python tool for exploring and publishing data (per GitHub metadata), licensed Apache-2.0. Its __main__ guard calls the CLI in datasette/cli.py; datasette/app.py hosts the Datasette and DatasetteRouter classes. Code splits into the datasette package plus tests and docs trees. Analysis is static-only: 15,850 of 21,338 relations remain unresolved.

What this repository is

GitHub metadata describes the project as "An open source multi-tool for exploring and publishing data", and gives datasette.io as its homepage. The primary language is Python; the byte breakdown lists about 2.47 million Python bytes alongside JavaScript, HTML, CSS, Shell, C, Dockerfile and Just files. Repository topics include asgi, automatic-api, csv, datasets, datasette, docker, json, python, sql and sqlite. The license is Apache-2.0, and a LICENSE file sits at the repository root. Structurally, the analyzed snapshot has 333 files: a datasette package (135 files) plus tests (102), docs (50), demos (7) and a few other top-level directories. The latest listed release is 1.0a39 (published 2026-09-11), and the repository had 11,460 stars on 2026-09-14.

How the program starts

The only launch code shown in datasette/__main__.py is a main guard that calls cli():

if __name__ == "__main__":
    cli()

A bounded static execution path records that __main__ hands off to cli in datasette/cli.py and stops there as a leaf. datasette/app.py and datasette/cli.py are both flagged as likely executable entrypoints (filename heuristic). app.py is labeled an entry/orchestration candidate with 356 incoming and 197 outgoing static calls. It contains the two large classes Datasette (lines 394-3037) and DatasetteRouter (lines 3040-3314). Note the limits: every traced execution path starting at app.py ends at an unresolved external boundary such as logging.getLogger, contextvars.ContextVar, collections.namedtuple or Setting, so deeper runtime wiring is not established.

Repository structure and most-connected modules

  • Top-level layout separates the application package datasette from the docs and tests subsystems.
  • datasette/utils/__init__.py is the most connected Python module (519 incoming / 53 outgoing calls) and defines CustomJSONEncoder and sqlite_timelimit.
  • datasette/utils/asgi.py is next (369 incoming) and defines Request, AsgiLifespan, AsgiStream and AsgiWriter, plus exception classes like NotFound and Forbidden.
  • datasette/views/table.py has the highest outgoing degree among the listed Python modules (283 out / 46 in), which suggests it coordinates many modules; it defines TableContext and Row.
  • datasette/__init__.py (348 in / 0 out) and datasette/resources.py (227 in / 0 out) look like leaf/data-boundary modules; resources.py defines DatabaseResource, TableResource and QueryResource.
  • Front-end assets live under datasette/static; the analyzer reports the highest overall degree for edit-tools.js (808/808) and table.js (83/83), but JavaScript analysis is only a bounded heuristic.

Dependencies and tests

Manifest evidence in this packet covers JavaScript tooling only. package.json, one of two detected build/dependency manifests, lists runtime dependencies @codemirror/lang-sql ^6.3.3, codemirror ^6.0.1, rollup ^3.30.0, @rollup/plugin-node-resolve ^15.0.1 and @rollup/plugin-terser ^0.1.0, plus prettier ^3.0.0 as a dev dependency. Dependency parsing has a hard limit here: only requirements-style manifests were parsed, and pyproject.toml dependency tables were not, so the Python package's own dependencies are not established by this analysis. The tests subsystem contains 102 test files. Sampled file tests/test_api_write.py defines helpers ds_write and write_token and tests such as test_structured_writes_require_ordinary_tables and test_base64_write_api_insert_upsert_update_decode_blobs. tests/build_small_spatialite_db.py is a project-important likely entrypoint whose __main__ guard calls generate_it("spatialite.db"), generating a SQLite test database.

A reading order for newcomers

  1. README.md - marked project-level important; the usual first stop.
  2. pyproject.toml and package.json - packaging and tooling manifests, both flagged important.
  3. datasette/__main__.py, then datasette/cli.py - the launch chain; the static path runs from the __main__ guard to cli.
  4. datasette/app.py - central orchestration module, holding the Datasette and DatasetteRouter classes.
  5. datasette/utils/__init__.py and datasette/utils/asgi.py - the highest incoming-call counts among the listed Python modules (519 and 369; edit-tools.js reports 808 incoming overall).
  6. datasette/views/table.py - view logic with the highest outgoing call degree among Python modules (283; edit-tools.js reports 808 outgoing overall), a good window into how requests reach the rest of the code.

When changing code, start tracing at the detected entrypoint datasette/app.py and check downstream effects by hand, because dynamic behaviour is not resolved statically.

What this analysis cannot tell you

  • Static only: reflection, dynamic imports, monkey-patching, generated code, framework runtime wiring and dynamic dispatch are not resolved, so how plugins are discovered and loaded cannot be established from this packet.
  • Install, run and build inference is partial; installation commands are not verified, and the packet contains no runtime or execution results.
  • Of 21,338 static relations, 15,850 are external or unresolved and 5,488 resolve locally.
  • Two files were inventoried but not parsed (oversized, minified or vendored); bounded analysis also skips files over 400 kB, minified bundles and vendored directories.
  • Dependency coverage is partial: pyproject.toml dependency tables were not parsed.
  • README claim extraction is line-based and may capture code lines, so any README-derived statement is author_claimed at best.

Symbols worth knowing

  • Datasette (datasette/app.py, lines 394-3037) and DatasetteRouter (lines 3040-3314): the two large classes in app.py, which the analyzer labels an entry/orchestration candidate.
  • DatabaseResource, TableResource, QueryResource (datasette/resources.py): classes in a module labeled a leaf/data-boundary candidate.
  • Request, AsgiLifespan, AsgiStream, AsgiWriter and the NotFound/Forbidden/BadRequest/PayloadTooLarge exceptions (datasette/utils/asgi.py): classes in the module with the second-highest incoming call count among the listed Python modules (369).
  • CustomJSONEncoder and sqlite_timelimit (datasette/utils/__init__.py) plus TableContext and Row (datasette/views/table.py): symbols in the listed Python modules with the most incoming calls (519) and the most outgoing calls (283).

What this analysis could not establish

The writing model's own notes on the analysis record. Identifiers such as lim_3, exec_* or claim_… name records of that analysis; the claims table cites the same records.

  • Python dependencies are unknown for this snapshot: the analyzer parsed only requirements-style manifests and skipped pyproject.toml dependency tables (lim_3).
  • 15,850 of 21,338 static relations are external or unresolved, so module-interaction statements beyond the cited samples may be incomplete.
  • Plugin discovery and loading behaviour could not be traced; dynamic imports and framework runtime wiring are unresolved (lim_1).
  • Two minified JavaScript bundles under datasette/static were inventoried but not parsed.
  • The analyzer's inferred purpose ('web or Node.js application') sits awkwardly with the Python-primary language statistics; that framing should be treated cautiously.
  • No runtime or execution evidence exists in the packet; startup behaviour beyond the __main__ -> cli edge is inference.
  • important_2 (readme.md) was excluded as a case-variant path of README.md, a filesystem path-matching quirk in the analysis.
Claims and evidence — 39 claims, 39 supported by an independent verifier

Every statement above is a claim that cites grounding IDs from the analysis. IDs are internal to the analysis run; the columns show what each claim rests on and how strong that ground is.

Every substantive statement above is a claim bound to grounding IDs of the analyzed revision. Global grounding IDs are namespaced by the analysis run.

Claim Epistemic status Verifier Grounding (global IDs)
c1 GitHub metadata describes the project as "An open source multi-tool for exploring and publishing data" and gives datasette.io as its homepage. author_claimed supported analysis_ef14c7222eb9f538:meta_description, analysis_ef14c7222eb9f538:meta_homepage
c2 The repository's primary language is Python, and the language-byte breakdown lists about 2.47 million Python bytes alongside JavaScript, HTML, CSS, Shell, C, Dockerfile and Just. observed supported analysis_ef14c7222eb9f538:meta_primary_language, analysis_ef14c7222eb9f538:meta_language_bytes
c3 Repository topics include asgi, automatic-api, csv, datasets, datasette, docker, json, python, sql and sqlite. observed supported analysis_ef14c7222eb9f538:meta_topics
c4 The license is Apache-2.0 per repository metadata, and a LICENSE file exists at the repository root. observed supported analysis_ef14c7222eb9f538:meta_license, analysis_ef14c7222eb9f538:important_5
c5 The analyzed snapshot has 333 files, including a datasette package of 135 files, a tests tree of 102 files, docs with 50 and demos with 7. inferred supported analysis_ef14c7222eb9f538:summary_repository, analysis_ef14c7222eb9f538:subsys_1, analysis_ef14c7222eb9f538:subsys_2, analysis_ef14c7222eb9f538:subsys_3
c6 The latest listed release is 1.0a39, published 2026-09-11; the repository had 11,460 stargazers as of 2026-09-14. observed supported analysis_ef14c7222eb9f538:meta_latest_release, analysis_ef14c7222eb9f538:meta_stars
c7 datasette/__main__.py contains a __main__ execution guard whose body calls cli(); it is classified as project-important and a likely entrypoint. observed supported analysis_ef14c7222eb9f538:py_entry_7cbf1557a33b, analysis_ef14c7222eb9f538:important_6
c8 A bounded static execution path records datasette/__main__.py transferring to cli in datasette/cli.py, terminating as a leaf. inferred supported analysis_ef14c7222eb9f538:exec_707222db7901
c9 datasette/app.py and datasette/cli.py are flagged as likely executable entrypoints by filename heuristic. observed supported analysis_ef14c7222eb9f538:entry_1, analysis_ef14c7222eb9f538:entry_2
c10 Call-degree evidence labels datasette/app.py an entry/orchestration candidate with 356 incoming and 197 outgoing static calls. inferred supported analysis_ef14c7222eb9f538:role_5
c11 app.py defines the Datasette class at lines 394-3037 and the DatasetteRouter class at lines 3040-3314. observed supported analysis_ef14c7222eb9f538:py_class_e1f78b54738f, analysis_ef14c7222eb9f538:py_class_5b91150ffc65
c12 Traced execution paths starting at app.py terminate at unresolved external boundaries including logging.getLogger, contextvars.ContextVar, collections.namedtuple and Setting. inferred supported analysis_ef14c7222eb9f538:exec_141532159c69, analysis_ef14c7222eb9f538:exec_6c1e96f0a6c1, analysis_ef14c7222eb9f538:exec_99dfaf114e63, analysis_ef14c7222eb9f538:exec_af5f4c46e06d, analysis_ef14c7222eb9f538:exec_bb193f5bffdb
c13 Top-level directories datasette, docs and tests are identified as subsystems. observed supported analysis_ef14c7222eb9f538:subsys_1, analysis_ef14c7222eb9f538:subsys_2, analysis_ef14c7222eb9f538:subsys_3
c14 datasette/utils/__init__.py has 519 incoming and 53 outgoing calls (service/core candidate) and defines helpers such as CustomJSONEncoder and sqlite_timelimit. inferred supported analysis_ef14c7222eb9f538:role_52, analysis_ef14c7222eb9f538:py_class_faf43d86d5e4, analysis_ef14c7222eb9f538:py_func_43f232c11a74
c15 datasette/utils/asgi.py has 369 incoming calls and defines Request, AsgiLifespan, AsgiStream, AsgiWriter, and exception classes including NotFound and Forbidden. inferred supported analysis_ef14c7222eb9f538:role_54, analysis_ef14c7222eb9f538:py_class_cd4cbe1b803b, analysis_ef14c7222eb9f538:py_class_35d6af4bda0b, analysis_ef14c7222eb9f538:py_class_95cbf9060202, analysis_ef14c7222eb9f538:py_class_817272a7a16b, analysis_ef14c7222eb9f538:py_class_d21aa11be3ea, analysis_ef14c7222eb9f538:py_class_82a449d307f2
c16 Among the listed Python modules, datasette/views/table.py has the highest outgoing degree (283 out, 46 in), suggesting it coordinates many modules; it defines TableContext and Row. inferred supported analysis_ef14c7222eb9f538:role_73, analysis_ef14c7222eb9f538:role_44, analysis_ef14c7222eb9f538:py_class_6bca6cbe2675, analysis_ef14c7222eb9f538:py_class_e322d4ac69f5
c17 datasette/__init__.py (348 in, 0 out) and datasette/resources.py (227 in, 0 out) are leaf/data-boundary candidates; resources.py defines DatabaseResource, TableResource and QueryResource. inferred supported analysis_ef14c7222eb9f538:role_1, analysis_ef14c7222eb9f538:role_41, analysis_ef14c7222eb9f538:py_class_03bbfae65c78, analysis_ef14c7222eb9f538:py_class_3c5aca171b90, analysis_ef14c7222eb9f538:py_class_dd9acf15784d
c18 The highest reported degree belongs to datasette/static/edit-tools.js (808 incoming/outgoing), with datasette/static/table.js at 83/83; JavaScript analysis is bounded-heuristic. inferred supported analysis_ef14c7222eb9f538:role_44, analysis_ef14c7222eb9f538:role_46
c19 package.json - one of two detected build/dependency manifests - lists runtime dependencies @codemirror/lang-sql ^6.3.3, @rollup/plugin-node-resolve ^15.0.1, @rollup/plugin-terser ^0.1.0, codemirror ^6.0.1, rollup ^3.30.0, and dev dependency prettier ^3.0.0. observed supported analysis_ef14c7222eb9f538:dep_1, analysis_ef14c7222eb9f538:dep_2, analysis_ef14c7222eb9f538:dep_3, analysis_ef14c7222eb9f538:dep_4, analysis_ef14c7222eb9f538:dep_5, analysis_ef14c7222eb9f538:dep_6, analysis_ef14c7222eb9f538:ev_manifest_1, analysis_ef14c7222eb9f538:important_4
c20 Dependency records come only from requirements-style manifests; pyproject.toml dependency tables were not parsed, so Python dependencies are not established by this analysis. observed supported analysis_ef14c7222eb9f538:lim_3
c21 The repository contains 102 test files or test-like files, and the tests directory is a recognized subsystem. observed supported analysis_ef14c7222eb9f538:ev_tests_1, analysis_ef14c7222eb9f538:subsys_3
c22 tests/test_api_write.py defines helpers ds_write and write_token plus tests such as test_structured_writes_require_ordinary_tables and test_base64_write_api_insert_upsert_update_decode_blobs; the analyzer counts 123 incoming calls for the file. inferred supported analysis_ef14c7222eb9f538:py_func_7e4eb77eebbc, analysis_ef14c7222eb9f538:py_func_cb2fb92f620c, analysis_ef14c7222eb9f538:py_func_44bcadc2eed8, analysis_ef14c7222eb9f538:py_func_5ee2d6343eed, analysis_ef14c7222eb9f538:role_92
c23 tests/build_small_spatialite_db.py is a project-important likely entrypoint whose __main__ guard calls generate_it("spatialite.db"), generating a SQLite test database. observed supported analysis_ef14c7222eb9f538:py_entry_f23c245ed3b2, analysis_ef14c7222eb9f538:important_7
c24 README.md is classified as a project-level important file, making it the first orientation stop. observed supported analysis_ef14c7222eb9f538:important_1
c25 pyproject.toml and package.json are both project-level important files covering packaging and tooling. observed supported analysis_ef14c7222eb9f538:important_3, analysis_ef14c7222eb9f538:important_4
c26 datasette/__main__.py and datasette/cli.py are important likely entrypoints, and the static execution path runs from the __main__ guard to cli. inferred supported analysis_ef14c7222eb9f538:important_6, analysis_ef14c7222eb9f538:important_10, analysis_ef14c7222eb9f538:exec_707222db7901
c27 datasette/app.py is a project-important likely entrypoint holding the Datasette and DatasetteRouter classes. observed supported analysis_ef14c7222eb9f538:important_9, analysis_ef14c7222eb9f538:entry_1, analysis_ef14c7222eb9f538:py_class_e1f78b54738f, analysis_ef14c7222eb9f538:py_class_5b91150ffc65
c28 datasette/utils/__init__.py and datasette/utils/asgi.py have the highest incoming-call counts among the listed Python modules (519 and 369); datasette/static/edit-tools.js reports 808 incoming overall. inferred supported analysis_ef14c7222eb9f538:role_52, analysis_ef14c7222eb9f538:role_54, analysis_ef14c7222eb9f538:role_44
c29 datasette/views/table.py has the highest outgoing call degree among Python modules (283), making it a useful window into how view logic reaches other modules; datasette/static/edit-tools.js reports 808 outgoing overall. inferred supported analysis_ef14c7222eb9f538:role_73, analysis_ef14c7222eb9f538:role_44
c30 Start modification tracing at detected entrypoint datasette/app.py and check downstream effects by hand, because dynamic behaviour is not resolved statically. observed supported analysis_ef14c7222eb9f538:entry_1, analysis_ef14c7222eb9f538:lim_1
c31 Install, run and build inference is partial; installation commands are not verified, and the packet contains no runtime or execution results. observed supported analysis_ef14c7222eb9f538:lim_2
c32 Reflection, dynamic imports, monkey-patching, generated code, framework runtime wiring and dynamic dispatch are not resolved, so plugin discovery and loading cannot be established from this packet. observed supported analysis_ef14c7222eb9f538:lim_1
c33 Of 21,338 static relations, 15,850 are external or unresolved and 5,488 resolve locally. observed supported analysis_ef14c7222eb9f538:relation_counts
c34 Two files were inventoried but not parsed (oversized, minified or vendored); bounded analysis also skips files over 400 kB, minified bundles and vendored directories. unresolved supported analysis_ef14c7222eb9f538:claim_e6126b089362, analysis_ef14c7222eb9f538:lim_6
c35 README claim extraction is line-based and may capture code lines, so README-derived statements are author_claimed at best. observed supported analysis_ef14c7222eb9f538:lim_4
c36 pyproject.toml is a project-important manifest, but its dependency tables were not parsed by the analyzer. observed supported analysis_ef14c7222eb9f538:important_3, analysis_ef14c7222eb9f538:lim_3
c37 Named symbols include Datasette (datasette/app.py, lines 394-3037), DatasetteRouter (lines 3040-3314), and DatabaseResource, TableResource, QueryResource in datasette/resources.py. observed supported analysis_ef14c7222eb9f538:py_class_e1f78b54738f, analysis_ef14c7222eb9f538:py_class_5b91150ffc65, analysis_ef14c7222eb9f538:py_class_03bbfae65c78, analysis_ef14c7222eb9f538:py_class_3c5aca171b90, analysis_ef14c7222eb9f538:py_class_dd9acf15784d
c38 datasette/utils/asgi.py defines Request (lines 86-284), AsgiLifespan, AsgiStream, AsgiWriter, and exceptions NotFound, Forbidden, BadRequest and PayloadTooLarge. observed supported analysis_ef14c7222eb9f538:py_class_cd4cbe1b803b, analysis_ef14c7222eb9f538:py_class_35d6af4bda0b, analysis_ef14c7222eb9f538:py_class_95cbf9060202, analysis_ef14c7222eb9f538:py_class_817272a7a16b, analysis_ef14c7222eb9f538:py_class_d21aa11be3ea, analysis_ef14c7222eb9f538:py_class_82a449d307f2, analysis_ef14c7222eb9f538:py_class_50ac9c96bf68, analysis_ef14c7222eb9f538:py_class_c8521a5abce5
c39 datasette/utils/__init__.py defines CustomJSONEncoder and sqlite_timelimit, and datasette/views/table.py defines TableContext and Row. observed supported analysis_ef14c7222eb9f538:py_class_faf43d86d5e4, analysis_ef14c7222eb9f538:py_func_43f232c11a74, analysis_ef14c7222eb9f538:py_class_6bca6cbe2675, analysis_ef14c7222eb9f538:py_class_e322d4ac69f5

Sources, rights and disclosure · attribution-license-templates/v0.1

Rights notice. Original repository hosted on GitHub. Repository source code, documentation, names, media, and related project materials remain subject to the rights of their respective authors, contributors, and other rights holders and to applicable repository license terms.

Platform notice. GitHub is the source hosting platform for the linked repository. GitHub and related marks are trademarks of GitHub, Inc. EVEMISS Technology is not affiliated with or endorsed by GitHub unless explicitly stated otherwise.

How this page is produced. This page was produced using revision-aware repository analysis and AI-assisted editorial tooling. Technical claims are tied to the analyzed repository revision and may be revalidated when the source repository changes.

AI-assisted analysis. Reviewed by EVEMISS Technology through human–AI collaborative review. · Report a rights concern · All repository guides