Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
212 commits
Select commit Hold shift + click to select a range
30a1e71
implement html representation
katosh Nov 28, 2025
5ce0afb
vizual inspection testing
katosh Nov 28, 2025
9da45fe
fix dark mode and nesting of htlm rep
katosh Nov 28, 2025
28292b9
handle disabled script in htlm rep
katosh Nov 28, 2025
774c942
more compact html rep
katosh Nov 28, 2025
42ec6e6
show categories in html rep
katosh Nov 28, 2025
73f0c5d
dark mode and stability
katosh Nov 28, 2025
292b4fc
make max_cats configurable in html rep
katosh Nov 28, 2025
181b4d4
test many cat and no JS for html rep
katosh Nov 28, 2025
1dd4f18
cnter folding icon in html rep
katosh Nov 28, 2025
3db23cd
max rows for counting n-unique in html rep
katosh Nov 28, 2025
d5974f6
header coloring in html rep
katosh Nov 28, 2025
5cd1dd5
max 20 categories in html rep
katosh Nov 28, 2025
ef178c5
udpate many cats viz test of html rep
katosh Nov 28, 2025
11949af
robust html rep for ad blocker
katosh Nov 28, 2025
139f94d
more tetsing of html rep
katosh Nov 29, 2025
8a14312
future proof html rep
katosh Nov 29, 2025
a64de45
htlm rep documentation
katosh Nov 29, 2025
e7461f8
show backed path inline in html rep
katosh Nov 29, 2025
966bb54
add custom uns rendering for html rep
katosh Nov 29, 2025
27b83f6
customizable section html rep
katosh Nov 29, 2025
bfe8221
fix som html rep previews
katosh Nov 29, 2025
065eb2c
better multi line categories in html rep
katosh Nov 29, 2025
9505b63
increase html rep testing
katosh Nov 29, 2025
8983df3
formatt and style of html rep
katosh Nov 29, 2025
bfe31eb
reduce complexity of html rep
katosh Nov 29, 2025
4b37eca
add "vart" to codespell's ignore-words-list
katosh Nov 29, 2025
07632cf
failed formatter wrnings in html
katosh Nov 29, 2025
4c7ab7c
explicit cleanup in html rep test
katosh Nov 29, 2025
c65952c
html rep aesthetics and formatting
katosh Nov 29, 2025
ad57064
more sepcific error catching in html rep
katosh Nov 29, 2025
dfdea32
fix pre-commit checks for html pre tests
katosh Nov 29, 2025
6f5e222
fix html rep pre-commit error
katosh Nov 29, 2025
178022c
fix overflow for long field names in html rep
katosh Nov 30, 2025
8813761
ruff format and misleading sentence in viz preview
katosh Nov 30, 2025
ee475c2
all html rep settings in settings typs stub
katosh Nov 30, 2025
fd289df
chore: align pytest requirement with hatch-test default (>=9.0)
katosh Nov 30, 2025
2767e15
disable docstring test in html rep
katosh Nov 30, 2025
c0428e4
increase testing coverage for html rep
katosh Nov 30, 2025
bf150c7
readme in html rep
katosh Nov 30, 2025
bbce954
isolate markdown parser for html rep
katosh Nov 30, 2025
0b08325
html rep aesthetics
katosh Nov 30, 2025
7e46896
markdown table in html rep
katosh Nov 30, 2025
878d3e0
update readme example
katosh Nov 30, 2025
d894f8b
prevent formatting on code blocks
katosh Nov 30, 2025
32fffbc
more robust resize detection of html rep
katosh Nov 30, 2025
de9a0c8
html rep accessibility and compatibility
katosh Nov 30, 2025
c61e0c7
protect links in markdown
katosh Nov 30, 2025
44ccc1a
markdown single linebreak to space
katosh Nov 30, 2025
0b7c667
URL protocol sanitization to prevent XSS attacks
katosh Dec 1, 2025
ac8153a
more carefully not load lazy data in html rep
katosh Dec 2, 2025
b89417a
satisfy ruff
katosh Dec 2, 2025
8202884
inlcude modata example in vizual test
katosh Dec 2, 2025
5c34a8d
fix: custom setcions after .X
katosh Dec 2, 2025
839b7f4
make anndatas in .mod expandable
katosh Dec 2, 2025
302a81c
Merge branch 'main' into html_rep
katosh Dec 2, 2025
47a0217
add `doc_url` in mudata html rep example
katosh Dec 2, 2025
cb9fee8
expose html rep building blocks
katosh Dec 3, 2025
efc7897
inlcude SpatialData example
katosh Dec 3, 2025
ff56397
illustrate customization in SpatialData example
katosh Dec 3, 2025
a5e44d5
custom sections for SpatialData
katosh Dec 3, 2025
1f7d0c6
keep nested anndata visible if search hits content
katosh Dec 3, 2025
9f84f99
fix vizual test in CI
katosh Dec 3, 2025
73fb5a6
multi level keep nested visible on search
katosh Dec 3, 2025
eb0d3db
safeguard infinte loop
katosh Dec 3, 2025
047b060
customizable meta column
katosh Dec 6, 2025
d0d009e
simplify/explain SpatialData custom html rep
katosh Dec 6, 2025
e8cf0cd
centralize mure UI elements
katosh Dec 7, 2025
611809e
improve nested search
katosh Dec 7, 2025
628e9c4
regex and case sensitive search
katosh Dec 7, 2025
86e9afe
merge html_rep
katosh Dec 7, 2025
a920208
SpatialData exmaple coordinate systems
katosh Dec 11, 2025
7c7058b
Merge remote-tracking branch 'origin/main' into html_rep
katosh Dec 12, 2025
5ba035e
Merge remote-tracking branch 'origin/main' into expose_html_rep
katosh Dec 15, 2025
7ee414a
improve .raw render in `_rep_html_`
katosh Dec 15, 2025
e6f261f
better error handling for html rep
katosh Dec 15, 2025
42fa262
Merge html_rep to sync main merge
katosh Dec 15, 2025
2fbd1db
multi section SectionFormatter & do not list fomratted sections in "o…
katosh Dec 15, 2025
55c6f50
document "Building Custom _repr_html_"
katosh Dec 15, 2025
2fc88e8
test html rep public API
katosh Dec 15, 2025
9bd4ae0
test serializability for columns of .obs and .var
katosh Dec 19, 2025
d47fd5b
test serializability of column names and keys
katosh Dec 19, 2025
181430c
also warn datetime non-serializability
katosh Dec 19, 2025
61e49ee
maintainer info in case of test failure
katosh Dec 19, 2025
29b5caa
futureproof more serializationw warnings
katosh Dec 19, 2025
2597d99
coding style: relative imports and no section headers
katosh Dec 20, 2025
74bd1a5
move a comment
katosh Dec 27, 2025
2281875
Merge remote-tracking branch 'upstream/main' into expose_html_rep
katosh Dec 27, 2025
c46ebd6
currectly use new keyword-only signature
katosh Dec 27, 2025
6f008f7
fix docstring errors
katosh Dec 27, 2025
64eb50e
avoid loading _rep on anndata import
katosh Dec 27, 2025
f6d7e92
update non-loading of lazy data implementation and example
katosh Dec 28, 2025
b6f1fa5
remove some dead code forom html rep
katosh Jan 4, 2026
3a5f06a
reduce branches in render_formatted_entry
katosh Jan 4, 2026
7017fec
reduce size of html.py
katosh Jan 4, 2026
fc7a66b
core.py avoids necessity for most circular imports
katosh Jan 4, 2026
43a34e1
consolidate html rep sttings in FormatterContext
katosh Jan 4, 2026
aa4ff38
call nunique only once in html rep
katosh Jan 4, 2026
2ed985e
"is lazy" badge for html rep and example
katosh Jan 4, 2026
73bb56c
see "9b. Lazy AnnData (Experimental)" in
katosh Jan 4, 2026
2ee5f12
toc in html rep vizual test
katosh Jan 4, 2026
5465ee8
issue wrong decoding in lazy example by using newer numpy
katosh Jan 5, 2026
a9164e2
richer html rep for fully lazy data
katosh Jan 6, 2026
8fe997d
cleanup html rep for lazy
katosh Jan 6, 2026
0ffdcf0
move last column definition to formatters
katosh Jan 6, 2026
298727a
refator FormattedOutput for clearity
katosh Jan 6, 2026
a141ac2
style and zebra stripe section
katosh Jan 6, 2026
bf93caf
rep module consolidations
katosh Jan 6, 2026
3b9eb40
fix ruff issues
katosh Jan 6, 2026
ee000f2
more features in 1st html rep viz example
katosh Jan 6, 2026
e081319
no data object for renderers
katosh Jan 6, 2026
c951807
consolidate renderers
katosh Jan 6, 2026
3d694da
more typing friendliness
katosh Jan 6, 2026
aef9083
ruff formatting
katosh Jan 6, 2026
2f0f4e1
add more serialzaition warning examples to test 23
katosh Jan 6, 2026
ed80c5e
test lazy _rep module loading and serialization warnings
katosh Jan 6, 2026
0330df9
formatting
katosh Jan 6, 2026
87a011e
reintroduce the number of columns in obsm/varm preview
katosh Jan 6, 2026
70530cc
remove reudnant test and re-trigger ci
katosh Jan 6, 2026
55efd3f
splot html rep test and validate html
katosh Jan 7, 2026
3217630
fix: unique ID for readme modal
katosh Jan 7, 2026
34856ab
explicitly test JupyterLab compatibility
katosh Jan 7, 2026
852dab6
improve maintainability of html rep
katosh Jan 8, 2026
dd7246a
valid css files before replcaements
katosh Jan 8, 2026
2c212b4
Merge remote-tracking branch 'origin/main' into html_rep
katosh Jan 8, 2026
b165e9f
remove remnants of the deprecated FormattedOutput.details attribute
katosh Jan 8, 2026
bb35847
improve description of vizual tests
katosh Jan 8, 2026
425bef8
better lazy anndata batch and info
katosh Jan 8, 2026
593b085
improve and test adversarial robustness
katosh Jan 9, 2026
e792b7a
fix pre-commit issues
katosh Jan 9, 2026
dd28bbd
tightening html rep testing
katosh Jan 9, 2026
a72ab71
ruff correction
katosh Jan 9, 2026
5661bd9
prevent CSS injection in colors
katosh Jan 9, 2026
665f590
prevent XSS via exception
katosh Jan 9, 2026
347ff93
prevent XSS in readme links
katosh Jan 9, 2026
cf7d206
reduce redundant or unuseful adverserial tests
katosh Jan 9, 2026
fcc4cb6
render section error message truncation indication
katosh Jan 9, 2026
ace5cf1
Merge remote-tracking branch 'origin/main' into html_rep
katosh Jan 9, 2026
01e73a0
fix settings.pyi and catch test warnings
katosh Jan 9, 2026
fb2c70d
fix catch warnings
katosh Jan 9, 2026
2b59e45
fix too broad warning catch in testing
katosh Jan 9, 2026
d263b2a
increase coverage of lazy html rep
katosh Jan 9, 2026
6a3b0f1
adopt BEM naming convention for CSS classes
katosh Jan 10, 2026
f4d1363
fix BEM migration issues in JavaScript
katosh Jan 10, 2026
e04c80c
test parallel renderers
katosh Jan 10, 2026
831d92e
use _repr_constants consistently and remove unused constants
katosh Jan 11, 2026
85541ae
add invalid color detection and warnings for color lists
katosh Jan 11, 2026
0144f9f
fix LazyColumnFormatter dtype matching and add coverage tests
katosh Jan 12, 2026
b0b8e32
remove dead code placeholder from markdown.py
katosh Jan 12, 2026
8ef0079
cover BackedSparseDatasetFormatter in repr tests
katosh Jan 12, 2026
6a0e6a7
consolidate error handling with FormattedOutput.error field
katosh Jan 16, 2026
cd9cadc
separate serialization warnings from rendering errors
katosh Jan 16, 2026
94e9afa
CategoricalFormatter error path via output.error
katosh Jan 16, 2026
789daa9
Merge remote-tracking branch 'origin/main' into html_rep
katosh Jan 17, 2026
8779cd0
use pointer cursor for warning icon tooltip (Safari compatibility)
katosh Jan 17, 2026
9f40a93
refactor field width calculation and section rendering
katosh Jan 19, 2026
3e9e3c8
add get_section_doc_url() helper to centralize doc URL generation
katosh Jan 19, 2026
2abf88d
use explicit INTERNAL_ANNDATA_ATTRS for unknown section detection
katosh Jan 19, 2026
d38738e
move render_formatted_entry to core.py to avoid circular import
katosh Jan 19, 2026
2e03a2c
add obsm/varm column preview to NumpyMaskedArrayFormatter and tests
katosh Jan 19, 2026
82b6b8b
add XSS tests for category values and DataFrame column names
katosh Jan 22, 2026
5481975
add Test 25: ecosystem package extensibility example for obs/var
katosh Jan 22, 2026
c07914d
consolidate can_format and can_format_with_context into single method
katosh Jan 22, 2026
5b8d57b
fix can_format signature in docstring examples
katosh Jan 22, 2026
a3ad950
rename FormatterContext.column_name to FormatterContext.key
katosh Jan 22, 2026
a7c6c0e
move key validation into FormatterRegistry.format_value()
katosh Jan 22, 2026
2576d2a
Merge remote-tracking branch 'origin/main' into html_rep
katosh Jan 23, 2026
875fc3a
simplify security tests: replace attack vectors with escaping coverage
katosh Jan 26, 2026
9452c48
typing: replace `Any` with `object` and precise types across _repr/
katosh Jan 26, 2026
ce085ee
css: native nesting, dark mode theme selectors, variable dedup
katosh Jan 26, 2026
aad1cf4
test: update HTML validators for native CSS nesting
katosh Jan 26, 2026
a8e4f8d
html: replace section fold/expand with native <details>/<summary>
katosh Jan 27, 2026
6b7ded3
Merge remote-tracking branch 'origin/main' into html_rep
katosh Jan 27, 2026
822b811
css: replace .anndata-section__header class with structural summary s…
katosh Jan 27, 2026
883747d
css: remove @media (prefers-color-scheme: dark) in favor of attribute…
katosh Jan 28, 2026
cb950ac
css: inline dark mode variables, remove Python substitution
katosh Jan 29, 2026
e002f7e
css: move inline styles to CSS classes, remove unused selectors
katosh Jan 30, 2026
1f8dffa
fix ruff issues
katosh Jan 30, 2026
51f63b3
css: restore .anndata-text--warning rule, add .anndata-dtype--ndarray…
katosh Jan 30, 2026
640692e
merge: resolve _settings.py conflict with origin/main
katosh Feb 10, 2026
8691627
repr: use has_xp() for array-api detection in ArrayAPIFormatter
katosh Feb 10, 2026
922b096
repr: surface device info in visible type text for array-api and cupy…
katosh Feb 10, 2026
b7a9f0a
repr: consolidate CuPyArrayFormatter into ArrayAPIFormatter with devi…
katosh Feb 10, 2026
e2b6a32
repr: address flying_sheep review β€” dark mode fallback, TypeGuard, re…
katosh Feb 10, 2026
80a01df
Merge remote-tracking branch 'origin/main' into html_rep
katosh Feb 10, 2026
c4e5f0a
fix: add maxsplit to str.split for ruff 0.15.0 compatibility
katosh Feb 10, 2026
38fef01
repr: show obs_names/var_names preview in raw section
katosh Feb 18, 2026
4416ec6
Merge remote-tracking branch 'origin/main' into html_rep
katosh Feb 18, 2026
4304061
fix: add `size` to MockArrayAPI for SupportsArrayApi protocol change
katosh Feb 18, 2026
451f030
style: ruff formatting fixes
katosh Feb 18, 2026
ed0554c
refactor: use CSS light-dark() for dark mode theming
katosh Feb 20, 2026
3c85af5
refactor: migrate HTML repr from <table> to <div> + CSS grid
katosh Feb 20, 2026
7cc08b9
ruff corrections
katosh Feb 20, 2026
44ed0b5
fix: address review findings from table-to-grid migration
katosh Feb 21, 2026
7eba3a4
docs: rename release note to match PR number
katosh Feb 21, 2026
9f1f491
Merge remote-tracking branch 'origin/main' into html_rep
katosh Mar 20, 2026
0200ac5
feat: add no-CSS fallback message for untrusted notebooks
katosh Mar 23, 2026
b136275
fix: handle repr(adata) crash in no-CSS fallback message
katosh Mar 25, 2026
5c9d47d
style: ruff format
katosh Mar 25, 2026
868b818
feat: add render_html override for SectionFormatter
katosh Mar 30, 2026
e2f1229
fix: sanitize null bytes in escape_html
katosh Mar 30, 2026
ecbb009
style: fix ruff EM101 string literal in exception
katosh Mar 30, 2026
a6e42cf
feat: graceful text fallback when CSS is stripped (GitHub, untrusted …
katosh Mar 31, 2026
c713e9b
feat: graceful no-CSS/no-JS degradation with inline span layout
katosh Apr 1, 2026
0a0c09a
Merge remote-tracking branch 'origin/main' into html_rep
katosh Apr 15, 2026
8f58f26
refactor: adopt iter_outer for section iteration
katosh Apr 15, 2026
47066f2
refactor: collect section names during iter_outer iteration
katosh Apr 15, 2026
e141f4b
style: some basic style
flying-sheep Apr 20, 2026
33ac844
fix: avoid `id="..."` in JS source and install repr JS once per page
katosh Apr 21, 2026
d274fc7
refactor(repr): iterate AnnDataElem directly; fix nested copy-button …
katosh Apr 21, 2026
e486c3c
Merge branch 'main' into html_rep
katosh Apr 28, 2026
f9c62cb
Merge remote-tracking branch 'origin/main' into html_rep
katosh May 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ __pycache__/
# Test results (nunit/junit) and coverage
/test-data/
/*coverage*
tests/repr_html_visual_test.html

# jupyter
.ipynb_checkpoints
Expand Down
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"[python][toml][json][jsonc]": {
"[python][javascript][toml][json][jsonc]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit",
Expand All @@ -12,7 +12,7 @@
"[toml]": {
"editor.defaultFormatter": "tamasfe.even-better-toml",
},
"[json][jsonc]": {
"[javascript][json][jsonc]": {
"editor.defaultFormatter": "biomejs.biome",
},
"python.analysis.typeCheckingMode": "basic",
Expand Down
14 changes: 13 additions & 1 deletion biome.jsonc
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
{
"$schema": "https://biomejs.dev/schemas/2.1.1/schema.json",
"$schema": "https://biomejs.dev/schemas/2.3.12/schema.json",
"formatter": { "useEditorconfig": true },
"linter": {
"rules": {
"complexity": {
"noForEach": "on",
},
},
},
"javascript": {
"formatter": {
"semicolons": "asNeeded",
},
},
"overrides": [
{
"includes": ["./.vscode/*.json", "**/*.jsonc", "**/asv.conf.json"],
Expand Down
1 change: 1 addition & 0 deletions docs/release-notes/2236.feat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add rich HTML representation for {class}`~anndata.AnnData` objects in Jupyter notebooks with foldable sections, search/filter, category color visualization, dark mode support, and configurable settings via {attr}`anndata.settings`
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ max-positional-args = 5

[tool.codespell]
skip = ".git,*.pdf,*.svg"
ignore-words-list = "theis,coo,homogenous,GroupT"
ignore-words-list = "theis,coo,homogenous,vart,GroupT"

[tool.towncrier]
package = "anndata"
Expand Down
58 changes: 58 additions & 0 deletions src/anndata/_core/anndata.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,64 @@ def __repr__(self) -> str:
else:
return self._gen_repr(self.n_obs, self.n_vars)

def _repr_html_(self) -> str | None:
"""Rich HTML representation for Jupyter notebooks.

Returns an interactive HTML representation with:

- Foldable sections for each attribute (auto-collapse for large sections)
- Search/filter functionality across all fields
- Copy-to-clipboard buttons for field names
- Color visualization for categorical data with color palettes
- Serialization warnings for non-serializable types
- Memory usage and version information
- Dark mode support (auto-detects Jupyter/VS Code themes)
- Graceful degradation when JavaScript is disabled

The representation can be configured via :attr:`anndata.settings`:

- ``repr_html_enabled``: Enable/disable HTML repr (default: True)
- ``repr_html_fold_threshold``: Auto-fold sections with more entries (default: 5)
- ``repr_html_max_depth``: Max recursion depth for nested AnnData (default: 3)
- ``repr_html_max_items``: Max items to show per section (default: 200)
- ``repr_html_max_categories``: Max category values to display inline (default: 100)
- ``repr_html_unique_limit``: Max rows for unique count computation (default: 1M)
- ``repr_html_max_field_width``: Max width in pixels for field name column (default: 400)
- ``repr_html_type_width``: Width in pixels for type column (default: 220)

Examples
--------
Disable HTML representation globally:

>>> import anndata
>>> anndata.settings.repr_html_enabled = False

Temporarily change settings using context manager::

with anndata.settings.override(repr_html_fold_threshold=10):
display(adata) # Sections fold only when >10 items

Returns
-------
str | None
HTML string if enabled, None otherwise (falls back to text repr).
"""
if not settings.repr_html_enabled:
return None

try:
from anndata._repr import generate_repr_html

return generate_repr_html(self)
except Exception as e: # noqa: BLE001
# Intentional broad catch: HTML repr should never crash the notebook
# Fall back to text repr if HTML generation fails, but log the error
warn(
f"HTML repr failed, falling back to text repr: {e}",
UserWarning,
)
return None

def __eq__(self, other):
"""Equality testing"""
msg = (
Expand Down
Loading
Loading