Taipy: Full-Stack Framework for Building Production-Ready AI Web Applications

# Taipy: Framework Full-Stack untuk Membangun Aplikasi Web AI yang Production-Ready Membangun aplikasi AI yang siap produksi sering kali membutuhkan kombinasi berbagai tools: framework frontend untuk...

By Ruby Abdullah · · tutorial
TaipyWeb FrameworkAI ApplicationDashboardPython

Taipy: Full-Stack Framework for Building Production-Ready AI Web Applications

Building production-ready AI applications often requires a combination of various tools: a frontend framework for UI, a backend for business logic, and pipeline orchestration for data processing. Taipy offers an all-in-one solution that enables data scientists and ML engineers to build complete AI web applications using only Python.

In this tutorial, we will explore Taipy in depth, from installation, GUI building, pipeline orchestration, to deploying a production-ready ML dashboard application.

What Is Taipy?

Taipy is an open-source Python framework designed specifically for building data and AI applications. Unlike Streamlit or Gradio, which focus on prototyping, Taipy is designed for production-grade applications with comprehensive features:

  • Taipy GUI: Build interactive web interfaces with visual elements
  • Taipy Core: Manage data pipelines, scenarios, and task scheduling
  • Multi-page support: Multi-page applications with routing
  • State management: Robust state management for complex applications
  • Scalability: Support for concurrent users and heavy workloads

Installation and Setup

Installing Taipy

pip install taipy

For installation with additional dependencies:

# With PostgreSQL support

pip install taipy[postgres]

With all extras

pip install taipy[all]

Verify installation

python -c "import taipy; print(taipy.version)"

Project Structure

taipy-ml-dashboard/

├── main.py

├── config.py

├── pages/

│ ├── home.py

│ ├── dashboard.py

│ ├── predictions.py

│ └── settings.py

├── algorithms/

│ ├── preprocessing.py

│ ├── training.py

│ └── inference.py

├── data/

│ └── dataset.csv

└── requirements.txt

Taipy GUI: Building Web Interfaces

Basic Visual Elements

Taipy uses a simple Markdown-like syntax to define UI components:

from taipy.gui import Gui

State variables

name = "Data Scientist"

message = "Welcome to Taipy!"

Page definition with Markdown syntax

page = """

AI Dashboard Application

Hello, <|{name}|>!

<|{message}|text|>

<|Click Me|button|onaction=onbuttonclick|>

"""

def onbuttonclick(state):

state.message = f"Hello {state.name}! Dashboard is ready to use."

if name == "main":

Gui(page=page).run(title="AI Dashboard", port=5000)

Input and Form Elements

from taipy.gui import Gui

State variables

username = ""

age = 25

role = "Data Scientist"

roles = ["Data Scientist", "ML Engineer", "Data Analyst", "AI Researcher"]

isactive = True

page = """

AI Team Registration Form

<|{username}|input|label=Full Name|>

<|{age}|slider|min=18|max=65|label=Age|>

<|{role}|selector|lov={roles}|dropdown|label=Select Role|>

<|{isactive}|toggle|label=Active Status|>

<|Submit|button|onaction=onsubmit|>

Input Summary:

  • Name: <|{username}|text|>
  • Age: <|{age}|text|>
  • Role: <|{role}|text|>
  • Active: <|{isactive}|text|>
"""

def onsubmit(state):

print(f"Registered: {state.username}, {state.age}, {state.role}")

Gui(page=page).run()

State Management

Taipy has a powerful state management system. Each user session has an independent state:

from taipy.gui import Gui, State

counter = 0

history = []

def onincrement(state: State):

state.counter += 1

state.history = state.history + [f"Counter: {state.counter}"]

def onreset(state: State):

state.counter = 0

state.history = []

def oninit(state: State):

"""Called when a new user opens the application"""

state.counter = 0

state.history = []

page = """

State Management Demo

Counter: <|{counter}|text|>

<|Increment|button|onaction=onincrement|>

<|Reset|button|onaction=onreset|>

History:

<|{history}|text|>

"""

Gui(page=page).run()

Callbacks and Event Handling

from taipy.gui import Gui, notify

datasetpath = ""

