Files
Dorod-Sky/skyvern/cli/core/client.py
2026-02-18 10:53:55 -08:00

65 lines
1.8 KiB
Python

from __future__ import annotations
import os
from contextvars import ContextVar
import structlog
from skyvern.client import SkyvernEnvironment
from skyvern.config import settings
from skyvern.library.skyvern import Skyvern
_skyvern_instance: ContextVar[Skyvern | None] = ContextVar("skyvern_instance", default=None)
_global_skyvern_instance: Skyvern | None = None
LOG = structlog.get_logger(__name__)
def get_skyvern() -> Skyvern:
"""Get or create a Skyvern client instance."""
global _global_skyvern_instance
instance = _skyvern_instance.get()
if instance is None:
instance = _global_skyvern_instance
if instance is not None:
_skyvern_instance.set(instance)
return instance
api_key = settings.SKYVERN_API_KEY or os.environ.get("SKYVERN_API_KEY")
base_url = settings.SKYVERN_BASE_URL or os.environ.get("SKYVERN_BASE_URL")
if api_key:
instance = Skyvern(
api_key=api_key,
environment=SkyvernEnvironment.CLOUD,
base_url=base_url,
)
else:
instance = Skyvern.local()
_global_skyvern_instance = instance
_skyvern_instance.set(instance)
return instance
async def close_skyvern() -> None:
"""Close active Skyvern client(s) and release Playwright resources."""
global _global_skyvern_instance
instances: list[Skyvern] = []
seen: set[int] = set()
for candidate in (_skyvern_instance.get(), _global_skyvern_instance):
if candidate is None or id(candidate) in seen:
continue
seen.add(id(candidate))
instances.append(candidate)
for instance in instances:
try:
await instance.aclose()
except Exception:
LOG.warning("Failed to close Skyvern client", exc_info=True)
_skyvern_instance.set(None)
_global_skyvern_instance = None