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
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 ๐ฌ
- Documentation ๐ (not available for now.)
- Discord Community ๐ฌ
- Issue Tracker ๐
๐ค 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
626149299fe6ad2156014e4a26ba9d5472acf1bb0ca9d25229f7e7d2a9ca4bd5
|
|
| MD5 |
d41d2da29850b38fa5fb80974574800e
|
|
| BLAKE2b-256 |
4177c3e2b8c7f87f2f7617761631d43cf33e740a7d5b2e09b8258369d133e200
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7cb58aff6d35a7fd197d192503408dfaf524864a0e6bdd362f805ef805933cef
|
|
| MD5 |
3ceb126c577d3e2af2567b4a6a8cd098
|
|
| BLAKE2b-256 |
a0447a35b83e826e602b8b8adb7057a91ff3ba08678a156b6abb4db244372709
|