Skip to main content

The GetX-inspired Python Framework for Building Reactive, Cross-Platform Apps with Flet

Project description

FletX ๐Ÿš€

The open-source GetX-inspired Python Framework for Building Reactive, Cross-Platform Apps with Flet

PyPI Version Downloads License Discord

Why FletX? โœจ

FletX brings Flutter's beloved GetX patterns to Python, combining Flet's UI capabilities with:

  • โšก Reactive state management
  • ๐Ÿงญ Declarative routing
  • ๐Ÿ’‰ Dependency injection
  • ๐Ÿงฉ Modular architecture
  • ๐ŸŽจ Widget library

Perfect for building desktop, web, and mobile apps with Python at lightning speed.


Showcase

Counter App Todo App
Reactive Forms

Quick Start ๐Ÿ

NOTE: FletX currently supports Python 3.12 only. Compatibility with newer versions is in progress โ€” we're actively working to expand support soon.

Installation

pip install FletXr

Create project

fletx new my_project --no-install

Created project structure ๐Ÿ—๏ธ

my_project/
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ controllers/     # Business logic controllers
โ”‚   โ”œโ”€โ”€ services/       # Business services and API calls
โ”‚   โ”œโ”€โ”€ models/         # Data models
โ”‚   โ”œโ”€โ”€ components/     # Reusable widgets
โ”‚   โ”œโ”€โ”€ pages/          # Application pages
โ”‚   โ””โ”€โ”€ routes.py       # App routing modules
โ”œโ”€โ”€ assets/             # Static assets (images, fonts, etc.)
โ”œโ”€โ”€ tests/              # Test files
โ”œโ”€โ”€ .python-version     # Python version
โ”œโ”€โ”€ pyproject.toml      # Python dependencies
โ”œโ”€โ”€ README.md           # Quick start README
โ””โ”€โ”€ main.py            # Application entry point

To run the project, just navigate to the project folder and run this command

fletx run --web # Will open app in a navigator
        # --desktop to open app in a desktop window
        # --android to open app on Android device
        # --ios to open app on a iOs device
        # --help for more option

Basic Usage (Counter App)

import flet as ft

from fletx.app import FletXApp
from fletx.core import (
    FletXPage, FletXController, RxInt, RxStr
)
from fletx.navigation import router_config
from fletx.decorators import (
    simple_reactive
)


class CounterController(FletXController):
    count = RxInt(0)  # Reactive state


@simple_reactive(
    bindings={
        'value': 'text'
    }
)
class MyReactiveText(ft.Text):

    def __init__(self, rx_text: RxStr, **kwargs):
        self.text: RxStr = rx_text
        super().__init__(**kwargs)

class CounterPage(FletXPage):
    ctrl = CounterController()
    
    def build(self):
        return ft.Column(
            controls = [
                MyReactiveText(rx_text=self.ctrl.count, size=200, weight="bold"),
                ft.ElevatedButton(
                    "Increment",
                    on_click = lambda e: self.ctrl.count.increment()  # Auto UI update
                )
            ]
        )


def main():

    # Defining route
    router_config.add_route(
        **{'path': '/', 'component': CounterPage}
    )
    app = FletXApp(
        title = "My Counter",
        initial_route = "/",
        debug = True
    ).with_window_size(400, 600).with_theme(
        ft.Theme(color_scheme_seed=ft.Colors.BLUE)
    )
    
    # Run sync
    app.run()

if __name__ == "__main__":
    main()

Core Features ๐Ÿง 

1. Reactive State Management

class SearchController(FletXController):
    """Search controller"""
    
    def __init__(self):
        self.query = RxStr("")
        self.results = RxList([])
        self.is_loading = RxBool(False)
        self.is_enabled = RxBool(True)
        
        # Configure reactives effects
        self._setup_reactive_effects()
    
    def _setup_reactive_effects(self):
        """Configure reactive effects"""
        
        # Search with debounce
        @reactive_debounce(0.5)
        @reactive_when(self.is_enabled)
        def search_handler():
            if self.query.value.strip():
                self.perform_search(self.query.value)
        
        # Listen query changes
        self.query.listen(search_handler)
        
        # Cache expensive search results
        @reactive_memo(maxsize=50)
        def expensive_search(query: str):
            # Expensive search simulation
            import time
            time.sleep(0.1)  # Simulate 
            return [f"Result {i} for '{query}'" for i in range(5)]
        
        self.expensive_search = expensive_search

        # Other actions here...

2. Smart Routing

# Define routes
from flex.navigation import router_config, navigate

# 1. simple routing
router_config.add_routes([
    {"path": "/", "component": HomePage},
    {"path": "/settings", "component": SettingsPage}
])

# 2. Dynamic routes with parameters
router_config.add_routes([
    {
        "path": "/users/:id",
        "component": lambda route: UserDetailPage(route.params['id'])
    },
    {
        "path": "/products/*category",
        "component": lambda route: ProductsPage(route.params['category'])
    }
])
# Navigate programmatically
navigate("/users/123")

3. Dependency Injection

# Register services
FletX.put(AuthService(), tag="auth")

# Retrieve anywhere
auth_service = FletX.find(AuthService, tag="auth")

4. Reactive Widgets

FletX allows you to quickly create reactive widgets from flet Controls by using reactive widget decorators.

from fletx.decorators import (
    reactive_control, simple_reactive,
    reactive_state_machine, reactive_form,
    two_way_reactive, reactive_list,
    ...
)

Community & Support ๐Ÿ’ฌ


๐Ÿค Contributing

We welcome contributions from the community! Please see the CONTRIBUTING.md guide for more information.


License ๐Ÿ“œ

MIT ยฉ 2025 AllDotPy

# Happy coding! 
# Let's build amazing apps with Python ๐Ÿ

Made with โค๏ธ By AllDotPy

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fletxr-0.1.3.tar.gz (329.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fletxr-0.1.3-py3-none-any.whl (376.5 kB view details)

Uploaded Python 3

File details

Details for the file fletxr-0.1.3.tar.gz.

File metadata

  • Download URL: fletxr-0.1.3.tar.gz
  • Upload date:
  • Size: 329.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.7

File hashes

Hashes for fletxr-0.1.3.tar.gz
Algorithm Hash digest
SHA256 626149299fe6ad2156014e4a26ba9d5472acf1bb0ca9d25229f7e7d2a9ca4bd5
MD5 d41d2da29850b38fa5fb80974574800e
BLAKE2b-256 4177c3e2b8c7f87f2f7617761631d43cf33e740a7d5b2e09b8258369d133e200

See more details on using hashes here.

File details

Details for the file fletxr-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: fletxr-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 376.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.7

File hashes

Hashes for fletxr-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 7cb58aff6d35a7fd197d192503408dfaf524864a0e6bdd362f805ef805933cef
MD5 3ceb126c577d3e2af2567b4a6a8cd098
BLAKE2b-256 a0447a35b83e826e602b8b8adb7057a91ff3ba08678a156b6abb4db244372709

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page