An interactive data visualization platform built on SQLAlchemy and Druid.io
npx @tessl/cli install tessl/pypi-panoramix@0.2.0Panoramix is an interactive data visualization platform built on SQLAlchemy and Druid.io. It provides a web-based interface for querying and visualizing data from various databases, with support for both SQL databases and Druid real-time analytics. Panoramix serves as the foundation for what would later become Apache Superset.
pip install panoramiximport panoramixMain application objects:
from panoramix import app, db, appbuilderData models:
from panoramix.models import Database, Table, Cluster, DatasourceVisualizations:
from panoramix.viz import TableViz, TimeSeriesViz, BubbleViz, viz_typesConfiguration:
from panoramix.config import ROW_LIMIT, PANORAMIX_WEBSERVER_PORTimport panoramix
from panoramix.models import Database, Table
# Start the web application
# panoramix.app.run()
# Connect to a database
db = Database(
database_name='my_database',
sqlalchemy_uri='sqlite:///my_data.db'
)
# Create a table reference
table = Table(
table_name='sales_data',
database=db,
main_datetime_column='created_at'
)
# Query the table
result = table.query(
groupby=['product'],
metrics=['sum__amount'],
granularity='day'
)
print(result.df) # Pandas DataFrame with resultsPanoramix includes a command line interface for starting the web server:
# Install and create admin user
pip install panoramix
fabmanager create-admin --app panoramix
# Start the development server
panoramix
# The server will be available at http://localhost:8088Panoramix follows a modular architecture centered around data sources and visualizations:
The platform provides a semantic layer that abstracts database specifics, allowing users to create metrics, filters, and visualizations without writing SQL directly.
SQL database and Druid cluster connection management, including database registration, table discovery, and metadata synchronization.
class Database(Model, AuditMixin):
def get_sqla_engine(self): ...
def get_table(self, table_name): ...
class Cluster(Model, AuditMixin):
def get_pydruid_client(self): ...
def refresh_datasources(self): ...SQL table management with query capabilities, metrics definition, and data exploration for traditional databases.
class Table(Model, Queryable, AuditMixin):
def query(self, groupby=None, metrics=None, granularity=None,
since=None, until=None, row_limit=None, **kwargs): ...
def fetch_metadata(self): ...Druid datasource management for real-time analytics, including dimension and metric configuration, and high-performance querying.
class Datasource(Model, AuditMixin, Queryable):
def query(self, groupby=None, metrics=None, granularity=None,
since=None, until=None, row_limit=None, **kwargs): ...
def get_metric_obj(self, metric_name): ...Comprehensive visualization system with multiple chart types, dynamic form generation, and chart rendering capabilities.
class BaseViz:
def bake_query(self): ...
def query_obj(self): ...
def render(self): ...
# Available chart types
viz_types = OrderedDict([
('table', TableViz),
('line', TimeSeriesViz),
('area', TimeSeriesAreaViz),
('bar', TimeSeriesBarViz),
('pie', DistributionPieViz),
('bubble', BubbleViz),
# ... and more
])Flask-based web interface with admin views for data source management and main visualization endpoints.
class Panoramix(BaseView):
@expose("/table/<table_id>/")
def table(self, table_id): ...
@expose("/datasource/<datasource_name>/")
def datasource(self, datasource_name): ...
@expose("/autocomplete/<datasource>/<column>/")
def autocomplete(self, datasource, column): ...Application configuration options, utility functions for date/time parsing, and helper functions for common operations.
# Configuration constants
ROW_LIMIT = 5000
PANORAMIX_WEBSERVER_PORT = 8088
APP_NAME = "Panoramix"
# Utility functions
def parse_human_datetime(s): ...
def parse_human_timedelta(s): ...class QueryResult:
"""Named tuple containing query results"""
df: pandas.DataFrame # Query results as DataFrame
query: str # Executed query string
duration: float # Query execution time in seconds
class AuditMixin:
"""Mixin providing audit fields for models"""
created_on: datetime.datetime
changed_on: datetime.datetime
created_by: User
changed_by: User
class Queryable:
"""Base mixin for queryable data sources"""
@property
def column_names(self) -> List[str]: ...
@property
def groupby_column_names(self) -> List[str]: ...
@property
def filterable_column_names(self) -> List[str]: ...