added new all in one setup CLI Skyvern quickstart (#2480)
This commit is contained in:
committed by
GitHub
parent
da4afddc21
commit
a7ff5aaade
20
skyvern/cli/__init__.py
Normal file
20
skyvern/cli/__init__.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""Skyvern CLI package."""
|
||||
|
||||
__all__ = [
|
||||
"cli_app",
|
||||
"quickstart_app",
|
||||
"run_app",
|
||||
"workflow_app",
|
||||
"tasks_app",
|
||||
"docs_app",
|
||||
"status_app",
|
||||
"init_app",
|
||||
]
|
||||
|
||||
from .commands import cli_app, init_app # init_app is defined in commands.py
|
||||
from .docs import docs_app
|
||||
from .quickstart import quickstart_app
|
||||
from .run_commands import run_app
|
||||
from .status import status_app
|
||||
from .tasks import tasks_app
|
||||
from .workflow import workflow_app
|
||||
@@ -3,6 +3,7 @@ from dotenv import load_dotenv
|
||||
|
||||
from .docs import docs_app
|
||||
from .init_command import init, init_browser
|
||||
from .quickstart import quickstart_app
|
||||
from .run_commands import run_app
|
||||
from .status import status_app
|
||||
from .tasks import tasks_app
|
||||
@@ -28,6 +29,11 @@ init_app = typer.Typer(
|
||||
)
|
||||
cli_app.add_typer(init_app, name="init")
|
||||
|
||||
# Add quickstart command
|
||||
cli_app.add_typer(
|
||||
quickstart_app, name="quickstart", help="One-command setup and start for Skyvern (combines init and run)."
|
||||
)
|
||||
|
||||
|
||||
@init_app.callback()
|
||||
def init_callback(
|
||||
|
||||
121
skyvern/cli/quickstart.py
Normal file
121
skyvern/cli/quickstart.py
Normal file
@@ -0,0 +1,121 @@
|
||||
"""Quickstart command for Skyvern CLI."""
|
||||
|
||||
import asyncio
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import typer
|
||||
from rich.panel import Panel
|
||||
from rich.progress import Progress, SpinnerColumn, TextColumn
|
||||
|
||||
# Import console after skyvern.cli to ensure proper initialization
|
||||
from skyvern.cli.console import console
|
||||
from skyvern.cli.init_command import init # init is used directly
|
||||
|
||||
quickstart_app = typer.Typer(help="Quickstart command to set up and run Skyvern with one command.")
|
||||
|
||||
|
||||
def check_docker() -> bool:
|
||||
"""Check if Docker is installed and running."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["docker", "info"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
)
|
||||
return result.returncode == 0
|
||||
except (FileNotFoundError, subprocess.SubprocessError):
|
||||
return False
|
||||
|
||||
|
||||
async def start_services(server_only: bool = False) -> None:
|
||||
"""Start Skyvern services in the background.
|
||||
|
||||
Args:
|
||||
server_only: If True, only start the server, not the UI.
|
||||
"""
|
||||
try:
|
||||
# Start server in the background
|
||||
server_process = await asyncio.create_subprocess_exec(
|
||||
sys.executable, "-m", "skyvern.cli.commands", "run", "server"
|
||||
)
|
||||
|
||||
# Give server a moment to start
|
||||
await asyncio.sleep(2)
|
||||
|
||||
if not server_only:
|
||||
# Start UI in the background
|
||||
ui_process = await asyncio.create_subprocess_exec(sys.executable, "-m", "skyvern.cli.commands", "run", "ui")
|
||||
|
||||
console.print("\n🎉 [bold green]Skyvern is now running![/bold green]")
|
||||
console.print("🌐 [bold]Access the UI at:[/bold] [cyan]http://localhost:8080[/cyan]")
|
||||
console.print("🔑 [bold]Your API key is in your .env file as SKYVERN_API_KEY[/bold]")
|
||||
|
||||
# Wait for processes to complete (they won't unless killed)
|
||||
if not server_only:
|
||||
await asyncio.gather(server_process.wait(), ui_process.wait())
|
||||
else:
|
||||
await server_process.wait()
|
||||
|
||||
except Exception as e:
|
||||
console.print(f"[bold red]Error starting services: {str(e)}[/bold red]")
|
||||
raise typer.Exit(1)
|
||||
|
||||
|
||||
@quickstart_app.callback(invoke_without_command=True)
|
||||
def quickstart(
|
||||
ctx: typer.Context,
|
||||
no_postgres: bool = typer.Option(False, "--no-postgres", help="Skip starting PostgreSQL container"),
|
||||
skip_browser_install: bool = typer.Option(
|
||||
False, "--skip-browser-install", help="Skip Chromium browser installation"
|
||||
),
|
||||
server_only: bool = typer.Option(False, "--server-only", help="Only start the server, not the UI"),
|
||||
) -> None:
|
||||
"""Quickstart command to set up and run Skyvern with one command."""
|
||||
# Check Docker
|
||||
with console.status("Checking Docker installation...") as status:
|
||||
if not check_docker():
|
||||
console.print(
|
||||
Panel(
|
||||
"[bold red]Docker is not installed or not running.[/bold red]\n"
|
||||
"Please install Docker and start it before running quickstart.\n"
|
||||
"Get Docker from: [link]https://www.docker.com/get-started[/link]",
|
||||
border_style="red",
|
||||
)
|
||||
)
|
||||
raise typer.Exit(1)
|
||||
status.update("✅ Docker is installed and running")
|
||||
|
||||
# Run initialization
|
||||
console.print(Panel("[bold green]🚀 Starting Skyvern Quickstart[/bold green]", border_style="green"))
|
||||
|
||||
try:
|
||||
# Initialize Skyvern
|
||||
console.print("\n[bold blue]Initializing Skyvern...[/bold blue]")
|
||||
init(no_postgres=no_postgres)
|
||||
|
||||
# Skip browser installation if requested
|
||||
if not skip_browser_install:
|
||||
with Progress(
|
||||
SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=True, console=console
|
||||
) as progress:
|
||||
progress.add_task("[bold blue]Installing Chromium browser...", total=None)
|
||||
try:
|
||||
subprocess.run(["playwright", "install", "chromium"], check=True, capture_output=True, text=True)
|
||||
console.print("✅ [green]Chromium installation complete.[/green]")
|
||||
except subprocess.CalledProcessError as e:
|
||||
console.print(f"[yellow]Warning: Failed to install Chromium: {e.stderr}[/yellow]")
|
||||
else:
|
||||
console.print("⏭️ [yellow]Skipping Chromium installation as requested.[/yellow]")
|
||||
|
||||
# Start services
|
||||
console.print("\n[bold blue]Starting Skyvern services...[/bold blue]")
|
||||
asyncio.run(start_services(server_only=server_only))
|
||||
|
||||
except KeyboardInterrupt:
|
||||
console.print("\n[bold yellow]Quickstart process interrupted by user.[/bold yellow]")
|
||||
raise typer.Exit(0)
|
||||
except Exception as e:
|
||||
console.print(f"[bold red]Error during quickstart: {str(e)}[/bold red]")
|
||||
raise typer.Exit(1)
|
||||
Reference in New Issue
Block a user