i have a big problem. I try to run FastAPI as a Windows Service after i converted the scripts in .exe with pyinstaller. This is my Code in apy.py: from fastapi import FastAPI, UploadFile, File, HTTPException, Request, Depends from fastapi.responses import JSONResponse from pydantic import BaseModel, Field import pandas as pd import io import numpy as np import logging from logging.handlers import RotatingFileHandler import sys import os import joblib from typing import Optional import json from fastapi.security import APIKeyHeader import string import datetime import uvicorn ############################################################################ ################################# Start #################################### ############################################################################ TicketClassifierPath = os.getenv("TicketClassifierPath") log_dir = os.path.join(TicketClassifierPath, "logs") if not os.path.exists(log_dir): os.makedirs(log_dir) # Logging einrichten log_file = os.path.join(log_dir, "api.log") # RotatingFileHandler konfigurieren handler = RotatingFileHandler( log_file, maxBytes=5 * 1024 * 1024, # 5 MB backupCount=3 # Anzahl der alten Logfiles, die behalten werden (server.log.1, server.log.2, ...) ) # Logging-Format formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) # Root-Logger konfigurieren logger = logging.getLogger() logger.setLevel(logging.INFO) logger.addHandler(handler) # FastAPI-App starten app = FastAPI() @app.get("/tst") def apikey(): return {"Hello World"} def start_api(): logging.info("Start uvicorn") uvicorn.run(app, host="0.0.0.0", port=8000, log_config=None, reload=False) if __name__ == '__main__': start_api() # Starte den API-Server mit: uvicorn api:app --reload # Im LAN auf allen Adressen erreichbar mit: uvicorn api:app --host 0.0.0.0 --port 8000 --reload This is my code in service.py: import os import logging from logging.handlers import RotatingFileHandler import sys import win32serviceutil import win32service import win32event import subprocess import servicemanager import socket from pydantic import BaseModel import json import time import api as api_server import threading # Unterverzeichnis für Logs erstellen TicketClassifierPath = os.getenv("TicketClassifierPath") log_dir = os.path.join(TicketClassifierPath, "logs") if not os.path.exists(log_dir): os.makedirs(log_dir) # Logging einrichten log_file = os.path.join(log_dir, "service.log") # RotatingFileHandler konfigurieren handler = RotatingFileHandler( log_file, maxBytes=5 * 1024 * 1024, # 5 MB backupCount=3 # Anzahl der alten Logfiles, die behalten werden (server.log.1, server.log.2, ...) ) # Logging-Format formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) # Root-Logger konfigurieren logger = logging.getLogger() logger.setLevel(logging.INFO) logger.addHandler(handler) class AppServerSvc (win32serviceutil.ServiceFramework): _svc_name_ = "TicketClassifierService" _svc_display_name_ = "Ticket Classifier API Service" _svc_description_ = "Dienst für die API des Ticket Classifiers" def __init__(self,args): win32serviceutil.ServiceFramework.__init__(self,args) self.hWaitStop = win32event.CreateEvent(None,0,0,None) socket.setdefaulttimeout(60) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) logging.info("Stop requested by service manager.") if self.process and self.process.poll() is None: logging.info("Terminating subprocess...") self.process.terminate() try: self.process.wait(timeout=10) logging.info("Subprocess terminated gracefully.") except subprocess.TimeoutExpired: logging.warning("Subprocess did not terminate in time. Killing it.") self.process.kill() logging.info("Subprocess killed.") def SvcDoRun(self): servicemanager.LogMsg( servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_,'')) self.main() def main(self): #Befindet sich hier im Python Pfad logging.info("Start Service...") python_path = os.getenv("python", "C:\\Program Files\\Python313\\python.exe") cmd = [python_path, "service.py", "run"] TicketClassifierPath = "C:\\Users\\orca\\Desktop\\TicketKIFull\\Ticket KI Small" ######################### For Run as a Exe ######################### #cmd = ["TicketClassifier.exe", "run"] #################################################################### try: logging.info(f"Starte Uvicorn-Prozess: {' '.join(cmd)}") self.process = subprocess.Popen(cmd, cwd=TicketClassifierPath) logging.info("Subprozess gestartet.") except Exception as e: logging.critical(f"Fehler beim Start des Subprozesses: {e}") return rc = None while rc != win32event.WAIT_OBJECT_0: rc = win32event.WaitForSingleObject(self.hWaitStop, 10 * 1000) logging.info("Service is alive...") logging.info("Service wird gestoppt...") if self.process and self.process.poll() is None: logging.info("Terminiere Uvicorn-Prozess...") self.process.terminate() try: self.process.wait(timeout=10) logging.info("Prozess erfolgreich gestoppt.") except subprocess.TimeoutExpired: logging.warning("Prozess reagiert nicht, erzwinge Kill.") self.process.kill() logging.info("Prozess wurde gekillt.") if __name__ == '__main__': if len(sys.argv) > 1 and sys.argv[1] == "run": api_server.start_api() else: win32serviceutil.HandleCommandLine(AppServerSvc) I tested the following: Run api.py manualy "python api.py" -> Works! Run service.py manualy "python service.py run" -> Works! Create Service with service.py and run that service -> Works! "python service.py install" "python service.py start" Create Exe with pyinstaller and Run that -> Works! uncomment in script: "cmd = ["TicketClassifier.exe", "run"]" Create exe with pyinstaller: "pyinstaller --onfile --console --name TicketClassifier --hidden-import=win32timezone service.py" Run the exe File: "TicketClassifier.exe run" Create Service with TicketClassifier.exe and run that service -> Doesn´t work!... "TicketClassifier.exe install" "TicketClassifier.exe start" Error 1053 at Start. But why it works before i converted it with pyinstaller? Anyone have a idea? Continue reading...