hyperview 0.1.1__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. {hyperview-0.1.1 → hyperview-0.3.1}/.gitignore +9 -0
  2. {hyperview-0.1.1 → hyperview-0.3.1}/LICENSE +1 -1
  3. {hyperview-0.1.1 → hyperview-0.3.1}/PKG-INFO +52 -39
  4. hyperview-0.3.1/README.md +132 -0
  5. {hyperview-0.1.1 → hyperview-0.3.1}/pyproject.toml +0 -6
  6. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/_version.py +2 -2
  7. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/api.py +26 -18
  8. hyperview-0.3.1/src/hyperview/cli.py +362 -0
  9. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/core/dataset.py +357 -189
  10. hyperview-0.3.1/src/hyperview/core/selection.py +309 -0
  11. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/embeddings/__init__.py +2 -3
  12. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/embeddings/engine.py +63 -2
  13. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/embeddings/pipelines.py +108 -39
  14. hyperview-0.3.1/src/hyperview/embeddings/projection.py +467 -0
  15. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/embeddings/providers/lancedb_providers.py +178 -0
  16. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/app.py +157 -35
  17. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/404/index.html +1 -1
  18. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/404.html +1 -1
  19. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/__next.__PAGE__.txt +2 -2
  20. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/__next._full.txt +3 -3
  21. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/__next._head.txt +1 -1
  22. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/__next._index.txt +2 -2
  23. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/__next._tree.txt +2 -2
  24. hyperview-0.3.1/src/hyperview/server/static/_next/static/chunks/077b38561d6ea80d.js +13 -0
  25. hyperview-0.1.1/src/hyperview/server/static/_next/static/chunks/e7ae0fd4a43b4ae1.css → hyperview-0.3.1/src/hyperview/server/static/_next/static/chunks/462c5e072cd14e02.css +1 -1
  26. hyperview-0.3.1/src/hyperview/server/static/_next/static/chunks/6ab4c63fd83a6bdc.js +1 -0
  27. hyperview-0.3.1/src/hyperview/server/static/_next/static/chunks/6adcb3a43c287a0a.js +407 -0
  28. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_not-found/__next._full.txt +2 -2
  29. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_not-found/__next._head.txt +1 -1
  30. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_not-found/__next._index.txt +2 -2
  31. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_not-found/__next._not-found.__PAGE__.txt +1 -1
  32. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_not-found/__next._not-found.txt +1 -1
  33. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_not-found/__next._tree.txt +2 -2
  34. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_not-found/index.html +1 -1
  35. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_not-found/index.txt +2 -2
  36. hyperview-0.3.1/src/hyperview/server/static/index.html +1 -0
  37. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/index.txt +3 -3
  38. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/storage/backend.py +2 -1
  39. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/storage/lancedb_backend.py +226 -23
  40. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/storage/memory_backend.py +35 -6
  41. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/storage/schema.py +53 -13
  42. hyperview-0.1.1/README.md +0 -119
  43. hyperview-0.1.1/src/hyperview/cli.py +0 -167
  44. hyperview-0.1.1/src/hyperview/core/selection.py +0 -53
  45. hyperview-0.1.1/src/hyperview/embeddings/projection.py +0 -267
  46. hyperview-0.1.1/src/hyperview/server/static/_next/static/chunks/3098f127ca49563b.js +0 -13
  47. hyperview-0.1.1/src/hyperview/server/static/_next/static/chunks/4543baba6321cb86.js +0 -301
  48. hyperview-0.1.1/src/hyperview/server/static/_next/static/chunks/80cd550edf03d788.js +0 -1
  49. hyperview-0.1.1/src/hyperview/server/static/index.html +0 -1
  50. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/__init__.py +0 -0
  51. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/core/__init__.py +0 -0
  52. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/core/sample.py +0 -0
  53. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/embeddings/compute.py +0 -0
  54. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/embeddings/providers/__init__.py +0 -0
  55. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/__init__.py +0 -0
  56. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/chunks/567993cf36cd4ab1.js +0 -0
  57. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/chunks/86c1fc4cf542f408.js +0 -0
  58. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  59. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/chunks/a6dad97d9634a72d.js.map +0 -0
  60. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/chunks/e954ba82c0a04100.js +0 -0
  61. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/chunks/f29dd35a99c216ea.js +0 -0
  62. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/chunks/turbopack-cb59e03a04a579d1.js +0 -0
  63. {hyperview-0.1.1/src/hyperview/server/static/_next/static/9UIGNc82PJ8k2Tsn68di9 → hyperview-0.3.1/src/hyperview/server/static/_next/static/gMy4JPL2K0MjiU7F71me_}/_buildManifest.js +0 -0
  64. {hyperview-0.1.1/src/hyperview/server/static/_next/static/9UIGNc82PJ8k2Tsn68di9 → hyperview-0.3.1/src/hyperview/server/static/_next/static/gMy4JPL2K0MjiU7F71me_}/_clientMiddlewareManifest.json +0 -0
  65. {hyperview-0.1.1/src/hyperview/server/static/_next/static/9UIGNc82PJ8k2Tsn68di9 → hyperview-0.3.1/src/hyperview/server/static/_next/static/gMy4JPL2K0MjiU7F71me_}/_ssgManifest.js +0 -0
  66. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/media/1bffadaabf893a1e-s.7cd81963.woff2 +0 -0
  67. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/media/2bbe8d2671613f1f-s.76dcb0b2.woff2 +0 -0
  68. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/media/2c55a0e60120577a-s.2a48534a.woff2 +0 -0
  69. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/media/5476f68d60460930-s.c995e352.woff2 +0 -0
  70. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2 +0 -0
  71. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/media/9c72aa0f40e4eef8-s.18a48cbc.woff2 +0 -0
  72. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/server/static/_next/static/media/ad66f9afd8947f86-s.7a40eb73.woff2 +0 -0
  73. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/storage/__init__.py +0 -0
  74. {hyperview-0.1.1 → hyperview-0.3.1}/src/hyperview/storage/config.py +0 -0
