• Stars
    star
    680
  • Rank 66,440 (Top 2 %)
  • Language
    Python
  • License
    MIT License
  • Created over 5 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Create desktop applications with Flask/Django/FastAPI!

Flaskwebgui

Downloads PyPI

Create desktop applications with Flask/FastAPI/Django!

Install

pip install flaskwebgui

If you are using conda checkout this link.

Usage with Flask

Let's say we have the following flask application:

#main.py

from flask import Flask  
from flask import render_template
from flaskwebgui import FlaskUI # import FlaskUI

app = Flask(__name__)


@app.route("/")
def hello():  
    return render_template('index.html')

@app.route("/home", methods=['GET'])
def home(): 
    return render_template('some_page.html')


if __name__ == "__main__":
  # If you are debugging you can do that in the browser:
  # app.run()
  # If you want to view the flaskwebgui window:
  FlaskUI(app=app, server="flask").run()
   

Install waitress for more performance.

Usage with Flask-SocketIO

Let's say we have the following SocketIO application:

#main.py
from flask import Flask, render_template
from flask_socketio import SocketIO
from flaskwebgui import FlaskUI


app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

@app.route("/")
def hello():  
    return render_template('index.html')

@app.route("/home", methods=['GET'])
def home(): 
    return render_template('some_page.html')


if __name__ == '__main__':
    # socketio.run(app) for development
    FlaskUI(
        app=app,
        socketio=socketio,
        server="flask_socketio",
        width=800,
        height=600,
    ).run()

App will be served by flask_socketio.

Usage with FastAPI

Pretty much the same, below you have the main.py file:

#main.py
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi import FastAPI
from flaskwebgui import FlaskUI

app = FastAPI()

# Mounting default static files
app.mount("/dist", StaticFiles(directory="dist/"), name="dist")
app.mount("/css", StaticFiles(directory="dist/css"), name="css")
app.mount("/img", StaticFiles(directory="dist/img"), name="img")
app.mount("/js", StaticFiles(directory="dist/js"), name="js")
templates = Jinja2Templates(directory="dist")


@app.get("/", response_class=HTMLResponse)
async def root(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})


@app.get("/home", response_class=HTMLResponse)
async def home(request: Request): 
    return templates.TemplateResponse("some_page.html", {"request": request})


if __name__ == "__main__":
    
    FlaskUI(app=app, server="fastapi").run()

FastApi will be served by uvicorn.

Usage with Django

Next to manage.py file create a gui.py file where you need to import application from project's wsgi.py file.

β”œβ”€β”€ project_name
β”‚   β”œβ”€β”€ asgi.py
β”‚   β”œβ”€β”€ settings.py
β”‚   β”œβ”€β”€ urls.py
β”‚   └── wsgi.py
β”œβ”€β”€ gui.py # this 
β”œβ”€β”€ manage.py

In gui.py file add below code.

#gui.py
from flaskwebgui import FlaskUI
from djangodesktop.wsgi import application as app

if __name__ == "__main__":
    FlaskUI(app=app, server="django").run()

Next start the application with:

python gui.py  

Install waitress for more performance.

Close application using a route

You can close the application using the close_application from flaskwebgui. Please note that this requires installing pyautogui package.

from flaskwebgui import FlaskUI, close_application

# Any python webframework routing here

@app.route("/close", methods=["GET"])
def close_window():
    close_application()

And somewhere a link:

<a href="/close" class="exit" role="button">
    CLOSE
</a>

When close_application is called ctrl+w keystrokes are pressed to close the chrome window and the current python process is killed. This hacky implemantation does the job. Feel free to open a PR for a cleaner cross platform alternative.

Configurations

Default FlaskUI class parameters:

  • server: Union[str, Callable[[Any], None]]: function which receives server_kwargs to start server (see examples folder);
  • server_kwargs: dict = None: kwargs which will be passed down to server function;
  • app: Any = None: wsgi or asgi app;
  • port: int = None: specify port if not a free port will set;
  • width: int = None: width of the window;
  • height: int = None: height of the window;
  • fullscreen: bool = True: start app in fullscreen (maximized);
  • on_startup: Callable = None: function to before starting the browser and webserver;
  • on_shutdown: Callable = None: function to after the browser and webserver shutdown;
  • browser_path: str = None: set path to chrome executable or let the defaults do that;
  • browser_command: List[str] = None: command line with starts chrome in app mode;
  • socketio: Any = None: socketio instance in case of flask_socketio;

Develop your app as you would normally do, add flaskwebgui at the end or for tests. flaskwebgui doesn't interfere with your way of doing an application it just helps converting it into a desktop app more easily with pyinstaller or pyvan.

Advanced Usage

