Skip to content

Commit 04df0a3

Browse files
committed
cli structure, openapi
1 parent 12bb1b3 commit 04df0a3

File tree

6 files changed

+586
-79
lines changed

6 files changed

+586
-79
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
2+
"""Common utilities for manifest runner CLI commands."""
3+
4+
import sys
5+
6+
import rich_click as click
7+
8+
# Import server dependencies with graceful fallback
9+
try:
10+
import fastapi # noqa: F401
11+
import uvicorn # noqa: F401
12+
13+
FASTAPI_AVAILABLE = True
14+
except ImportError:
15+
FASTAPI_AVAILABLE = False
16+
17+
18+
def check_manifest_runner_dependencies() -> None:
19+
"""Check if manifest-runner dependencies are installed."""
20+
if not FASTAPI_AVAILABLE:
21+
click.echo(
22+
"❌ Manifest runner dependencies not found. Please install with:\n\n"
23+
" pip install airbyte-cdk[manifest-runner]\n"
24+
" # or\n"
25+
" poetry install --extras manifest-runner\n",
26+
err=True,
27+
)
28+
sys.exit(1)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
2+
"""Info command for the manifest runner CLI."""
3+
4+
import rich_click as click
5+
6+
# Import server dependencies with graceful fallback
7+
try:
8+
import fastapi
9+
import uvicorn
10+
11+
FASTAPI_AVAILABLE = True
12+
except ImportError:
13+
FASTAPI_AVAILABLE = False
14+
fastapi = None
15+
uvicorn = None
16+
17+
18+
@click.command()
19+
def info() -> None:
20+
"""Show manifest runner information and status."""
21+
if FASTAPI_AVAILABLE:
22+
click.echo("✅ Manifest runner dependencies are installed")
23+
click.echo(f" FastAPI version: {fastapi.__version__}")
24+
click.echo(f" Uvicorn version: {uvicorn.__version__}")
25+
else:
26+
click.echo("❌ Manifest runner dependencies not installed")
27+
click.echo(" Install with: pip install airbyte-cdk[manifest-runner]")
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
2+
"""Generate OpenAPI command for the manifest runner CLI."""
3+
4+
from pathlib import Path
5+
6+
import rich_click as click
7+
from yaml import dump
8+
9+
from ._common import check_manifest_runner_dependencies
10+
11+
12+
@click.command("generate-openapi")
13+
@click.option(
14+
"--output",
15+
"-o",
16+
default="airbyte_cdk/manifest_runner/openapi.yaml",
17+
help="Output path for the OpenAPI YAML file",
18+
show_default=True,
19+
)
20+
def generate_openapi(output: str) -> None:
21+
"""Generate OpenAPI YAML specification for the manifest runner."""
22+
check_manifest_runner_dependencies()
23+
24+
# Import the FastAPI app
25+
from airbyte_cdk.manifest_runner.app import app
26+
27+
# Get OpenAPI schema
28+
openapi_schema = app.openapi()
29+
30+
# Ensure output directory exists
31+
output_path = Path(output)
32+
output_path.parent.mkdir(parents=True, exist_ok=True)
33+
34+
# Write YAML file with header comment
35+
with open(output_path, "w") as f:
36+
f.write("# This file is auto-generated. Do not edit manually.\n")
37+
f.write("# To regenerate, run: manifest-runner generate-openapi\n")
38+
f.write("\n")
39+
dump(openapi_schema, f, default_flow_style=False, sort_keys=False)
40+
41+
click.echo(f"✅ OpenAPI YAML generated at: {output_path}")
42+
click.echo(f" Title: {openapi_schema.get('info', {}).get('title', 'N/A')}")
43+
click.echo(f" Version: {openapi_schema.get('info', {}).get('version', 'N/A')}")

airbyte_cdk/cli/manifest_runner/_run.py

Lines changed: 8 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
22
"""Standalone CLI for the Airbyte CDK Manifest Runner.
33
4-
This CLI provides commands for running and managing the FastAPI-based manifest runner server.
4+
This CLI provides commands for running and managing the manifest runner server.
55
66
**Installation:**
77
@@ -22,103 +22,32 @@
2222
```
2323
"""
2424

25-
import sys
26-
from typing import Optional
27-
2825
import rich_click as click
2926