dataloaded = False

rowcount = 0

columns = []

def onfileupload(state, varname, payload):

"""Callback when file is uploaded"""

import pandas as pd

filepath = payload["args"][0]["path"]

state.datasetpath = filepath

try:

df = pd.readcsv(filepath)

state.rowcount = len(df)

state.columns = list(df.columns)

state.dataloaded = True

notify(state, "success", f"Dataset loaded successfully: {state.rowcount} rows")

except Exception as e:

notify(state, "error", f"Failed to load dataset: {str(e)}")

page = """

Upload Dataset

<|{datasetpath}|fileselector|extensions=.csv,.xlsx|onaction=onfileupload|label=Upload Dataset|>

<|part|render={dataloaded}|

Dataset Information

  • Number of rows: <|{rowcount}|text|>
  • Columns: <|{columns}|text|>
|>

"""

Gui(page=page).run()

Charts and Visualization

Taipy provides powerful chart components based on Plotly:

from taipy.gui import Gui

import pandas as pd

import numpy as np

Generate sample data

np.random.seed(42)

dates = pd.daterange("2025-01-01", periods=100, freq="D")

data = pd.DataFrame({

"Date": dates,

"Accuracy": np.cumsum(np.random.randn(100) 0.5) + 85,

"Loss": np.abs(np.cumsum(np.random.randn(100) 0.3)) + 0.1,

"Predictions": np.random.randint(100, 1000, 100),

})

Confusion matrix data

confusiondata = pd.DataFrame({

"x": ["Positive", "Positive", "Negative", "Negative"],

"y": ["Positive", "Negative", "Positive", "Negative"],

"z": [850, 50, 30, 870],

})

page = """

ML Metrics Dashboard

Model Accuracy Trend

<|{data}|chart|type=scatter|x=Date|y=Accuracy|mode=lines+markers|title=Model Accuracy Over Time|>

Training Loss

<|{data}|chart|type=scatter|x=Date|y=Loss|mode=lines|color=#ff6347|title=Training Loss|>

Prediction Distribution

<|{data}|chart|type=histogram|x=Predictions|title=Prediction Count Distribution|>

Confusion Matrix

<|{confusiondata}|chart|type=heatmap|x=x|y=y|z=z|title=Confusion Matrix|>

"""

Gui(page=page).run()

Taipy Core: Pipeline and Scenario Management

Taipy Core is the engine for managing data pipelines and business scenarios:

from taipy.core import Config, Scope

import pandas as pd

from sklearn.ensemble import RandomForestClassifier

from sklearn.modelselection import traintestsplit

from sklearn.metrics import accuracyscore

import pickle

Pipeline functions

def loaddata(path: str) -> pd.DataFrame:

"""Load dataset from CSV file"""

df = pd.readcsv(path)

print(f"Dataset loaded: {len(df)} rows, {len(df.columns)} columns")

return df

def preprocess(df: pd.DataFrame) -> tuple:

"""Preprocess data: split features and target"""

X = df.drop("target", axis=1)

y = df["target"]

Xtrain, Xtest, ytrain, ytest = traintestsplit(

X, y, testsize=0.2, randomstate=42

)

return Xtrain, Xtest, ytrain, ytest

def trainmodel(Xtrain, ytrain, nestimators: int = 100) -> object:

"""Train a Random Forest model"""

model = RandomForestClassifier(nestimators=nestimators, randomstate=42)

model.fit(Xtrain, ytrain)

return model

def evaluate(model, Xtest, ytest) -> dict:

"""Evaluate model and return metrics"""

predictions = model.predict(Xtest)

accuracy = accuracyscore(ytest, predictions)

return {"accuracy": accuracy, "npredictions": len(predictions)}

Data Node Configuration

datapathcfg = Config.configuredatanode(

id="datapath",

defaultdata="data/dataset.csv",

scope=Scope.SCENARIO,

)

rawdatacfg = Config.configuredatanode(id="rawdata", scope=Scope.SCENARIO)

traindatacfg = Config.configuredatanode(id="traindata", scope=Scope.SCENARIO)

testdatacfg = Config.configuredatanode(id="testdata", scope=Scope.SCENARIO)

