Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
6ba7aa3
chore(web): remove experimental dash web port
May 22, 2026
1f60243
feat(web): scaffold v2 web app (react + fastapi)
May 22, 2026
162b1e6
chore: gitignore .idea and apply prettier formatting
May 22, 2026
95e09e0
feat(web): add ontology data model and TSV parser
May 22, 2026
dcc384a
fix(web): preserve real ontology rows over synthetic placeholders
May 22, 2026
d3b15e4
feat(web): add count propagation engine and parity harness
May 22, 2026
b13cb30
feat(web): add color propagation engine and parity harness
May 22, 2026
54c1495
feat: complete ontology sunburst app with live propagation, grid, exp…
May 22, 2026
746133a
feat(web): add blocking loading overlay with staged progress
May 22, 2026
5b1251e
chore(web): migrate eslint to v9 flat config
May 22, 2026
48089c9
feat(web): redesign UI with toolbar, drawer settings, editable table,…
May 22, 2026
0a82434
fix(web): guard giant counts, block during edits, scope grid to subtree
May 22, 2026
f53cb0a
feat(web): clickable logo resets with confirmation, drop header buttons
May 22, 2026
43d6ef9
feat(web): redesign landing page with OBO Foundry fetch + templates
May 22, 2026
aadcdaa
feat(web): split template cards, drop example submenu, v2.0.1
May 26, 2026
ad4a577
chore(server): source __version__ from package metadata, bump to 2.0.1
May 26, 2026
f8ea97c
feat(web): simplify footer with GitHub and Delta4 links
May 26, 2026
d313f76
feat(packaging): consolidate desktop + server + web into one ontolovi…
May 26, 2026
84815cd
chore: ignore .playwright-mcp/ and document pnpm test:watch
May 26, 2026
60ba822
feat(server): production-ready entry point + Dockerfile
May 26, 2026
e81b64f
feat(templates): consolidate into web/public/templates as single source
May 26, 2026
c77b477
feat(web): differentiate landing entry groups with visual hierarchy
May 26, 2026
54616da
feat(branding): add layered ontology logo, wire into web + desktop
May 26, 2026
ed51596
docs(readme): note Linux GUI workaround for uv's prebuilt Tk
May 26, 2026
30aac04
feat(web): add small-multiples overview grid as default view
May 26, 2026
0a25acf
fix(web): sunburst bg follows theme, drop overview depth cap
May 26, 2026
66bb00f
feat(obo): per-ontology root override, fetch cache, landing sunburst
May 26, 2026
ccf97b7
feat(web): show root term name on overview tiles
May 26, 2026
37b370c
feat(sunburst): animate focus zoom and walk one level up on inner-click
May 26, 2026
87f06e4
fix(web): unscope data table and dropdown when entering overview
May 26, 2026
7b11fd4
refactor(web): fold data-table status into header, drop redundant con…
May 26, 2026
5b15a3c
feat(web): polish sunburst settings UX and hover contrast
May 26, 2026
6a892c6
fix(web): pick alphabetically-first subtree when entering detail view
May 26, 2026
0915289
perf(web): defer count/color propagation with loading indicator
May 26, 2026
85d9619
feat(web): add OntoloViz-compatible TSV export
May 26, 2026
4d1de6b
feat(web): swap loading bar for spinning accent ring on chart
May 26, 2026
38c43c1
feat(web): wire TSV export into header and refine output
May 26, 2026
8fad123
fix(web): make recompute ring glow more visible
May 26, 2026
c64031e
feat(web): make HTML exports interactive with themed drill-down
May 26, 2026
ee07ede
fix(web): stop clipping long tooltips in exported HTML
May 26, 2026
dac2d87
feat(web): add configurable export workspace for publication figures
May 26, 2026
d0dc97b
feat(web): scope export controls to current view mode
May 26, 2026
6702e84
feat(web): per-label positions, subtree exclusion, snappy export preview
May 26, 2026
725f75c
feat(web): add OBO Foundry attribution banner to picker modal
May 27, 2026
21a73ea
feat(web): redesign settings panel with plain-language controls
May 27, 2026
cc6c39c
feat(web): add per-depth ring thickness control to sunburst
May 27, 2026
48e8f27
chore(web): reflow OBO Foundry attribution text
May 27, 2026
be2057d
fix(test): point ontology tests at web/public/templates
May 27, 2026
605dbe6
feat(web): add configurable id/header/description labels to detail ex…
May 27, 2026
75898db
feat(web): add ring-thickness taper control and header logo
May 27, 2026
425da80
feat: add ontology handoff API and reverse-proxy-ready deployment
Jun 1, 2026
2e68ae8
build: support building the frontend on the prod host
Jun 1, 2026
f54e329
fix: make web build mount-point agnostic and unblock prod pnpm build
Jun 1, 2026
46e7974
fix(web): move pnpm onlyBuiltDependencies to pnpm-workspace.yaml
Jun 1, 2026
0ba88c5
fix(web): approve esbuild build via pnpm 11 allowBuilds key
Jun 1, 2026
31222a1
fix(web): make pnpm 11 build-script gate non-fatal via strictDepBuilds
Jun 1, 2026
8e0bf37
fix: create service venv with uv to avoid python3-venv dependency
Jun 1, 2026
a70aece
fix(deploy): default service bind to 0.0.0.0 and reconcile env overrides
Jun 1, 2026
56bed09
feat(web): default count propagation to keep each node's own value
Jun 1, 2026
63672f5
refactor(deploy): make git-pull+rebuild the default update-service path
Jun 1, 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
26 changes: 26 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# OntoloViz server environment variables. Copy to `.env` and adjust.
# All values are optional — defaults are dev-safe.

