flut 0.0.0a15
Flutter, but in Python
Requires Python: >=3.8

# Flut

Flutter, but in Python

## Overview

Flut is a Python project that exposes Flutter to Python's ecosystem. Flut is designed to honestly expose Flutter's API as closely as possible.

### True Flutter

Flutter code maps almost 1:1 from Dart to Python.

```dart
// Flutter (Dart)
Container(
  padding: EdgeInsets.all(16),
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(8),
  ),
  child: Text('Hello'),
)
```

```python
# Flut (Python)
Container(
  padding=EdgeInsets.all(16),
  decoration=BoxDecoration(
    color=Colors.blue,
    borderRadius=BorderRadius.circular(8),
  ),
  child=Text('Hello'),
)
```

Under the hood, the real Flutter widget system is used.

### State-of-the-Art asyncio Integration

Flut provides a true async integration, bridging asyncio with the Flutter UI thread in a design that exactly matches Flutter. Thread safety and event loop conflicts are handled internally.

### No Performance Surprises

The majority of projects using Flut will enjoy near identical performance to Flutter. FFI between Python and Dart does bring additional communication overhead, but the cost is fixed.

## Status

This project is in **Technical Preview**.
- APIs are subject to change.
- Not ready for production use.

## Installation

```bash
pip install flut
```

Prebuilt wheels are available for Windows (x64), macOS (x64, arm64), and Linux (x64).

Building from source is also supported and requires the Flutter SDK.

## Usage

Create a file `app.py`:

```python
from flut import run_app
from flut.flutter.widgets import StatelessWidget, StatefulWidget, State, Text, Center, Column, Icon, MainAxisAlignment
from flut.flutter.material import MaterialApp, Scaffold, AppBar, FloatingActionButton, Icons, ThemeData, ColorScheme, Colors, Theme


class MyApp(StatelessWidget):
    def build(self, context):
        return MaterialApp(
            title="Flut Demo",
            theme=ThemeData(
                colorScheme=ColorScheme.fromSeed(seedColor=Colors.deepPurple),
            ),
            home=MyHomePage(title="Flut Demo Home Page"),
        )


class MyHomePage(StatefulWidget):
    def __init__(self, title):
        super().__init__()
        self.title = title

    def createState(self):
        return _MyHomePageState()


class _MyHomePageState(State[MyHomePage]):
    def initState(self):
        self._counter = 0

    def _incrementCounter(self):
        def _update():
            self._counter += 1

        self.setState(_update)

    def build(self, context):
        return Scaffold(
            appBar=AppBar(
                title=Text(self.widget.title),
                backgroundColor=Theme.of(context).colorScheme.inversePrimary,
            ),
            body=Center(
                child=Column(
                    mainAxisAlignment=MainAxisAlignment.center,
                    children=[
                        Text("You have pushed the button this many times:"),
                        Text(
                            f"{self._counter}",
                            style=Theme.of(context).textTheme.headlineMedium,
                        ),
                    ],
                ),
            ),
            floatingActionButton=FloatingActionButton(
                onPressed=self._incrementCounter,
                tooltip="Increment",
                child=Icon(Icons.add),
            ),
        )


if __name__ == "__main__":
    run_app(MyApp())

```

Run it:

```bash
python app.py
```

For async support:

```python
import asyncio
from flut import run_app_async

# ... your app code ...

if __name__ == "__main__":
    asyncio.run(run_app_async(MyApp()))
```


## Development Setup
```
cd flut/.flutter
flutter build windows/macos/linux --no-tree-shake-icons
```

## License

MIT