modelcfg = Config.configuredatanode(id="trainedmodel", scope=Scope.SCENARIO)

metricscfg = Config.configuredatanode(id="metrics", scope=Scope.SCENARIO)

Task Configuration

loadtaskcfg = Config.configuretask(

id="loaddata",

function=loaddata,

input=[datapathcfg],

output=[rawdatacfg],

)

preprocesstaskcfg = Config.configuretask(

id="preprocess",

function=preprocess,

input=[rawdatacfg],

output=[traindatacfg, testdatacfg],

)

traintaskcfg = Config.configuretask(

id="trainmodel",

function=trainmodel,

input=[traindatacfg],

output=[modelcfg],

)

evaluatetaskcfg = Config.configuretask(

id="evaluate",

function=evaluate,

input=[modelcfg, testdatacfg],

output=[metricscfg],

)

Scenario Configuration

scenariocfg = Config.configurescenario(

id="mlpipeline",

taskconfigs=[

loadtaskcfg,

preprocesstaskcfg,

traintaskcfg,

evaluatetaskcfg,

],

)

Running a Scenario

import taipy.core as tp

Initialize Taipy Core

tp.Core().run()

Create and run a scenario

scenario = tp.createscenario(scenariocfg)

tp.submit(scenario)

Read results

metrics = scenario.metrics.read()

print(f"Model Accuracy: {metrics['accuracy']:.4f}")

Create a new scenario with different parameters

scenario2 = tp.createscenario(scenariocfg)

scenario2.datapath.write("data/datasetv2.csv")

tp.submit(scenario2)

Multi-Page Applications

from taipy.gui import Gui

import taipy.gui.builder as tgb

Home page

homepage = """

Welcome to ML Dashboard

This application provides:

  • Dashboard: Model metrics monitoring
  • Predictions: Run new predictions
  • Settings: Model configuration

<|Dashboard|button|onaction=navigatedashboard|>

<|Predictions|button|onaction=navigatepredictions|>

"""

Dashboard page

dashboardpage = """

Monitoring Dashboard

Model Performance

<|{metricsdata}|chart|type=bar|x=Model|y=Accuracy|title=Model Accuracy Comparison|>

<|{dailydata}|chart|type=scatter|x=Date|y=Requests|mode=lines|title=Daily Requests|>

<|{dailydata}|table|>

"""

Prediction page

predictionpage = """

New Prediction

Input Features

<|{feature1}|input|label=Feature 1|>

<|{feature2}|input|label=Feature 2|>

<|{feature3}|input|label=Feature 3|>

<|Run Prediction|button|onaction=runprediction|>

<|part|render={predictionresult is not None}|

Prediction Result

  • Class: <|{predictionresult}|text|>
  • Confidence: <|{confidence}|text|>%
|>

"""

Root page with navbar

rootpage = """

<|navbar|>

"""

def navigatedashboard(state):

state.navigate("/dashboard")

def navigatepredictions(state):

state.navigate("/predictions")

Setup multi-page app

pages = {

"/": rootpage,

"home": homepage,

"dashboard": dashboardpage,

"predictions": predictionpage,

}

Gui(pages=pages).run(title="ML Dashboard", port=5000)

Practical Example: ML Dashboard with Model Inference

Here is a complete ML dashboard example that combines Taipy GUI and Core:

from taipy.gui import Gui, notify

import pandas as pd

import numpy as np

from sklearn.datasets import loadiris

from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier

from sklearn.modelselection import traintestsplit, crossvalscore

from sklearn.metrics import classificationreport, confusionmatrix

Load and prepare data

iris = loadiris()

df = pd.DataFrame(iris.data, columns=iris.featurenames)

df["target"] = iris.target

df["species"] = df["target"].map({0: "Setosa", 1: "Versicolor", 2: "Virginica"})

X = df[iris.featurenames]

y = df["target"]

Xtrain, Xtest, ytrain, ytest = traintestsplit(X, y, testsize=0.2, randomstate=42)

Train models

models = {

"Random Forest": RandomForestClassifier(nestimators=100, randomstate=42),

"Gradient Boosting": GradientBoostingClassifier(nestimators=100, randomstate=42),

}

