Creating Web Applications Using PyWebIO

PyWebIO is a python library for creating web applications that turns your browser into a rich text terminal.

If you want to create a web application using Python, you can choose to use sophisticated and highly customizable packages like Flask, FastAPI or Django; or create a barebones web application using Streamlit. PyWebIO is another Python package that enables you to create simple web applications without prior knowledge of  HTML and Javascript. The idea behind PyWebIO is to use the browser as a rich-text terminal, which is reflected in how web applications are written.  

What’s the difference between Streamlit and PyWebIO?

The key factor that differentiates the two libraries is how applications are coded and their execution flow. Streamlit works responsively, i.e., every time the user interacts with a widget, the script is re-executed and the output of the widget is updated with the new value returned in the run. On the other hand, PyWebIO linearly runs the code much like a series of terminal commands. The output functions display content in the browser in real-time, and the input function blocks the execution until the user submits the input, much like Python’s built-in input(). This enables developers to easily convert existing terminal programs into web applications by replacing the input and output functions. 

Let’s go through the basic input and output functions of PyWebIO, but we’ll need to install it first. 


Sign up for your weekly dose of what's up in emerging technology.

pip install -U pywebio


PyWebIO provides a plethora of input functions to fetch user input through the browser. When an input function is called, a new browser tab pops up with an input form. Similar to the Python built-in input(), the PyWebIO input function is blocking, i.e., it stops the flow of execution until the form is successfully submitted.

Download our Mobile App

 from pywebio.input import *

 meaning = input("What is the meaning of life?") #not the built-in method
 pill_color = select("Which one will you choose", ['Red Pill', 'Blue Pill'], multiple=True)
 device = radio("What device are you using right now?", options=["Laptop", "Desktop", "Smartphone", "Tablet"])
 os = checkbox("What operating system do you prefer for smartphones?", options=["Android", "iOS"]) 

You can learn more about the different input functions here.


It also provides a wide range of output functions to render all kinds of output in the browser. Refer here to find the list of all available output functions. 

 from pywebio.output import *
 from pywebio.input import * 
 import time

 with popup("Subscribe to the page"):
     put_text("I hope you are having a great day!")

 put_markdown('## Welcome to our fruit store')
     ['Fruit', 'Price'],
     ['Blueberry', 20],
     ['Mango', 25], 
     ['Kiwi', 15]

 fruit = select("Choose your favorite Fruit", ['Blueberry', 'Mango', 'Kiwi'])
 put_text(f"You chose {fruit}. Please wait until it is served!")
 for i in range(1, 11):
     set_processbar('bar', i / 10)
 put_markdown(f"Here is your {fruit}! Enjoy!")
 if fruit == 'Mango':
     put_image(open('mango.jpg', 'rb').read())
 elif fruit == 'Blueberry':
     put_image(open('noodle.jpg', 'rb').read())
     put_image(open('kiwi.jpg', 'rb').read()) 

Creating an EDA Web Application with PyWebIO and Plotly

  1. Import necessary libraries and classes.
 from pywebio.input import *
 from pywebio.output import put_html, put_loading
 from pywebio import start_server
 import csv 
 import re
 import pandas as pd
 import as px 
  1. Create a function that generates a CSV file from a list of rows.
 def list_to_dataframe(file_content):
     with open("data.csv", "w") as csv_file:
         writer = csv.writer(csv_file, delimiter = '\t')
         for line in file_content:
     return pd.read_csv("data.csv") 
  1. Create the app method and run the PyWebIO server.
 def app():
     file = file_upload(label='Upload CSV file', accept='.csv')
     content = file['content'].decode('utf-8').splitlines()
     df = list_to_dataframe(content)
     columns = list(df.columns)
     target = select("Select target variable", columns)

     # create a scatter plot for every feature pair
     fig = px.scatter_matrix(df, columns, color=target)
     html = fig.to_html(include_plotlyjs="require", full_html=False)

     while True:  
         features = select("Select up to three features to plot", options = columns, multiple=True)
         if len(features) == 1:
             fig = px.histogram(df, x=features[0])
             html = fig.to_html(include_plotlyjs="require", full_html=False)
         elif len(features) == 2:
             plot_type = radio("What type of plot?", options=["Line", "Scatter", "Bar"])
             if plot_type == "Bar":
                 fig =, x=features[0], y = features[1])
                 html = fig.to_html(include_plotlyjs="require", full_html=False)
             elif plot_type == "Line":
                 fig = px.line(df, x=features[0], y = features[1])
                 html = fig.to_html(include_plotlyjs="require", full_html=False)
             else :
                 fig = px.scatter(df, x=features[0], y = features[1])
                 html = fig.to_html(include_plotlyjs="require", full_html=False)
             plot_type = radio("What type of plot?", options=["Line", "Scatter"])
             if plot_type == "Scatter":
                 fig = px.scatter_3d(df, x=features[0], y = features[1], z=features[2],
                 html = fig.to_html(include_plotlyjs="require", full_html=False)
                 fig = px.line_3d(df, x=features[0], y = features[1], z=features[2])
                 html = fig.to_html(include_plotlyjs="require", full_html=False)
         x = radio("Do you want to continue?", options=["Continue", "Quit"])
         if x == "Quit":

 if __name__=='__main__':
     start_server(app, debug=True) 

Last Epoch

This article introduced PyWebIO, a python library for creating web applications that turns your browser into a rich text terminal. It provides input and output functions that enable the easy conversion of pre-existing terminal scripts into web applications. PyWebIO is compatible with data visualization libraries, such as Plotly, bokeh, etc and supports asyncio and coroutine. It can also be integrated with existing web projects created using libraries like Flask, Django, Tornado.


More Great AIM Stories

Aditya Singh
A machine learning enthusiast with a knack for finding patterns. In my free time, I like to delve into the world of non-fiction books and video essays.

AIM Upcoming Events

Early Bird Passes expire on 3rd Feb

Conference, in-person (Bangalore)
Rising 2023 | Women in Tech Conference
16-17th Mar, 2023

Conference, in-person (Bangalore)
Data Engineering Summit (DES) 2023
27-28th Apr, 2023

3 Ways to Join our Community

Telegram group

Discover special offers, top stories, upcoming events, and more.

Discord Server

Stay Connected with a larger ecosystem of data science and ML Professionals

Subscribe to our Daily newsletter

Get our daily awesome stories & videos in your inbox

Do machines feel pain?

Scientists worldwide have been finding ways to bring a sense of awareness to robots, including feeling pain, reacting to it, and withstanding harsh operating conditions.

IT professionals and DevOps say no to low-code

The obsession with low-code is led by its drag-and-drop interface, which saves a lot of time. In low-code, every single process is shown visually with the help of a graphical interface that makes everything easier to understand.

Neuralink elon musk

What could go wrong with Neuralink?

While the broad aim of developing such a BCI is to allow humans to be competitive with AI, Musk wants Neuralink to solve immediate problems like the treatment of Parkinson’s disease and brain ailments.

Understanding cybersecurity from machine learning POV 

Today, companies depend more on digitalisation and Internet-of-Things (IoT) after various security issues like unauthorised access, malware attack, zero-day attack, data breach, denial of service (DoS), social engineering or phishing surfaced at a significant rate.