Building an Interface with Taipy

Hey there, my name is Blake Downward from Australia. Background in e-commerce, finance and economics - now making the move to Data Science and applied Machine Learning.
Welcome to the second post in this series where we are designing and building a web application with Python and Taipy. In the first post we covered Project Conception and Design, where we walked through the steps to take an idea for a project, define it's core functionality, think about the user experience, then produce wireframes and other graphical assets for the next phase of development - building the web application.
The Tech Stack
Before we start building anything, we need to decide on a framework we are comfortable with using (or at least confident we can learn), and one that can handle the functionality we require. I've used python and Streamlit for a number of interfaces over the years. I do love how simple it is to get started and build GUI prototypes rapidly - but it does come with its limitations, particularly around "state management" and working with large amounts of data.
Recently I discovered Taipy, a new player in this space and looking quite promising. Being a new framework, Taipy doesn't have a huge community like Streamlit yet (although their Discord server is quite active and growing), and their documentation has a lot of room for improvement - but these are small matters that will organically improve in time. It is the core of Taipy which really has me interested to learn this framework... not only can you build prototypes rapidly, they can be turned into production grade apps.
To use Taipy, you'll need an environment with Python (version 3.8 to 3.11) and pip installed. I'll be using PyCharm, but feel free to use whatever code editor/IDE you are most comfortable with.
Create a new project in your IDE and ensure you have a compatible version of Python installed.
Installing Taipy
Although not strictly required, it is good practice to create a virtual environment to avoid dependency conflicts. Anaconda is a popular choice for managing environments, but you can also do this within your IDE or even from the command line with the "venv" package.
With your new virtual environment ready and activated, open a terminal and upgrade pip with the following command.
python -m pip install --upgrade pip
Then run the following command to install Taipy (This might take a minute or two to download and install the required dependencies).
pip install taipy
Planning the Build
Before we get started, let's take a look at the wireframe we produced in the first post... let's determine what elements we'll need, how to structure them, and how to style them.

The green box represents our application's main body - think of it as a container for the rest of the elements to live in.
Inside our main container, we have three distinct sections (pink boxes). At the top we have a logo (static image), then next is a timer display (dynamic variable in "HH:MM:SS" format), then at the bottom we have a set of four buttons (3 x static, 1 x dynamic with callbacks).
Since we have already defined some structure and styling, let's start with the low-hanging fruit and put the skeleton of our project together.
Taipy Project Structure
The only file required for a Taipy application is a "main.py" file. In this one file you can define the layout, styling and logic for your app. For complicated projects, keeping everything in the "main.py" file can get a bit messy, so it is a good idea to break-out your functions, styling or structure into other files.
For a simple web app like this one, I like to keep the project structure quite flat - so my "main.py" script will live in the top-level of the project directory. I've opted for the "main.py" to hold functions and structure, and I'll create "main.css" file for styling. I will also create an "assets" directory to store images, fonts and other files we might need in the project.
The initial project structure should look something like this:
project
│ main.py
| main.css
│
└───assets
│ │ AnonymousPro-Regular.ttf
| | chime.mp3
│ │ chimely-style-notes.txt
│ │ Chimely_logo.png
| | chimely-favicon.png
Taipy GUI
Before we build-out the application, let's start with the bare minimum required to spin-up a server and display a basic "hello world" example.
Add the following lines of code to your "main.py" file, then run the script from your IDE or the command line.
# main.py
from taipy.gui import Gui
markdown = """
# Hello World
"""
gui = Gui(page=markdown)
gui.run()
If everything is installed correctly, you should see the following screen open in your web browser.

Rendering Page Content
From the above example, you might've noticed the content of the page was rendered from a variable called "markdown". As the name suggests, this variable holds a string of markdown formatted text which Taipy uses for displaying content. Markdown is perhaps the simplest way to show content with Taipy, but they also allow the use of HTML or Python code for greater customisation if required.
My suggestion is to start with markdown syntax. Then, if you come across something you can't do with markdown, write that part in HTML or Python. You can then insert this custom part into your markdown with a Taipy feature called "partials".
Taipy Visual Elements
Taipy comes packaged with a bunch of predefined visual elements which cannot be rendered with markdown alone. Block elements are basically containers for structure (part, expandable, layout and pane), and control elements are for inputting, interacting and displaying (plain text, buttons, text/numerical inputs, file selectors, sliders, images, toggles, charts, tables, menus etc).
General Markdown Syntax
Visual elements are defined in markdown by an opening tag <|, some values or parameters separated by pipes ..|.., then a closing tag |>. For example, displaying the text "Hello world!"...
<|Hello world!|text|>
Variables can be accessed with curly braces {} to make the content dynamic.
var = "Hello world!"
<|{var}|text|>
Additional attributes like "class" and "id" can be assigned to each element to give you greater control when styling.
<|Hello world!|text|id=header-text|class=primary-font|>
Block elements are defined similarly to control elements, and also allow for additional attributes like "class" and "id".
<|block-element|id=block-id|
***CONTENT FOR THE BLOCK ELEMENT GOES HERE***
|>
Luckily for this project, all the elements we need can be produced with Taipy Visual Elements and basic markdown syntax.
Building the General Structure
We'll be using Taipy block elements called "parts" (similar to a div in HTML). These will act as containers for each section of the app (logo, timer, buttons), which we can build out accordingly.
Let's start by defining the three parts, add the logo to the first one, then we'll add some placeholder text and buttons to the second and third parts.
Return to your "main.py" file, delete the "hello world" example, then add the following...
from taipy.gui import Gui
logo_path = "assets/Chimely_logo.png"
markdown = """
<|part|
<|{logo_path}|image|id=header_logo|>
|>
<|part|
TIMER DISPLAY
<|00:00:00|text|id=timer_display|>
|>
<|part|
INTERACTIVE BUTTONS
<|1 MINUTE|button|>
<|15 MINUTES|button|>
<|1 HOUR|button|>
<|CUSTOM INTERVAL|button|>
|>
"""
gui = Gui(page=markdown)
gui.run(dark_mode=False)
If everything ran alright, you should have something in your browser similar to the left image below.
Not a great deal of work is needed to get the general structure of our application ready, but it doesn't look great. Before we start working on the logic, let's add some styling so it's easier on the eye.

I won't go too deep into the css styling side of things here, but you can find all the code for this project at the Chimely GitHub repo if you want to follow along.
In a nutshell, the "main.css" file does the following:
Imports and sets a custom font from the "assets" directory
Sets the background colour
background-color: #215B6DAligns everything in the body
text-align:centerAdds a border to the timer and button sections
Increases the size of the timer
Not a lot of work, but quite effective. It renders in the browser just like the wireframe now. We could spend more time jazzing it up, but it's at a pretty good stage now, that's something we can do later if needed.
So all of this and we haven't defined a single Python function. It might look pretty, but it's not much of an application if it doesn't do anything. So that's where we'll kick off the next post in this series - state management and interacting with the interface to make it function the way it should. See you there...