results = []

trainedmodels = {}

for name, model in models.items():

model.fit(Xtrain, ytrain)

scores = crossvalscore(model, X, y, cv=5)

results.append({

"Model": name,

"Accuracy": round(scores.mean() 100, 2),

"Std": round(scores.std() 100, 2),

})

trainedmodels[name] = model

metricsdf = pd.DataFrame(results)

Feature importance

rfmodel = trainedmodels["Random Forest"]

importancedf = pd.DataFrame({

"Feature": iris.featurenames,

"Importance": rfmodel.featureimportances,

}).sortvalues("Importance", ascending=False)

State variables

selectedmodel = "Random Forest"

modelnames = list(models.keys())

sepallength = 5.1

sepalwidth = 3.5

petallength = 1.4

petalwidth = 0.2

predictionresult = None

confidence = 0

predictionhistory = pd.DataFrame(columns=["Time", "Model", "Prediction", "Confidence"])

def runprediction(state):

"""Run prediction with the selected model"""

model = trainedmodels[state.selectedmodel]

features = np.array([[

state.sepallength,

state.sepalwidth,

state.petallength,

state.petalwidth

]])

pred = model.predict(features)[0]

proba = model.predictproba(features)[0]

speciesmap = {0: "Setosa", 1: "Versicolor", 2: "Virginica"}

state.predictionresult = speciesmap[pred]

state.confidence = round(max(proba) * 100, 2)

# Update history

newrow = pd.DataFrame([{

"Time": pd.Timestamp.now().strftime("%Y-%m-%d %H:%M:%S"),

"Model": state.selectedmodel,

"Prediction": state.predictionresult,

"Confidence": f"{state.confidence}%",

}])

state.predictionhistory = pd.concat(

[newrow, state.predictionhistory], ignoreindex=True

)

notify(state, "success", f"Prediction: {state.predictionresult} ({state.confidence}%)")

Dashboard page

dashboard = """

ML Model Dashboard

Model Comparison

<|{metricsdf}|chart|type=bar|x=Model|y=Accuracy|title=Model Accuracy (%)|>

<|{metricsdf}|table|>

Feature Importance (Random Forest)

<|{importancedf}|chart|type=bar|x=Feature|y=Importance|title=Feature Importance|>

Dataset Distribution

<|{df}|chart|type=scatter|x=sepal length (cm)|y=petal length (cm)|color=species|title=Scatter Plot: Sepal vs Petal Length|>

"""

Prediction page

prediction = """

Iris Species Prediction

Select Model

<|{selectedmodel}|selector|lov={modelnames}|dropdown|label=Model|>

Input Features

<|{sepallength}|slider|min=4.0|max=8.0|step=0.1|label=Sepal Length (cm)|>

<|{sepalwidth}|slider|min=2.0|max=5.0|step=0.1|label=Sepal Width (cm)|>

<|{petallength}|slider|min=1.0|max=7.0|step=0.1|label=Petal Length (cm)|>

<|{petalwidth}|slider|min=0.1|max=3.0|step=0.1|label=Petal Width (cm)|>

<|Predict|button|onaction=runprediction|>

<|part|render={predictionresult is not None}|

Prediction Result

Species: <|{predictionresult}|text|> (Confidence: <|{confidence}|text|>%)

|>

Prediction History

<|{predictionhistory}|table|>

"""

pages = {

"/": "<|navbar|>",

"Dashboard": dashboard,

"Prediction": prediction,

}

if name == "main":

Gui(pages=pages).run(

title="Iris ML Dashboard",

port=5000,

darkmode=True,

)

Taipy vs Streamlit vs Gradio Comparison

| Feature | Taipy | Streamlit | Gradio |

|---------|-------|-----------|--------|

| Target use case | Production apps | Prototyping | ML demos |

| Multi-page | Native support | Recently added | Limited |

| State management | Advanced (per-session) | Re-run script | Minimal |

| Pipeline orchestration | Taipy Core built-in | None | None |

| Callback system | Event-driven | Re-run based | Event-driven |

| Concurrent users | Optimized | Less optimal | Decent |

| Learning curve | Medium | Low | Low |