# Bind address. Use 0.0.0.0 to accept connections from outside the container.
ONTOLOVIZ_HOST=127.0.0.1

# TCP port the FastAPI server listens on.
ONTOLOVIZ_PORT=8000

# Number of uvicorn worker processes. Rule of thumb: 2*CPU + 1.
# Ignored when ONTOLOVIZ_RELOAD=1.
ONTOLOVIZ_WORKERS=1

# Hot-reload on source changes. Dev only — must be 0 in production.
ONTOLOVIZ_RELOAD=0

# Trust X-Forwarded-* headers. Enable when behind nginx/Caddy/an LB.
ONTOLOVIZ_PROXY_HEADERS=0

# Uvicorn log level: critical | error | warning | info | debug | trace
ONTOLOVIZ_LOG_LEVEL=info

# Comma-separated list of allowed CORS origins. In a same-origin deployment
# (SPA + API served by this process) CORS is unused; set it only when the
# frontend is hosted elsewhere.
ONTOLOVIZ_CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
13 changes: 10 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
/lib/
/lib64/
parts/
sdist/
var/
Expand Down Expand Up @@ -128,4 +128,11 @@ dmypy.json
# Pyre type checker
.pyre/

# custom
# custom
.idea/

# Web frontend build artifact bundled into the wheel
src/ontoloviz_server/web_dist/

# Playwright MCP session output (console logs, page snapshots, screenshots)
.playwright-mcp/
52 changes: 52 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# syntax=docker/dockerfile:1.7

# --- Stage 1: build the web frontend ---------------------------------------
FROM node:20-bookworm-slim AS web-builder

WORKDIR /web
RUN corepack enable

COPY web/package.json web/pnpm-lock.yaml* ./
RUN pnpm install --frozen-lockfile || pnpm install

COPY web/ ./
RUN pnpm build

# --- Stage 2: assemble the Python wheel ------------------------------------
FROM python:3.12-slim-bookworm AS wheel-builder

WORKDIR /src
RUN pip install --no-cache-dir build

COPY pyproject.toml MANIFEST.in VERSION README.md LICENSE ./
COPY src/ ./src/
COPY --from=web-builder /web/dist/ ./src/ontoloviz_server/web_dist/

RUN python -m build --wheel --outdir /wheels

# --- Stage 3: lean runtime --------------------------------------------------
FROM python:3.12-slim-bookworm AS runtime

# Run as non-root.
RUN useradd --create-home --uid 10001 ontoloviz
WORKDIR /home/ontoloviz

