Reflex. Cooler Web Apps?

Reflex. Cooler Web Apps?

February 12, 2025
ℹ️
See the source code magic 🔥💻

The Reflex Package

Apache v2 | 🕸️ Web apps in pure Python 🐍

What I want to use it for?

How about enhancing this streamlit projects?

Enhancing in a way…that they are also good looking and providing UI/UX for mobile users?

Lets have a look.

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!)
sudo docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

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

These are the main files and structure of a Reflex Project:

    • _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

    Now its time to rebuild with Reflex some Streamlit apps I made!

    Historical Job Market Data with Reflex

    For this one

    See the details 📌

    Real Estate with Reflex

    Lately Ive been playing with RE data driven apps.

    And with Reflex and some tricks with Gemini…

    Reflex using Components

    More 📌

    RE Questions

    1. In which month does interest and payments are 50/50?
    2. When does the rent cover the interest costs?
    3. The interest/principal split just depends on: years and %interest
    4. The PER of the flats depends on the city/neighbourhood you look:
    Examples of PER for RE 📌

    More RE Costs

    Those are gross yields, remember that there are many costs, amortizations,… related that you will have to plug for your specific case.

    Lets say that it cost ~65eur afor 15kg of paint.

    With that one, you can paint ~100m2.

    Price of the painting 📌

    How to estimate the wall size in your flat based on the floor plan and the total area.

    Understanding the Challenge

    We only have the area of each room, not the exact dimensions (length and width). To estimate wall length, we’ll need to make some assumptions about the shape of the rooms.

    Assumptions

    1. Rectangular Rooms: We’ll assume all rooms are roughly rectangular. This is a common assumption for floor plans.
    2. Simplified Shapes: We’ll treat the overall shape of the flat as a rectangle for easier calculation.

    Estimation Process

    1. Calculate the Perimeter of Each Room:

      • For a rectangle, the perimeter is 2 * (length + width).
      • Since we only have the area, we’ll need to estimate the length and width. We can do this by assuming the rooms are close to square for an initial estimate.
      • For example, for a room with 26.4 m², assuming it’s square, each side would be approximately √26.4 ≈ 5.14 meters. The perimeter would be roughly 4 * 5.14 ≈ 20.56 meters.
    2. Sum the Perimeters: Add up the estimated perimeters of all the rooms.

    3. Adjust for Shared Walls: The sum of the perimeters will overcount the walls because it counts each wall twice (once for each room it borders). We need to subtract the length of the shared walls.

    4. Estimate Shared Walls:

      • Look at the floor plan and estimate which walls are shared between rooms.
      • Make reasonable estimations of the length of these shared walls.
    5. Subtract Shared Wall Lengths: Subtract the estimated total length of shared walls from the sum of the perimeters.

    Let’s Do the Calculations (Rough Estimate)

    1. Room Perimeters (Approximations):

      • Pokój dzienny (26.4 m²): ≈ 20.56 m
      • Pokój (9.2 m²): ≈ 12.12 m
      • Łazienka (4.4 m²): ≈ 8.37 m
      • Kuchnia (6.4 m²): ≈ 10.12 m
      • Przedpokój (7 m²): ≈ 10.58 m
      • Loggia (2.6 m²): ≈ 6.44 m
    2. Sum of Perimeters: 20.56 + 12.12 + 8.37 + 10.12 + 10.58 + 6.44 ≈ 68.19 meters

    3. Estimate Shared Walls:

      • Looking at the floor plan, there are several shared walls. We need to estimate their lengths.
      • This is where it gets tricky without exact dimensions. Let’s make a rough guess that the total length of shared walls is about 20 meters (this is just an estimation).
    4. Subtract Shared Walls: 68.19 - 20 ≈ 48.19 meters

    Important Note: This is a rough estimation. Without precise dimensions, it’s impossible to get an exact wall length.

    Refining the Estimate

    To improve the estimate, you would need:

    • More Detailed Dimensions: If you have the length and width of each room, the calculations would be much more accurate.
    • Wall Thickness: We haven’t accounted for wall thickness, which would add to the overall length.

    Be knowing the area (55m2 for example), you already know the ceiling paint.

    Or you can just estimate the internal walls with sqrt(area=55) = 7.7

    So that would be 15m, times the height of the walls (say 2m), which would be 30 m2.

    But you are missing all internal walls which make the rooms, say thats 100% more.

    First estimation ~ 55+30*2 = 115m2, which for 2 layers would be ~30kg

    RE Resources

    1. https://tradingeconomics.com/poland/consumer-price-index-cpi (see the change %)
    2. https://tradingeconomics.com/poland/interest-rate

    Conclusions

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

    That makes it easier to iterate.

    But definitely, Reflex apps can look really cool, also on smartphones!


    FAQ

    There is a good range of Python web Apps 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.

    Let’s summarize 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 Python Web App fwk 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.
    Popular Full-Stack… Tech Stacks 📌

    Some of the most popular and in-demand full-stack tech stacks currently used in software development:

    • MERN Stack:
      • MongoDB (Database)
      • Express.js (Backend Framework)
      • React.js (Frontend Library)
      • Node.js (Backend Runtime)
      • This JavaScript-based stack is highly popular for building dynamic, single-page applications.
    • MEAN Stack:
      • MongoDB (Database)
      • Express.js (Backend Framework)
      • Angular (Frontend Framework)
      • Node.js (Backend Runtime)
      • Similar to MERN, but uses Angular instead of React.
    • LAMP Stack:
      • Linux (Operating System)
      • Apache (Web Server)
      • MySQL (Database)
      • PHP (Backend Language)
      • A classic and reliable stack, widely used for building dynamic websites and web applications.
    • Python/Django Stack:
      • Python (Backend Language)
      • Django (Backend Framework)
      • PostgreSQL or MySQL (Database)
      • Ideal for data-driven applications, machine learning projects, and complex web applications.
    • Ruby on Rails (RoR):
      • Ruby (Backend Language)
      • Rails (Backend Framework)
      • PostgreSQL or MySQL (Database)
      • Known for its rapid development capabilities and convention-over-configuration approach.
    • Java Spring Boot Stack:
      • Java (Backend Language)
      • Spring Boot (Backend Framework)
      • MySQL or PostgreSQL (Database)
      • React or Angular (Frontend)
      • A robust and scalable stack commonly used for enterprise-level applications.
    • .NET Stack:
      • C# (Backend Language)
      • ASP.NET Core (Backend Framework)
      • SQL Server or PostgreSQL (Database)
      • A Microsoft-developed stack, well-suited for building scalable and secure web applications.
    • Serverless Stack:
      • AWS Lambda or Google Cloud Functions (Backend)
      • API Gateway (API Management)
      • DynamoDB or Firestore (Database)
      • React or Vue.js (Frontend)
      • Focuses on serverless computing, offering scalability and cost-efficiency.
    • MEVN Stack:
      • MongoDB (Database)
      • Express.js (backend framework)
      • Vue.js (frontend framework)
      • Node.js (server-side runtime)
    • Flutter/Firebase Stack:
      • Dart (Programming language)
      • Flutter (UI toolkit)
      • Firebase (Backend-as-a-service)
      • Very popular for cross platform mobile app development.

    Key Considerations:

    • Project Requirements: The nature of your project will significantly influence your tech stack choice.
    • Team Expertise: Your team’s familiarity with specific technologies is crucial.
    • Scalability: Consider the stack’s ability to handle future growth.
    • Community Support: A strong community provides ample resources and assistance.
    Django… and what about the UI? 📌

    When using Django for the backend, developers have a wide range of choices for their UI frontend.

    Here are some of the most common and popular options:

    1. Django’s Built-in Templating System:

    • This is the most straightforward option. Django’s templating language allows you to embed dynamic content directly within your HTML.
    • It’s well-suited for simpler applications or when you want tight integration between the backend and frontend.
    • Pros: Easy to learn, tightly integrated with Django.
    • Cons: Can become less maintainable for complex UIs.

    2. React.js:

    • React is a very popular JavaScript library for building user interfaces.
    • It’s excellent for creating single-page applications (SPAs) and complex UIs.
    • Pros: Component-based architecture, excellent performance, large community.
    • Cons: Requires separate development for the frontend and backend, steeper learning curve.
    • Often Django Rest Framework is used to create an API that the React front end consumes.

    3. Vue.js:

    • Vue.js is another progressive JavaScript framework for building user interfaces.
    • It’s known for its simplicity and ease of integration.
    • Pros: Easy to learn, flexible, good performance.
    • Cons: Smaller community compared to React, but growing rapidly.
    • Often Django Rest Framework is used to create an API that the Vue.js front end consumes.

    4. Angular:

    • Angular is a powerful JavaScript framework developed by Google.
    • It’s well-suited for building large-scale applications.
    • Pros: Comprehensive framework, strong type checking, good for enterprise applications.
    • Cons: Steeper learning curve, can be more complex than React or Vue.
    • Often Django Rest Framework is used to create an API that the Angular front end consumes.

    5. HTML, CSS, and JavaScript (Vanilla):

    • For simpler applications, you can use plain HTML, CSS, and JavaScript without any frameworks.
    • This gives you complete control over the frontend.
    • Pros: Lightweight, no external dependencies.
    • Cons: Can become difficult to manage for complex UIs.

    6. Tailwind CSS:

    • While not a full front end framework, Tailwind CSS is very popular with django projects. It is a utility first CSS framework, that allows for very rapid UI development.
    • It can be combined with any of the above, and is most often used with Django’s built in templating, or with Vue.js.

    Key Considerations:

    • Complexity: For simple applications, Django’s templating or vanilla JavaScript might suffice. For complex UIs, React, Vue, or Angular are better choices.
    • Single Page Applications: If you’re building an SPA, React, Vue, or Angular are ideal.
    • Team Expertise: Choose a technology that your team is comfortable with.
    • API Development: If you’re using a JavaScript framework, you’ll need to create an API using Django REST Framework (DRF) to connect the frontend and backend.

    In summary, while Django’s templating is a valid option, the trend leans heavily towards using JavaScript frameworks like React, Vue, or Angular for more modern and dynamic user interfaces.

    Yes, you can achieve similar outcomes with Dash, Shiny, Streamlit, and Reflex as you can with Django, but the approaches and use cases differ significantly. Here’s a breakdown:

    Core Differences:

    • Django:
      • A full-fledged web framework for building complex, scalable web applications.
      • Handles both frontend and backend, with robust ORM, templating, and routing.
      • Ideal for large, data-driven web applications and APIs.
    • Dash, Shiny, Streamlit, Reflex:
      • Primarily focused on building interactive data visualizations and web applications with Python or R.
      • Emphasize rapid development and ease of use, particularly for data scientists and analysts.
      • Generally, they are not used for complex web applications that require a lot of user management, or complex relational databases.
      • They are more focused on data visualization, and data exploration.

    Similarities and Differences:

    1. Dash (Python):
      • Built on top of Flask, React, and Plotly.
      • Excellent for creating interactive dashboards and data visualizations.
      • More customizable than Streamlit or Shiny.
      • Can handle more complex layouts and interactions.
      • Less focused on general web application development than Django.
      • Good for data dashboards.
    2. Shiny (R):
      • Specifically designed for R users to build interactive web applications.
      • Seamless integration with R’s data analysis and visualization capabilities.
      • Ideal for sharing R-based analyses and models.
      • Less general-purpose than Django or Dash.
      • Good for R based data dashboards.
    3. Streamlit (Python):
      • Extremely easy to use for creating data-driven web applications.
      • Focuses on simplicity and rapid prototyping.
      • Automatically renders changes, making development very fast.
      • Less customizable than Dash or Django.
      • Excellent for quickly sharing data science projects.
      • Good for quick data app creation.
    4. Reflex (Python):
      • A newer framework that allows you to build fully reactive web apps in pure python.
      • Combines frontend and backend logic into a single python codebase.
      • Good for creating interactive web apps, with a focus on ease of use.
      • Less mature than Django.
      • Good for python first web apps.

    When to Use Which:

    • Use Django:
      • When building complex web applications with user authentication, database management, and API development.
      • For large-scale projects requiring robustness and scalability.
      • For projects that need a traditional web application structure.
    • Use Dash, Shiny, Streamlit, or Reflex:
      • When creating interactive data visualizations and dashboards.
      • For rapid prototyping and sharing data science projects.
      • When you need to quickly build web applications with Python or R.
      • When your primary goal is to display and interact with data.
      • When you do not need complex user management.

    In essence:

    • Django is a general-purpose web framework.
    • Dash, Shiny, Streamlit, and Reflex are specialized tools for building interactive data applications.

    Therefore, while you can create web applications with all of them, the best choice depends on your specific project requirements.