Skip to main content
Glama
commands.py6.66 kB
"""Google Sheets CLI commands.""" import typer from typing import Optional from rich.console import Console from rich.table import Table console = Console() # Sheets command group sheets_app = typer.Typer( name="sheets", help="Google Sheets operations - read and export spreadsheet data", rich_markup_mode="rich", ) @sheets_app.command("info") def sheets_info( spreadsheet_id: str = typer.Argument(..., help="Spreadsheet ID or URL"), ): """ Get spreadsheet metadata. Shows spreadsheet title, locale, timezone, and list of sheets. """ from .api import SheetsAPI try: api = SheetsAPI() info = api.get_spreadsheet(spreadsheet_id) console.print(f"\n[bold blue]Spreadsheet Info[/bold blue]") console.print(f"[dim]ID:[/dim] {info['spreadsheetId']}") console.print(f"[dim]Title:[/dim] [green]{info['title']}[/green]") if info.get('locale'): console.print(f"[dim]Locale:[/dim] {info['locale']}") if info.get('timeZone'): console.print(f"[dim]Timezone:[/dim] {info['timeZone']}") console.print(f"\n[bold]Sheets ({len(info['sheets'])}):[/bold]") table = Table() table.add_column("Index", style="dim", justify="right") table.add_column("Title", style="cyan") table.add_column("Rows", justify="right", style="green") table.add_column("Columns", justify="right", style="magenta") for sheet in info['sheets']: table.add_row( str(sheet['index']), sheet['title'], str(sheet['rowCount']), str(sheet['columnCount']) ) console.print(table) except Exception as e: console.print(f"[red]Error: {e}[/red]") raise typer.Exit(1) @sheets_app.command("list") def sheets_list_sheets( spreadsheet_id: str = typer.Argument(..., help="Spreadsheet ID or URL"), ): """ List all sheets in a spreadsheet. Shows sheet names with row and column counts. """ from .api import SheetsAPI try: api = SheetsAPI() sheets = api.list_sheets(spreadsheet_id) if not sheets: console.print("[yellow]No sheets found.[/yellow]") return table = Table(title="Sheets") table.add_column("Index", style="dim", justify="right") table.add_column("Sheet ID", style="dim") table.add_column("Title", style="cyan") table.add_column("Size", style="green") for sheet in sheets: table.add_row( str(sheet['index']), str(sheet['sheetId']), sheet['title'], f"{sheet['rowCount']} x {sheet['columnCount']}" ) console.print(table) except Exception as e: console.print(f"[red]Error: {e}[/red]") raise typer.Exit(1) @sheets_app.command("read") def sheets_read( spreadsheet_id: str = typer.Argument(..., help="Spreadsheet ID or URL"), range_notation: Optional[str] = typer.Argument(None, help="A1 notation range (e.g., A1:D10)"), sheet: Optional[str] = typer.Option(None, "--sheet", "-s", help="Sheet name"), output: Optional[str] = typer.Option(None, "--output", "-o", help="Output file path"), format: str = typer.Option("table", "--format", "-f", help="Output format: table, csv, json"), limit: int = typer.Option(100, "--limit", "-l", help="Max rows to display in table format"), header: bool = typer.Option(True, "--header/--no-header", help="Treat first row as header"), ): """ Read data from a spreadsheet. Supports table, CSV, and JSON output formats. Examples: gtools sheets read SPREADSHEET_ID gtools sheets read SPREADSHEET_ID A1:D10 gtools sheets read SPREADSHEET_ID --sheet "Sheet1" --format csv -o data.csv gtools sheets read "https://docs.google.com/spreadsheets/d/ID/edit" --format json """ from .api import SheetsAPI import json try: api = SheetsAPI() data = api.read_values(spreadsheet_id, range_notation, sheet) values = data["values"] if not values: console.print("[yellow]No data found in the specified range.[/yellow]") return # Format output if format == "csv": csv_content = api.export_to_csv(spreadsheet_id, range_notation, sheet) if output: with open(output, "w", encoding="utf-8") as f: f.write(csv_content) console.print(f"[green]✓ Exported {data['rowCount']} rows to {output}[/green]") else: console.print(csv_content) elif format == "json": if header and len(values) > 1: headers = values[0] json_data = [ dict(zip(headers, row)) for row in values[1:] ] else: json_data = values json_output = json.dumps(json_data, indent=2, ensure_ascii=False) if output: with open(output, "w", encoding="utf-8") as f: f.write(json_output) console.print(f"[green]✓ Exported {len(json_data)} records to {output}[/green]") else: console.print(json_output) else: # table format table = Table(title=f"Data from {data['range']}") # Use first row as headers if enabled if header and len(values) > 0: for col in values[0]: table.add_column(str(col), style="cyan") data_rows = values[1:limit+1] if len(values) > 1 else [] else: # Generate column headers for i in range(data['columnCount']): table.add_column(f"Col {i+1}", style="cyan") data_rows = values[:limit] for row in data_rows: table.add_row(*[str(cell) for cell in row]) console.print(table) console.print(f"\n[dim]Showing {len(data_rows)} of {data['rowCount']} rows, {data['columnCount']} columns[/dim]") console.print(f"[dim]Range: {data['range']}[/dim]") if output: csv_content = api.export_to_csv(spreadsheet_id, range_notation, sheet) with open(output, "w", encoding="utf-8") as f: f.write(csv_content) console.print(f"[green]✓ Also exported to {output}[/green]") except Exception as e: console.print(f"[red]Error: {e}[/red]") raise typer.Exit(1)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/maksdizzy/google-forms-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server