Эта статья представляет собой сводное руководство по интеграции Flask и Electron. Цель состоит в том, чтобы охватить все важные моменты для этой задачи, поскольку информации для этого варианта использования недостаточно, и она не доступна в одном месте. Я надеюсь, что эта статья будет вам полезна, если я исходлю от человека, которому недавно пришлось тщательно исследовать эту проблему для решения той же проблемы.

Мы намерены остановиться на проблеме интеграции, поэтому я остановлюсь на простой программе «Hello World» на бэкэнде.

Создание базового приложения Electron

Чтобы создать базовое приложение для быстрого запуска Electron, вы можете перейти к электронной JS doc в качестве руководства.

А пока давайте сосредоточимся на коде main.js, приведенном в документации, который создает окно браузера приложения. Вот фрагмент кода из приведенной выше ссылки, на который мы будем ссылаться в нашей статье:

const { app, BrowserWindow } = require(‘electron’)
function createWindow () {
 const win = new BrowserWindow({
 width: 800,
 height: 600,
 webPreferences: {
 nodeIntegration: true
 }
 })
win.loadFile(‘index.html’)
}
app.whenReady().then(createWindow)
app.on(‘window-all-closed’, () => {
 if (process.platform !== ‘darwin’) {
 app.quit()
 }
})
app.on(‘activate’, () => {
 if (BrowserWindow.getAllWindows().length === 0) {
 createWindow()
 }
})

Код создает окно приложения для нашего приложения Electron. Здесь мы должны интегрировать наше приложение Flask с Electron.

Создание базового приложения Flask

Вот простой код приложения Flask, который мы собираемся использовать для серверного приложения.

from flask import Flask
app = Flask(__name__)


@app.route('/test')
def hello():
    return "Hello World!"

if __name__ == '__main__':
    app.run()

Порт по умолчанию будет 127.0.0.1:80, но вы можете изменить порт, изменив последнюю строку как:

app.run(host=’127.0.0.1', port=5000)

Теперь для нашей проблемы мы собираемся использовать дочерний процесс. Для тех, кто уже знает о дочернем процессе, пропустите определение ниже.

Дочерний процесс
Дочерний процесс - это создание родительского процесса, который можно определить как основной процесс, создающий дочерний процесс или подпроцессы для выполнения определенных операций. У каждого процесса может быть много дочерних процессов, но только один родительский. Дочерний процесс наследует большинство своих родительских атрибутов.

Существует несколько способов создания дочернего процесса, но в нашем случае мы будем придерживаться следующих двух методов:

spawn: Запуск приложения Flask в качестве исходного кода (app.py)

Если разработчик хочет протестировать приложение Electron / Flask без создания исполняемого файла Flask, он может использовать метод spawn. Это можно сделать, написав следующий код внутри функции окна создания:

var python = require('child_process').spawn('py', ['./backend/app.py']);
  python.stdout.on('data', function (data) {
    console.log("data: ", data.toString('utf8'));
  });
  python.stderr.on('data', (data) => {
    console.log(`stderr: ${data}`); // when error
  });

Это только для временного использования, пока серверное приложение не будет завершено. Когда бэкэнд-код готов в соответствии с требованиями, вам необходимо создать исполняемый файл для приложения Flask, который приложение Electron запускает в своем основном процессе при каждом запуске приложения Electron.

execFile: запуск исполняемого файла приложения Flask в Electron (app.exe)

Чтобы создать исполняемый файл приложения Flask, вам понадобится pyinstaller. Его можно просто установить с помощью pip install pyinstaller. После установки pyinstaller вам нужно перейти в командную строку и ввести pyinstaller -F app.py.

Обратите внимание, что здесь используется -F для создания приложения только в одном файле. Вы можете не делать этого. Исполняемое приложение будет находиться в папке dist в корневом каталоге внутреннего кода.

let backend;
backend = path.join(process.cwd(), 'resources/backend/dist/app.exe')
var execfile = require(‘child_process’).execFile;
execfile(
 backend,
 {
  windowsHide: true,
 },
 (err, stdout, stderr) => {
  if (err) {
  console.log(err);
  }
  if (stdout) {
  console.log(stdout);
  }
  if (stderr) {
  console.log(stderr);
  }
 }
)

Удаление app.exe при выходе из приложения Electron

Вы успешно интегрировали приложение Flask с Electron, вы запускаете приложение, запускаете свою задачу и закрываете приложение, но, подождите ... приложение Flask все еще работает в фоновом режиме. Он никогда не закрывался. Эта проблема возникла, когда я думал, что теперь все работает хорошо. Для этой цели не так много конкретной информации. Я попробовал tree-kill npm для уничтожения дочернего процесса, но у меня это не сработало. Лучшее решение, которое я нашел, - это создать еще один дочерний процесс, которому дана команда убить работающее приложение. Ниже приведен фрагмент кода, который необходимо поместить в функцию app.on ('window-all-closed') перед app.quit () строка:

const { exec } = require(‘child_process’);
exec(‘taskkill /f /t /im app.exe’, (err, stdout, stderr) => {
 if (err) {
  console.log(err)
 return;
 }
 console.log(`stdout: ${stdout}`);
 console.log(`stderr: ${stderr}`);
});

Приведенный выше код работал у меня хорошо, поскольку он убил все фоновые процессы, когда я закрыл свое приложение.

Взаимодействие между серверной частью и клиентской частью

Лучший способ связи между интерфейсом и серверной частью - это отправлять запросы на конечную точку сервера Flask из пользовательского интерфейса одним нажатием кнопки или вводом пользователя. Для этого вы можете использовать один из наиболее часто используемых методов http. Для этого я обычно предпочитаю Axios. Вам необходимо использовать следующий код в вашем Renderer.js при отправке запросов на сервер Flask.

test = 'Hello'
async function makePostRequest(test) {
 axios.post(‘http://127.0.0.1:5000/test', test)
 .then(function (response) {
  console.log(“It says: “, response.data);
 })
 .catch(function (error) {
  console.log(error);
 });
}

Вы найдете ответ от сервера Flask в журнале своего приложения. Дальнейшие операции можно выполнять внутри кода .then ().

Когда интерфейс готов, вы можете эффективно собрать устанавливаемое электронное приложение с помощью электронного строителя. Перейдите к документации по указанной ссылке, внесите необходимые изменения в файл package.json и запустите команду сборки в своем терминале, чтобы создать свое приложение.

Избегайте ошибки в каталоге маршрутов

Обратите внимание: поскольку исполняемый файл приложения Flask будет открыт в среде приложения Electron, на пути внутри кода приложения Flask необходимо ссылаться в соответствии с корневым каталогом приложения Electron. Возможна ошибка упоминания путей к файлам относительно среды Flask, что будет чуждо среде Electron. Поэтому, если ваше приложение Flask загружает файл, вам нужно указать путь в соответствии с Electron, а не в соответствии с вашей средой Flask.

Об Ахмаде Сахале

О Red Buffer

Ссылки для обучения