You have an idea for a web application, and you’re ready to get started, but alas!
You’re a Python expert;
Guido van Rossum and you went to the same kindergarten;
What do you have to do with JavaScript?
What do you know about Cascading Style Sheets?
Or g-d forbid, Hypertext Markup Language!
But my fellow Pythonists, fear not, because in these beautiful days of ours, it is possible to develop web applications (with an emphasis on frontend) using Python… well, maybe not exactly, but very close to it.
So what’s the purpose of this post?
In this post, I want to explore the somewhat emerging, somewhat necessary relationship between Python and frontend development.
Allow me to guide you and divide this exploration into three vectors that I find interesting on the topic:
And one more word before we begin: all expressions and metaphors are how I see fit to present things to make the reading smoother; there might be inaccuracies or technical simplifications.
The Nostalgic Veteran
Well, if it rhymes with “ninja,” it must be… Jinja(2)!
The veteran and proven template engine paradigm!
Almost without JavaScript, everything happens on the server by HTTP requests and responses.
Overall Jinja was inspired by Django’s (released in 2005) template engine.
Since its first recorded public release in 2008, Jinja2 has become a standard in the Python ecosystem due to its balance between flexibility and safety, making it an essential tool for many Python web developers.
Today Jinja is most known as the default template engine for Flask.
Key Features
- Sandboxed Execution: Provides a protected framework for testing programs with unknown behavior.
- HTML Escaping: Offers automatic HTML escaping to prevent Cross-site Scripting (XSS) attacks.
- Template Inheritance: Allows templates to inherit from a base template, reducing code repetition and improving maintainability.
- Expressive Syntax: Uses a syntax similar to Python, making it intuitive for Python developers.
- Customization: Allows customization of tags, filters, tests, and globals.
Jinja In Action
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title> {# Output the value of 'title' passed from the Python context #}
</head>
<body>
{# A simple comment :) #}
<h1>Welcome, {{ user.name }}!</h1> {# Display the user's name from the Python context #}
<p>Here are your favorite fruits:</p>
<ul>
{# Loop through a list of fruits passed from Python and display each one #}
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>
{# If-else block to check if the user is an admin #}
{% if user.is_admin %}
<p>You have admin access.</p>
{% else %}
<p>You are a regular user.</p>
{% endif %}
{# Including another template (e.g., a footer) #}
{% include 'footer.html' %}
</body>
</html>
Into the Browser
“If you cannot beat them, join them” - Someone somewhere…
PyScript is relatively new idea, introduced by Anaconda at the 2022 PyCon US.
PyScript lets you run Python directly in the browser. No, you didn’t read that wrong.
What is PyScript?
PyScript is a Pythonic framework that lets you integrate Python into the frontend of your web apps. It allows you to write and execute Python code directly in your HTML files, all thanks to the magic of WebAssembly.
This is a game-changer for Python developers who have avoided JavaScript like the plague. With PyScript, you can build dynamic web applications using Python without needing to switch mental gears to learn JavaScript.
PyScript in Action
<!DOCTYPE html>
<html lang="en">
<head>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
</head>
<body>
<py-script>
def greet(): name = input("What's your name?") print(f"Hello, {name}!")
greet()
</py-script>
</body>
</html>
In this snippet, we’re running Python directly in the browser to interact with the user. Pretty wild, right?
A Word of Caution
Well… while promising, PyScript is still in early development and not ready to replace JavaScript, which remains the web standard due to its maturity and widespread support. PyScript is great for small projects or experiments but isn’t yet suited for large-scale applications.
Abstraction Over The Abstraction
If you’ve ever thought, “I wish I could just write Python for the entire web stack,” then Reflex is the answer to your prayers. Reflex was first introduced in December 2022 as Pynecone and in 2023, the project was renamed from Pynecone to Reflex
What is Reflex?
At its core, Reflex allows you to build both the backend and frontend of your application using Python. It handles the backend by providing a framework for creating APIs, managing server-side logic, and handling data persistence—all within the same Python environment. On the frontend side, Reflex works by “transpiling” your Python code into React components (essentially, an “abstraction over the abstraction”).
Behind the scenes, Reflex integrates with Radix, a popular React-based component library, to generate the actual frontend elements.
This means you don’t have to worry about writing HTML, CSS, or JavaScript directly. Reflex compiles your Python code into the necessary JavaScript to run on the browser, while the backend logic is handled in Python—creating a truly full-stack Python web app.
For a more detailed explanation, I highly recommend checking out their documentation, as Reflex is under rapid and ongoing development.
Key Features
- Full-Stack Python Development: Write both backend and frontend in Python. Reflex manages the backend logic, database interactions, and API handling, while also generating the frontend using Radix.
- State Synchronization: Reflex handles automatic state management, ensuring the Python logic stays in sync with the UI on the browser.
- Declarative UI: You describe your UI using Python functions, and Reflex converts these into JSX-like React components.
- Backend and API Support: Reflex lets you manage your app’s backend entirely in Python, handling database queries, server-side routes, and data processing based on the well acclaimed FastAPI package.
Reflex In Action
import reflex as rx
# State based backend component
class State(rx.State):
count: int = 0
def increment(self):
self.count += 1
def decrement(self):
self.count -= 1
# Frontend declaration
def index():
return rx.hstack(
rx.button(
"Decrement",
color_scheme="ruby",
on_click=State.decrement,
),
rx.heading(State.count, font_size="2em"),
rx.button(
"Increment",
color_scheme="grass",
on_click=State.increment,
),
spacing="4",
)
# Backend routing
app = rx.App()
app.add_page(index)
My Take: The Need for Easy Frontend in Data Science
The “somewhat necessary” relationship I mentioned earlier between Python and frontend development is especially evident in data science. Data scientists often need to present their findings interactively, but many aren’t proficient in JavaScript. Tools like Reflex and PyScript provide a way to build dynamic web apps using Python, simplifying the process of showcasing data insights without the need to master complex frontend technologies.
Conclusion: The Future of Python in Frontend Development
The relationship between Python and frontend development is evolving, driven by the need for more accessible tools. Solutions like Jinja2, PyScript, and Reflex simplify web development for Python developers, making it easier to build dynamic, interactive apps without heavy reliance on JavaScript.
While JavaScript remains the standard, Python is steadily carving out its own space in the web development landscape.