COPY --from=wheel-builder /wheels/*.whl /tmp/
RUN pip install --no-cache-dir /tmp/*.whl && rm -rf /tmp/*.whl

USER ontoloviz

ENV ONTOLOVIZ_HOST=0.0.0.0 \
ONTOLOVIZ_PORT=8000 \
ONTOLOVIZ_WORKERS=4 \
ONTOLOVIZ_PROXY_HEADERS=1 \
ONTOLOVIZ_LOG_LEVEL=info \
PYTHONUNBUFFERED=1

EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD python -c "import urllib.request,sys; \
sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8000/api/health',timeout=3).status==200 else 1)"

ENTRYPOINT ["ontoloviz-server"]
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include VERSION
include LICENSE
include README.md
91 changes: 91 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
.PHONY: dev dev-web dev-server install test test-web test-server lint typecheck build build-web build-wheel clean parity-fixtures version set-version

# --- Top-level dev loop ----------------------------------------------------

dev:
@echo "Starting frontend (web/) and backend (ontoloviz-server) concurrently..."
@trap 'kill 0' INT TERM; \
$(MAKE) -s dev-server & \
$(MAKE) -s dev-web & \
wait

dev-web:
cd web && pnpm dev

# Backend runs out of the unified repo-root package. Editable installs do NOT
# auto-rebuild the JS bundle — Vite's dev server is the source of truth for
# the frontend in development; the SPA mount in main.py stays dormant when
# src/ontoloviz_server/web_dist/ is empty.
dev-server:
uv run ontoloviz-server --dev

# --- Install ---------------------------------------------------------------

install:
cd web && pnpm install
uv sync --extra dev

# --- Tests -----------------------------------------------------------------

test: test-web test-server

test-web:
cd web && pnpm test

test-server:
uv run pytest -q

# --- Quality ---------------------------------------------------------------

lint:
cd web && pnpm lint
uv run ruff check .

typecheck:
cd web && pnpm typecheck

# --- Build -----------------------------------------------------------------

# Full release build: compile the web frontend, embed it into the Python
# package, and produce wheel + sdist under ./dist/.
build: build-web build-wheel

build-web:
cd web && pnpm build
rm -rf src/ontoloviz_server/web_dist
mkdir -p src/ontoloviz_server/web_dist
cp -r web/dist/. src/ontoloviz_server/web_dist/

build-wheel:
uv build

# --- Parity ----------------------------------------------------------------

# Regenerate JSON fixtures under web/tests/fixtures/parity/ from the
# Python reference (src/ontoloviz/core.py + tests/parity logic). Run after
# changing the propagation semantics in either language.
parity-fixtures:
uv run python tests/parity/generate_fixtures.py

# --- Version ---------------------------------------------------------------

# Print the canonical version (root VERSION file is the source of truth).
# Both the wheel and web/package.json read it (statically or dynamically);
# pyproject.toml picks it up via [tool.setuptools.dynamic].
version:
@cat VERSION

# Usage: make set-version VERSION=3.0.1
set-version:
@if [ -z "$(VERSION)" ]; then echo "Usage: make set-version VERSION=X.Y.Z"; exit 1; fi
@echo "$(VERSION)" > VERSION
@node -e "const f='web/package.json';const j=require('fs').readFileSync(f,'utf8');const o=JSON.parse(j);o.version='$(VERSION)';require('fs').writeFileSync(f,JSON.stringify(o,null,2)+'\n')"
@echo "Version set to $(VERSION) (VERSION + web/package.json). pyproject.toml picks it up dynamically."

# --- Cleanup ---------------------------------------------------------------

clean:
rm -rf web/dist web/node_modules/.vite
rm -rf src/ontoloviz_server/web_dist
rm -rf dist build src/ontoloviz.egg-info
rm -rf .pytest_cache .ruff_cache .mypy_cache
75 changes: 61 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,72 @@ Quickstart
**Install OntoloViz**
- Using pip:
```bash
pip install ontoloviz # Classic UI
pip install ontoloviz[web] # With experimental web interface
pip install ontoloviz # Classic desktop UI (Tkinter)
```
- Using uv:
```bash
git clone https://github.com/Delta4AI/OntoloViz.git
cd OntoloViz
uv sync # Classic UI
uv sync --extra web # With experimental web interface
uv sync # Classic desktop UI
```

**Run OntoloViz**
```bash
ontoloviz # Launch classic UI
ontoloviz-web # Launch web interface
```

> **Linux note (desktop GUI only):** uv's prebuilt CPython ships a Tk build
> that crashes the file dialog on some distros (e.g. Fedora) with
> `[xcb] Aborting, sorry about that.` Use the distro's Python for the GUI:
> ```bash
> uv sync --python /usr/bin/python3
> uv run --python /usr/bin/python3 ontoloviz
> ```
> Building wheels (`uv build`) and running the web app are unaffected and
> work with either Python.

**Web app**

A browser-based version lives in `web/` (Vite + React + TS + D3 + Canvas)
backed by a FastAPI server packaged alongside the GUI in `src/ontoloviz_server/`.

Development (Vite + reloading FastAPI):
```bash
make install # one-time: installs frontend and backend deps
make dev # runs Vite on :5173 and FastAPI on :8000
```

End-user install (bundled SPA served by the FastAPI process):
```bash
pip install ontoloviz
ontoloviz-server # serves the web UI at http://127.0.0.1:8000
ontoloviz # launches the legacy desktop GUI
```

Production launch:
```bash
ontoloviz-server --host 0.0.0.0 --port 8000 --workers 4 --proxy-headers
# or via env vars — see .env.example
```
All flags have `ONTOLOVIZ_*` env-var fallbacks. Behind nginx/Caddy on the
public edge, `--proxy-headers` makes FastAPI trust forwarded client IPs.

Container:
```bash
docker build -t ontoloviz .
docker run --rm -p 8000:8000 ontoloviz
```
The image bundles the web build, exposes :8000, runs as a non-root user,
and ships a `/api/health` healthcheck.

Another application can push a fully-built ontology to the server and hand the
user a link that renders it live (`POST /api/ontology` → open `?session=<id>`).
See [docs/ontology-handoff.md](docs/ontology-handoff.md).

Docs: [web/README.md](web/README.md) (frontend) ·
[docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) (dev setup + commands) ·
[docs/RUNBOOK.md](docs/RUNBOOK.md) (deploy, env vars, API surface, reverse proxy).



**Pre-built Windows Binaries**
Expand Down Expand Up @@ -190,15 +239,13 @@ Templates and Examples

| Filename | Description |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [atc_example_covid_drugs_experimental.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/templates/atc_example_covid_drugs_experimental.tsv) | ATC-based example with data from the [DrugBank](https://go.drugbank.com) indicating experimental drugs related to COVID-19. |
| [atc_example_covid_drugs_trial_summary.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/templates/atc_example_covid_drugs_trial_summary.tsv) | ATC-based example with data from [publicly available clinical trial data](https://clinicaltrials.gov/) indicating drugs tested in clinical studies, one count represents usage in one study. |
| [atc_template.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/templates/atc_template.tsv) | ATC-based empty template of the [ATC](https://www.who.int/tools/atc-ddd-toolkit/atc-classification) tree based on the manually curated chemical database of bioactive molecules [ChEMBL v29](https://chembl.gitbook.io/chembl-interface-documentation/downloads). |
| [custom_template_parent_based.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/templates/custom_template_parent_based.tsv) | Template for creating your own ontology based on any child and parent terms. |
| [custom_template_separator_based.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/templates/custom_template_separator_based.tsv) | Template to create your own ontology based on a separator-based tree structure - for this template the underscore character `_` has been used. |
| [mesh_example_pubmed_mapped.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/templates/mesh_example_pubmed_mapped.tsv) | MeSH-based example with data from the publicly available [PubMed](https://pubmed.ncbi.nlm.nih.gov/) database of publications (title + abstract), where disease-related MeSH terms were extracted and mapped to the MeSH-tree. |
| [mesh_template.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/templates/mesh_template.tsv) | MeSH-based empty template of the [MeSH](https://meshb.nlm.nih.gov/treeView) tree `C` and `F03`. Terms are unique and mapped to all related parent nodes. |
| [atc_example.html](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/templates/atc_example.html) | ATC-based sample plot generated with the provided `covid_drugs_trial_summary.tsv` file. |
| [mesh_example.html](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/templates/mesh_example.html) | MeSH-based sample plot generated with the provided `covid_drugs_trial_summary.tsv` file. |
| [atc_template.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/web/public/templates/atc_template.tsv) | Empty [ATC](https://www.who.int/tools/atc-ddd-toolkit/atc-classification) drug-hierarchy template, prefilled from the curated chemical database [ChEMBL v29](https://chembl.gitbook.io/chembl-interface-documentation/downloads). |
| [mesh_template.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/web/public/templates/mesh_template.tsv) | Empty [MeSH](https://meshb.nlm.nih.gov/treeView) `C` and `F03` subject-hierarchy template; terms are unique and mapped to all related parent nodes. |
| [atc_example_covid_drugs_experimental.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/web/public/templates/atc_example_covid_drugs_experimental.tsv) | ATC-based example with [DrugBank](https://go.drugbank.com) data marking experimental drugs related to COVID-19. |
| [atc_example_covid_drugs_trial_summary.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/web/public/templates/atc_example_covid_drugs_trial_summary.tsv) | ATC-based example with [publicly available clinical trial data](https://clinicaltrials.gov/) — one count per study a drug was tested in. |
| [mesh_example_pubmed_mapped.tsv](https://raw.githubusercontent.com/Delta4AI/OntoloViz/master/web/public/templates/mesh_example_pubmed_mapped.tsv) | MeSH-based example from [PubMed](https://pubmed.ncbi.nlm.nih.gov/) titles + abstracts; disease-related MeSH terms extracted and mapped onto the MeSH tree. |

All five files also ship inside the wheel and are reachable at `/templates/*.tsv` from the bundled web app.

---

Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.0.1
Binary file added branding/logo.ico
Binary file not shown.
Binary file added branding/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions branding/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading