Skyvern/skyvern/utils/__init__.py
Shuchang Zheng 72caccd3d6
Some checks are pending
Run tests and pre-commit / Frontend Lint and Build (push) Waiting to run
Run tests and pre-commit / Run tests and pre-commit hooks (push) Waiting to run
Publish Fern Docs / run (push) Waiting to run
Add PostHog analytics for setup pain points tracking (#4840)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-21 15:32:56 -08:00

94 lines
3 KiB
Python

import asyncio
import platform
import subprocess
from pathlib import Path
from typing import Optional
from alembic import command
from alembic.config import Config
from skyvern.constants import REPO_ROOT_DIR
def setup_windows_event_loop_policy() -> None:
"""
Ensure the Windows event loop policy supports subprocesses (required by Playwright).
Explicitly setting the Proactor event loop policy prevents third-party packages or older
Python defaults from forcing the Selector policy, which does not implement subprocess
transports and causes runtime failures when Playwright tries to launch a browser.
"""
if platform.system() != "Windows":
return
windows_policy_cls = getattr(asyncio, "WindowsProactorEventLoopPolicy", None)
if windows_policy_cls is None:
return
current_policy = asyncio.get_event_loop_policy()
if isinstance(current_policy, windows_policy_cls):
return
asyncio.set_event_loop_policy(windows_policy_cls())
def migrate_db() -> None:
# Import here to avoid circular import (config -> utils -> analytics -> config)
from skyvern.analytics import capture_setup_error, capture_setup_event
capture_setup_event("migration-start")
try:
alembic_cfg = Config()
path = f"{REPO_ROOT_DIR}/alembic"
alembic_cfg.set_main_option("script_location", path)
command.upgrade(alembic_cfg, "head")
capture_setup_event("migration-complete", success=True)
except Exception as e:
capture_setup_error("migration-fail", e, error_type="alembic_migration_error")
raise
def detect_os() -> str:
"""
Detects the operating system.
Returns:
str: The name of the OS in lowercase.
Returns 'wsl' for Windows Subsystem for Linux,
'linux' for native Linux,
or the lowercase name of other platforms (e.g., 'windows', 'darwin').
"""
system = platform.system()
if system == "Linux":
try:
with open("/proc/version") as f:
version_info = f.read().lower()
if "microsoft" in version_info:
return "wsl"
except Exception:
pass
return "linux"
else:
return system.lower()
def get_windows_appdata_roaming() -> Optional[Path]:
"""
Retrieves the Windows 'AppData\\Roaming' directory path from WSL.
Returns:
Optional[Path]: A Path object representing the translated Linux-style path
to the Windows AppData\\Roaming folder, or None if retrieval fails.
"""
try:
output = (
subprocess.check_output(
["powershell.exe", "-NoProfile", "-Command", "[Environment]::GetFolderPath('ApplicationData')"],
stderr=subprocess.DEVNULL,
)
.decode("utf-8")
.strip()
)
linux_path = "/mnt/" + output[0].lower() + output[2:].replace("\\", "/")
return Path(linux_path)
except Exception:
return None