From c0bcbee664f403cfceaa2d5af448d57b5e440ab3 Mon Sep 17 00:00:00 2001 From: ChanaChelem Date: Mon, 16 Aug 2021 15:09:38 +0300 Subject: [PATCH] #567 --- backend/t2wml-service.py | 125 ++++++++++++++++++++++++++++++++++++ backend/t2wml-service.spec | 80 +++++++++++++++++++++++ backend/t2wml-waitress.spec | 2 +- 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 backend/t2wml-service.py create mode 100644 backend/t2wml-service.spec diff --git a/backend/t2wml-service.py b/backend/t2wml-service.py new file mode 100644 index 00000000..fcdd506c --- /dev/null +++ b/backend/t2wml-service.py @@ -0,0 +1,125 @@ +""" +# Prerequisites: +pip install -r requirements.txt +pip install --upgrade pyinstaller +pip install pywin32 +pip install waitress +pip install requests +pip install -e ../../t2wml-api + +# Build: +pyinstaller --clean --noupx t2wml-service.spec + +# With Administrator privilges +# Install: +dist\t2wml-service.exe install + +# Start: +dist\t2wml-service.exe start + +# Install with autostart: +dist\t2wml-service.exe --startup delayed install + +# Debug: +dist\myservice.exe debug + +# Stop: +dist\myservice.exe stop + +# Uninstall: +dist\myservice.exe remove + +""" + +import time +import ctypes +import sys +import win32serviceutil # ServiceFramework and commandline helper +import win32service # Events +import servicemanager # Simple setup and logging +import win32event +from waitress import serve +import threading + +from application import app + + +def runApp(): + app.run(port=13000, debug=False, host=None, use_reloader=False) + + +class WaitressService(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + + # def stop(self): + # """Stop the service""" + # self.running = False + + def run(self): + print('thread start\n') + serve(runApp(), listen='localhost:*', host='localhost', port=13000) + print('thread done\n') + + def get_id(self): + # returns id of the respective thread + if hasattr(self, '_thread_id'): + return self._thread_id + for id, thread in threading._active.items(): + if thread is self: + return id + + def exit(self): + thread_id = self.get_id() + res = ctypes.pythonapi.PyThreadState_SetAsyncExc( + thread_id, ctypes.py_object(SystemExit)) + if res > 1: + ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0) + print('Exception raise failure') + + +class MyServiceFramework(win32serviceutil.ServiceFramework): + + _svc_name_ = 'WaitressService' + _svc_display_name_ = 'Waitress server' + _svc_description_ = 'Python waitress WSGI service' + + def SvcStop(self): + """Stop the service""" + # self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) + # self.service_impl.exit() + # self.ReportServiceStatus(win32service.SERVICE_STOPPED) + + servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, + servicemanager.PYS_SERVICE_STOPPED, + (self._svc_name_, '')) + self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) + win32event.SetEvent(self.stopEvt) + + def SvcDoRun(self): + """Start the service; does not return until stopped""" + self.ReportServiceStatus(win32service.SERVICE_START_PENDING) + self.service_impl = WaitressService() + self.ReportServiceStatus(win32service.SERVICE_RUNNING) + # Run the service + self.service_impl.run() + + print('waiting on win32event') + win32event.WaitForSingleObject(self.stopEvt, win32event.INFINITE) + self.server.exit() # raise SystemExit in inner thread + print('waiting on thread') + self.server.join() + print('main done') + + +def init(): + if len(sys.argv) == 1: + servicemanager.Initialize() + servicemanager.PrepareToHostSingle(MyServiceFramework) + servicemanager.StartServiceCtrlDispatcher() + else: + win32serviceutil.HandleCommandLine(MyServiceFramework) + + +if __name__ == '__main__': + init() diff --git a/backend/t2wml-service.spec b/backend/t2wml-service.spec new file mode 100644 index 00000000..5cba24e3 --- /dev/null +++ b/backend/t2wml-service.spec @@ -0,0 +1,80 @@ +# -*- mode: python ; coding: utf-8 -*- + +""" +# Prerequisites: +pip install -r requirements.txt +pip install --upgrade pyinstaller +pip install pywin32 +pip install waitress +pip install requests +pip install -e ../../t2wml-api + +# Build: +pyinstaller --clean --noupx t2wml-service.spec + +# With Administrator privilges +# Install: +dist\t2wml-service.exe install + +# Start: +dist\t2wml-service.exe start + +# Install with autostart: +dist\t2wml-service.exe --startup delayed install + +# Debug: +dist\myservice.exe debug + +# Stop: +dist\myservice.exe stop + +# Uninstall: +dist\myservice.exe remove + +""" + +import sys +from os import path, getcwd +site_packages = next(p for p in sys.path if 'site-packages' in p) + +def copy_package(name): + return [(path.join(site_packages, name), name)] + +block_cipher = None + + +a = Analysis(['t2wml-service.py'], + pathex=[getcwd()], + binaries=[], + datas=copy_package('distributed'), + hiddenimports=['win32timezone', 'pandas','pandas._libs.tslibs.base', 'rltk', 'logging.config', 'cmath'], + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) + +pyz = PYZ(a.pure, a.zipped_data, + cipher=block_cipher) + +exe = EXE(pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + [], + name='t2wml-service', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir='.', + console=True, + disable_windowed_traceback=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None + ) diff --git a/backend/t2wml-waitress.spec b/backend/t2wml-waitress.spec index 1c4ab9ff..55f81048 100644 --- a/backend/t2wml-waitress.spec +++ b/backend/t2wml-waitress.spec @@ -11,13 +11,13 @@ site_packages = next(p for p in sys.path if 'site-packages' in p) def copy_package(name): return [(path.join(site_packages, name), name)] + block_cipher = None a = Analysis(['t2wml-waitress.py'], pathex=[getcwd()], binaries=[], - # datas=copy_package("pandas") + copy_package('distributed'), datas=copy_package('distributed'), hiddenimports=['pandas','pandas._libs.tslibs.base', 'rltk', 'logging.config', 'cmath'], hookspath=[],