yuzou1121's picture
Publish com.orulink.vision_debug_lab 1.0.0
44628ce verified
Raw
History Blame Contribute Delete
2.37 kB
"""Run the loopback-only WatcheRobot Vision Debug Lab."""
from __future__ import annotations
import asyncio
import os
import socket
import webbrowser
from pathlib import Path
import uvicorn
from service import (
DaemonDeviceStatusProvider,
VisionDebugLabService,
create_web_app,
)
from watcherobot.application import ApplicationContext
ROOT = Path(__file__).resolve().parent
HOST = "127.0.0.1"
async def main() -> None:
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind((HOST, 0))
listener.listen(128)
port = int(listener.getsockname()[1])
url = f"http://{HOST}:{port}"
try:
async with ApplicationContext.from_environment() as app:
device_status_url = os.environ.get(
"WATCHER_APP_DEVICE_STATUS_URL",
"",
).strip()
if not device_status_url:
raise RuntimeError(
"Daemon did not inject WATCHER_APP_DEVICE_STATUS_URL"
)
service = VisionDebugLabService(
robot=app.robot,
artifacts_dir=ROOT / "artifacts",
device_status_provider=DaemonDeviceStatusProvider(
device_status_url
),
)
web_app = create_web_app(service, web_root=ROOT / "web")
server = uvicorn.Server(
uvicorn.Config(
web_app,
host=HOST,
port=port,
access_log=False,
log_level="warning",
)
)
server_task = asyncio.create_task(
server.serve(sockets=[listener]),
name="vision-debug-lab-http",
)
while not server.started:
if server_task.done():
await server_task
await asyncio.sleep(0.02)
app.logger.info("Vision Debug Lab: %s", url)
if os.environ.get("WATCHER_VISION_LAB_NO_BROWSER") != "1":
await asyncio.to_thread(webbrowser.open, url)
await server_task
finally:
listener.close()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
pass