StreamLana
'Business Intelligence as Configuration' 🚀
Motivation
Think of Streamlit in Grafana style...
Build your BI dashboards with ease, using simple configuration files.
Live App & Examples:
Its deployed live at https://streamlana.streamlit.app/
For the live app - refer to 'demo' branch of this repo. (refer 'streamlana_demo.py')
Lets do Hello World app
- Install streamlana
pip install streamlana
mkdir page_configs
touch hello_world_app.yaml
touch hello_world_app.py
touch page_configs/stats.json
touch page_configs/about.json
- Define your pages in
hello_world_app.yaml
#hello_world_app.yaml
side_bar:
- heading: "Hello StreamLana"
pages:
- name: "Stats page"
enabled: True
anonymous: False
config_file_path: "page_configs/stats.json"
- name: "About page"
config_file_path: "page_configs/about.json"
enabled: True
anonymous: False
- Lets define page1 layout - number of rows, the widgets in each row, Query powering the widget, widget settings.
Lets do 1 row with 2 widgets in it -> page_configs/stats.json
{
"page_title": "Hello StreamLana",
"page_rows": [
{
"widgets_width_spec": [
0.4,0.6
],
"widgets_border": true,
"with_expander": {
"label": "2 widgets in 1st row, 40/60% width",
"expanded": true
},
"widgets_gap": "small",
"widgets_vertical_alignment": "top",
"widgets": [
{
"type": "dataframe",
"widget_enabled": true,
"query": "SELECT avg_spend,order_date FROM (SELECT order_date, RANDOM() * 1000 AS avg_spend FROM generate_series(CURRENT_DATE - INTERVAL 30 DAY, CURRENT_DATE, INTERVAL 1 DAY) AS t(order_date)) as sub",
"config": {
"column_order": [
"avg_spend",
"order_date"
]
}
},
{
"type": "line_chart",
"widget_enabled": true,
"query": "SELECT avg_spend,order_date FROM (SELECT order_date, RANDOM() * 1000 AS avg_spend FROM generate_series(CURRENT_DATE - INTERVAL 30 DAY, CURRENT_DATE, INTERVAL 1 DAY) AS t(order_date)) as sub",
"config": {
"x": "order_date",
"y": ["avg_spend"],
"title": "avgSpend Over Time"
}
}
]
}
]
}
- Lets define page2 layout - number or rows, the widgets in each row, query powering the widget, widget settings.
Lets keep this simple 1 widget and 1 row -> page_configs/about.json
{
"page_title": "About StreamLana",
"page_rows": [
{
"widgets_width_spec": [1],
"widgets": [{"type": "title", "config": {"body": "Business Intelligence as Configuration"}}]
}
]
}
- Few lines of code for the main app ->
hello_world_app.py
# hello_world_app.py
import logging
import duckdb
from streamlana import side_bar_util
from streamlana.side_bar_util import load_side_bar_config_yaml, render_side_bar_pages
# ✅ First thing to do, set page layout of streamlit
side_bar_util.set_page_layout(layout="wide")
# logging level
logging.basicConfig(level=logging.INFO)
# ✅ Load side bar configuration from YAML file
side_bar_config = load_side_bar_config_yaml("hello_world_app.yaml")
# ✅ Create DuckDB connection (do your setup with it)
con = duckdb.connect()
# ✅ Render side bar pages based on the configuration
try:
render_side_bar_pages(side_bar_config, con)
finally:
# ✅ Close the DuckDB connection
con.close()
logging.info("DuckDB connection closed.")
- Run the app
streamlit run hello_world_app.py
Widget Library
Currently, we support the following widgets: (see examples with their configs in live demo)
- st.dataframe
- st.line_chart
- st.area_chart
- st.bar_chart
- st.pie_chart
- st.json
- st.title
- st.metric
- st.text
- st.markdown
- st.image
- st.map
- st.empty
- st.selectbox
- st.header
Adding new widgets is easy, just add a new widget type in the chart_helpers.py.
ex: implement 'render_<chart_name>(data:pd.DataFrame, config_dict: dict)'
data comes from the duckdb sql query u configure.
The Design
- Streamlana supports Multipage app (based on st.navigation).
- We start off with the side bar configuration file, which defines the pages and their corresponding configuration files.
- In the sidebar configuration file, each page can be enabled or disabled, and it can have a title. Optionally it can have anonymous page id. (refer to demo)
- The page configuration file defines the layout of the page.
- The page layout is defined in terms of rows, each row can have multiple widgets + a page can have optional title.
- Each row has "widgets_width_spec", which is a list of widths for each widget in the row, summing up to 1.0 (100%) - similar to st.columns 'spec'.
- Each row can have "widgets_border" to add a border around the widgets in the row. (similar to st.columns with border)
- Each row can have a Expander (similar to st.expander) to group widgets together in the row, with optional label and expanded state. (Set to null if not needed)
- Each Row can have a gap between widgets, and vertical alignment of widgets. (similar to st.columns with gap and vertical alignment)
- Each row has a list of widgets.
- Each widget has a type, query (duckdb), and configuration. It can be enabled/disabled too.
- Most of the configuration parameters for a widget are the same as those provided by Streamlit. (see examples in live demo)
Metadata
Release files for streamlana 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| streamlana-0.1.4.tar.gz | 45.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| streamlana-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 88.3 kB
Release files / streamlana-0.1.4.tar.gz
| Download URL | streamlana-0.1.4.tar.gz |
|---|---|
| Size | 45.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
43db1646e82d8a14dae3efe4e36f7a29d2aa2232e9bba9617e39d6cba4f21905
|
|
BLAKE2b-256 checksum How to use checksums |
a12961ed22bb94acd6c4a14f989cdd6d3cbdba41c3e2d7dd725979cbd0599d63
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.6.1 CPython/3.11.13 Darwin/24.5.0
|
Release files / streamlana-0.1.4-py3-none-any.whl
| Download URL | streamlana-0.1.4-py3-none-any.whl |
|---|---|
| Size | 43.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bd89babcf145e722e824bd4b13630049c4dd72a9e4287f4f8dfd08b8a2d2b643
|
|
BLAKE2b-256 checksum How to use checksums |
961dc664cefebd4218cfc4fd707f621f616ba363a8096ae7656623b51ae06d22
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.6.1 CPython/3.11.13 Darwin/24.5.0
|