Reflex. Cooler Web Apps?

Reflex. Cooler Web Apps?

February 12, 2025

The Reflex Package

Apache v2 | 🕸️ Web apps in pure Python 🐍

What I want to use it for?

How about enhancing this streamlit projects?

Compile Python on a Pi 📌
wget https://www.python.org/ftp/python/3.11.5/Python-3.11.5.tgz
tar xzf Python-3.11.5.tgz

cd Python-3.11.5
./configure --enable-optimizations --with-ensurepip --prefix=/usr/local/python311  # Adjust path and version if needed


#compile
make -j$(nproc)  # Use all available cores for faster compilation
#install
sudo make altinstall  #  "altinstall" is IMPORTANT!
nano ~/.bashrc  # Or nano ~/.zshrc if you use zsh

export PATH="/usr/local/python311/bin:$PATH"
source ~/.bashrc  # Or source ~/.zshrc
python3.11 --version  # Or python3.x if you installed a different minor version
pip3.11 --version
pip3.11 install --upgrade virtualenv --user
sudo apt-get install python3-virtualenv

python3.11 -m venv my_env  # Creates a virtual environment named my_env
source my_env/bin/activate  # Activates the environment

Reflex 101

pip install reflex
reflex init
reflex run #this compiles and execute the sample app

The front end UI will be at localhost:3000

ℹ️
You will also need localhost:8000 for the BE (which can conflict with Portainer!) s

