Streamlit দিয়ে ডেটা অ্যাপ
এই পাঠে যা শিখবেন
- Streamlit-এর core concept — script reruns top-to-bottom
- প্রধান widget ও layout components
- Caching strategy — performance optimization
- Streamlit Cloud-এ deployment
১ · Streamlit-এর জন্ম ও দর্শন
২০১৯-এ StreamlitStreamlit২০১৯-এ Adrien Treuille, Thiago Teixeira ও Amanda Kelly-র শুরু করা open-source framework। ২০২২-এ Snowflake $৮০০ million-এ acquire করেছে। আজ data scientists-এর সবচেয়ে জনপ্রিয় web framework।-এর প্রতিষ্ঠাতারা CMU ও Google-এর data scientist ছিলেন। তারা দেখলেন প্রতিটি ML model-এর demo-র জন্য Flask/Django learn করতে হয় — যা data scientist-এর জন্য উপদ্রব। তাদের solution: "Python script যেমন আছে, তেমনই web app হয়ে যাক"।
Streamlit-এর core idea — script-as-app। প্রতিবার user widget-এ click করলে — পুরো script পুনরায় execute হয় top-to-bottom। কোনো callback, no event handler, no state management library।
১) Pure Python: HTML/CSS/JS লেখা না।
২) Reactive: widget বদলালে — auto rerun।
৩) Cached: heavy work একবার — তারপর memoized।
২ · প্রথম app — Hello World
Install: pip install streamlit। নিচের কোড app.py-তে save করুন, terminal-এ streamlit run app.py চালান।
import streamlit as st
import pandas as pd
import numpy as np
st.title('আমার প্রথম Streamlit app')
st.write('স্বাগতম! এটি ABCL TECH-এর demo।')
# একটা slider
n = st.slider('কতটি random সংখ্যা?', 10, 1000, 100)
data = np.random.randn(n)
st.line_chart(data)
st.write(f'Mean: {data.mean():.3f}, Std: {data.std():.3f}')
localhost:8501 খুলবে। Slider সরালে — chart ও mean instantly update। কোনো JavaScript নেই।
৩ · প্রধান widgets
st.text_input— text boxst.slider— numeric rangest.selectbox— dropdownst.multiselect— multiple selectionst.checkbox,st.radiost.date_input,st.time_inputst.file_uploader— CSV/image uploadst.button— action trigger
প্রতিটি widget-এর return value-ই Python variable। তাই use ১ লাইনে:
name = st.text_input('আপনার নাম')
if name:
st.write(f'হ্যালো, {name}!')
৪ · Layout — sidebar, columns, tabs
import streamlit as st
st.set_page_config(page_title='Sales Dashboard', layout='wide')
st.title('Daraz BD — Sales Dashboard')
# Sidebar — filter
with st.sidebar:
st.header('Filter')
region = st.selectbox('Region', ['All','Dhaka','Chattogram','Sylhet'])
date_range = st.date_input('Date range', [])
# Main — columns
col1, col2, col3 = st.columns(3)
col1.metric('Revenue', '৳ ১২ কোটি', '+১২%')
col2.metric('Orders', '৪৫,৩২০', '+৮%')
col3.metric('AOV', '৳ ২,৬৫০', '-২%')
# Tabs
tab1, tab2, tab3 = st.tabs(['Overview','Trend','Top Products'])
with tab1:
st.write('সারসংক্ষেপ এখানে...')
with tab2:
st.line_chart([10,20,15,25,30])
with tab3:
st.bar_chart([100,80,60,40])
st.set_page_config(layout='wide') — full-width। st.metric KPI card built-in। st.tabs — chart organize।
৫ · Caching — performance-এর গোপন রহস্য
Streamlit-এর script প্রতিবার rerun — মানে যদি ১০ MB CSV load করেন, প্রতিটি widget-এ ১০ MB load হবে। সমাধান: @st.cache_data decorator।
import streamlit as st
import pandas as pd
@st.cache_data
def load_data():
# heavy operation — শুধু একবার চলবে
return pd.read_csv('big_file.csv')
@st.cache_resource
def load_model():
# ML model — singleton
import joblib
return joblib.load('model.pkl')
df = load_data()
model = load_model()
st.write(f'লোড হয়েছে {len(df)} রো')
n = st.slider('Top N', 1, 100, 10)
st.dataframe(df.head(n)) # rerun-এ — load_data() cache থেকে instant
cache_data — DataFrame, dict, list। cache_resource — model, DB connection (singleton)।
৬ · Session state — widget-এর বাইরে memory
Streamlit-এর script rerun মানে — সাধারণ Python variable হারিয়ে যায়। যদি counter বানাতে চান (button-এ চাপলে +১) — st.session_state লাগবে।
if 'count' not in st.session_state:
st.session_state.count = 0
if st.button('+1'):
st.session_state.count += 1
st.write(f'Count: {st.session_state.count}')
৭ · Plotly + Streamlit — KPI app
import streamlit as st
import pandas as pd
import plotly.express as px
@st.cache_data
def get_sales():
return pd.DataFrame({
'month': ['Jan','Feb','Mar','Apr','May','Jun'],
'Dhaka': [120, 135, 150, 145, 170, 195],
'Chattogram': [80, 90, 100, 95, 110, 130],
'Sylhet': [40, 45, 50, 48, 55, 65]
})
st.title('🛍️ Sales Dashboard')
df = get_sales()
regions = st.multiselect('Region',
['Dhaka','Chattogram','Sylhet'],
default=['Dhaka','Chattogram'])
if regions:
long_df = df.melt(id_vars='month',
value_vars=regions,
var_name='region',
value_name='sales')
fig = px.line(long_df, x='month', y='sales', color='region',
markers=True, title='মাসিক বিক্রি')
st.plotly_chart(fig, use_container_width=True)
total = long_df['sales'].sum()
st.metric('মোট বিক্রি (নির্বাচিত)', f'৳ {total} কোটি')
else:
st.warning('কমপক্ষে একটি region বেছে নিন')
৮ · Streamlit Cloud-এ deployment
Streamlit Cloud (share.streamlit.io) — ফ্রি hosting:
requirements.txt-এ dependency লিস্ট:streamlit, pandas, plotly।- GitHub repo-এ push।
- share.streamlit.io-এ login → "New app" → repo + branch + file।
- ~১ মিনিটে live URL:
your-app.streamlit.app।
৯ · Streamlit-এর সীমাবদ্ধতা
- Custom HTML/CSS limited: brand-heavy site-এ React/Next.js better।
- Authentication: built-in nেই — Streamlit Cloud-এ paid feature।
- Multi-user state: session_state per-user — global shared state কঠিন।
- Mobile UX: ঠিকঠাক — কিন্তু native mobile app feel না।
- Real-time updates: WebSocket-based, কিন্তু sub-second ধীর।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ Streamlit বনাম Dash বনাম Flask — কোন সিচুয়েশনে কোনটা? Bangladesh-এ একটি analytics startup-এর জন্য আপনি কী recommend করবেন?
Python data-app framework-এর তিন বড় খেলোয়াড় — সবার নিজস্ব sweet spot।
Streamlit (Snowflake-owned, Apache 2.0):
- সবচেয়ে সরল API — script-style।
- Data scientist-friendly — pandas/plotly direct।
- ৫ মিনিটে first app।
- Limited customization — opinionated layout।
- Best for: prototype, demo, internal tool, dashboard।
Dash (Plotly-owned, MIT):
- React under the hood — ২০১৭।
- Callback-based architecture — explicit reactivity।
- সম্পূর্ণ HTML/CSS control — custom CSS লেখা যায়।
- Multi-page, complex layout সহজ।
- Steeper learning curve।
- Best for: production dashboard, complex interactivity, white-label।
Flask (Pallets, BSD):
- General-purpose web framework — micro-framework।
- সম্পূর্ণ flexibility — কিন্তু সব নিজে।
- Frontend আলাদা — Jinja template বা React/Vue।
- API server, custom auth, complex business logic।
- Best for: production app, REST API, full-stack web।
Bangladesh startup recommendation:
- 0-1 stage (MVP): Streamlit। ১ developer, ১ সপ্তাহে demo। investor-pitch অগ্রাধিকার।
- 1-10 stage (early customer): Streamlit চালিয়ে যান। Streamlit Cloud paid plan ($20/mo) — auth + private app।
- 10-100 stage (scaling): Mixed — internal tool Streamlit, customer-facing Dash বা Next.js + Flask API।
- 100+ stage (mature): Streamlit internal use only। B2C product custom React/Next + FastAPI।
Real-world pattern:
- bKash analytics team — internal Streamlit dashboard।
- Pathao data team — early Streamlit, এখন Tableau Server।
- BJIT — client-deliverable Dash বা Power BI।
Decision framework:
- "Pure data scientist team?" → Streamlit।
- "Frontend dev আছে?" → Dash বা React+Flask।
- "৫ minute UI demo?" → Streamlit।
- "Multi-tenant, white-label?" → Dash + Flask।
- "১০-জন user-এর dashboard?" → Streamlit সহজে।
- "১,০০০-জন user concurrent?" → Streamlit hard, Flask বা Dash production-mode।
মূল উপলব্ধি: Streamlit dominant for internal/prototype, Dash for production dashboards, Flask for full-stack apps। Stage-অনুযায়ী evolve করুন।
প্র ০২ Streamlit-এর "rerun on every interaction" model — pros/cons কী? কখন এটা frustrating, কীভাবে handle করবেন?
Streamlit-এর core philosophy — কিন্তু এতে surprise আছে।
Pros:
- Mental model সরল: "script যেমন run হয়, app তেমন behave"।
- State management library নেই — Redux, Vuex avoid।
- Hot reload — file save → app update।
- Debug সহজ — print statement, breakpoint কাজ করে।
Cons:
- Heavy computation প্রতিবার — slow ছাড়া বাঁচার উপায় caching।
- External API call rerun-এ — quota exceed দ্রুত।
- Form-এ ৫ field — প্রতি field-এ rerun = ৫x compute।
- Side-effect (database write) trigger বুঝা কঠিন।
Frustrating scenarios:
(১) "Submit" button-এর আগে rerun:
- Form-এ name, email, age — type করার সাথে সাথে rerun।
- সমাধান:
st.form()wrapper — submit button-এই rerun।
with st.form('register'):
name = st.text_input('Name')
age = st.slider('Age', 18, 80)
submitted = st.form_submit_button('Submit')
if submitted:
st.write(f'{name}, {age}')
(২) Expensive API call:
- OpenAI API per-rerun — quickly $$$।
- সমাধান:
@st.cache_data(ttl=3600)— ১ ঘণ্টা cache। - বা
st.button('Fetch')— চাপলেই API call।
(৩) Counter increment:
- Naive
count = 0; if button: count+=1— কাজ করবে না। - সমাধান:
st.session_state.count।
(৪) Database write:
- "Save" button — কিন্তু form-এ অন্য widget-এ rerun-এ ও write?
- সমাধান: explicit
if st.button('Save'):guard। - Idempotency ensure — same data multiple write safe।
(৫) File upload:
- Upload-এর পর rerun-এ file আবার process?
- সমাধান: file hash cache key।
@st.cache_data
def process(file_bytes):
return pd.read_csv(io.BytesIO(file_bytes))
Mental shifts:
- "Function = pure computation" — side effect minimize।
- "Cache aggressive" — ভয় পেয়ে under-cache না।
- "Form for grouped input" — atomic update।
- "session_state for memory" — variable persistence।
Advanced: fragment (Streamlit 1.33+):
@st.fragment— শুধু এই function-এর part rerun।- Performance massive gain।
- Use sparingly — debugging complex।
মূল উপলব্ধি: Rerun model = Streamlit's superpower এবং Achilles heel। Mastery মানে কী cache, কী session_state, কী form — automatic বুঝা।
প্র ০৩ আপনার Streamlit dashboard ১০০ জন user concurrent চালাচ্ছেন — slow হচ্ছে। scaling-এর জন্য কী করবেন?
Streamlit-এর deployment-এ scaling একটি real challenge। Standard Streamlit single-process — built-in scaling সীমিত।
Bottleneck identification:
- প্রতিটি user → আলাদা session, আলাদা script execution।
- ৪-core machine, ১০০ concurrent — CPU-bound।
- Memory linear grow — leak ঝুঁকি।
Solution layers:
(১) Caching aggressive:
- সব expensive computation
@st.cache_data। - DB query cache — TTL set।
- ML model
@st.cache_resource(singleton)। - Result: first user slow, rest fast।
(২) Pre-aggregation:
- Real-time query — DB-এ heavy।
- Nightly batch job — pre-compute summary table।
- Streamlit query summary table —
SELECTinstant।
(৩) Multi-process deployment:
- Standard Streamlit — async-await, single Tornado server।
- Production: Streamlit + Nginx + multiple Gunicorn workers।
- Or: Streamlit-in-Snowflake (managed scale)।
(৪) Container orchestration:
- Docker image — Streamlit app।
- Kubernetes — auto-scale pod count।
- Load balancer — sticky session (একই user → একই pod)।
(৫) Architecture redesign:
- Backend আলাদা: FastAPI service for heavy compute।
- Streamlit thin layer — just UI।
- API caching, rate-limiting আলাদা।
(৬) Database optimization:
- Read replica — read traffic distribute।
- Connection pool —
SQLAlchemy। - Index missing? — slow query log analyze।
(৭) Streamlit Cloud limits:
- Free tier — ১ GB RAM, public app।
- Paid Cloud — শুধু private + auth, scaling limited।
- Heavy load — self-host AWS/GCP।
(৮) UX-level optimization:
- Lazy load tab — শুধু active tab compute।
- Pagination large dataframe।
- Spinner প্রদর্শন — perceived performance।
Capacity planning:
- প্রতি user ~১০০ MB RAM (cache সহ)।
- ৪ vCPU, ১৬ GB RAM machine — comfortably ৫০-১০০ user।
- ৫০০+ user — multi-instance অপরিহার্য।
Migration consideration:
- ১,০০০+ concurrent — Streamlit drop, Dash বা Next.js+API।
- Streamlit prototype-stage rocket fuel; massive scale wrong tool।
মূল উপলব্ধি: Scale Streamlit ১-১০০ user comfortable, ১০০-১০০০ effort, ১০০০+ different tool।
প্র ০৪ আপনার boss চান একটি ML model demo — input form, prediction, confidence score। Streamlit-এ design কেমন হবে? কী কী UX consideration?
ML model demo Streamlit-এর সবচেয়ে common use case। UX ঠিক হলে — non-technical stakeholder মুগ্ধ হবেন।
Layout design:
import streamlit as st
import joblib
import pandas as pd
@st.cache_resource
def load_model():
return joblib.load('credit_model.pkl')
model = load_model()
st.title('💰 Credit Score Predictor')
st.write('গ্রাহকের credit risk score ১ মিনিটে।')
# Sidebar — info
with st.sidebar:
st.header('About')
st.write('Model: Random Forest, AUC=0.87')
st.write('Trained: ১০০K Bangladesh credit records')
# Form-এ input grouped
with st.form('predict'):
st.subheader('গ্রাহকের তথ্য')
col1, col2 = st.columns(2)
with col1:
age = st.slider('বয়স', 18, 80, 30)
income = st.number_input('মাসিক আয় (BDT)', 0, 1000000, 35000)
with col2:
loans = st.slider('পূর্ব loans', 0, 10, 1)
defaults = st.slider('Default history', 0, 5, 0)
submitted = st.form_submit_button('Predict', type='primary')
if submitted:
X = pd.DataFrame([[age, income, loans, defaults]],
columns=['age','income','loans','defaults'])
pred = model.predict(X)[0]
proba = model.predict_proba(X)[0]
if pred == 1:
st.error(f'❌ HIGH RISK ({proba[1]:.0%} confidence)')
else:
st.success(f'✅ LOW RISK ({proba[0]:.0%} confidence)')
# Feature importance
st.subheader('কেন এই prediction?')
imp = pd.DataFrame({
'feature': X.columns,
'value': X.values[0],
'importance': model.feature_importances_
}).sort_values('importance', ascending=False)
st.dataframe(imp, hide_index=True)
UX considerations:
(১) Form-based input:
- Submit button-এ rerun — wasted compute এড়ানো।
- সব field একসাথে valid — coherent prediction।
(২) Visual feedback:
st.error,st.success— color-coded।- Confidence percentage — uncertainty communicate।
- Emoji — friendly, instant recognition।
(৩) Explainability:
- Feature importance — কেন এই decision।
- SHAP values (advanced)।
- Counterfactual: "যদি income ৫০K হতো?" — slider দিয়ে interactive।
(৪) Confidence display:
- Probability bar — visual not just number।
- "Low risk: 78%, High risk: 22%"।
- Threshold explained — কোথায় low/high split।
(৫) Model info transparency:
- Sidebar-এ training data, accuracy, last-updated date।
- Trust building — non-technical user-এর জন্য essential।
(৬) Error handling:
- Invalid input — graceful message।
- Out-of-distribution warning ("আমাদের training-এ এই age range কম")।
(৭) Privacy:
- Input log করবেন কি? — consent disclaimer।
- Bangladesh DPA compliance।
(৮) Multi-row prediction:
st.file_uploader— CSV upload, batch predict।st.download_button— result CSV export।
(৯) A/B testing built-in:
- Model_v1 vs Model_v2 — radio button।
- Side-by-side prediction comparison।
(১০) Bangladesh-specific:
- BDT format — ১,০০,০০০ readable।
- Bengali label optional toggle।
- Mobile-responsive — অনেক user phone-এ।
Pre-launch checklist:
- Stress test — edge case input।
- Stakeholder demo before public।
- Monitoring — error rate log।
- Feedback button — "এই prediction কি ঠিক?"।
মূল উপলব্ধি: ML demo just accuracy-র না — explainability, trust, UX সব মিলে। Streamlit এই combination ১০০ লাইনে দেয়।
অনুশীলন
-
প্রথম app: একটি Streamlit app বানান — user-এর নাম input নেয়, একটি random সংখ্যা generate করে greet করে।
import streamlit as st import random st.title('Random Greet') name = st.text_input('আপনার নাম') if name: n = random.randint(1, 100) st.success(f'হ্যালো {name}! আজকের ভাগ্যের সংখ্যা: {n}') -
Cache + slider: ১ লাখ random number generate করুন (slow simulation)।
@st.cache_dataদিয়ে speed up করুন।import streamlit as st import numpy as np import time @st.cache_data def slow_generate(n, seed): time.sleep(2) # simulation np.random.seed(seed) return np.random.randn(n) st.title('Cache demo') seed = st.slider('Seed', 0, 100, 42) data = slow_generate(100000, seed) st.line_chart(data[:1000]) st.write(f'Mean: {data.mean():.4f}')Slider সরালে — প্রথমবার ২ সেকেন্ড, পরের বার একই seed-এ instant।
-
Deployment: উপরের app-কে Streamlit Cloud-এ deploy করার জন্য কী কী step?
- Local-এ test —
streamlit run app.py। requirements.txtবানান:streamlit==1.32.0,numpy।- GitHub repo বানান, push।
- share.streamlit.io-এ login।
- "New app" → repo + branch + file।
- ~১ মিনিটে live URL পাবেন।
সাধারণ ভুল:
requirements.txtmiss; secret (API key) GitHub-এ commit; absolute file path use। - Local-এ test —
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ২৭ · Tableau ও Power BI পরিচিতি পরবর্তী পাঠ Code-free dashboard tools — enterprise BI।
- পাঠ ২৫ · Plotly interactive chart আগের পাঠ Streamlit-এর সাথে মিলিয়ে দারুণ dashboard।
- পাঠ ২৯ · প্রজেক্ট: e-commerce ড্যাশবোর্ড এই পাঠের সাথে সম্পর্কিত Streamlit-এ full project।
- সব AI Courses দেখুন ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps।