def api(
config: Annotated[
Path | None,
typer.Option(
"--config",
"-c",
help="Path to configuration file (TOML, JSON, or YAML)",
exists=True,
file_okay=True,
dir_okay=False,
readable=True,
rich_help_panel="Configuration",
),
] = None,
port: Annotated[
int | None,
typer.Option(
"--port",
"-p",
help="Port to run the server on",
callback=validate_port,
rich_help_panel="Server Settings",
),
] = None,
host: Annotated[
str | None,
typer.Option(
"--host",
"-h",
help="Host to bind the server to",
rich_help_panel="Server Settings",
),
] = None,
reload: Annotated[
bool | None,
typer.Option(
"--reload/--no-reload",
help="Enable auto-reload for development",
rich_help_panel="Server Settings",
),
] = None,
log_level: Annotated[
str | None,
typer.Option(
"--log-level",
help="Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL). Use WARNING for minimal output.",
callback=validate_log_level,
rich_help_panel="Server Settings",
),
] = None,
log_file: Annotated[
str | None,
typer.Option(
"--log-file",
help="Path to JSON log file. If specified, logs will be written to this file in JSON format",
rich_help_panel="Server Settings",
),
] = None,
auth_token: Annotated[
str | None,
typer.Option(
"--auth-token",
help="Bearer token for API authentication",
callback=validate_auth_token,
rich_help_panel="Security Settings",
),
] = None,
enable_plugin: Annotated[
list[str] | None,
typer.Option(
"--enable-plugin",
help="Enable a plugin by name (repeatable)",
rich_help_panel="Plugin Settings",
),
] = None,
disable_plugin: Annotated[
list[str] | None,
typer.Option(
"--disable-plugin",
help="Disable a plugin by name (repeatable)",
rich_help_panel="Plugin Settings",
),
] = None,
# Removed unused flags: plugin_setting, no_network_calls,
# disable_version_check, disable_pricing_updates
) -> None:
"""Start the CCProxy API server."""
try:
if config is None:
config = get_config_path_from_context()
# Base CLI context; plugin-injected args merged below
cli_context = {
"port": port,
"host": host,
"reload": reload,
"log_level": log_level,
"log_file": log_file,
"auth_token": auth_token,
"enabled_plugins": enable_plugin,
"disabled_plugins": disable_plugin,
}
# Merge plugin-provided CLI args via helper
try:
from ccproxy.cli.helpers import get_plugin_cli_args
plugin_args = get_plugin_cli_args()
if plugin_args:
cli_context.update(plugin_args)
except Exception:
pass
# Pass CLI context to settings creation
settings = Settings.from_config(config_path=config, cli_context=cli_context)
setup_logging(
json_logs=settings.logging.format == "json",
log_level_name=settings.logging.level,
log_file=settings.logging.file,
)
logger = get_logger(__name__)
logger.debug(
"configuration_loaded",
host=settings.server.host,
port=settings.server.port,
log_level=settings.logging.level,
log_file=settings.logging.file,
auth_enabled=bool(settings.security.auth_token),
duckdb_enabled=bool(
(settings.plugins.get("duckdb_storage") or {}).get("enabled", False)
),
)
_run_local_server(settings)
except ConfigurationError as e:
toolkit = get_rich_toolkit()
toolkit.print(f"Configuration error: {e}", tag="error")
raise typer.Exit(1) from e
except OSError as e:
toolkit = get_rich_toolkit()
toolkit.print(
f"Server startup failed (port/permission issue): {e}", tag="error"
)
raise typer.Exit(1) from e
except ImportError as e:
toolkit = get_rich_toolkit()
toolkit.print(f"Import error during server startup: {e}", tag="error")
raise typer.Exit(1) from e
except Exception as e:
toolkit = get_rich_toolkit()
toolkit.print(f"Error starting server: {e}", tag="error")
raise typer.Exit(1) from e