{"id":46995518,"url":"https://github.com/sqlhabit/select-bq","last_synced_at":"2026-03-15T19:01:16.353Z","repository":{"id":343241825,"uuid":"1176881694","full_name":"sqlhabit/select-bq","owner":"sqlhabit","description":"Wrapper around BigQuery's bq CLI tool to ensure safe access.","archived":false,"fork":false,"pushed_at":"2026-03-09T16:23:27.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-11T19:13:53.891Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sqlhabit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-09T13:27:30.000Z","updated_at":"2026-03-09T16:23:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sqlhabit/select-bq","commit_stats":null,"previous_names":["sqlhabit/safe-bq"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sqlhabit/select-bq","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sqlhabit%2Fselect-bq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sqlhabit%2Fselect-bq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sqlhabit%2Fselect-bq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sqlhabit%2Fselect-bq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sqlhabit","download_url":"https://codeload.github.com/sqlhabit/select-bq/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sqlhabit%2Fselect-bq/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30431514,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T14:34:45.044Z","status":"ssl_error","status_checked_at":"2026-03-12T14:09:33.793Z","response_time":114,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-03-11T15:00:28.185Z","updated_at":"2026-03-12T16:01:08.525Z","avatar_url":"https://github.com/sqlhabit.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# select-bq\n\nA **SELECT-only BigQuery CLI wrapper** for agentic use (e.g. with Cursor). Wraps the official `bq` CLI and enforces:\n\n- **SELECT-only**: Queries are validated via SQL AST parsing—no DML, DDL, scripting, `EXECUTE IMMEDIATE`, or hidden CTEs that could modify data.\n- **Allowlist**: Optional config restricts queries to specific project/dataset/table. Empty or missing allowlist = no restriction.\n- **Audit logging**: All queries (including rejections) are logged to a YAML file with timestamps.\n\n## Install\n\n```bash\npip install select-bq\n```\n\nRequires the [Google Cloud SDK](https://cloud.google.com/sdk/docs/install) (`bq` CLI) and `gcloud auth login`.\n\n## Setup\n\nCreate a config file `.select-bq.yaml` in your project root:\n\n```yaml\n# Where to log queries (default: select-bq-queries.yaml in current dir)\nlog_path: select-bq-queries.yaml\n\n# Optional allowlist. Omit or leave empty to allow all tables.\n# When present, only these tables can be queried.\nallowlist:\n  - project: my-gcp-project\n    dataset: analytics\n    table: events\n  - project: my-gcp-project\n    dataset: analytics\n    table: \"*\"   # wildcard: all tables in this dataset\n```\n\n- **`log_path`** — Path for the query log (default: `select-bq-queries.yaml`). Use an absolute path to log outside the project.\n- **`allowlist`** — List of allowed `project`/`dataset`/`table`. Use `table: \"*\"` for all tables in a dataset. Omit to allow all tables.\n\nTo use a different config path: `select-bq query --config ./my-config.yaml \"SELECT 1\"`.\n\nTo use an external allowlist file:\n\n```yaml\nlog_path: select-bq-queries.yaml\nallowlist_path: allowlist.yaml\n```\n\n## Usage\n\n```bash\n# Run a SELECT query (same as bq query, but validated)\nselect-bq query \"SELECT 1\"\nselect-bq query \"SELECT * FROM project.dataset.table LIMIT 10\" --format=pretty\n\n# Query from file\nselect-bq query -f query.sql\n\n# Custom config\nselect-bq query --config ./my-config.yaml \"SELECT * FROM my_table\"\n\n# Use Standard SQL (default) or legacy SQL\nselect-bq query --use_legacy_sql=false \"SELECT 1\"\nselect-bq query --use_legacy_sql=true \"SELECT 1\"\n\n# All bq query flags are passed through (format, project_id, etc.)\nselect-bq query --format=pretty --project_id=my-project \"SELECT 1\"\n```\n\n## Query Log\n\nLogged to `log_path` (default `select-bq-queries.yaml`):\n\n```yaml\nqueries:\n  - timestamp: \"2025-03-09T12:00:00.000000+00:00\"\n    query: \"SELECT 1\"\n    success: true\n  - timestamp: \"2025-03-09T12:01:00.000000+00:00\"\n    query: \"INSERT INTO t VALUES (1)\"\n    success: false\n    error: \"Statement type 'Insert' is not allowed. Only SELECT queries are permitted.\"\n```\n\n## Security\n\n- **AST parsing**: Uses [sqlglot](https://github.com/tobymao/sqlglot) with BigQuery dialect. Only `SELECT` statements are allowed; `INSERT`, `UPDATE`, `DELETE`, `CREATE`, `DROP`, `EXECUTE IMMEDIATE`, `DECLARE`, `SET`, and similar are rejected.\n- **Allowlist**: When configured, only tables matching the allowlist can be queried. Supports wildcards (`table: \"*\"` for all tables in a dataset).\n- **No eval/exec**: Validation is purely structural—no dynamic execution of user input.\n\n## Cursor Integration\n\nAdd to your project's Cursor rules or AGENTS.md:\n\n```markdown\nUse `select-bq query \"SELECT ...\"` when querying BigQuery. Do not use raw `bq` for queries.\n```\n\n## Publishing\n\nTo build and publish to PyPI:\n\n```bash\npip install build twine\npython -m build\ntwine upload dist/*\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsqlhabit%2Fselect-bq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsqlhabit%2Fselect-bq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsqlhabit%2Fselect-bq/lists"}