Пусть Flask-приложение стартует первым и запускает твой worker-скрипт в отдельном процессе. Так они друг другу мешать не будут, и если твой worker вылетит, Flask выживет и сможет сообщить о случившемся (ну и перезапустить worker, если надо будет).
Вопрос тут в выборе способа обмена данными между скриптом и Flask, а также между Flask и браузером.
1. Worker -> Flask:
- запуск worker через multiprocessing, обмен данными через очередь (multiprocessing.Queue).
Плюс: возможен обмен простыми структурами данных, типа списков и кортежей.
Минус: требует переделки скрипта-worker, чтобы вместо print() он отправлял данные в Queue, да и в целом его надо будет импортировать в Flask-приложение. Что-то кроме питона той же версии так не запустишь.
- запуск worker через subprocess, обмен данными через перехват stdout.
Плюс: worker остаётся без изменений, и может быть запущен отдельно. Строго говоря, любая консольная программа, не требующая ввода, может быть так запущена.
Минус: обмен данными только как последовательность строк. Что-то другое потребует сериализации на стороне воркера, и десериализации на стороне Flask.
2. Flask -> browser:
- Самый простой и дубовый способ - long-running request.
Твой обработчик запроса на Flask запускает воркера, но не закрывает соединение, а потихоньку читает поступающие от воркера данные и отдаёт клиенту. Проблема в том, что если клиент отрубился, восстановить соединение будет нельзя.
- Чуточку более сложный - polling. Один обработчик запроса на Flask запускает воркера и всё. Другой обработчик пытается прочитать накопившиеся у воркера данные, и отдаёт их клиенту. Тогда на клиенте должен крутиться JS-скрипт, который будет периодически дергать второй обработчик. Проблема в том, что если данные от воркера долго не считываются (клиент отключился), очередь/pipe для связи между процессами переполнится, и воркер "подвиснет" на операции отдачи данных Flask. Также этот подход не будет работать с двумя и более клиентами.
- Ещё более сложный, но надёжный - buffered polling. Данные от worker помещаются в какое-то хранилище (грубо говоря, в переменную). Хранилище может хранить как полную историю вывода, так и только последний полученный блок данных - смотря что тебе интересно. Тогда Flask-приложение должно отдельным потоком забирать данные у worker, и помещать их в хранилище. Основной поток будет обслуживать запросы, и отдельный обработчик запроса будет отдавать клиенту текущее состояние хранилища (целиком или последние изменения, смотря сколько хранишь).
Плюс: такая схема будет работать при любом разумном числе клиентов, в том числе при нуле.
Минус: доступ к хранилищу нужно аккуратно синхронизировать, например, с помощью threading.Lock().