Implement LiveKit calls

This commit is contained in:
2026-04-22 23:19:38 +03:00
Unverified
parent b7d884df58
commit 66a1060685
16 changed files with 465 additions and 27 deletions
+242
View File
@@ -0,0 +1,242 @@
#!/usr/bin/env python3
"""
Download the LiveKit server binary for the current OS/arch from the latest GitHub release.
macOS: GitHub releases often omit darwin assets. If `livekit-server` is missing, this script
runs `brew install livekit` automatically (Homebrew must be installed).
Linux / Windows: download the matching .tar.gz / .zip from the latest release.
"""
from __future__ import annotations
import json
import os
import platform
import shutil
import stat
import subprocess
import sys
import tarfile
import urllib.request
import zipfile
from pathlib import Path
REPO = "livekit/livekit"
API_LATEST = f"https://api.github.com/repos/{REPO}/releases/latest"
def repo_root() -> Path:
return Path(__file__).resolve().parents[2]
def tools_dir(root: Path) -> Path:
return root / ".tools" / "livekit"
def platform_triple() -> tuple[str, str, str]:
"""Returns (os_name, arch, archive_ext). archive_ext is tar.gz or zip."""
system = platform.system().lower()
machine = platform.machine().lower()
if system == "darwin":
os_name = "darwin"
arch = "arm64" if machine in ("arm64", "aarch64") else "amd64"
return os_name, arch, "tar.gz"
if system == "linux":
os_name = "linux"
if machine in ("aarch64", "arm64"):
arch = "arm64"
elif machine in ("armv7l", "armv7"):
arch = "armv7"
else:
arch = "amd64"
return os_name, arch, "tar.gz"
if system == "windows":
os_name = "windows"
arch = "arm64" if machine in ("arm64", "aarch64") else "amd64"
return os_name, arch, "zip"
raise SystemExit(f"Unsupported OS: {system!r}")
def fetch_latest_release() -> dict:
req = urllib.request.Request(
API_LATEST,
headers={"Accept": "application/vnd.github+json", "User-Agent": "fromchat-livekit-ensure"},
)
with urllib.request.urlopen(req, timeout=120) as resp:
return json.load(resp)
def pick_asset(assets: list[dict], filename: str) -> dict | None:
for a in assets:
if a.get("name") == filename:
return a
return None
def download(url: str, dest: Path) -> None:
dest.parent.mkdir(parents=True, exist_ok=True)
req = urllib.request.Request(url, headers={"User-Agent": "fromchat-livekit-ensure"})
with urllib.request.urlopen(req, timeout=300) as resp:
dest.write_bytes(resp.read())
def chmod_plus_x(path: Path) -> None:
if path.suffix.lower() == ".exe" or platform.system().lower() == "windows":
return
mode = path.stat().st_mode
path.chmod(mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
def find_server_binary(extract_dir: Path) -> Path | None:
for name in ("livekit-server", "livekit-server.exe"):
for p in extract_dir.rglob(name):
if p.is_file():
return p
return None
def resolve_macos_binary(td: Path) -> str | None:
w = shutil.which("livekit-server")
if w:
return w
# Homebrew default locations (Apple Silicon / Intel)
for candidate in (
Path("/opt/homebrew/bin/livekit-server"),
Path("/usr/local/bin/livekit-server"),
):
if candidate.is_file():
return str(candidate)
return None
def find_brew() -> str | None:
w = shutil.which("brew")
if w:
return w
for candidate in ("/opt/homebrew/bin/brew", "/usr/local/bin/brew"):
p = Path(candidate)
if p.is_file():
return str(p)
return None
def install_livekit_via_homebrew() -> bool:
brew = find_brew()
if not brew:
print(
"Homebrew not found. Install it from https://brew.sh then re-run this task.",
file=sys.stderr,
)
return False
print("Installing LiveKit via Homebrew (brew install livekit) …", file=sys.stderr)
result = subprocess.run(
[brew, "install", "livekit"],
check=False,
)
if result.returncode != 0:
print("brew install livekit failed.", file=sys.stderr)
return False
return True
def main() -> int:
root = repo_root()
td = tools_dir(root)
td.mkdir(parents=True, exist_ok=True)
os_name, arch, ext = platform_triple()
# macOS: GitHub release assets often omit darwin; use Homebrew (auto-install if needed).
if os_name == "darwin":
mac_bin = resolve_macos_binary(td)
if not mac_bin:
if not install_livekit_via_homebrew():
return 1
mac_bin = resolve_macos_binary(td)
if not mac_bin:
print(
"livekit-server still not found after brew install. "
"Open a new terminal or run: hash -r",
file=sys.stderr,
)
return 1
(td / ".version").write_text("system\n", encoding="utf-8")
print(f"Using LiveKit server: {mac_bin}", file=sys.stderr)
print(mac_bin)
return 0
release = fetch_latest_release()
tag = release.get("tag_name") or ""
if not tag.startswith("v"):
print("Unexpected release tag", tag, file=sys.stderr)
return 1
ver = tag[1:]
assets = release.get("assets") or []
if ext == "zip":
archive_name = f"livekit_{ver}_{os_name}_{arch}.zip"
else:
archive_name = f"livekit_{ver}_{os_name}_{arch}.tar.gz"
version_file = td / ".version"
bin_hint = td / ("livekit-server.exe" if ext == "zip" else "livekit-server")
if (
version_file.is_file()
and bin_hint.is_file()
and version_file.read_text(encoding="utf-8").strip() == tag
):
print(f"LiveKit {tag} already present at {bin_hint}", file=sys.stderr)
print(str(bin_hint))
return 0
asset = pick_asset(assets, archive_name)
if not asset:
print(
f"No GitHub asset {archive_name!r} for {tag}. See https://github.com/{REPO}/releases",
file=sys.stderr,
)
return 1
url = asset["browser_download_url"]
staging = td / "_staging"
if staging.exists():
shutil.rmtree(staging)
staging.mkdir(parents=True)
archive = staging / asset["name"]
print(f"Downloading LiveKit {tag}: {asset['name']}", file=sys.stderr)
download(url, archive)
extract_dir = staging / "extract"
extract_dir.mkdir()
if archive_name.endswith(".tar.gz"):
with tarfile.open(archive, "r:gz") as tf:
tf.extractall(extract_dir)
elif archive_name.endswith(".zip"):
with zipfile.ZipFile(archive, "r") as zf:
zf.extractall(extract_dir)
else:
print(f"Unsupported archive: {archive_name}", file=sys.stderr)
return 1
binary = find_server_binary(extract_dir)
if not binary:
print("Could not find livekit-server binary after extract.", file=sys.stderr)
return 1
if bin_hint.exists():
bin_hint.unlink()
shutil.move(str(binary), str(bin_hint))
chmod_plus_x(bin_hint)
shutil.rmtree(staging)
version_file.write_text(tag + "\n", encoding="utf-8")
print(f"Installed LiveKit {tag}{bin_hint}", file=sys.stderr)
print(str(bin_hint))
return 0
if __name__ == "__main__":
raise SystemExit(main())