Web приложение на Python Flask/PySide6 в виде десктопной программы


В этой статье мы рассмотрим вариант создания веб-приложения на Python Flask / PySide6 в качестве настольной программы для Windows. Библиотека Flask будет отвечать за обработку запросов, а PySide6 - за вывод полученной информации.
В этой статье мы рассмотрим вариант создания веб-приложения на Python Flask / PySide6 в качестве настольной программы для Windows. Библиотека Flask будет отвечать за обработку запросов, а PySide6 - за вывод полученной информации.
Как это работает
- start: Основной скрипт, который запускает веб-службу и браузер через субпроцессы;
- web_service: Веб-служба, работающая на Flask, обрабатывает запросы и предоставляет интерфейс;
- browser: Интерфейсный модуль на PySide6, который использует встроенный браузер (QWebEngineView) для отображения сайта;
- design: Директория, в которой находится структура сайта (HTML, CSS, JS);
Start
#-*- coding: UTF-8 -*-
import time, subprocess
class Main():
def __init__(self):
host = '127.0.0.1'
port = '5000'
try:
web_service = subprocess.Popen(["python", "web_service.py", host, port])
browser = subprocess.Popen(["python", "browser.py", host, port])
while True:
time.sleep(1)
except KeyboardInterrupt:
pass
print("Основной процесс завершен. Завершаем субпроцесс.")
web_service.terminate()
browser.terminate()
web_service.wait()
browser.wait()
print("Субпроцессы завершены.")
if __name__ == "__main__":
Main()
Browser
#-*- coding: UTF-8 -*-
import sys
from PySide6.QtCore import QUrl
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtWebEngineWidgets import QWebEngineView
host = sys.argv[1]
port = sys.argv[2]
url = 'http://'+host+':'+port
class Browser():
def __init__(self):
app = QApplication(sys.argv)
mw = QMainWindow()
mw.setWindowTitle("WebApp")
mw.setGeometry(100, 100, 800, 600)
mw.browser = QWebEngineView()
mw.browser.setUrl(QUrl(url))
mw.setCentralWidget(mw.browser)
mw.show()
sys.exit(app.exec())
if __name__ == "__main__":
Browser()
Web_service
#-*- coding: UTF-8 -*-
from flask import Flask, request, Response
import re, mimetypes, sys
host = sys.argv[1]
port = sys.argv[2]
class webService:
def __init__(self):
self.app = Flask(__name__)
# Получение запроса
@self.app.route('/', defaults={'path': ''})
@self.app.route('/', methods=['GET', 'POST'])
def route(path):
answer = self.process_route()
return Response(response = answer['response'], status = answer['status'], mimetype = answer['mimetype'])
self.app.run(host=host, port=port, debug=True)
# Определение mimeType
def get_mime_type(self, file_path):
mime_type, _ = mimetypes.guess_type(file_path)
return mime_type
# Изменение данных в строке с помощью replace через цикл
def replace_str(self, strData, mData):
for keyItem, dataItem in mData.items():
strData = strData.replace(keyItem, dataItem)
return strData
# Очистка параметров
def clean_string(self, input_string):
cleaned_string = re.sub(r'[^a-zA-Z0-9]', '', input_string)
return cleaned_string
# Обработка входящих параметров
def proccess_params(self):
result = {}
try:
urlRequest = request.url
mParam = urlRequest.split('?')
if len(mParam) > 1:
mVar = mParam[1].split('&')
for item in mVar:
mItem = item.split('=')
if mItem[0] == '' or len(mItem) == 1:
continue
result[self.clean_string(mItem[0])] = self.clean_string(mItem[1])
except Exception as e:
print('proccess_params: '+str(e))
return result
# Работа с шаблоном
def process_template(self, path_file, typeRead = 'r'):
try:
if typeRead == 'rb':
with open(path_file, typeRead) as f:
result = f.read()
else:
with open(path_file, typeRead, encoding='utf-8') as f:
result = f.read()
except Exception as e:
raise Exception('404')
return result
# Обработка запроса
def process_route(self):
result = {'status': 200, 'response': '', 'mimetype': 'text/html', 'typeRead': 'r'}
try:
server_host = str(request.scheme)+'://'+str(request.server[0])+':'+str(request.server[1])
request_data = {'method': request.method, 'path': request.view_args['path'].split('/'), 'variable': self.proccess_params()}
if request_data['method'] == 'GET':
if request_data['path'][0] == '':
request_data['path'][0] = 'index.html'
# Подгрузка страницы
if len(request_data['path']) == 1:
result['response'] = self.process_template('design/template/'+request_data['path'][0])
# Подгрузка дизайна
elif request_data['path'][0] == 'design':
result['mimetype'] = self.get_mime_type(request.view_args['path'])
mMimetype = str(result['mimetype']).split('/')
result['typeRead'] = 'rb' if mMimetype[0] == 'image' else 'r'
result['response'] = self.process_template(request.view_args['path'], result['typeRead'])
if result['response'] == False:
raise Exception('404')
else:
raise Exception('404')
else:
raise Exception('404')
except Exception as e:
# Подгрузка 404 страницы
result['response'] = self.process_template('design/template/404.html')
result['status'] = 404
if result['typeRead'] != 'rb':
mData = {'SERVER_HOST': server_host}
result['response'] = self.replace_str(result['response'], mData)
return result
if __name__ == "__main__":
webService()
Design
project/
├── start.py
├── browser.py
├── web_service.py
├── design/
│ ├── template/
│ └── css/
│ └── img/
│ └── js/
Для создания дополнительных страниц, достаточно в директорию design/template/ добавить html файл с названием страницы.
Запуск
Установите необходимые библиотеки:
pip install flask PySide6
Запустите start.py
python start.py
После запуска приложение откроется в виде окна, а внутри него будет отображаться веб-интерфейс, работающий на Flask.
Исходный кодЗаключение
Мы создали десктопное приложение, которое использует Flask для обработки веб-запросов и PySide6 для отображения интерфейса в настольном окне. Эта архитектура позволяет легко разрабатывать приложения с гибкими веб-технологиями, обеспечивая десктопный интерфейс.
- 27.12.2024
- 129
- 0
Web приложение на Python Flask/PySide6 в виде десктопной программы
В этой статье мы рассмотрим вариант создания веб-приложения на Python Flask / PySide6 в качестве настольной программы для Windows. Библиотека Flask будет отвечать за обработку запросов, а PySide6 - за вывод полученной информации.
Как это работает
- start: Основной скрипт, который запускает веб-службу и браузер через субпроцессы;
- web_service: Веб-служба, работающая на Flask, обрабатывает запросы и предоставляет интерфейс;
- browser: Интерфейсный модуль на PySide6, который использует встроенный браузер (QWebEngineView) для отображения сайта;
- design: Директория, в которой находится структура сайта (HTML, CSS, JS);
Start
#-*- coding: UTF-8 -*-
import time, subprocess
class Main():
def __init__(self):
host = '127.0.0.1'
port = '5000'
try:
web_service = subprocess.Popen(["python", "web_service.py", host, port])
browser = subprocess.Popen(["python", "browser.py", host, port])
while True:
time.sleep(1)
except KeyboardInterrupt:
pass
print("Основной процесс завершен. Завершаем субпроцесс.")
web_service.terminate()
browser.terminate()
web_service.wait()
browser.wait()
print("Субпроцессы завершены.")
if __name__ == "__main__":
Main()
Browser
#-*- coding: UTF-8 -*-
import sys
from PySide6.QtCore import QUrl
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtWebEngineWidgets import QWebEngineView
host = sys.argv[1]
port = sys.argv[2]
url = 'http://'+host+':'+port
class Browser():
def __init__(self):
app = QApplication(sys.argv)
mw = QMainWindow()
mw.setWindowTitle("WebApp")
mw.setGeometry(100, 100, 800, 600)
mw.browser = QWebEngineView()
mw.browser.setUrl(QUrl(url))
mw.setCentralWidget(mw.browser)
mw.show()
sys.exit(app.exec())
if __name__ == "__main__":
Browser()
Web_service
#-*- coding: UTF-8 -*-
from flask import Flask, request, Response
import re, mimetypes, sys
host = sys.argv[1]
port = sys.argv[2]
class webService:
def __init__(self):
self.app = Flask(__name__)
# Получение запроса
@self.app.route('/', defaults={'path': ''})
@self.app.route('/', methods=['GET', 'POST'])
def route(path):
answer = self.process_route()
return Response(response = answer['response'], status = answer['status'], mimetype = answer['mimetype'])
self.app.run(host=host, port=port, debug=True)
# Определение mimeType
def get_mime_type(self, file_path):
mime_type, _ = mimetypes.guess_type(file_path)
return mime_type
# Изменение данных в строке с помощью replace через цикл
def replace_str(self, strData, mData):
for keyItem, dataItem in mData.items():
strData = strData.replace(keyItem, dataItem)
return strData
# Очистка параметров
def clean_string(self, input_string):
cleaned_string = re.sub(r'[^a-zA-Z0-9]', '', input_string)
return cleaned_string
# Обработка входящих параметров
def proccess_params(self):
result = {}
try:
urlRequest = request.url
mParam = urlRequest.split('?')
if len(mParam) > 1:
mVar = mParam[1].split('&')
for item in mVar:
mItem = item.split('=')
if mItem[0] == '' or len(mItem) == 1:
continue
result[self.clean_string(mItem[0])] = self.clean_string(mItem[1])
except Exception as e:
print('proccess_params: '+str(e))
return result
# Работа с шаблоном
def process_template(self, path_file, typeRead = 'r'):
try:
if typeRead == 'rb':
with open(path_file, typeRead) as f:
result = f.read()
else:
with open(path_file, typeRead, encoding='utf-8') as f:
result = f.read()
except Exception as e:
raise Exception('404')
return result
# Обработка запроса
def process_route(self):
result = {'status': 200, 'response': '', 'mimetype': 'text/html', 'typeRead': 'r'}
try:
server_host = str(request.scheme)+'://'+str(request.server[0])+':'+str(request.server[1])
request_data = {'method': request.method, 'path': request.view_args['path'].split('/'), 'variable': self.proccess_params()}
if request_data['method'] == 'GET':
if request_data['path'][0] == '':
request_data['path'][0] = 'index.html'
# Подгрузка страницы
if len(request_data['path']) == 1:
result['response'] = self.process_template('design/template/'+request_data['path'][0])
# Подгрузка дизайна
elif request_data['path'][0] == 'design':
result['mimetype'] = self.get_mime_type(request.view_args['path'])
mMimetype = str(result['mimetype']).split('/')
result['typeRead'] = 'rb' if mMimetype[0] == 'image' else 'r'
result['response'] = self.process_template(request.view_args['path'], result['typeRead'])
if result['response'] == False:
raise Exception('404')
else:
raise Exception('404')
else:
raise Exception('404')
except Exception as e:
# Подгрузка 404 страницы
result['response'] = self.process_template('design/template/404.html')
result['status'] = 404
if result['typeRead'] != 'rb':
mData = {'SERVER_HOST': server_host}
result['response'] = self.replace_str(result['response'], mData)
return result
if __name__ == "__main__":
webService()
Design
project/
├── start.py
├── browser.py
├── web_service.py
├── design/
│ ├── template/
│ └── css/
│ └── img/
│ └── js/
Для создания дополнительных страниц, достаточно в директорию design/template/ добавить html файл с названием страницы.
Запуск
Установите необходимые библиотеки:
pip install flask PySide6
Запустите start.py
python start.py
После запуска приложение откроется в виде окна, а внутри него будет отображаться веб-интерфейс, работающий на Flask.
Исходный кодЗаключение
Мы создали десктопное приложение, которое использует Flask для обработки веб-запросов и PySide6 для отображения интерфейса в настольном окне. Эта архитектура позволяет легко разрабатывать приложения с гибкими веб-технологиями, обеспечивая десктопный интерфейс.