How to Build a Python Web App: Complete Tutorial

Introducing xy in Reflex Build


You know Python, but every web framework tutorial still makes you learn a frontend framework in JavaScript to build anything interactive. This python web application framework tutorial focuses on Reflex, which under the hood compiles your Python code into React components so you can build complete web apps without context-switching between languages. You'll set up your environment, build components, manage state, connect a database, and deploy to production while writing nothing but Python code.

TLDR:

Setting Up Your Python Development Environment

Before writing any code, verify Python 3.10 or higher is installed by running python --version in your terminal. If needed, download the latest version from python.org.

Next, create a virtual environment to isolate project dependencies and avoid version conflicts. In your project folder, run:

python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

Your terminal prompt will change when active. Activate this environment each time you work on the project to keep dependencies contained and prevent debugging headaches.

Understanding Python Web Frameworks in 2026

Python's popularity in web development stems from its readability and extensive library ecosystem. 51% of developers globally use Python, making it the most widely adopted language for building web applications.

When choosing a Python web framework, you'll encounter three main categories:

Reflex breaks this pattern by letting you write both frontend and backend in pure Python. You don't context-switch between languages or manage separate codebases.

Reflex (Full-Stack Python)

Django

Flask

Installing and Initializing Your First Reflex Project

With your virtual environment activated, install Reflex using pip:

pip install reflex

Create a new directory for your project and move into it:

mkdir my_app
cd my_app

Run the initialization command:

reflex init

Reflex generates a project structure with a single Python file containing your entire application. You'll see my_app.py with state management and UI components already defined, plus rxconfig.py for project settings and an assets folder for static files.

Start the development server:

reflex run

Your browser opens to localhost:3000 showing your running app. The server includes fast refresh, so code changes appear instantly without manual reloading.

Building UI Components with Pure Python

Reflex provides 60+ built-in components that handle everything from simple text and buttons to complex data tables and charts. Each component is a Python function you import and call with keyword arguments. No HTML templates, no JSX syntax, just Python functions that return UI elements.

Here's how you create a basic button:

import reflex as rx

rx.button("Click me", on_click=handle_click)

The component accepts text as the first argument and event handlers as keyword arguments. Behind the scenes, Reflex compiles Python to React components, but you never write or see the JavaScript.

Build complex layouts by nesting components inside container functions:

def user_card():
    return rx.box(
        rx.heading("Welcome Back"),
        rx.text("Your dashboard is ready"),
        rx.button("Get Started"),
        padding="20px",
        border_radius="8px",
        box_shadow="lg"
    )

Style components using keyword arguments that map to CSS properties. The box component acts as a container with visual properties controlling appearance.

Managing Application State and Event Handlers

State in Reflex uses Python classes that inherit from rx.State. Variables are class attributes, and methods modify these variables. When a method changes a variable, Reflex updates every UI component displaying that value.

Counter example:

class CounterState(rx.State):
    count: int = 0

def increment(self):
        self.count += 1

def decrement(self):
        self.count -= 1

Connect state to UI components:

def counter():
    return rx.box(
        rx.text(f"Count: {CounterState.count}"),
        rx.button("Add", on_click=CounterState.increment),
        rx.button("Subtract", on_click=CounterState.decrement)
    )

Event handlers run when users interact with components. The on_click, on_change, and on_submit arguments connect actions to state methods.

Connecting Your Web App to a Database

Reflex includes built-in database support through SQLAlchemy, letting you define models as Python classes. Each class attribute becomes a database column with automatic type mapping. Reflex handles table creation, migrations, and query generation without writing SQL.

class User(rx.Model, table=True):
    email: str
    username: str
    created_at: str

Access database records inside your state class using the with rx.session() context manager:

class AppState(rx.State):
    users: list[User] = []

def load_users(self):
        with rx.session() as session:
            self.users = session.exec(User).all()

This works with SQLite by default for local development. Switch to PostgreSQL or MySQL in production by updating the database URL in your config file.

Building Multi-Page Applications with Routing

Reflex handles routing through a function-based system where each page is a Python function decorated with @rx.page. Define routes by specifying the URL path:

@rx.page(route="/")
def home():
    return rx.box(rx.heading("Home Page"))

@rx.page(route="/about")
def about():
    return rx.box(rx.heading("About Us"))

Create flexible routes using square brackets for parameters. Access them through AppState.router.page.params:

@rx.page(route="/user/[username]")
def user_profile():
    return rx.box(rx.text(f"Profile: {AppState.router.page.params.username}"))

Build navigation with rx.link components that connect pages without full reloads.

Styling and Theming Your Web App

Reflex includes a theming system that controls colors, fonts, and spacing across your entire application. Set a theme once and every component inherits those styles automatically.

Switch between dark and light modes with a single line of code:

rx.theme(appearance="dark")

Users can toggle between modes at runtime by binding the appearance property to a state variable. The theme handles all color inversions and contrast adjustments.

Customize your theme by passing configuration options:

rx.theme(
    accent_color="blue",
    gray_color="slate",
    radius="large"
)

Apply CSS directly to components using keyword arguments that match CSS property names:

rx.box(
    rx.text("Styled Text"),
    background_color="#f0f0f0",
    padding="20px",
    border="1px solid #ddd"
)

Snake case replaces hyphens in property names, making styles readable as Python code without separate CSS files.

Deploying Your Python Web App to Production

Once your app is ready, deployment takes one command. The web development market reached $10.5 billion in 2026, making fast deployment critical for staying competitive.

Test locally with reflex run to catch errors. Verify all dependencies appear in requirements.txt and database connections work in production mode.

Deploy by running:

reflex deploy

This packages your application, provisions infrastructure, and launches your app across a multi-region network. You'll receive a live URL within minutes, with deployment status, metrics, and logs available through the dashboard.

For organizations requiring on-premises deployment or VPC infrastructure, custom deployment configurations are available that meet enterprise compliance requirements while maintaining the same Python codebase you developed locally.

Building Production Apps with Reflex

Reflex has powered over 1 million applications because it keeps everything in Python code your team can debug and extend. 40% of Fortune 500 companies use Reflex for internal tools and data applications. On-premises deployment options meet compliance requirements for healthcare, finance, and government sectors, while role-based access control lets you define granular permissions in Python code that security teams can audit. When systems behave unexpectedly, engineers read the Python source to diagnose issues without specialized frontend debugging tools.

Final Thoughts on Python Web Application Development

This Python web app tutorial shows you can skip the JavaScript learning curve and build modern web apps entirely in Python. You control your UI, manage state, connect databases, and deploy to production without leaving your favorite language. The framework handles the complexity while you focus on building features. Give it a try and see what you can create.