mirror of
https://github.com/open-webui/open-terminal.git
synced 2026-11-04 08:10:53 +00:00
Allow loading the API key from a file via OPEN_TERMINAL_API_KEY_FILE, following the convention used by the official PostgreSQL Docker image. - Add _resolve_file_env() helper in env.py - Add file_env shell function in entrypoint.sh - Add _FILE fallback in cli.py run command - Update README with Docker Compose example - Bump version to 0.4.3 Closes #14
112 lines
3.2 KiB
Python
112 lines
3.2 KiB
Python
import os
|
|
|
|
import click
|
|
import uvicorn
|
|
|
|
|
|
@click.group()
|
|
def main():
|
|
"""open-terminal — terminal interaction API"""
|
|
pass
|
|
|
|
|
|
BANNER = r"""
|
|
____ _____ _ _
|
|
/ __ \ |_ _| (_) | |
|
|
| | | |_ __ ___ _ __ | | ___ _ __ _ __ ___ _ _ __ __ _| |
|
|
| | | | '_ \ / _ | '_ \ | |/ _ | '__| '_ ` _ \| | '_ \ / _` | |
|
|
| |__| | |_) | __| | | | | | __| | | | | | | | | | | | (_| | |
|
|
\____/| .__/ \___|_| |_| \_/\___|_| |_| |_| |_|_|_| |_|\__,_|_|
|
|
| |
|
|
|_|
|
|
"""
|
|
|
|
|
|
@main.command()
|
|
@click.option("--host", default="0.0.0.0", help="Bind host")
|
|
@click.option("--port", default=8000, type=int, help="Bind port")
|
|
@click.option(
|
|
"--cwd",
|
|
type=click.Path(exists=True, file_okay=False, resolve_path=True, path_type=str),
|
|
default=None,
|
|
help="Working directory for the server process.",
|
|
)
|
|
@click.option(
|
|
"--api-key",
|
|
default="",
|
|
envvar="OPEN_TERMINAL_API_KEY",
|
|
help="Bearer API key (or set OPEN_TERMINAL_API_KEY env var)",
|
|
)
|
|
@click.option(
|
|
"--cors-allowed-origins",
|
|
default="*",
|
|
envvar="OPEN_TERMINAL_CORS_ALLOWED_ORIGINS",
|
|
help="Allowed CORS origins, comma-separated (default: * for all)",
|
|
)
|
|
def run(host: str, port: int, cwd: str | None, api_key: str, cors_allowed_origins: str):
|
|
"""Start the sandbox API server."""
|
|
import secrets
|
|
|
|
if cwd:
|
|
os.chdir(cwd)
|
|
|
|
# Support Docker secrets: load from _FILE variant if no key was given
|
|
if not api_key:
|
|
file_path = os.environ.get("OPEN_TERMINAL_API_KEY_FILE")
|
|
if file_path:
|
|
with open(file_path) as f:
|
|
api_key = f.read().strip()
|
|
|
|
generated = not api_key
|
|
if not api_key:
|
|
api_key = secrets.token_urlsafe(24)
|
|
|
|
os.environ["OPEN_TERMINAL_API_KEY"] = api_key
|
|
os.environ["OPEN_TERMINAL_CORS_ALLOWED_ORIGINS"] = cors_allowed_origins
|
|
|
|
click.echo(BANNER)
|
|
if generated:
|
|
click.echo("=" * 60)
|
|
click.echo(f" API Key: {api_key}")
|
|
click.echo("=" * 60)
|
|
click.echo()
|
|
|
|
uvicorn.run("open_terminal.main:app", host=host, port=port)
|
|
|
|
|
|
@main.command()
|
|
@click.option(
|
|
"--transport",
|
|
default="stdio",
|
|
type=click.Choice(["stdio", "streamable-http"]),
|
|
help="MCP transport (default: stdio)",
|
|
)
|
|
@click.option("--host", default="0.0.0.0", help="Bind host (streamable-http only)")
|
|
@click.option("--port", default=8000, type=int, help="Bind port (streamable-http only)")
|
|
@click.option(
|
|
"--cwd",
|
|
type=click.Path(exists=True, file_okay=False, resolve_path=True, path_type=str),
|
|
default=None,
|
|
help="Working directory for the server process.",
|
|
)
|
|
def mcp(transport: str, host: str, port: int, cwd: str | None):
|
|
"""Start the MCP server (requires 'pip install open-terminal[mcp]')."""
|
|
if cwd:
|
|
os.chdir(cwd)
|
|
|
|
try:
|
|
from open_terminal.mcp_server import mcp as mcp_server
|
|
except ImportError:
|
|
click.echo(
|
|
"Missing MCP dependencies. Install with:\n"
|
|
" pip install open-terminal[mcp]",
|
|
err=True,
|
|
)
|
|
raise SystemExit(1)
|
|
|
|
mcp_server.run(transport=transport, host=host, port=port)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|