| Deployment | Docker, cloud-native | Streamlit Cloud | Hugging Face Spaces |

| Customization | High (CSS, themes) | Limited | Limited |

When to use Taipy:
  • AI/ML applications requiring pipeline orchestration
  • Production dashboards with many concurrent users
  • Complex multi-page applications
  • Projects requiring robust state management

When to use Streamlit:
  • Rapid prototyping
  • Simple data exploration
  • Internal team demos

When to use Gradio:
  • ML model demos for non-technical audiences
  • Hugging Face integration
  • Simple interfaces for model inference

Deployment

Docker Deployment

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000

CMD ["python", "main.py"]

# docker-compose.yml

version: "3.8"

services:

taipy-app:

build: .

ports:

  • "5000:5000"
volumes:

  • ./data:/app/data
environment:

  • TAIPYPORT=5000
  • TAIPYHOST=0.0.0.0
restart: unless-stopped

Production Configuration

from taipy.gui import Gui

if name == "main":

gui = Gui(pages=pages)

gui.run(

title="Production ML Dashboard",

host="0.0.0.0",

port=5000,

debug=False,

usereloader=False,

darkmode=True,

watermark="PT RUBYTHALIB DATA KONSULTA",

)

Nginx Reverse Proxy

server {

listen 80;

servername ml-dashboard.example.com;

location / {

proxypass http://localhost:5000;

proxysetheader Host $host;

proxysetheader X-Real-IP $remoteaddr;

proxysetheader X-Forwarded-For $proxyaddxforwardedfor;

proxyhttpversion 1.1;

proxysetheader Upgrade $httpupgrade;

proxysetheader Connection "upgrade";

}

}

Tips and Best Practices

  • Use Taipy Core for complex pipelines: Separate business logic from UI. Define pipelines in a separate config file.
  • Leverage caching: Taipy has built-in caching for data nodes. Configure the appropriate scope (SCENARIO, CYCLE, or GLOBAL).
  • Clean project structure: Separate pages, algorithms, and configurations into different folders.
  • Performance monitoring: Use Taipy's built-in logging to monitor pipeline execution.
  • Testing: Write unit tests for pipeline functions separately from the UI:
  • import pytest
    

    from algorithms.preprocessing import preprocess

    def testpreprocess():

    import pandas as pd

    df = pd.DataFrame({"feature1": [1, 2, 3], "target": [0, 1, 0]})

    Xtrain, Xtest, ytrain, ytest = preprocess(df)

    assert len(Xtrain) > 0

    assert len(Xtest) > 0

    Conclusion

    Taipy is an exceptionally powerful framework for building production-grade AI/ML applications. With the combination of Taipy GUI for web interfaces and Taipy Core for pipeline orchestration, developers can build end-to-end applications without needing multiple separate tools.

    The key advantage of Taipy over alternatives like Streamlit and Gradio is its ability to handle complex applications with robust state management, native multi-page support, and built-in pipeline orchestration. This makes it the ideal choice for serious AI projects that require high scalability.

    Start with simple examples, then gradually add complexity as your project needs grow. The official Taipy documentation at docs.taipy.io provides many additional examples and references.

    Related Articles

    Complete Streamlit Advanced Tutorial: Build Production-Ready ML Apps

    Tutorial Lengkap Streamlit Advanced: Build Production-Ready ML Apps Streamlit adalah library Python yang powerful untuk ...

    PaddleOCR: High Accuracy Text Extraction from Images and Documents

    PaddleOCR: Ekstraksi Teks dari Gambar dan Dokumen dengan Akurasi Tinggi Halo temen-temen, kali ini kita bahas salah satu...

    DSPy: Stop Hand-Tuning Prompts, Let the Compiler Optimize Them

    DSPy: Berhenti Ngoprek Prompt Manual, Biarkan Compiler yang Optimasi Halo temen-temen, kali ini aku mau ngenalin satu li...

    Hamilton: Build Clean, Maintainable Dataflows and ML Pipelines in Python

    Hamilton: Bikin Dataflow dan Pipeline ML yang Rapi dan Gampang Dirawat di Python Halo temen-temen, ketemu lagi sama aku ...