You can plug in any python webframework you want just by providing a function to start the server in server FlaskUI parameter which will be feed server_kwargs.

Example:

# until here is the flask example from above

def start_flask(**server_kwargs):

    app = server_kwargs.pop("app", None)
    server_kwargs.pop("debug", None)

    try:
        import waitress

        waitress.serve(app, **server_kwargs)
    except:
        app.run(**server_kwargs)


if __name__ == "__main__":

    # Custom start flask

    def saybye():
        print("on_exit bye")

    FlaskUI(
        server=start_flask,
        server_kwargs={
            "app": app,
            "port": 3000,
            "threaded": True,
        },
        width=800,
        height=600,
        on_shutdown=saybye,
    ).run()

In this way any webframework can be plugged in and the webframework can be started in a more customized manner.

Here is another example with the nicegui package:

from flaskwebgui import FlaskUI
from nicegui import ui

ui.label("Hello Super NiceGUI!")
ui.button("BUTTON", on_click=lambda: ui.notify("button was pressed"))

def start_nicegui(**kwargs):
    ui.run(**kwargs)

if __name__ in {"__main__", "__mp_main__"}:
    DEBUG = False

    if DEBUG:
        ui.run()
    else:
        FlaskUI(
            server=start_nicegui,
            server_kwargs={"dark": True, "reload": False, "show": False, "port": 3000},
            width=800,
            height=600,
        ).run()

Checkout examples for more information.

Distribution

You can distribute it as a standalone desktop app with pyinstaller or pyvan. If pyinstaller failes try pyinstaller version 5.6.2.

Observations

  • Parameters width, height and maybe fullscreen may not work on Mac;
  • Window control is limited to width, height, fullscreen;
  • Remember the gui is still a browser - pressing F5 will refresh the page + other browser specific things (you can hack it with js though);
  • You don't need production level setup with gunicorn etc - you just have one user to serve;
  • If you want to debug/reload features - just run it as you would normally do with app.run(**etc), uvicorn.run(**etc), python manage.py runserver etc. flaskwebgui does not provide auto-reload you already have it in the webframework you are using;

Credits

It's a combination of https://github.com/Widdershin/flask-desktop and https://github.com/ChrisKnott/Eel

It has some advantages over flask-desktop because it doesn't use PyQt5, so you won't have any issues regarding licensing and over Eel because you don't need to learn any logic other than Flask/Django/FastAPI/etc.

Submit any questions/issues you have! Fell free to fork it and improve it!

More Repositories

1

pyvan

Make runnable desktop apps from your python scripts more easily with pyvan!
Python
138
star
2

fastapi-mongo-caddy2-vue-react-svelte

JavaScript
14
star
3

fiberwebgui

Create cross-platform desktop apps using Fiber and GO!
Go
13
star
4

PFASimplu

Aplicatie/soft pentru cei care tin contabilitatea in partida simpla (PFA/II, etc)
HTML
10
star
5

Local-Remote-Developer-Jobs-Aggregator

Customizable remote jobs aggregator.
JavaScript
9
star
6

vue-mithril-comparison

A comparison between Vue and Mithril.
JavaScript
9
star
7

pandas-dataframe-to-sqlite3-database

This file can be used to save to database all existing excel/txt files from a given folder
Jupyter Notebook
5
star
8

pywebview-flask-boilerplate-for-python-desktop-apps

Boilerplate for pywebview + flask medium size apps
Python
5
star
9

pyrobogui

Wrapper around pyautogui - plus some new functions. Ideal for doing robotic process automation.
Jupyter Notebook
5
star
10

kerground

Stupid simple background worker based on python.
Python
4
star
11

react-mithril-comparison

A comparison between React and Mithril.
JavaScript
4
star
12

htmgem

Generate HTML with Python.
Python
3
star
13

py7zip

Unzipping password protected files with 7zip and python fast!
Python
3
star
14

tkinter-boilerplate

tkinter boilerplate with progress bar/ status bar/ percentage indicator / fields inputs / labels
Python
3
star
15

simple-server-monitor

Monitor your web apps with a simple chrome extension. Get notified on events you consider important.
JavaScript
3
star
16

simple-firebase

Firebase made a little bit easier.
HTML
2
star
17

svelte-mithril-comparison

A comparison between Svelte and Mithril
JavaScript
2
star
18

sales-assistant-react-golang-sql

TypeScript
1
star
19

bunjucks

Create custom static websites fast!
CSS
1
star
20

vamp-theme-notepad

Dark theme for notepad++
1
star
21

dsjs

Snippets for doing data science stuff with Javascript in the browser
JavaScript
1
star
22

gobadrepo

Useful CRUD funcs over sqlx go package
Go
1
star
23

Python-reverse-binary-from-files

Reverse binary from files given
Python
1
star