An interactive data visualization platform built on SQLAlchemy and Druid.io
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Panoramix provides a Flask-based web interface with admin views for data source management, visualization endpoints, and user interaction. The interface is built using Flask-AppBuilder for consistent admin functionality.
The core Panoramix view class handles visualization requests and data exploration endpoints.
class Panoramix(BaseView):
"""
Main visualization controller for the web interface.
Provides endpoints for table and datasource visualization,
metadata management, and interactive data exploration.
"""
@expose("/table/<table_id>/")
def table(self, table_id):
"""
SQL table visualization endpoint.
Args:
table_id (str): ID of the table to visualize
Returns:
str: Rendered HTML page with visualization interface
"""
@expose("/datasource/<datasource_name>/")
def datasource(self, datasource_name):
"""
Druid datasource visualization endpoint.
Args:
datasource_name (str): Name of the datasource to visualize
Returns:
str: Rendered HTML page with visualization interface
"""
@expose("/refresh_datasources/")
def refresh_datasources(self):
"""
Refresh metadata for all Druid datasources.
Triggers synchronization of datasource metadata
from all configured Druid clusters.
Returns:
str: Success/failure message
"""
@expose("/autocomplete/<datasource>/<column>/")
def autocomplete(self, datasource, column):
"""
Autocomplete endpoint for column values.
Args:
datasource (str): Datasource name
column (str): Column name for value suggestions
Returns:
list: JSON list of suggested values
"""Flask-AppBuilder model views provide CRUD operations for managing data sources through the web interface.
class DatabaseView(ModelView):
"""
Admin view for managing SQL database connections.
Features:
- Create/edit database connections
- Test connectivity
- Manage connection parameters
- View connection status
"""
datamodel = SQLAInterface(Database)
list_columns = ['database_name', 'sqlalchemy_uri', 'created_by', 'created_on']
add_columns = ['database_name', 'sqlalchemy_uri', 'extra', 'cache_timeout']
edit_columns = add_columns
class ClusterModelView(ModelView):
"""
Admin view for managing Druid cluster connections.
Features:
- Configure cluster endpoints
- Test cluster connectivity
- Manage cluster metadata
- Monitor cluster status
"""
datamodel = SQLAInterface(Cluster)
list_columns = ['cluster_name', 'coordinator_host', 'broker_host', 'created_on']
add_columns = ['cluster_name', 'coordinator_host', 'coordinator_port',
'broker_host', 'broker_port']
edit_columns = add_columns
class TableView(ModelView):
"""
Admin view for managing SQL tables.
Features:
- Register tables from databases
- Configure table metadata
- Define metrics and columns
- Set access permissions
"""
datamodel = SQLAInterface(Table)
list_columns = ['table_link', 'database', 'owner', 'created_on']
add_columns = ['table_name', 'database', 'main_datetime_column', 'description']
edit_columns = add_columns
class DatasourceModelView(ModelView):
"""
Admin view for managing Druid datasources.
Features:
- Configure datasource metadata
- Define dimensions and metrics
- Set caching and permissions
- Sync from Druid clusters
"""
datamodel = SQLAInterface(Datasource)
list_columns = ['datasource_link', 'cluster', 'owner', 'created_on']
add_columns = ['datasource_name', 'cluster', 'description', 'is_featured']
edit_columns = add_columnsInline views provide embedded editing capabilities for related objects.
class TableColumnInlineView(CompactCRUDMixin, ModelView):
"""
Inline view for editing table columns.
Allows editing column metadata directly within
the table edit interface.
"""
datamodel = SQLAInterface(TableColumn)
edit_columns = ['column_name', 'verbose_name', 'type', 'groupby', 'filterable']
class ColumnInlineView(CompactCRUDMixin, ModelView):
"""
Inline view for editing datasource dimensions.
Allows editing dimension metadata directly within
the datasource edit interface.
"""
datamodel = SQLAInterface(Column)
edit_columns = ['column_name', 'verbose_name', 'type', 'groupby', 'filterable']
class SqlMetricInlineView(CompactCRUDMixin, ModelView):
"""Inline view for editing SQL metrics"""
datamodel = SQLAInterface(SqlMetric)
edit_columns = ['metric_name', 'verbose_name', 'expression', 'metric_type']
class MetricInlineView(CompactCRUDMixin, ModelView):
"""Inline view for editing Druid metrics"""
datamodel = SQLAInterface(Metric)
edit_columns = ['metric_name', 'verbose_name', 'metric_type', 'json']class DeleteMixin:
"""
Mixin providing bulk delete functionality.
Adds bulk delete operations to model views
with proper permission checking.
"""
def validate_json(form, field):
"""
Validator for JSON fields in forms.
Args:
form: WTForms form instance
field: Form field to validate
Raises:
ValidationError: If field contains invalid JSON
"""@app.route('/health')
def health():
"""
System health check endpoint.
Returns:
dict: System status and health information
"""
@app.route('/ping')
def ping():
"""
Simple ping endpoint for connectivity testing.
Returns:
str: "OK" response
"""# SQL table visualization
# GET /panoramix/table/1/
# Opens visualization interface for table with ID 1
# Druid datasource visualization
# GET /panoramix/datasource/events/
# Opens visualization interface for 'events' datasource# Get autocomplete suggestions for a column
# GET /panoramix/autocomplete/events/country/
# Returns: ["US", "UK", "CA", "DE", "FR", ...]
# Client-side JavaScript usage
fetch('/panoramix/autocomplete/sales/product_category/')
.then(response => response.json())
.then(values => {
// Populate autocomplete dropdown
updateAutocompleteOptions(values);
});# Refresh all datasource metadata
# GET /panoramix/refresh_datasources/
# Triggers cluster.refresh_datasources() for all clustersPanoramix uses Jinja2 templates for rendering the web interface:
# Base templates
'panoramix/base.html' # Main application layout
'index.html' # Home page template
'panoramix/viz_table.html' # Table visualization template
# Form templates
'appbuilder/general/model/edit.html' # Edit forms
'appbuilder/general/model/list.html' # List viewsThe web interface integrates with Flask-AppBuilder's security system:
# Permission strings
'datasource_access' # Access to specific datasources
'database_access' # Access to specific databases
'can_edit' # Edit permissions
'can_delete' # Delete permissions# Static file paths
'/static/chaudron_white.png' # Application icon
'/static/css/' # Stylesheets
'/static/js/' # JavaScript files
'/static/img/' # Images and iconsThe web interface provides a complete admin experience for managing data sources and an intuitive visualization interface for data exploration and analysis.
Install with Tessl CLI
npx tessl i tessl/pypi-panoramix