Skip to content

Commit fa7ac40

Browse files
committed
Add demo entrypoint
1 parent e49bf62 commit fa7ac40

File tree

3 files changed

+128
-8
lines changed

3 files changed

+128
-8
lines changed

pyproject.toml

+9-2
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ classifiers = [
1919
"Programming Language :: Python :: 3.10",
2020
"Programming Language :: Python :: 3.11",
2121
]
22-
requires-python = ">=3.8"
22+
requires-python = ">=3.8,<3.12"
2323
dependencies = [
2424
"anywidget>=0.2.3",
2525
"cev-metrics>=0.1.2",
2626
"ipywidgets>=8.0.0",
2727
"jinja2>=3.0.0",
2828
"jupyter-scatter>=0.14.0",
29-
"pandas>=1.0",
29+
"pandas>=1.0,<2.0",
30+
"numpy>=1.0,<2.0",
31+
"pyarrow",
32+
"pooch>=1.3.0",
33+
"rich>=13.0.0",
3034
]
3135
dynamic = ["version"]
3236

@@ -45,6 +49,9 @@ notebooks = [
4549
"matplotlib",
4650
]
4751

52+
[project.scripts]
53+
cev = "cev._cli:main"
54+
4855
[project.urls]
4956
homepage = "https://github.com/OzetteTech/comparative-embedding-visualization"
5057

src/cev/__init__.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
from importlib.metadata import PackageNotFoundError, version
1+
from cev._version import __version__ # noqa
22

33
import cev.metrics as metrics # noqa
44
import cev.widgets as widgets # noqa
5-
6-
try:
7-
__version__ = version("cev")
8-
except PackageNotFoundError:
9-
__version__ = "uninstalled"

src/cev/_cli.py

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import argparse
2+
import json
3+
import os
4+
import sys
5+
import textwrap
6+
import zipfile
7+
from pathlib import Path
8+
9+
import pooch
10+
11+
from cev._version import __version__
12+
13+
14+
def download_data() -> tuple[Path, Path]:
15+
archive = pooch.retrieve(
16+
url="https://figshare.com/ndownloader/articles/23063615/versions/1",
17+
path=pooch.os_cache("cev"),
18+
fname="data.zip",
19+
known_hash=None,
20+
)
21+
archive = Path(archive)
22+
files = [
23+
"mair-2022-tissue-138-umap.pq",
24+
"mair-2022-tissue-138-ozette.pq",
25+
]
26+
with zipfile.ZipFile(archive, "r") as zip_ref:
27+
for file in files:
28+
zip_ref.extract(file, path=archive.parent)
29+
return (
30+
archive.parent / "mair-2022-tissue-138-umap.pq",
31+
archive.parent / "mair-2022-tissue-138-ozette.pq",
32+
)
33+
34+
35+
def write_notebook(output: Path):
36+
umap_path, ozette_path = download_data()
37+
source = textwrap.dedent(f"""
38+
import pandas as pd
39+
from cev.widgets import Embedding, EmbeddingComparisonWidget
40+
41+
umap_embedding = pd.read_parquet("{umap_path}").pipe(Embedding.from_ozette)
42+
ozette_embedding = pd.read_parquet("{ozette_path}").pipe(Embedding.from_ozette)
43+
44+
EmbeddingComparisonWidget(
45+
umap_embedding,
46+
ozette_embedding,
47+
titles=("Standard UMAP", "Annotation-Transformed UMAP"),
48+
metric="confusion",
49+
selection="synced",
50+
auto_zoom=True,
51+
row_height=320,
52+
)
53+
""").strip()
54+
55+
nb = {
56+
"cells": [
57+
{
58+
"cell_type": "code",
59+
"execution_count": None,
60+
"metadata": {},
61+
"outputs": [],
62+
"source": source,
63+
}
64+
],
65+
"metadata": {
66+
"kernelspec": {
67+
"display_name": "Python 3",
68+
"language": "python",
69+
"name": "python3",
70+
}
71+
},
72+
"nbformat": 4,
73+
"nbformat_minor": 5,
74+
}
75+
with output.open("w") as f:
76+
json.dump(nb, f, indent=2)
77+
78+
79+
def run_notebook(notebook_path: Path):
80+
DEV = True
81+
command = [
82+
"uvx",
83+
"--python",
84+
"3.11",
85+
"--with",
86+
"." if DEV else f"cev=={__version__}",
87+
"--with",
88+
"jupyterlab",
89+
"jupyter",
90+
"lab",
91+
str(notebook_path),
92+
]
93+
try:
94+
os.execvp(command[0], command)
95+
except OSError as e:
96+
print(f"Error executing {command[0]}: {e}", file=sys.stderr)
97+
sys.exit(1)
98+
99+
100+
def main():
101+
parser = argparse.ArgumentParser(prog="cev")
102+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
103+
subparsers.add_parser("download", help="Download the demo notebook (and data)")
104+
subparsers.add_parser("demo", help="Run the demo notebook in JupyterLab")
105+
args = parser.parse_args()
106+
107+
notebook_path = Path("cev-demo.ipynb")
108+
if args.command == "download":
109+
write_notebook(notebook_path)
110+
elif args.command == "demo":
111+
write_notebook(notebook_path)
112+
run_notebook(notebook_path)
113+
else:
114+
parser.print_help()
115+
116+
117+
if __name__ == "__main__":
118+
main()

0 commit comments

Comments
 (0)