Skip to content

Instantly share code, notes, and snippets.

@roflsunriz
Last active February 20, 2025 13:43
Show Gist options
  • Save roflsunriz/c4da95f38afdb39f15635e426f458cf3 to your computer and use it in GitHub Desktop.
Save roflsunriz/c4da95f38afdb39f15635e426f458cf3 to your computer and use it in GitHub Desktop.
OpenWebUI.py : Open-WebUIサーバーを127.0.0.1:8081で自動的に開始し、文字列が現れるのを待った後Firefoxでページを開く。
import subprocess
import time
import psutil
import threading
import os
try:
import tkinter as tk
from tkinter import ttk
except ImportError:
subprocess.check_call(["pip", "install", "tk"])
import tkinter as tk
from tkinter import ttk
# Configuration
OPENWEUI_HOST = "127.0.0.1"
OPENWEUI_PORT = 8081
OPENWEUI_COMMAND = f"open-webui serve --host {OPENWEUI_HOST} --port {OPENWEUI_PORT}"
FIREFOX_PATH = r"C:\Program Files\Mozilla Firefox\firefox.exe"
# 必要なライブラリチェック
required_packages = ['psutil']
for package in required_packages:
try:
__import__(package)
except ImportError:
print(f"Installing {package}...")
subprocess.check_call(["pip", "install", package])
def start_openwebui(host, port, log_callback, ready_callback=None):
"""GUI用に改造したサーバー起動関数"""
# 環境変数を設定
env = os.environ.copy()
env.update({
"CORS_ALLOW_ORIGINS": f"http://{host}:{port}",
"DISABLE_INSPECTOR": "1",
"WEBSOCKET_MODE": "asgi" # WebSocketモードを明示的に指定
})
proc = subprocess.Popen(
["open-webui", "serve", "--host", host, "--port", str(port)],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=env
)
def output_reader():
server_ready = False
while True:
line = proc.stdout.readline()
if not line:
time.sleep(0.1)
continue
decoded = line.decode('cp932', errors='replace').strip()
log_callback(decoded)
# 起動完了検知(1回だけ実行)
if not server_ready and any(msg in decoded for msg in ["Application startup complete", "Uvicorn running"]):
log_callback("Server ready!")
if ready_callback:
ready_callback()
server_ready = True # フラグを立てて重複実行防止
# プロセスが終了したらループを抜ける
if proc.poll() is not None:
break
threading.Thread(target=output_reader, daemon=True).start()
return proc
def is_firefox_running():
"""Check if Firefox is already running."""
for proc in psutil.process_iter():
try:
if "firefox.exe" in proc.name().lower():
return True
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
return False
class Application(tk.Tk):
def __init__(self):
super().__init__()
self.title("OpenWebUI Controller")
# 設定フレーム
self.settings_frame = ttk.LabelFrame(self, text="Settings")
self.settings_frame.pack(padx=10, pady=5, fill="x")
# ホスト設定
ttk.Label(self.settings_frame, text="Host:").grid(row=0, column=0)
self.host_entry = ttk.Entry(self.settings_frame)
self.host_entry.insert(0, "127.0.0.1")
self.host_entry.grid(row=0, column=1)
# ポート設定
ttk.Label(self.settings_frame, text="Port:").grid(row=1, column=0)
self.port_entry = ttk.Entry(self.settings_frame)
self.port_entry.insert(0, "8081")
self.port_entry.grid(row=1, column=1)
# Firefoxチェックボックス
self.use_firefox = tk.BooleanVar(value=True)
self.firefox_check = ttk.Checkbutton(
self.settings_frame,
text="Use Firefox",
variable=self.use_firefox
)
self.firefox_check.grid(row=2, columnspan=2)
# 実行ボタン
self.start_btn = ttk.Button(self, text="Start", command=self.start_process)
self.start_btn.pack(pady=5, side=tk.LEFT)
# 停止ボタン追加
self.stop_btn = ttk.Button(
self,
text="Stop",
command=self.stop_process,
state=tk.DISABLED
)
self.stop_btn.pack(pady=5, side=tk.LEFT)
# ログ表示エリア
self.log_frame = ttk.Frame(self)
self.log_frame.pack(fill="both", expand=True, padx=5, pady=5)
# スクロールバー追加
self.log_scroll = ttk.Scrollbar(self.log_frame)
self.log_text = tk.Text(self.log_frame, wrap="word", yscrollcommand=self.log_scroll.set)
self.log_scroll.config(command=self.log_text.yview)
self.log_text.pack(side="left", fill="both", expand=True)
self.log_scroll.pack(side="right", fill="y")
def log_message(self, message):
self.log_text.insert("end", message + "\n")
self.log_text.see("end") # 自動で最下部にスクロール
self.update_idletasks()
def start_process(self):
self.start_btn.config(state=tk.DISABLED)
self.stop_btn.config(state=tk.NORMAL) # 停止ボタンを有効化
host = self.host_entry.get()
port = self.port_entry.get()
# サーバー起動処理(コールバック付き)
self.server_proc = start_openwebui(
host,
port,
self.log_message,
ready_callback=lambda: self.launch_firefox(host, port) if self.use_firefox.get() else None
)
def launch_firefox(self, host, port):
url = f"http://{host}:{port}"
if not is_firefox_running():
subprocess.Popen([FIREFOX_PATH, url])
else:
subprocess.Popen([FIREFOX_PATH, "-new-tab", url])
def stop_process(self):
if hasattr(self, 'server_proc'):
try:
parent = psutil.Process(self.server_proc.pid)
children = parent.children(recursive=True)
for child in children:
child.kill()
gone, still_alive = psutil.wait_procs(children, timeout=5)
parent.kill()
parent.wait(5)
except psutil.NoSuchProcess:
pass
self.log_message("Server stopped!")
self.start_btn.config(state=tk.NORMAL)
self.stop_btn.config(state=tk.DISABLED)
if __name__ == "__main__":
root = Application()
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment