""" pyserve ps / status - Show service status """ import json from pathlib import Path from typing import Any, Optional import click @click.command("ps") @click.argument("services", nargs=-1) @click.option( "-a", "--all", "show_all", is_flag=True, help="Show all services (including stopped)", ) @click.option( "-q", "--quiet", is_flag=True, help="Only show service names", ) @click.option( "--format", "output_format", type=click.Choice(["table", "json", "yaml"]), default="table", help="Output format", ) @click.option( "--filter", "filter_status", default=None, help="Filter by status (running, stopped, failed)", ) @click.pass_obj def ps_cmd( ctx: Any, services: tuple[str, ...], show_all: bool, quiet: bool, output_format: str, filter_status: Optional[str], ) -> None: """ Show status of services. \b Examples: pyserve ps # Show running services pyserve ps -a # Show all services pyserve ps api admin # Show specific services pyserve ps --format json # JSON output pyserve ps --filter running # Filter by status """ from ..output import ( console, create_services_table, format_health, format_status, format_uptime, print_info, ) from ..state import StateManager state_manager = StateManager(Path(".pyserve"), ctx.project) all_services = state_manager.get_all_services() # Check if daemon is running daemon_running = state_manager.is_daemon_running() # Filter services if services: all_services = {k: v for k, v in all_services.items() if k in services} if filter_status: all_services = {k: v for k, v in all_services.items() if v.state.lower() == filter_status.lower()} if not show_all: # By default, show only running/starting/failed services all_services = {k: v for k, v in all_services.items() if v.state.lower() in ("running", "starting", "stopping", "failed", "restarting")} if not all_services: if daemon_running: print_info("No services found. Daemon is running but no services are configured.") else: print_info("No services running. Use 'pyserve up' to start services.") return if quiet: for name in all_services: click.echo(name) return if output_format == "json": data = {name: svc.to_dict() for name, svc in all_services.items()} console.print(json.dumps(data, indent=2)) return if output_format == "yaml": import yaml data = {name: svc.to_dict() for name, svc in all_services.items()} console.print(yaml.dump(data, default_flow_style=False)) return table = create_services_table() for name, service in sorted(all_services.items()): ports = f"{service.port}" if service.port else "-" uptime = format_uptime(service.uptime) if service.state == "running" else "-" health = format_health(service.health.status if service.state == "running" else "-") pid = str(service.pid) if service.pid else "-" workers = f"{service.workers}" if service.workers else "-" table.add_row( name, format_status(service.state), ports, uptime, health, pid, workers, ) console.print() console.print(table) console.print() total = len(all_services) running = sum(1 for s in all_services.values() if s.state == "running") failed = sum(1 for s in all_services.values() if s.state == "failed") summary_parts = [f"[bold]{total}[/bold] service(s)"] if running: summary_parts.append(f"[green]{running} running[/green]") if failed: summary_parts.append(f"[red]{failed} failed[/red]") if total - running - failed > 0: summary_parts.append(f"[dim]{total - running - failed} stopped[/dim]") console.print(" | ".join(summary_parts)) console.print()