30-
# Import server dependencies with graceful fallback
31-
try:
32-
import fastapi
33-
import uvicorn
34-
35-
FASTAPI_AVAILABLE = True
36-
except ImportError:
37-
FASTAPI_AVAILABLE = False
38-
fastapi = None
39-
uvicorn = None
40-
41-
42-
def _check_manifest_runner_dependencies() -> None:
43-
"""Check if manifest-runner dependencies are installed."""
44-
if not FASTAPI_AVAILABLE:
45-
click.echo(
46-
"❌ Manifest runner dependencies not found. Please install with:\n\n"
47-
" pip install airbyte-cdk[manifest-runner]\n"
48-
" # or\n"
49-
" poetry install --extras manifest-runner\n",
50-
err=True,
51-
)
52-
sys.exit(1)
27+
from ._info import info
28+
from ._openapi import generate_openapi
29+
from ._start import start
5330

5431

5532
@click.group(
5633
help=__doc__.replace("\n", "\n\n"), # Render docstring as help text (markdown)
5734
invoke_without_command=True,
5835
)
59-
@click.option(
60-
"--version",
61-
is_flag=True,
62-
help="Show the version of the Airbyte CDK Manifest Runner.",
63-
)
6436
@click.pass_context
6537
def cli(
6638
ctx: click.Context,
67-
version: bool,
6839
) -> None:
69-
"""Airbyte CDK Manifest Runner CLI."""
70-
if version:
71-
click.echo("Airbyte CDK Manifest Runner v1.0.0")
72-
ctx.exit()
40+
"""Airbyte Manifest Runner CLI."""
7341

7442
if ctx.invoked_subcommand is None:
7543
# If no subcommand is provided, show the help message.
7644
click.echo(ctx.get_help())
7745
ctx.exit()
7846

7947

80-
@cli.command()
81-
@click.option(
82-
"--host",
83-
default="127.0.0.1",
84-
help="Host to bind the server to",
85-
show_default=True,
86-
)
87-
@click.option(
88-
"--port",
89-
default=8000,
90-
help="Port to bind the server to",
91-
show_default=True,
92-
)
93-
@click.option(
94-
"--reload",
95-
is_flag=True,
96-
help="Enable auto-reload for development",
97-
)
98-
def start(host: str, port: int, reload: bool) -> None:
99-
"""Start the FastAPI manifest runner server."""
100-
_check_manifest_runner_dependencies()
101-
102-
# Import and use the main server function
103-
from airbyte_cdk.manifest_runner.main import run_server
104-
105-
run_server(
106-
host=host,
107-
port=port,
108-
reload=reload,
109-
)
110-
111-
112-
@cli.command()
113-
def info() -> None:
114-
"""Show manifest runner information and status."""
115-
if FASTAPI_AVAILABLE:
116-
click.echo("✅ Manifest runner dependencies are installed")
117-
click.echo(f" FastAPI version: {fastapi.__version__}")
118-
click.echo(f" Uvicorn version: {uvicorn.__version__}")
119-
else:
120-
click.echo("❌ Manifest runner dependencies not installed")
121-
click.echo(" Install with: pip install airbyte-cdk[manifest-runner]")
48+
cli.add_command(start)
49+
cli.add_command(info)
50+
cli.add_command(generate_openapi)
12251

12352

12453
def run() -> None:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
2+
"""Start command for the manifest runner CLI."""
3+
4+
import rich_click as click
5+
6+
from ._common import check_manifest_runner_dependencies
7+
8+
9+
@click.command()
10+
@click.option(
11+
"--host",
12+
default="127.0.0.1",
13+
help="Host to bind the server to",
14+
show_default=True,
15+
)
16+
@click.option(
17+
"--port",
18+
default=8000,
19+
help="Port to bind the server to",
20+
show_default=True,
21+
)
22+
@click.option(
23+
"--reload",
24+
is_flag=True,
25+
help="Enable auto-reload for development",
26+
)
27+
def start(host: str, port: int, reload: bool) -> None:
28+
"""Start the FastAPI manifest runner server."""
29+
check_manifest_runner_dependencies()
30+
31+
# Import and use the main server function
32+
from airbyte_cdk.manifest_runner.main import run_server
33+
34+
run_server(
35+
host=host,
36+
port=port,
37+
reload=reload,
38+
)

0 commit comments

Comments
 (0)