squawk-cli


Namesquawk-cli JSON
Version 2.19.0 PyPI version JSON
download
home_pageNone
SummaryLinter for PostgreSQL migrations
upload_time2025-07-10 02:06:09
maintainerNone
docs_urlNone
authorSquawk Team & Contributors
requires_python>=3.8
licenseApache-2.0 OR MIT
keywords postgres postgresql linter
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # squawk [![npm](https://img.shields.io/npm/v/squawk-cli)](https://www.npmjs.com/package/squawk-cli)

> Linter for Postgres migrations & SQL

[Quick Start](https://squawkhq.com/docs/) | [Playground](https://play.squawkhq.com) | [Rules Documentation](https://squawkhq.com/docs/rules) | [GitHub Action](https://github.com/sbdchd/squawk-action) | [DIY GitHub Integration](https://squawkhq.com/docs/github_app)

## Why?

Prevent unexpected downtime caused by database migrations and encourage best
practices around Postgres schemas and SQL.

## Install

```shell
npm install -g squawk-cli

# or via PYPI
pip install squawk-cli

# or install binaries directly via the releases page
https://github.com/sbdchd/squawk/releases
```

### Or via Docker

You can also run Squawk using Docker. The official image is available on GitHub Container Registry.

```shell
# Assuming you want to check sql files in the current directory
docker run --rm -v $(pwd):/data ghcr.io/sbdchd/squawk:latest *.sql
```

### Or via the Playground

Use the WASM powered playground to check your SQL locally in the browser!

<https://play.squawkhq.com>

### Or via VSCode

<https://marketplace.visualstudio.com/items?itemName=sbdchd.squawk>

## Usage

```shell
❯ squawk example.sql
warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit.
 --> example.sql:6:10
  |
6 |     "id" serial NOT NULL PRIMARY KEY,
  |          ------
  |
  = help: Use 64-bit integer values instead to prevent hitting this limit.
warning[prefer-identity]: Serial types make schema, dependency, and permission management difficult.
 --> example.sql:6:10
  |
6 |     "id" serial NOT NULL PRIMARY KEY,
  |          ------
  |
  = help: Use Identity columns instead.
warning[prefer-text-field]: Changing the size of a `varchar` field requires an `ACCESS EXCLUSIVE` lock, that will prevent all reads and writes to the table.
 --> example.sql:7:13
  |
7 |     "alpha" varchar(100) NOT NULL
  |             ------------
  |
  = help: Use a `TEXT` field with a `CHECK` constraint.
warning[require-concurrent-index-creation]: During normal index creation, table updates are blocked, but reads are still allowed.
  --> example.sql:10:1
   |
10 | CREATE INDEX "field_name_idx" ON "table_name" ("field_name");
   | ------------------------------------------------------------
   |
   = help: Use `CONCURRENTLY` to avoid blocking writes.
warning[constraint-missing-not-valid]: By default new constraints require a table scan and block writes to the table while that scan occurs.
  --> example.sql:12:24
   |
12 | ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);
   |                        --------------------------------------------------------
   |
   = help: Use `NOT VALID` with a later `VALIDATE CONSTRAINT` call.
warning[disallowed-unique-constraint]: Adding a `UNIQUE` constraint requires an `ACCESS EXCLUSIVE` lock which blocks reads and writes to the table while the index is built.
  --> example.sql:12:28
   |
12 | ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);
   |                            ----------------------------------------------------
   |
   = help: Create an index `CONCURRENTLY` and create the constraint using the index.

Find detailed examples and solutions for each rule at https://squawkhq.com/docs/rules
Found 7 issues in 1 file (checked 1 source file)
```

### `squawk --help`

```
squawk
Find problems in your SQL

USAGE:
    squawk [FLAGS] [OPTIONS] [path]... [SUBCOMMAND]

FLAGS:
        --assume-in-transaction
            Assume that a transaction will wrap each SQL file when run by a migration tool

            Use --no-assume-in-transaction to override this setting in any config file that exists
    -h, --help
            Prints help information

    -V, --version
            Prints version information

        --verbose
            Enable debug logging output


OPTIONS:
    -c, --config <config-path>
            Path to the squawk config file (.squawk.toml)

        --debug <format>
            Output debug info [possible values: Lex, Parse]

        --exclude-path <excluded-path>...
            Paths to exclude

            For example: --exclude-path=005_user_ids.sql --exclude-path=009_account_emails.sql

            --exclude-path='*user_ids.sql'

    -e, --exclude <rule>...
            Exclude specific warnings

            For example: --exclude=require-concurrent-index-creation,ban-drop-database

        --pg-version <pg-version>
            Specify postgres version

            For example: --pg-version=13.0
        --reporter <reporter>
            Style of error reporting [possible values: Tty, Gcc, Json]

        --stdin-filepath <filepath>
            Path to use in reporting for stdin


ARGS:
    <path>...
            Paths to search


SUBCOMMANDS:
    help                Prints this message or the help of the given subcommand(s)
    upload-to-github    Comment on a PR with Squawk's results
```

## Rules

Individual rules can be disabled via the `--exclude` flag

```shell
squawk --exclude=adding-field-with-default,disallowed-unique-constraint example.sql
```

### Disabling rules via comments

Rule violations can be ignored via the `squawk-ignore` comment:

```sql
-- squawk-ignore ban-drop-column
alter table t drop column c cascade;
```

You can also ignore multiple rules by making a comma seperated list:

```sql
-- squawk-ignore ban-drop-column, renaming-column,ban-drop-database
alter table t drop column c cascade;
```

### Configuration file

Rules can also be disabled with a configuration file.

By default, Squawk will traverse up from the current directory to find a `.squawk.toml` configuration file. You may specify a custom path with the `-c` or `--config` flag.

```shell
squawk --config=~/.squawk.toml example.sql
```

The `--exclude` flag will always be prioritized over the configuration file.

**Example `.squawk.toml`**

```toml
excluded_rules = [
    "require-concurrent-index-creation",
    "require-concurrent-index-deletion",
]
```

See the [Squawk website](https://squawkhq.com/docs/rules) for documentation on each rule with examples and reasoning.

## Bot Setup

Squawk works as a CLI tool but can also create comments on GitHub Pull
Requests using the `upload-to-github` subcommand.

Here's an example comment created by `squawk` using the `example.sql` in the repo:

<https://github.com/sbdchd/squawk/pull/14#issuecomment-647009446>

See the ["GitHub Integration" docs](https://squawkhq.com/docs/github_app) for more information.

## `pre-commit` hook

Integrate Squawk into Git workflow with [pre-commit](https://pre-commit.com/). Add the following
to your project's `.pre-commit-config.yaml`:

```yaml
repos:
  - repo: https://github.com/sbdchd/squawk
    rev: v0.10.0
    hooks:
      - id: squawk
        files: path/to/postgres/migrations/written/in/sql
```

Note the `files` parameter as it specifies the location of the files to be linted.

## Prior Art / Related

- <https://github.com/erik/squabble>
- <https://github.com/yandex/zero-downtime-migrations>
- <https://github.com/tbicr/django-pg-zero-downtime-migrations>
- <https://github.com/3YOURMIND/django-migration-linter>
- <https://github.com/ankane/strong_migrations>
- <https://github.com/AdmTal/PostgreSQL-Query-Lock-Explainer>
- <https://github.com/stripe/pg-schema-diff>
- <https://github.com/kristiandupont/schemalint>
- <https://github.com/supabase-community/postgres-language-server>
- <https://github.com/premium-minds/sonar-postgres-plugin>
- <https://engineering.fb.com/2022/11/30/data-infrastructure/static-analysis-sql-queries/>
- <https://github.com/xNaCly/sqleibniz>
- <https://github.com/sqlfluff/sqlfluff>
- <https://atlasgo.io/lint/analyzers>
- <https://github.com/tobymao/sqlglot>
- <https://github.com/paupino/pg_parse>
- <https://github.com/sql-formatter-org/sql-formatter>
- <https://github.com/darold/pgFormatter>
- <https://github.com/sqls-server/sqls>
- <https://github.com/joe-re/sql-language-server>
- <https://github.com/nene/sql-parser-cst>
  - <https://github.com/nene/prettier-plugin-sql-cst>
- <https://www.sqlstyle.guide>
- <https://github.com/ivank/potygen>

## Related Blog Posts / SE Posts / PG Docs

- <https://www.braintreepayments.com/blog/safe-operations-for-high-volume-postgresql/>
- <https://gocardless.com/blog/zero-downtime-postgres-migrations-the-hard-parts/>
- <https://www.citusdata.com/blog/2018/02/22/seven-tips-for-dealing-with-postgres-locks/>
- <https://realpython.com/create-django-index-without-downtime/#non-atomic-migrations>
- <https://dba.stackexchange.com/questions/158499/postgres-how-is-set-not-null-more-efficient-than-check-constraint>
- <https://www.postgresql.org/docs/10/sql-altertable.html#SQL-ALTERTABLE-NOTES>
- <https://www.postgresql.org/docs/current/explicit-locking.html>
- <https://benchling.engineering/move-fast-and-migrate-things-how-we-automated-migrations-in-postgres-d60aba0fc3d4>
- <https://medium.com/paypal-tech/postgresql-at-scale-database-schema-changes-without-downtime-20d3749ed680>

## Dev

```shell
cargo install
cargo run
./s/test
./s/lint
./s/fmt
```

... or with nix:

```
$ nix develop
[nix-shell]$ cargo run
[nix-shell]$ cargo insta review
[nix-shell]$ ./s/test
[nix-shell]$ ./s/lint
[nix-shell]$ ./s/fmt
```

### Adding a New Rule

When adding a new rule, running `cargo xtask new-rule` will create stubs for your rule in the Rust crate and in Documentation site.

```bash
cargo xtask new-rule 'prefer big serial'
```

### Releasing a New Version

1. Update the `CHANGELOG.md`

   Include a description of any fixes / additions. Make sure to include the PR numbers and credit the authors.

2. Run `s/update-version`

   ```bash
   # update version in squawk/Cargo.toml, package.json, flake.nix to 4.5.3
   s/update-version 4.5.3
   ```

3. Create a new release on GitHub

   Use the text and version from the `CHANGELOG.md`

### Algolia

The squawkhq.com Algolia index can be found on [the crawler website](https://crawler.algolia.com/admin/crawlers/9bf0dffb-bc5a-4d46-9b8d-2f1197285213/overview). Algolia reindexes the site every day at 5:30 (UTC).

## How it Works

Squawk uses its parser (based on rust-analyzer's parser) to create a CST. The
linters then use an AST layered on top of the CST to navigate and record
warnings, which are then pretty printed!


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "squawk-cli",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "postgres, postgresql, linter",
    "author": "Squawk Team & Contributors",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/d4/a1/462c5761b8f38694113e15a60f71020759d0a3c4429a746de5c99c9148b6/squawk_cli-2.19.0.tar.gz",
    "platform": null,
    "description": "# squawk [![npm](https://img.shields.io/npm/v/squawk-cli)](https://www.npmjs.com/package/squawk-cli)\n\n> Linter for Postgres migrations & SQL\n\n[Quick Start](https://squawkhq.com/docs/) | [Playground](https://play.squawkhq.com) | [Rules Documentation](https://squawkhq.com/docs/rules) | [GitHub Action](https://github.com/sbdchd/squawk-action) | [DIY GitHub Integration](https://squawkhq.com/docs/github_app)\n\n## Why?\n\nPrevent unexpected downtime caused by database migrations and encourage best\npractices around Postgres schemas and SQL.\n\n## Install\n\n```shell\nnpm install -g squawk-cli\n\n# or via PYPI\npip install squawk-cli\n\n# or install binaries directly via the releases page\nhttps://github.com/sbdchd/squawk/releases\n```\n\n### Or via Docker\n\nYou can also run Squawk using Docker. The official image is available on GitHub Container Registry.\n\n```shell\n# Assuming you want to check sql files in the current directory\ndocker run --rm -v $(pwd):/data ghcr.io/sbdchd/squawk:latest *.sql\n```\n\n### Or via the Playground\n\nUse the WASM powered playground to check your SQL locally in the browser!\n\n<https://play.squawkhq.com>\n\n### Or via VSCode\n\n<https://marketplace.visualstudio.com/items?itemName=sbdchd.squawk>\n\n## Usage\n\n```shell\n\u276f squawk example.sql\nwarning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit.\n --> example.sql:6:10\n  |\n6 |     \"id\" serial NOT NULL PRIMARY KEY,\n  |          ------\n  |\n  = help: Use 64-bit integer values instead to prevent hitting this limit.\nwarning[prefer-identity]: Serial types make schema, dependency, and permission management difficult.\n --> example.sql:6:10\n  |\n6 |     \"id\" serial NOT NULL PRIMARY KEY,\n  |          ------\n  |\n  = help: Use Identity columns instead.\nwarning[prefer-text-field]: Changing the size of a `varchar` field requires an `ACCESS EXCLUSIVE` lock, that will prevent all reads and writes to the table.\n --> example.sql:7:13\n  |\n7 |     \"alpha\" varchar(100) NOT NULL\n  |             ------------\n  |\n  = help: Use a `TEXT` field with a `CHECK` constraint.\nwarning[require-concurrent-index-creation]: During normal index creation, table updates are blocked, but reads are still allowed.\n  --> example.sql:10:1\n   |\n10 | CREATE INDEX \"field_name_idx\" ON \"table_name\" (\"field_name\");\n   | ------------------------------------------------------------\n   |\n   = help: Use `CONCURRENTLY` to avoid blocking writes.\nwarning[constraint-missing-not-valid]: By default new constraints require a table scan and block writes to the table while that scan occurs.\n  --> example.sql:12:24\n   |\n12 | ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);\n   |                        --------------------------------------------------------\n   |\n   = help: Use `NOT VALID` with a later `VALIDATE CONSTRAINT` call.\nwarning[disallowed-unique-constraint]: Adding a `UNIQUE` constraint requires an `ACCESS EXCLUSIVE` lock which blocks reads and writes to the table while the index is built.\n  --> example.sql:12:28\n   |\n12 | ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);\n   |                            ----------------------------------------------------\n   |\n   = help: Create an index `CONCURRENTLY` and create the constraint using the index.\n\nFind detailed examples and solutions for each rule at https://squawkhq.com/docs/rules\nFound 7 issues in 1 file (checked 1 source file)\n```\n\n### `squawk --help`\n\n```\nsquawk\nFind problems in your SQL\n\nUSAGE:\n    squawk [FLAGS] [OPTIONS] [path]... [SUBCOMMAND]\n\nFLAGS:\n        --assume-in-transaction\n            Assume that a transaction will wrap each SQL file when run by a migration tool\n\n            Use --no-assume-in-transaction to override this setting in any config file that exists\n    -h, --help\n            Prints help information\n\n    -V, --version\n            Prints version information\n\n        --verbose\n            Enable debug logging output\n\n\nOPTIONS:\n    -c, --config <config-path>\n            Path to the squawk config file (.squawk.toml)\n\n        --debug <format>\n            Output debug info [possible values: Lex, Parse]\n\n        --exclude-path <excluded-path>...\n            Paths to exclude\n\n            For example: --exclude-path=005_user_ids.sql --exclude-path=009_account_emails.sql\n\n            --exclude-path='*user_ids.sql'\n\n    -e, --exclude <rule>...\n            Exclude specific warnings\n\n            For example: --exclude=require-concurrent-index-creation,ban-drop-database\n\n        --pg-version <pg-version>\n            Specify postgres version\n\n            For example: --pg-version=13.0\n        --reporter <reporter>\n            Style of error reporting [possible values: Tty, Gcc, Json]\n\n        --stdin-filepath <filepath>\n            Path to use in reporting for stdin\n\n\nARGS:\n    <path>...\n            Paths to search\n\n\nSUBCOMMANDS:\n    help                Prints this message or the help of the given subcommand(s)\n    upload-to-github    Comment on a PR with Squawk's results\n```\n\n## Rules\n\nIndividual rules can be disabled via the `--exclude` flag\n\n```shell\nsquawk --exclude=adding-field-with-default,disallowed-unique-constraint example.sql\n```\n\n### Disabling rules via comments\n\nRule violations can be ignored via the `squawk-ignore` comment:\n\n```sql\n-- squawk-ignore ban-drop-column\nalter table t drop column c cascade;\n```\n\nYou can also ignore multiple rules by making a comma seperated list:\n\n```sql\n-- squawk-ignore ban-drop-column, renaming-column,ban-drop-database\nalter table t drop column c cascade;\n```\n\n### Configuration file\n\nRules can also be disabled with a configuration file.\n\nBy default, Squawk will traverse up from the current directory to find a `.squawk.toml` configuration file. You may specify a custom path with the `-c` or `--config` flag.\n\n```shell\nsquawk --config=~/.squawk.toml example.sql\n```\n\nThe `--exclude` flag will always be prioritized over the configuration file.\n\n**Example `.squawk.toml`**\n\n```toml\nexcluded_rules = [\n    \"require-concurrent-index-creation\",\n    \"require-concurrent-index-deletion\",\n]\n```\n\nSee the [Squawk website](https://squawkhq.com/docs/rules) for documentation on each rule with examples and reasoning.\n\n## Bot Setup\n\nSquawk works as a CLI tool but can also create comments on GitHub Pull\nRequests using the `upload-to-github` subcommand.\n\nHere's an example comment created by `squawk` using the `example.sql` in the repo:\n\n<https://github.com/sbdchd/squawk/pull/14#issuecomment-647009446>\n\nSee the [\"GitHub Integration\" docs](https://squawkhq.com/docs/github_app) for more information.\n\n## `pre-commit` hook\n\nIntegrate Squawk into Git workflow with [pre-commit](https://pre-commit.com/). Add the following\nto your project's `.pre-commit-config.yaml`:\n\n```yaml\nrepos:\n  - repo: https://github.com/sbdchd/squawk\n    rev: v0.10.0\n    hooks:\n      - id: squawk\n        files: path/to/postgres/migrations/written/in/sql\n```\n\nNote the `files` parameter as it specifies the location of the files to be linted.\n\n## Prior Art / Related\n\n- <https://github.com/erik/squabble>\n- <https://github.com/yandex/zero-downtime-migrations>\n- <https://github.com/tbicr/django-pg-zero-downtime-migrations>\n- <https://github.com/3YOURMIND/django-migration-linter>\n- <https://github.com/ankane/strong_migrations>\n- <https://github.com/AdmTal/PostgreSQL-Query-Lock-Explainer>\n- <https://github.com/stripe/pg-schema-diff>\n- <https://github.com/kristiandupont/schemalint>\n- <https://github.com/supabase-community/postgres-language-server>\n- <https://github.com/premium-minds/sonar-postgres-plugin>\n- <https://engineering.fb.com/2022/11/30/data-infrastructure/static-analysis-sql-queries/>\n- <https://github.com/xNaCly/sqleibniz>\n- <https://github.com/sqlfluff/sqlfluff>\n- <https://atlasgo.io/lint/analyzers>\n- <https://github.com/tobymao/sqlglot>\n- <https://github.com/paupino/pg_parse>\n- <https://github.com/sql-formatter-org/sql-formatter>\n- <https://github.com/darold/pgFormatter>\n- <https://github.com/sqls-server/sqls>\n- <https://github.com/joe-re/sql-language-server>\n- <https://github.com/nene/sql-parser-cst>\n  - <https://github.com/nene/prettier-plugin-sql-cst>\n- <https://www.sqlstyle.guide>\n- <https://github.com/ivank/potygen>\n\n## Related Blog Posts / SE Posts / PG Docs\n\n- <https://www.braintreepayments.com/blog/safe-operations-for-high-volume-postgresql/>\n- <https://gocardless.com/blog/zero-downtime-postgres-migrations-the-hard-parts/>\n- <https://www.citusdata.com/blog/2018/02/22/seven-tips-for-dealing-with-postgres-locks/>\n- <https://realpython.com/create-django-index-without-downtime/#non-atomic-migrations>\n- <https://dba.stackexchange.com/questions/158499/postgres-how-is-set-not-null-more-efficient-than-check-constraint>\n- <https://www.postgresql.org/docs/10/sql-altertable.html#SQL-ALTERTABLE-NOTES>\n- <https://www.postgresql.org/docs/current/explicit-locking.html>\n- <https://benchling.engineering/move-fast-and-migrate-things-how-we-automated-migrations-in-postgres-d60aba0fc3d4>\n- <https://medium.com/paypal-tech/postgresql-at-scale-database-schema-changes-without-downtime-20d3749ed680>\n\n## Dev\n\n```shell\ncargo install\ncargo run\n./s/test\n./s/lint\n./s/fmt\n```\n\n... or with nix:\n\n```\n$ nix develop\n[nix-shell]$ cargo run\n[nix-shell]$ cargo insta review\n[nix-shell]$ ./s/test\n[nix-shell]$ ./s/lint\n[nix-shell]$ ./s/fmt\n```\n\n### Adding a New Rule\n\nWhen adding a new rule, running `cargo xtask new-rule` will create stubs for your rule in the Rust crate and in Documentation site.\n\n```bash\ncargo xtask new-rule 'prefer big serial'\n```\n\n### Releasing a New Version\n\n1. Update the `CHANGELOG.md`\n\n   Include a description of any fixes / additions. Make sure to include the PR numbers and credit the authors.\n\n2. Run `s/update-version`\n\n   ```bash\n   # update version in squawk/Cargo.toml, package.json, flake.nix to 4.5.3\n   s/update-version 4.5.3\n   ```\n\n3. Create a new release on GitHub\n\n   Use the text and version from the `CHANGELOG.md`\n\n### Algolia\n\nThe squawkhq.com Algolia index can be found on [the crawler website](https://crawler.algolia.com/admin/crawlers/9bf0dffb-bc5a-4d46-9b8d-2f1197285213/overview). Algolia reindexes the site every day at 5:30 (UTC).\n\n## How it Works\n\nSquawk uses its parser (based on rust-analyzer's parser) to create a CST. The\nlinters then use an AST layered on top of the CST to navigate and record\nwarnings, which are then pretty printed!\n\n",
    "bugtrack_url": null,
    "license": "Apache-2.0 OR MIT",
    "summary": "Linter for PostgreSQL migrations",
    "version": "2.19.0",
    "project_urls": {
        "Source Code": "https://github.com/sbdchd/squawk"
    },
    "split_keywords": [
        "postgres",
        " postgresql",
        " linter"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0001fa469e99652f63acb17969b27ddc424f88efd148f3be416432cf4b66eee2",
                "md5": "6d0522e8af68aad0cdd1029ec11a2671",
                "sha256": "7303e0b89f4109bb530bbff617c137589260d9c87dbdbb7a56ae4b1978445a83"
            },
            "downloads": -1,
            "filename": "squawk_cli-2.19.0-py3-none-macosx_10_12_x86_64.whl",
            "has_sig": false,
            "md5_digest": "6d0522e8af68aad0cdd1029ec11a2671",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 3359656,
            "upload_time": "2025-07-10T02:06:07",
            "upload_time_iso_8601": "2025-07-10T02:06:07.509107Z",
            "url": "https://files.pythonhosted.org/packages/00/01/fa469e99652f63acb17969b27ddc424f88efd148f3be416432cf4b66eee2/squawk_cli-2.19.0-py3-none-macosx_10_12_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6564b93ced423c74847b8011debfb63ab6cf7da9dd3f36d762158c39ecb1dced",
                "md5": "45da36bb69365b96a59b0727ef6882fc",
                "sha256": "7824cbed0369757363013b4144c020779ce3f9480c151d872571facf11153a5b"
            },
            "downloads": -1,
            "filename": "squawk_cli-2.19.0-py3-none-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "45da36bb69365b96a59b0727ef6882fc",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 3235977,
            "upload_time": "2025-07-10T02:06:05",
            "upload_time_iso_8601": "2025-07-10T02:06:05.517420Z",
            "url": "https://files.pythonhosted.org/packages/65/64/b93ced423c74847b8011debfb63ab6cf7da9dd3f36d762158c39ecb1dced/squawk_cli-2.19.0-py3-none-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1c2c9d236334ddf94d273f54077f3e3592a4c1c5cbed79c4bfcdcb39c99d29b6",
                "md5": "1832f6c4fcda82395859ae4bbce2b712",
                "sha256": "d807585a9d5caac1aa129d1b02367ffe301c24a699a8452e5f536ec630ca12d6"
            },
            "downloads": -1,
            "filename": "squawk_cli-2.19.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "has_sig": false,
            "md5_digest": "1832f6c4fcda82395859ae4bbce2b712",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 3844584,
            "upload_time": "2025-07-10T02:06:01",
            "upload_time_iso_8601": "2025-07-10T02:06:01.097212Z",
            "url": "https://files.pythonhosted.org/packages/1c/2c/9d236334ddf94d273f54077f3e3592a4c1c5cbed79c4bfcdcb39c99d29b6/squawk_cli-2.19.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "37caeb1baff3ea25b834bb5afea1019de539652925ad6685ebe5e5dfa281af65",
                "md5": "6a955172e0d9422e7d20625537d17f1c",
                "sha256": "d63db98dfa4f931dc60d9008395c0697f0945d2afd5561a5b5585f3924c2a304"
            },
            "downloads": -1,
            "filename": "squawk_cli-2.19.0-py3-none-manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "6a955172e0d9422e7d20625537d17f1c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 4708967,
            "upload_time": "2025-07-10T02:06:03",
            "upload_time_iso_8601": "2025-07-10T02:06:03.282748Z",
            "url": "https://files.pythonhosted.org/packages/37/ca/eb1baff3ea25b834bb5afea1019de539652925ad6685ebe5e5dfa281af65/squawk_cli-2.19.0-py3-none-manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5a7b8d2f35000087b329e88e9d3f38a2277d2880359e87e6319f9670c342daeb",
                "md5": "6e5cf127a8be8e9a6378425eae5bc336",
                "sha256": "8d42ae02965c8b037770821cae5073af0f89867bc6d84376700cdc2352550dcf"
            },
            "downloads": -1,
            "filename": "squawk_cli-2.19.0-py3-none-win32.whl",
            "has_sig": false,
            "md5_digest": "6e5cf127a8be8e9a6378425eae5bc336",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 2722831,
            "upload_time": "2025-07-10T02:06:13",
            "upload_time_iso_8601": "2025-07-10T02:06:13.094768Z",
            "url": "https://files.pythonhosted.org/packages/5a/7b/8d2f35000087b329e88e9d3f38a2277d2880359e87e6319f9670c342daeb/squawk_cli-2.19.0-py3-none-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "be68bf9fe873e95f46192ebba8c4bd9090ae2f50fd3cab5322620f59a39ca38a",
                "md5": "4d3d97db950bd5830484f1c1d54f5dda",
                "sha256": "463ad497458e1f041495d0ccaf7c097aa6334cfb5f0a851bbe80e34e3a5024a8"
            },
            "downloads": -1,
            "filename": "squawk_cli-2.19.0-py3-none-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "4d3d97db950bd5830484f1c1d54f5dda",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 2925663,
            "upload_time": "2025-07-10T02:06:10",
            "upload_time_iso_8601": "2025-07-10T02:06:10.970883Z",
            "url": "https://files.pythonhosted.org/packages/be/68/bf9fe873e95f46192ebba8c4bd9090ae2f50fd3cab5322620f59a39ca38a/squawk_cli-2.19.0-py3-none-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d4a1462c5761b8f38694113e15a60f71020759d0a3c4429a746de5c99c9148b6",
                "md5": "fa41531bb82b797f64e24ef88f129ef5",
                "sha256": "16287158a6d06a54b809561e928eefb580310ad147175a5c840820eb915fa5ee"
            },
            "downloads": -1,
            "filename": "squawk_cli-2.19.0.tar.gz",
            "has_sig": false,
            "md5_digest": "fa41531bb82b797f64e24ef88f129ef5",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 1293762,
            "upload_time": "2025-07-10T02:06:09",
            "upload_time_iso_8601": "2025-07-10T02:06:09.370472Z",
            "url": "https://files.pythonhosted.org/packages/d4/a1/462c5761b8f38694113e15a60f71020759d0a3c4429a746de5c99c9148b6/squawk_cli-2.19.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-10 02:06:09",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "sbdchd",
    "github_project": "squawk",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "squawk-cli"
}
        
Elapsed time: 0.46011s