@@ -70,7 +70,16 @@ TESTS.md
70
70
  AGENTS.md
71
71
  **/AGENTS.md
72
72
  .github/agents/
73
+ .github/instructions/
74
+ .github/hooks/
75
+ .github/skills/
76
+ .agents/
73
77
  .specstory/
74
78
 
79
+ # Deployment repo (managed as a separate nested git repository)
80
+ hyper-models/
81
+ hyperview-spaces/
82
+ eval/
83
+
75
84
  # Generated version file (hatch-vcs)
76
85
  src/hyperview/_version.py
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Matin Mahmood
3
+ Copyright (c) 2025 Hyper3Labs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperview
3
- Version: 0.1.1
3
+ Version: 0.3.1
4
4
  Summary: Open-source dataset curation with hyperbolic embeddings visualization
5
5
  Project-URL: Homepage, https://github.com/Hyper3Labs/HyperView
6
6
  Project-URL: Documentation, https://github.com/Hyper3Labs/HyperView#readme
@@ -48,14 +48,14 @@ Description-Content-Type: text/markdown
48
48
 
49
49
  > **Open-source dataset curation + embedding visualization (Euclidean + Poincaré disk)**
50
50
 
51
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Hyper3Labs/HyperView)
51
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Hyper3Labs/HyperView) [![Open in HF Spaces](https://huggingface.co/datasets/huggingface/badges/resolve/main/open-in-hf-spaces-sm.svg)](https://huggingface.co/spaces/hyper3labs/HyperView) [![Discord](https://img.shields.io/badge/Discord-hyper%C2%B3labs-5865F2?logo=discord&logoColor=white)](https://discord.gg/Za3rBkTPSf)
52
52
 
53
53
  <p align="center">
54
- <a href="https://youtu.be/XLaa8FHSQtc" target="_blank">
55
- <img src="assets/screenshot.png" alt="HyperView Screenshot" width="100%">
54
+ <a href="https://huggingface.co/spaces/hyper3labs/HyperView" target="_blank">
55
+ <img src="https://raw.githubusercontent.com/Hyper3Labs/HyperView/main/assets/screenshot.png" alt="HyperView Screenshot" width="100%">
56
56
  </a>
57
57
  <br>
58
- <a href="https://youtu.be/XLaa8FHSQtc" target="_blank">Watch the Demo Video</a>
58
+ <a href="https://huggingface.co/spaces/hyper3labs/HyperView" target="_blank">Try the live demo on HuggingFace Spaces</a>
59
59
  </p>
60
60
 
61
61
  ---
@@ -63,10 +63,16 @@ Description-Content-Type: text/markdown
63
63
  ## Features
64
64
 
65
65
  - **Dual-Panel UI**: Image grid + scatter plot with bidirectional selection
66
- - **Euclidean/Poincaré Toggle**: Switch between standard 2D UMAP and Poincaré disk visualization
66
+ - **Multi-Layout Visualizations**: Explore Euclidean, Poincare, and spherical layouts in 2D or 3D with UMAP or PCA projections
67
67
  - **HuggingFace Integration**: Load datasets directly from HuggingFace Hub
68
68
  - **Fast Embeddings**: Uses EmbedAnything for CLIP-based image embeddings
69
69
 
70
+ ## Updates
71
+
72
+ - **01-02-26** — [The Geometry of Image Embeddings, Hands-on Coding Workshop](https://www.meetup.com/berlin-computer-vision-group/events/312927919/) (Berlin Computer Vision Group)
73
+ - **17-01-26** — [The Geometry of Image Embeddings, Hands-on Coding Workshop, Part I](https://www.meetup.com/berlin-computer-vision-group/events/312636174/) (Berlin Computer Vision Group)
74
+ - **11-12-25** — [Hacker Room Demo Day #2](https://youtu.be/KnOiaNXN3Q0?t=2483) (Merantix AI Campus Berlin) — First version of HyperView presented
75
+
70
76
  ## Quick Start
71
77
 
72
78
  **Docs:** [docs/datasets.md](docs/datasets.md) · [docs/colab.md](docs/colab.md) · [CONTRIBUTING.md](CONTRIBUTING.md) · [TESTS.md](TESTS.md)
@@ -74,26 +80,45 @@ Description-Content-Type: text/markdown
74
80
  ### Installation
75
81
 
76
82
  ```bash
77
- git clone https://github.com/Hyper3Labs/HyperView.git
78
- cd HyperView
79
-
80
- # Install with uv
81
- uv venv .venv
82
- source .venv/bin/activate
83
- uv pip install -e ".[dev]"
83
+ uv pip install hyperview
84
84
  ```
85
85
 
86
- ### Run the Demo
86
+ ### Run HyperView
87
87
 
88
88
  ```bash
89
- hyperview demo --samples 500
89
+ hyperview \
90
+ --dataset cifar10_demo \
91
+ --hf-dataset uoft-cs/cifar10 \
92
+ --split train \
93
+ --image-key img \
94
+ --label-key label \
95
+ --samples 500 \
96
+ --model openai/clip-vit-base-patch32 \
97
+ --layout euclidean \
98
+ --layout poincare
90
99
  ```
91
100
 
92
101
  This will:
93
- 1. Load 500 samples from CIFAR-100
94
- 2. Compute CLIP embeddings
95
- 3. Generate Euclidean and Poincaré visualizations
96
- 4. Start the server at **http://127.0.0.1:6262**
102
+ 1. Use dataset `cifar10_demo`
103
+ 2. Load up to 500 samples from CIFAR-10
104
+ 3. Compute CLIP embeddings
105
+ 4. Generate Euclidean and Poincare visualizations
106
+ 5. Start the server at **http://127.0.0.1:6262**
107
+
108
+ You can also launch with explicit dataset/model/projection args:
109
+
110
+ ```bash
111
+ hyperview \
112
+ --dataset imagenette_clip \
113
+ --hf-dataset fastai/imagenette \
114
+ --split train \
115
+ --image-key image \
116
+ --label-key label \
117
+ --samples 1000 \
118
+ --model openai/clip-vit-base-patch32 \
119
+ --method umap \
120
+ --layout euclidean
121
+ ```
97
122
 
98
123
  ### Python API
99
124
 
@@ -125,26 +150,19 @@ hv.launch(dataset) # Opens http://127.0.0.1:6262
125
150
 
126
151
  See [docs/colab.md](docs/colab.md) for a fast Colab smoke test and notebook-friendly launch behavior.
127
152
 
128
- ### Save and Load Datasets
153
+ ## Why Hyperbolic?
129
154
 
130
- ```python
131
- # Save dataset with embeddings
132
- dataset.save("my_dataset.json")
155
+ Traditional Euclidean embeddings struggle with hierarchical data. In Euclidean space, volume grows polynomially ($r^d$), causing **[Representation Collapse](https://hyper3labs.github.io/collapse)** where minority classes get crushed together.
133
156
 
134
- # Load later
135
- dataset = hv.Dataset.load("my_dataset.json")
136
- hv.launch(dataset)
137
- ```
157
+ **[Hyperbolic space](https://hyper3labs.github.io/warp)** (Poincaré disk) has exponential volume growth ($e^r$), naturally preserving hierarchical structure and keeping rare classes distinct.
138
158
 
139
- ## Why Hyperbolic?
159
+ **[Try the live demo on HuggingFace Spaces→](https://huggingface.co/spaces/hyper3labs/HyperView)**
140
160
 
141
- Traditional Euclidean embeddings struggle with hierarchical data. In Euclidean space, volume grows polynomially ($r^d$), causing **Representation Collapse** where minority classes get crushed together.
161
+ ## Community
142
162
 
143
- **Hyperbolic space** (Poincaré disk) has exponential volume growth ($e^r$), naturally preserving hierarchical structure and keeping rare classes distinct.
163
+ **Weekly Open Discussion** Every Tuesday at 15:00 UTC on [Discord](https://discord.gg/Az7k4Ure?event=1469730571440885944)
144
164
 
145
- <p align="center">
146
- <img src="assets/hyperview_infographic.png" alt="Euclidean vs Hyperbolic" width="100%">
147
- </p>
165
+ Join us to see the latest features demoed live, walk through new code, and get help with local setup. Whether you're a core maintainer or looking for your first contribution, everyone is welcome.
148
166
 
149
167
  ## Contributing
150
168
 
@@ -153,12 +171,7 @@ Development setup, frontend hot-reload, and backend API notes live in [CONTRIBUT
153
171
  ## Related projects
154
172
 
155
173
  - **hyper-scatter**: High-performance WebGL scatterplot engine (Euclidean + Poincaré) used by the frontend: https://github.com/Hyper3Labs/hyper-scatter
156
- - **hyper-models**: Non-Euclidean model zoo + ONNX exports (e.g. for hyperbolic VLM experiments): https://github.com/Hyper3Labs/hyper-models
157
-
158
- ## References
159
-
160
- - [Poincaré Embeddings for Learning Hierarchical Representations](https://arxiv.org/abs/1705.08039) (Nickel & Kiela, 2017)
161
- - [Hyperbolic Neural Networks](https://arxiv.org/abs/1805.09112) (Ganea et al., 2018)
174
+ - **hyper-models**: Non-Euclidean model zoo + ONNX exports : https://github.com/Hyper3Labs/hyper-models
162
175
 
163
176
  ## License
164
177
 
@@ -0,0 +1,132 @@
1
+ # HyperView
2
+
3
+ > **Open-source dataset curation + embedding visualization (Euclidean + Poincaré disk)**
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Hyper3Labs/HyperView) [![Open in HF Spaces](https://huggingface.co/datasets/huggingface/badges/resolve/main/open-in-hf-spaces-sm.svg)](https://huggingface.co/spaces/hyper3labs/HyperView) [![Discord](https://img.shields.io/badge/Discord-hyper%C2%B3labs-5865F2?logo=discord&logoColor=white)](https://discord.gg/Za3rBkTPSf)
6
+
7
+ <p align="center">
8
+ <a href="https://huggingface.co/spaces/hyper3labs/HyperView" target="_blank">
9
+ <img src="https://raw.githubusercontent.com/Hyper3Labs/HyperView/main/assets/screenshot.png" alt="HyperView Screenshot" width="100%">
10
+ </a>
11
+ <br>
12
+ <a href="https://huggingface.co/spaces/hyper3labs/HyperView" target="_blank">Try the live demo on HuggingFace Spaces</a>
13
+ </p>
14
+
15
+ ---
16
+
17
+ ## Features
18
+
19
+ - **Dual-Panel UI**: Image grid + scatter plot with bidirectional selection
20
+ - **Multi-Layout Visualizations**: Explore Euclidean, Poincare, and spherical layouts in 2D or 3D with UMAP or PCA projections
21
+ - **HuggingFace Integration**: Load datasets directly from HuggingFace Hub
22
+ - **Fast Embeddings**: Uses EmbedAnything for CLIP-based image embeddings
23
+
24
+ ## Updates
25
+
26
+ - **01-02-26** — [The Geometry of Image Embeddings, Hands-on Coding Workshop](https://www.meetup.com/berlin-computer-vision-group/events/312927919/) (Berlin Computer Vision Group)
27
+ - **17-01-26** — [The Geometry of Image Embeddings, Hands-on Coding Workshop, Part I](https://www.meetup.com/berlin-computer-vision-group/events/312636174/) (Berlin Computer Vision Group)
28
+ - **11-12-25** — [Hacker Room Demo Day #2](https://youtu.be/KnOiaNXN3Q0?t=2483) (Merantix AI Campus Berlin) — First version of HyperView presented
29
+
30
+ ## Quick Start
31
+
32
+ **Docs:** [docs/datasets.md](docs/datasets.md) · [docs/colab.md](docs/colab.md) · [CONTRIBUTING.md](CONTRIBUTING.md) · [TESTS.md](TESTS.md)
33
+
34
+ ### Installation
35
+
36
+ ```bash
37
+ uv pip install hyperview
38
+ ```
39
+
40
+ ### Run HyperView
41
+
42
+ ```bash
43
+ hyperview \
44
+ --dataset cifar10_demo \
45
+ --hf-dataset uoft-cs/cifar10 \
46
+ --split train \
47
+ --image-key img \
48
+ --label-key label \
49
+ --samples 500 \
50
+ --model openai/clip-vit-base-patch32 \
51
+ --layout euclidean \
52
+ --layout poincare
53
+ ```
54
+
55
+ This will:
56
+ 1. Use dataset `cifar10_demo`
57
+ 2. Load up to 500 samples from CIFAR-10
58
+ 3. Compute CLIP embeddings
59
+ 4. Generate Euclidean and Poincare visualizations
60
+ 5. Start the server at **http://127.0.0.1:6262**
61
+
62
+ You can also launch with explicit dataset/model/projection args:
63
+
64
+ ```bash
65
+ hyperview \
66
+ --dataset imagenette_clip \
67
+ --hf-dataset fastai/imagenette \
68
+ --split train \
69
+ --image-key image \
70
+ --label-key label \
71
+ --samples 1000 \
72
+ --model openai/clip-vit-base-patch32 \
73
+ --method umap \
74
+ --layout euclidean
75
+ ```
76
+
77
+ ### Python API
78
+
79
+ ```python
80
+ import hyperview as hv
81
+
82
+ # Create dataset
83
+ dataset = hv.Dataset("my_dataset")
84
+
85
+ # Load from HuggingFace
86
+ dataset.add_from_huggingface(
87
+ "uoft-cs/cifar100",
88
+ split="train",
89
+ max_samples=1000
90
+ )
91
+
92
+ # Or load from local directory
93
+ # dataset.add_images_dir("/path/to/images", label_from_folder=True)
94
+
95
+ # Compute embeddings and visualization
96
+ dataset.compute_embeddings(model="openai/clip-vit-base-patch32")
97
+ dataset.compute_visualization()
98
+
99
+ # Launch the UI
100
+ hv.launch(dataset) # Opens http://127.0.0.1:6262
101
+ ```
102
+
103
+ ### Google Colab
104
+
105
+ See [docs/colab.md](docs/colab.md) for a fast Colab smoke test and notebook-friendly launch behavior.
106
+
107
+ ## Why Hyperbolic?
108
+
109
+ Traditional Euclidean embeddings struggle with hierarchical data. In Euclidean space, volume grows polynomially ($r^d$), causing **[Representation Collapse](https://hyper3labs.github.io/collapse)** where minority classes get crushed together.
110
+
111
+ **[Hyperbolic space](https://hyper3labs.github.io/warp)** (Poincaré disk) has exponential volume growth ($e^r$), naturally preserving hierarchical structure and keeping rare classes distinct.
112
+
113
+ **[Try the live demo on HuggingFace Spaces→](https://huggingface.co/spaces/hyper3labs/HyperView)**
114
+
115
+ ## Community
116
+
117
+ **Weekly Open Discussion** — Every Tuesday at 15:00 UTC on [Discord](https://discord.gg/Az7k4Ure?event=1469730571440885944)
118
+
119
+ Join us to see the latest features demoed live, walk through new code, and get help with local setup. Whether you're a core maintainer or looking for your first contribution, everyone is welcome.
120
+
121
+ ## Contributing
122
+
123
+ Development setup, frontend hot-reload, and backend API notes live in [CONTRIBUTING.md](CONTRIBUTING.md).
124
+
125
+ ## Related projects
126
+
127
+ - **hyper-scatter**: High-performance WebGL scatterplot engine (Euclidean + Poincaré) used by the frontend: https://github.com/Hyper3Labs/hyper-scatter
128
+ - **hyper-models**: Non-Euclidean model zoo + ONNX exports : https://github.com/Hyper3Labs/hyper-models
129
+
130
+ ## License
131
+
132
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -98,9 +98,3 @@ ignore = ["E501"]
98
98
  [tool.pytest.ini_options]
99
99
  asyncio_mode = "auto"
100
100
  testpaths = ["tests"]
101
-
102
- [tool.uv.workspace]
103
- members = ["hyper_models"]
104
-
105
- [tool.uv.sources]
106
- hyper-models = { workspace = true }
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.1.1'
32
- __version_tuple__ = version_tuple = (0, 1, 1)
31
+ __version__ = version = '0.3.1'
32
+ __version_tuple__ = version_tuple = (0, 3, 1)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -7,6 +7,7 @@ import threading
7
7
  import time
8
8
  import webbrowser
9
9
  from dataclasses import dataclass
10
+ from importlib.util import find_spec
10
11
  from urllib.error import URLError
11
12
  from urllib.request import Request, urlopen
12
13
  from uuid import uuid4
@@ -55,6 +56,16 @@ def _read_health(url: str, timeout_s: float) -> _HealthResponse:
55
56
  )
56
57
 
57
58
 
59
+ def _resolve_default_launch_layout(dataset: Dataset) -> str:
60
+ spaces = dataset.list_spaces()
61
+
62
+ if any(space.geometry not in ("hyperboloid", "hypersphere") for space in spaces):
63
+ return "euclidean:2d"
64
+ if any(space.geometry == "hypersphere" for space in spaces):
65
+ return "spherical:3d"
66
+ return "poincare:2d"
67
+
68
+
58
69
  class Session:
59
70
  """A session for the HyperView visualizer."""
60
71
 
@@ -228,9 +239,9 @@ def launch(
228
239
  """Launch the HyperView visualization server.
229
240
 
230
241
  Note:
231
- HyperView's UI needs at least one 2D layout. If layouts are missing but
232
- embedding spaces exist, this function will compute a default layout
233
- automatically (Euclidean if any Euclidean space exists, otherwise Poincaré).
242
+ HyperView needs at least one visualization to display. If no layouts
243
+ exist yet but embedding spaces do, this function computes one default
244
+ layout automatically.
234
245
 
235
246
  Args:
236
247
  dataset: The dataset to visualize.
@@ -318,26 +329,26 @@ def launch(
318
329
  "port or stop the process listening on that port."
319
330
  )
320
331
 
321
- # The frontend requires 2D coords from /api/embeddings.
322
- # Ensure at least one layout exists; do not auto-generate optional geometries.
323
332
  layouts = dataset.list_layouts()
324
333
  spaces = dataset.list_spaces()
325
334
 
326
- if not spaces:
335
+ if not layouts and not spaces:
327
336
  raise ValueError(
328
- "HyperView launch requires 2D projections for the UI. "
329
- "No projections or embedding spaces were found. "
337
+ "HyperView launch requires at least one visualization or embedding space. "
338
+ "No visualizations or embedding spaces were found. "
330
339
  "Call `dataset.compute_embeddings()` and `dataset.compute_visualization()` "
331
- "before `hv.launch()`."
340
+ "or `dataset.set_coords()` before `hv.launch()`."
332
341
  )
333
342
 
334
343
  if not layouts:
335
- has_euclidean_space = any(s.geometry != "hyperboloid" for s in spaces)
336
- default_geometry = "euclidean" if has_euclidean_space else "poincare"
344
+ default_layout = _resolve_default_launch_layout(dataset)
337
345
 
338
- print(f"No layouts found. Computing {default_geometry} visualization...")
346
+ print(f"No visualizations found. Computing {default_layout} visualization...")
339
347
  # Let compute_visualization pick the most appropriate default space.
340
- dataset.compute_visualization(space_key=None, geometry=default_geometry)
348
+ dataset.compute_visualization(
349
+ space_key=None,
350
+ layout=default_layout,
351
+ )
341
352
 
342
353
  session = Session(dataset, host, port)
343
354
 
@@ -390,9 +401,6 @@ def _is_colab() -> bool:
390
401
  """Check if running inside a Google Colab notebook runtime."""
391
402
  if os.environ.get("COLAB_RELEASE_TAG"):
392
403
  return True
393
- try:
394
- import google.colab # type: ignore[import-not-found]
395
-
404
+ if find_spec("google.colab") is not None:
396
405
  return True
397
- except ImportError:
398
- return False
406
+ return False