Learn to code by building series from Coding Entrepreneur is great (and not only for Reflex)

    • _index.md
      • _index.md
      • introduction.md
      • introduction.fr.md
  • hugo.toml
  • If you inspect, this is how the reflex main.py looks:

    """Welcome to Reflex! This file outlines the steps to create a basic app.""" #Shown as title
    
    import reflex as rx
    
    from rxconfig import config
    
    
    class State(rx.State):
        """The app state."""
    
        ...
    
    
    def index() -> rx.Component:
        # Welcome Page (Index)
        return rx.container(
            rx.color_mode.button(position="top-right"),
            rx.vstack(
                rx.heading("Welcome to Reflex!", size="9"),
                rx.text(
                    "Get started by editing ",
                    rx.code(f"{config.app_name}/{config.app_name}.py"),
                    size="5",
                ),
                rx.link(
                    rx.button("Check out our docs!"),
                    href="https://reflex.dev/docs/getting-started/introduction/",
                    is_external=True,
                ),
                spacing="5",
                justify="center",
                min_height="85vh",
            ),
            rx.logo(),
        )
    
    
    app = rx.App()
    app.add_page(index)

    Now, its all about adding components to the def index(), like: https://reflex.dev/docs/library/data-display/moment/

    rx.moment(MomentState.date_now), #you will need to define its associated MomentState(), also given in the docs

    Not long after get that working, you will build some demo, using graph components:

    testing Sample Components with Reflex 📌
    #pip install reflex
    #reflex init
    
    import reflex as rx
    
    from datetime import datetime, timezone
    
    
    class MomentState(rx.State):
        date_now: datetime = datetime.now(timezone.utc)
    
        @rx.event
        def update(self):
            self.date_now = datetime.now(timezone.utc)
    
    
    def moment_update_example():
        return rx.button(
            "Update",
            rx.moment(MomentState.date_now),
            on_click=MomentState.update,
        )
    
    ##
    
    data = [
        {"name": "Page A", "uv": 4000, "pv": 2400, "amt": 2400},
        {"name": "Page B", "uv": 3000, "pv": 1398, "amt": 2210},
        {"name": "Page C", "uv": 2000, "pv": 9800, "amt": 2290},
        {"name": "Page D", "uv": 2780, "pv": 3908, "amt": 2000},
        {"name": "Page E", "uv": 1890, "pv": 4800, "amt": 2181},
        {"name": "Page F", "uv": 2390, "pv": 3800, "amt": 2500},
        {"name": "Page G", "uv": 3490, "pv": 4300, "amt": 2100},
    ]
    
    def bar_simple():
        return rx.recharts.bar_chart(
            rx.recharts.bar(
                data_key="uv",
                stroke=rx.color("accent", 9),
                fill=rx.color("accent", 8),
            ),
            rx.recharts.x_axis(data_key="name"),
            rx.recharts.y_axis(),
            data=data,
            width="100%",
            height=250,
        )
    
    def composed():
        return rx.recharts.composed_chart(
            rx.recharts.area(
                data_key="uv", stroke="#8884d8", fill="#8884d8"
            ),
            rx.recharts.bar(
                data_key="amt", bar_size=20, fill="#413ea0"
            ),
            rx.recharts.line(
                data_key="pv",
                type_="monotone",
                stroke="#ff7300",
            ),
            rx.recharts.x_axis(data_key="name"),
            rx.recharts.y_axis(),
            rx.recharts.cartesian_grid(stroke_dasharray="3 3"),
            rx.recharts.graphing_tooltip(),
            data=data,
            height=250,
            width="100%",
        )
    #####
    
    """Welcome to Reflex! This file outlines the steps to create a basic app."""
    
    import reflex as rx
    from rxconfig import config
    
    
    class State(rx.State):
        """The app state."""
    
        ...
    
    def index() -> rx.Component:
        # Welcome Page (Index)
        return rx.container(
            rx.color_mode.button(position="top-right"),
            rx.vstack(
                rx.heading("Welcome to Reflex!", size="9"),
                rx.heading("Yessss, this works!", size="5"),
                
                rx.callout(
                    "One step closer to do cool things :)",
                    icon="info",
                ),
                rx.moment(MomentState.date_now),
                #moment_update_example(),
                bar_simple(),
                composed(),
                
                rx.text(
                    "Get started by editing ",
                    rx.code(f"{config.app_name}/{config.app_name}.py"),
                    size="5",
                ),
                rx.link(
                    rx.button("Check out our docs!"),
                    href="https://reflex.dev/docs/getting-started/introduction/",
                    is_external=True,
                ),
                spacing="5",
                justify="center",
                min_height="85vh",
            ),
            rx.logo(),
        )
    
    app = rx.App()
    app.add_page(index)

    Reflex 101

    You will find also useful:

    1. rx.input - https://reflex.dev/docs/library/forms/input/
    2. rx.datatable - https://reflex.dev/docs/library/tables-and-data-grids/data-table/ or table

    Building with Reflex

    Historical Job Market Data with Reflex

    📌

    Real Estate with Reflex

    Lately Ive been playing with RE data driven apps.

    And with Reflex and some tricks with Gemini…

    Reflex using Components

    📌

    Conclusions

    I find it easier to iterate with streamlit, as there is no waiting time for compiling.

    But definitely, Reflex apps can look really cool.


    FAQ

    There is a good range of Python web UI frameworks… 📌

    1. Reflex:

    • Focus: Building interactive web apps with a reactive programming model. It’s designed for complex UIs where you need real-time updates and dynamic behavior.
    • Technology: Uses a Python backend (typically FastAPI) and a frontend built with React. This allows for a rich, single-page application (SPA) experience.
    • Strengths: Excellent for data-driven applications, dashboards, and anything requiring frequent UI updates. The reactive model makes complex interactions manageable.
    • Weaknesses: Steeper learning curve compared to some other frameworks due to the reactive paradigm and the use of both Python and JavaScript (React under the hood, though you mostly interact with it through Python). Can be overkill for very simple UIs.

    2. Flet:

    • Focus: Creating cross-platform desktop and web applications using Flutter (Google’s UI toolkit).
    • Technology: Python backend with a Flutter frontend. This enables native-like performance on desktop and a good web experience.
    • Strengths: Fast development for both desktop and web from a single codebase. Good performance and a modern UI. Relatively easy to learn.
    • Weaknesses: While it handles web, its primary strength is cross-platform desktop development. The UI might not feel completely native on the web compared to frameworks specifically designed for the web.

    3. Streamlit:

    • Focus: Rapidly building data-driven web applications and dashboards, especially for machine learning and data science.
    • Technology: Pure Python, and it handles the frontend rendering for you.
    • Strengths: Extremely easy to learn and use. Excellent for quickly prototyping and deploying data science tools. Has built-in support for displaying data visualizations and interactive widgets.
    • Weaknesses: Not ideal for complex, highly interactive applications. The UI is more basic compared to Reflex or Flet. Not as suitable for apps that require fine-grained UI control or complex event handling.

    4. PySimpleGUI (PyNiceGUI):

    • Focus: Making it easy to create simple GUIs in Python. Its primary focus is on desktop applications.
    • Technology: Wraps various GUI toolkits (Tkinter, Qt, WxPython, etc.) to provide a simplified API.
    • Strengths: Very beginner-friendly. Great for quickly creating simple desktop utilities or tools.
    • Weaknesses: Limited in terms of UI customization and modern look and feel. Not designed for web applications. While there is a project called NiceGUI which is a separate project from PySimpleGUI that allows you to create web UIs, it’s not a direct web equivalent of PySimpleGUI. NiceGUI is more comparable to Streamlit, but with a different syntax and approach.

    Here’s a table summarizing the key differences:

    FeatureReflexFletStreamlitPySimpleGUI/NiceGUI
    Primary FocusComplex web appsCross-platform (desktop & web)Data-driven web appsSimple desktop GUIs / web
    TechnologyPython/ReactPython/FlutterPure PythonPython/Various GUI toolkits
    Learning CurveSteeperModerateEasiestEasiest (PySimpleGUI) / Moderate (NiceGUI)
    UI ComplexityHighModerateLowLow (PySimpleGUI) / Moderate (NiceGUI)
    Web CapabilitiesExcellentGoodGoodNot designed for web (PySimpleGUI) / Good (NiceGUI)
    Data ScienceGoodModerateExcellentLimited (PySimpleGUI) / Good (NiceGUI)

    Which one should you choose?

    • Reflex: If you need to build a complex, interactive web application with real-time updates and a rich UI.
    • Flet: If you want to create a cross-platform application that runs on both desktop and web from a single codebase.
    • Streamlit: If you’re building a data-driven web app or dashboard quickly and easily, especially for data science projects.
    • PySimpleGUI: If you need to create a simple desktop utility or tool with a basic UI.
    • NiceGUI: If you want to create a simple web UI quickly and easily, with a focus on data visualization and interactivity.