This template provides a starting point for building native-like desktop applications using Python, powered by a Flask backend and a dynamic frontend using HTMX, all packaged within a PyWebview window.
It allows you to leverage Python for backend logic while using standard web technologies (HTML, CSS) enhanced with HTMX for creating interactive UIs with minimal JavaScript.
- Native Window: Uses
pywebviewto create a lightweight native OS window. - Python Backend: Employs
Flaskfor handling requests, routing, and server-side logic. - Dynamic Frontend: Uses
HTMXto enable modern browser features (AJAX, CSS Transitions, WebSockets) directly from HTML, reducing the need for custom JavaScript. - Standard Web Tech: Build your UI with HTML, CSS, and Flask's Jinja2 templating.
- Cross-Platform: Compatible with Windows, macOS, and Linux.
/
├── .venv/ # Virtual environment directory
├── static/ # Static files (CSS, JS, images)
│ ├── css/style.css
│ └── js/ # (Optional JS if needed)
├── templates/ # HTML templates (Jinja2)
│ └── index.html
├── app.py # Main application entry point (Initializes Flask & PyWebview)
├── routes.py # Flask Blueprint containing application routes/view functions
├── requirements.txt # Python dependencies
├── user_methods.py # (Optional) For non-route Python helper functions/classes
└── README.md # This file
-
Clone the repository and remove the .git folder:
# Linux/Mac git clone https://github.com/slate20/PyWebNative NEW_PROJECT_NAME cd NEW_PROJECT_NAME rm -rf .git
# Windows git clone https://github.com/slate20/PyWebNative NEW_PROJECT_NAME cd NEW_PROJECT_NAME rmdir /s /q .git
-
Create and activate a virtual environment:
# Linux/Mac python3 -m venv .venv source .venv/bin/activate
# Windows python -m venv .venv .venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
# Linux/Mac
python3 app.py# Windows
python app.pyThis will start the Flask development server and open the pywebview window, loading the application.
-
Define a Route: Add a new function decorated with
@bp.route('/your-new-route', methods=['GET', 'POST'])inroutes.py.- This function will handle requests to
/your-new-route. - It should typically return an HTML fragment or redirect.
- This function will handle requests to
-
Update the Frontend: In
templates/index.html(or other templates):- Add HTML elements.
- Use HTMX attributes (e.g.,
hx-get,hx-post,hx-target,hx-swap) on elements (like buttons or forms) to trigger requests to your new route. - Specify a target element where the HTML response from your route should be placed.
-
Add Static Files: Place CSS, JavaScript (if absolutely necessary), or images in the
static/directory and reference them in your templates using{{ url_for('static', filename='path/to/your/file') }}.
-
routes.py:
import os # ... other imports ... @bp.route('/clear_data', methods=['POST']) def clear_data_route(): try: if os.path.exists('data.json'): os.remove('data.json') return "<p style='color: orange;'>Data cleared.</p>" else: return "<p style='color: grey;'>No data file to clear.</p>" except Exception as e: return f"<p style='color: red;'>Error clearing data: {e}</p>"
-
templates/index.html (Inside the 'Save Data Test' section):
<section class="card"> <h2>Save Data Test</h2> <div class="form-group" hx-swap="innerHTML"> <textarea id="data-input" name="data-input" placeholder="Enter JSON data to save..."></textarea> <!-- Existing Save Button --> <button hx-post="/save_data" hx-include="[name='data-input']" hx-target="#save-result" hx-indicator="#save-result">Save Data</button> <!-- New Clear Button --> <button hx-post="/clear_data" hx-target="#save-result" hx-indicator="#save-result">Clear Saved Data</button> </div> <div id="save-result" class="result"></div> </section>
This template includes some demo functionality (getting system info, echoing input, saving data) to showcase how Flask, HTMX, and pywebview work together. To start a fresh project, you can remove the following:
-
Demo Routes in
routes.py:- Delete the
@bp.route('/get_system_info'),@bp.route('/echo'), and@bp.route('/save_data')blocks. - Remove the corresponding import from
logicif it's no longer needed (e.g.,get_formatted_system_info,get_echo_response,save_json_data).
- Delete the
-
Demo Logic in
logic.py:- Delete the
get_formatted_system_info(),get_echo_response(), andsave_json_data()functions. - Remove unused imports like
sysandtimeif they were only for the demo functions.
- Delete the
-
Demo UI Elements in
templates/index.html:- Remove the
<div>sections related to "System Info", "Echo Test", and "Save Data". - Clean up any associated HTMX attributes (
hx-get,hx-post,hx-target,hx-swap) from the remaining HTML if they pointed to the deleted routes.
- Remove the
-
Demo Data File:
- Delete the
data.jsonfile (if it was created during testing).
- Delete the
After removing these, you'll have a clean structure with app.py, routes.py (containing just the root / route initially), logic.py (ready for your functions), and templates/index.html (ready for your UI) to build upon.
- PyWebview: https://pywebview.flowrl.com/
- Flask: https://flask.palletsprojects.com/
- HTMX: https://htmx.org/
- Jinja2 (Templating): https://jinja.palletsprojects.com/