Skip to content

Instantly share code, notes, and snippets.

@search5
Last active April 23, 2024 10:55
Show Gist options
  • Save search5/fc15e79a338070b327c47a624a9a765c to your computer and use it in GitHub Desktop.
Save search5/fc15e79a338070b327c47a624a9a765c to your computer and use it in GitHub Desktop.
trac windows service
import socket
import win32serviceutil
import servicemanager
import win32event
import win32service
import sys
import os
from waitress.server import create_server
import trac.web.main
from dotenv import load_dotenv
sys.stdout = sys.stderr
# file content
# "TRAC_ENV_PARENT_DIR=C:\\Users\\gdhong\\repos\\\nPYTHON_EGG_CACHE=C:\\Users\\gdhong\\projects\\.eggs\\"
config = open("C:\\Foo\\Bar\\trac.env") # or trac.env location from os environment variable
load_dotenv(stream=config)
application = trac.web.main.dispatch_request
class TracWinService(win32serviceutil.ServiceFramework):
'''Base class to create winservice in Python'''
_svc_name_ = 'trac_service'
_svc_display_name_ = 'Trac Windows Service'
_svc_description_ = 'Trac Windows on python waitress'
@classmethod
def parse_command_line(cls):
'''
ClassMethod to parse the command line
'''
win32serviceutil.HandleCommandLine(cls)
def __init__(self, args):
'''
Constructor of the winservice
'''
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
self.wsgi_server = None
def SvcStop(self):
'''
Called when the service is asked to stop
'''
self.stop()
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
'''
Called when the service is asked to start
'''
self.start()
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def start(self):
'''
Override to add logic before the start
eg. running condition
'''
self.wsgi_server = create_server(application, host='0.0.0.0', port=80)
# TODO Windows NT Logging
def stop(self):
'''
Override to add logic before the stop
eg. invalidating running condition
'''
# TODO Windows NT Logging
self.wsgi_server.close()
def main(self):
'''
Main class to be ovverridden to add logic
'''
# TODO Windows NT Logging
self.wsgi_server.run()
# entry point of the module: copy and paste into the new module
# ensuring you are calling the "parse_command_line" of the new created class
if __name__ == '__main__':
TracWinService.parse_command_line()
@search5
Copy link
Author

search5 commented Apr 23, 2024

@search5
Copy link
Author

search5 commented Apr 23, 2024

I have not tested it, and I am not responsible for the results of your testing and use.

If you find this gist helpful, please follow my github account.

@search5
Copy link
Author

search5 commented Apr 23, 2024

requirements:
pywin32
python-dotenv
trac
waitress

@search5
Copy link
Author

search5 commented Apr 23, 2024

python PythonCornerExample.py install
python PythonCornerExample.py update
mmc Services.msc
python PythonCornerExample.py debug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment