|
| 1 | +import subprocess |
| 2 | +from importlib.metadata import version |
| 3 | +from pathlib import Path |
| 4 | + |
| 5 | +import click |
| 6 | +import rich |
| 7 | +from rich.box import ROUNDED |
| 8 | +from rich.panel import Panel |
| 9 | + |
| 10 | +from codegen.configs.models.secrets import SecretsConfig |
| 11 | +from codegen.git.schemas.repo_config import RepoConfig |
| 12 | + |
| 13 | + |
| 14 | +@click.command(name="start") |
| 15 | +@click.option("--platform", "-t", type=click.Choice(["linux/amd64", "linux/arm64", "linux/amd64,linux/arm64"]), default="linux/amd64,linux/arm64", help="Target platform(s) for the Docker image") |
| 16 | +@click.option("--port", "-p", type=int, default=8000) |
| 17 | +@click.option("--detached", "-d", is_flag=True, default=False, help="Starts up the server as detached background process") |
| 18 | +def start_command(port: int, platform: str, detached: bool): |
| 19 | + """Starts a local codegen server""" |
| 20 | + codegen_version = version("codegen") |
| 21 | + rich.print(f"[bold green]Codegen version:[/bold green] {codegen_version}") |
| 22 | + codegen_root = Path(__file__).parent.parent.parent.parent.parent.parent |
| 23 | + |
| 24 | + try: |
| 25 | + rich.print("[bold blue]Building Docker image...[/bold blue]") |
| 26 | + _build_docker_image(codegen_root, platform) |
| 27 | + rich.print("[bold blue]Starting Docker container...[/bold blue]") |
| 28 | + _run_docker_container(port, platform, detached) |
| 29 | + rich.print(Panel(f"[green]Server started successfully![/green]\nAccess the server at: [bold]http://0.0.0.0:{port}[/bold]", box=ROUNDED, title="Codegen Server")) |
| 30 | + except subprocess.CalledProcessError as e: |
| 31 | + rich.print(f"[bold red]Error:[/bold red] Failed to {e.cmd[0]} Docker container") |
| 32 | + raise click.Abort() |
| 33 | + except Exception as e: |
| 34 | + rich.print(f"[bold red]Error:[/bold red] {e!s}") |
| 35 | + raise click.Abort() |
| 36 | + |
| 37 | + |
| 38 | +def _build_docker_image(codegen_root: Path, platform: str): |
| 39 | + build_cmd = [ |
| 40 | + "docker", |
| 41 | + "buildx", |
| 42 | + "build", |
| 43 | + "--platform", |
| 44 | + platform, |
| 45 | + "-f", |
| 46 | + str(codegen_root / "Dockerfile-runner"), |
| 47 | + "-t", |
| 48 | + "codegen-runner", |
| 49 | + "--load", |
| 50 | + str(codegen_root), |
| 51 | + ] |
| 52 | + rich.print(f"build_cmd: {str.join(' ', build_cmd)}") |
| 53 | + subprocess.run(build_cmd, check=True) |
| 54 | + |
| 55 | + |
| 56 | +def _run_docker_container(port: int, detached: bool): |
| 57 | + repo_path = Path.cwd().resolve() |
| 58 | + repo_config = RepoConfig.from_repo_path(repo_path) |
| 59 | + container_repo_path = f"/app/git/{repo_config.name}" |
| 60 | + envvars = { |
| 61 | + "REPOSITORY_LANGUAGE": repo_config.language.value, |
| 62 | + "REPOSITORY_OWNER": repo_config.organization_name, |
| 63 | + "REPOSITORY_PATH": container_repo_path, |
| 64 | + "GITHUB_TOKEN": SecretsConfig().github_token, |
| 65 | + } |
| 66 | + envvars_args = [arg for k, v in envvars.items() for arg in ("--env", f"{k}={v}")] |
| 67 | + |
| 68 | + mount_args = ["-v", f"{repo_path}:{container_repo_path}"] |
| 69 | + run_mode = "-d" if detached else "-it" |
| 70 | + entry_point = f"uv run --frozen uvicorn codegen.runner.sandbox.server:app --host 0.0.0.0 --port {port}" |
| 71 | + run_cmd = ["docker", "run", run_mode, "-p", f"8000:{port}", *mount_args, *envvars_args, "codegen-runner", entry_point] |
| 72 | + |
| 73 | + rich.print(f"run_cmd: {str.join(' ', run_cmd)}") |
| 74 | + subprocess.run(run_cmd, check=True) |
0 commit comments