Add configurable OpenSearch feature and UI improvements
All checks were successful
Security Scan / security (pull_request) Successful in 49s
Security Scan / dependency-check (pull_request) Successful in 51s
Test Suite / lint (pull_request) Successful in 41s
Test Suite / test (3.11) (pull_request) Successful in 1m43s
Test Suite / build (pull_request) Successful in 37s

- Add MIT license with Austin Godber copyright
  - Implement optional OpenSearch feature toggle via EMBEDDINGBUDDY_OPENSEARCH_ENABLED
  - Disable OpenSearch by default in production for security
  - Add development environment flag to test OpenSearch disable state
  - Update about modal to open by default with improved content
  - Reorganize text input component: move model selection below text input
  - Conditionally show/hide OpenSearch tab and callbacks based on configuration
  - Update tooltips to reflect OpenSearch availability status
This commit is contained in:
2025-09-17 19:01:51 -07:00
parent 89dcafd311
commit 2f458884a2
10 changed files with 85 additions and 17 deletions

View File

@@ -85,6 +85,9 @@ class AppSettings:
GUNICORN_KEEPALIVE = int(os.getenv("GUNICORN_KEEPALIVE", "5"))
# OpenSearch Configuration
OPENSEARCH_ENABLED = (
os.getenv("EMBEDDINGBUDDY_OPENSEARCH_ENABLED", "True").lower() == "true"
)
OPENSEARCH_DEFAULT_SIZE = 100
OPENSEARCH_SAMPLE_SIZE = 5
OPENSEARCH_CONNECTION_TIMEOUT = 30

View File

@@ -82,19 +82,23 @@ class DataProcessingCallbacks:
)
def render_tab_content(active_tab):
from ...ui.components.datasource import DataSourceComponent
from ...config.settings import AppSettings
datasource = DataSourceComponent()
if active_tab == "opensearch-tab":
if active_tab == "opensearch-tab" and AppSettings.OPENSEARCH_ENABLED:
return [datasource.create_opensearch_tab()]
elif active_tab == "text-input-tab":
return [datasource.create_text_input_tab()]
else:
return [datasource.create_file_upload_tab()]
# Register callbacks for both data and prompts sections
self._register_opensearch_callbacks("data", self.opensearch_client_data)
self._register_opensearch_callbacks("prompts", self.opensearch_client_prompts)
# Register callbacks for both data and prompts sections (only if OpenSearch is enabled)
if AppSettings.OPENSEARCH_ENABLED:
self._register_opensearch_callbacks("data", self.opensearch_client_data)
self._register_opensearch_callbacks(
"prompts", self.opensearch_client_prompts
)
# Register collapsible section callbacks
self._register_collapse_callbacks()

View File

@@ -5,9 +5,31 @@ import dash_bootstrap_components as dbc
class AboutComponent:
def _get_about_content(self):
return """
# 🔍 Interactive Embedding Visualization
# 🔍 Interactive Embedding Vector Visualization
EmbeddingBuddy is a web application for interactive exploration and
visualization of embedding vectors through dimensionality reduction techniques
(PCA, t-SNE, UMAP).
You have two ways to get started:
1. Generate embeddings directly in the browser if it supports WebGPU.
2. Upload your NDJSON file containing embedding vectors and metadata.
## Generating Embeddings in Browser
1. Expand the "Generate Embeddings" section.
2. Input your text data (one entry per line).
1. Optionally you can use the built in sample data by clicking "Load Sample Data" button.
3. Click "Generate Embeddings" to create vectors using a pre-trained model.
## NDJSON File Format
```json
{"id": "doc_001", "embedding": [0.1, -0.3, 0.7, ...], "text": "Sample text content", "category": "news", "subcategory": "politics", "tags": ["election", "politics"]}
{"id": "doc_002", "embedding": [0.2, -0.1, 0.9, ...], "text": "Another example", "category": "review", "subcategory": "product", "tags": ["tech", "gadget"]}
```
EmbeddingBuddy is a modular Python Dash web application for interactive exploration and visualization of embedding vectors through dimensionality reduction techniques (PCA, t-SNE, UMAP).
## ✨ Features
@@ -35,7 +57,7 @@ EmbeddingBuddy is a modular Python Dash web application for interactive explorat
return dbc.Modal(
[
dbc.ModalHeader(
dbc.ModalTitle("About EmbeddingBuddy"),
dbc.ModalTitle("Welcome to EmbeddingBuddy"),
close_button=True,
),
dbc.ModalBody(
@@ -53,7 +75,7 @@ EmbeddingBuddy is a modular Python Dash web application for interactive explorat
),
],
id="about-modal",
is_open=False,
is_open=True,
size="lg",
)

View File

@@ -1,6 +1,7 @@
from dash import dcc, html
import dash_bootstrap_components as dbc
from .upload import UploadComponent
from embeddingbuddy.config.settings import AppSettings
class DataSourceComponent:
@@ -9,15 +10,18 @@ class DataSourceComponent:
def create_tabbed_interface(self):
"""Create tabbed interface for different data sources."""
tabs = [dbc.Tab(label="File Upload", tab_id="file-tab")]
# Only add OpenSearch tab if enabled
if AppSettings.OPENSEARCH_ENABLED:
tabs.append(dbc.Tab(label="OpenSearch", tab_id="opensearch-tab"))
return dbc.Card(
[
dbc.CardHeader(
[
dbc.Tabs(
[
dbc.Tab(label="File Upload", tab_id="file-tab"),
dbc.Tab(label="OpenSearch", tab_id="opensearch-tab"),
],
tabs,
id="data-source-tabs",
active_tab="file-tab",
)

View File

@@ -3,6 +3,7 @@ import dash_bootstrap_components as dbc
from .upload import UploadComponent
from .datasource import DataSourceComponent
from .textinput import TextInputComponent
from embeddingbuddy.config.settings import AppSettings
class SidebarComponent:
@@ -102,6 +103,10 @@ class SidebarComponent:
)
def _create_data_sources_item(self):
tooltip_text = "Load existing embeddings: upload files"
if AppSettings.OPENSEARCH_ENABLED:
tooltip_text += " or read from OpenSearch"
return dbc.AccordionItem(
[
self.datasource_component.create_error_alert(),
@@ -115,7 +120,7 @@ class SidebarComponent:
className="fas fa-info-circle text-muted",
style={"cursor": "pointer"},
id="load-embeddings-info-icon",
title="Load existing embeddings: upload files or read from OpenSearch",
title=tooltip_text,
),
]
),

View File

@@ -16,14 +16,14 @@ class TextInputComponent:
"""Create the complete text input interface with model selection and processing options."""
return html.Div(
[
# Model selection section
self._create_model_selection(),
html.Hr(),
# Text input section
self._create_text_input_area(),
# Text action buttons
self._create_text_action_buttons(),
html.Hr(),
# Model selection section
self._create_model_selection(),
html.Hr(),
# Processing options
self._create_processing_options(),
html.Hr(),