topcat


Nametopcat JSON
Version 0.1.2 PyPI version JSON
download
home_page
SummaryA tool for concatenating files in topological order
upload_time2024-03-13 23:56:36
maintainer
docs_urlNone
authorjosha@jci.dev
requires_python>=3.7
licenseMIT
keywords file dependency topological graph concatenation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # topcat

**top**ological con**cat**enation of files

## Description

`topcat` is a simple tool to concatenate files in a topological order. It is useful when you have a set of files that
depend on each other and you want to concatenate them in the right order.

For my use case this is SQL files.

I like to treat my SQL files as a set of functions and views that depend on each other. I like to keep them in separate
files and concatenate them in the right order to create a single file that I can run in my database.

## Installation

pip:

```sh
pip install topcat
```

poetry:

```sh
poetry add topcat
```

## Usage

### The quick version

```sh
topcat -i /path/to/input -o /path/to/output.sql
```

Where `/path/to/input` is the directory containing the files to concatenate and `/path/to/output.sql` will be where the
concatenated file will be written.

### The long version

```sh
USAGE:
    topcat [FLAGS] [OPTIONS] --output <FILE>

FLAGS:
        --dry        Only print the output, do not write to file.
    -h, --help       Prints help information
    -V, --version    Prints version information
    -v, --verbose    Print debug information

OPTIONS:
        --comment-str <comment-str>
            The string used to denote a comment. eg '--' [default: --]

        --ensure-each-file-ends-with <ensure-each-file-ends-with-str>
            Add this string to the end of files if it does not exist. eg ';' [default: ;]

    -x, --exclude <PATTERN>...                                           Exclude files matching given glob pattern
        --file-separator-str <file-separator-str>
            Add this between each concatenated file in the output. eg '---' [default:
            ------------------------------------------------------------------------------------------------------------------------]
    -n, --include <PATTERN>...                                           Only include files matching glob pattern
    -i, --input_dir <DIR>...
            Path to directory containing files to be concatenated

    -o, --output <FILE>                                                  Path to generate combined output file
```

Some quirks here:

- `-i` is the input directory. You can have multiple input directories. This is useful if you have a set of files in
  different directories that depend on each other.
- `-o` is the output file. This is where the concatenated file will be written.
- `-x` and `-n` are used to exclude and include files respectively. These are glob patterns. For example `-x
  **/tests/*` will exclude all files in any `tests` directory. `-n **/functions/*` will **only** include files in the
  `functions` directory. You can use these together to include and exclude files as you need. You can use these multiple
  times.
- `--comment-str` is the string used to denote a comment. This is used to find the `name`, `requires`, `dropped_by` and
  `exists` comments in the files. The default is `--`. In SQL this is `--` but in other languages it might be `//`
  or `#`.
- `--ensure-each-file-ends-with` is the string to add to the end of each file if it doesn't exist. This is useful for
  SQL
  files where you might want to ensure each file ends with a `;`. The default is `;`.
- `--file-separator-str` is the string to add between each concatenated file in the output. The default is a long line
  of
  dashes. This is just visually useful to see where one file ends and the next begins.
- `--dry` will only print the output, it will not write to the output file.
- `-v` will print debug information and a `.dot` format of the dependency graph.

## What a file needs to include to be concatenated

### `name`

The only requirement for a file to be included in the concatenation is that it needs to have a `name` comment at the top
of the file.

This can be anything you want, but it needs to be unique. This is used to define a node in the dependency graph.

For example:

```postgresql
-- name: my_schema
```

### `requires`

If a file requires another file to be concatenated before it, you can add a `requires` comment to the file.
An alias for `requires` is `dropped_by`. I use `dropped_by` in SQL files for clarity to show that the DDL in the file
gets dropped so I don't need to use `CREATE OR REPLACE FUNCTION` or the like.

For example:

```postgresql
-- name: my_schema.b
-- dropped_by: my_schema
-- requires: my_schema.a
```

### `exists`

`exists` is for soft dependencies. For example in plpgsql functions, the body isn't parsed until the function is called.
So any dependent objects you can't use `requires` for, you can use `exists` to ensure the file is included in the
concatenated file but order of creation doesn't matter.

For example:

```postgresql
-- name: my_schema.b
-- dropped_by: my_schema
-- requires: my_schema.a
-- exists: my_schema.c
```

## Example

Lets say you have a directory with the following files:

```

sql
├── my_other_schema
│ ├── functions
│ │ ├── a.sql
│ │ ├── b.sql
│ │ └── c.sql
│ └── schema.sql
└── my_schema
├── functions
│ └── a.sql
└── schema.sql

```

And the content of the files is:

`sql/my_schema/schema.sql`:

```postgresql
-- name: my_schema

DROP SCHEMA IF EXISTS my_schema CASCADE;
CREATE SCHEMA IF NOT EXISTS my_schema;
```

`sql/my_schema/functions/a.sql`:

```postgresql
-- name: my_schema.a
-- dropped_by: my_schema

CREATE FUNCTION my_schema.a() RETURNS INT AS
$$
SELECT 1;
$$ LANGUAGE SQL IMMUTABLE
                PARALLEL SAFE;
```

`sql/my_schema/functions/b.sql`:

```postgresql
-- name: my_schema.b
-- dropped_by: my_schema
-- requires: my_schema.a

CREATE FUNCTION my_schema.b() RETURNS INT AS
$$
SELECT my_schema.a() + 1
$$ LANGUAGE SQL;
```

`sql/my_schema/functions/c.sql`:

```postgresql
-- name: my_schema.c
-- dropped_by: my_schema
-- requires: my_schema.b

CREATE FUNCTION my_schema.c() RETURNS INT AS
$$
SELECT my_schema.b() + 1
$$ LANGUAGE SQL IMMUTABLE
                PARALLEL SAFE;
```

`sql/my_other_schema/schema.sql`:

```postgresql
-- name: my_other_schema

DROP SCHEMA IF EXISTS my_schema CASCADE;
CREATE SCHEMA IF NOT EXISTS my_schema;
```

`sql/my_other_schema/functions/a.sql`:

```postgresql
-- name: my_other_schema.a
-- dropped_by: my_other_schema
-- requires: my_schema.b

CREATE FUNCTION my_other_schema.a() RETURNS INT AS
$$
SELECT my_schema.b() + 1
$$ LANGUAGE SQL IMMUTABLE
                PARALLEL SAFE;
```

So the dependency graph looks like:
![](https://github.com/joshainglis/topcat/raw/main/docs/assets/graph.png)

Now you can run `topcat` to concatenate the files in the right order:

```sh
topcat -i tests/input/sql -o tests/output/sql/output.sql
```

The content of `output.sql` will be:

```postgresql
-- This file was generated by topcat. To regenerate run:
--
-- topcat -i tests/input/sql -o tests/output/sql/output.sql -v

------------------------------------------------------------------------------------------------------------------------
-- tests/input/sql/my_other_schema/schema.sql
-- name: my_schema

DROP SCHEMA IF EXISTS my_schema CASCADE;
CREATE SCHEMA IF NOT EXISTS my_schema;

------------------------------------------------------------------------------------------------------------------------
-- tests/input/sql/my_other_schema/functions/a.sql
-- name: my_schema.a
-- dropped_by: my_schema

CREATE FUNCTION my_schema.a() RETURNS INT AS
$$
SELECT 1;
$$ LANGUAGE SQL;

------------------------------------------------------------------------------------------------------------------------
-- tests/input/sql/my_other_schema/functions/b.sql
-- name: my_schema.b
-- dropped_by: my_schema
-- requires: my_schema.a

CREATE FUNCTION my_schema.b() RETURNS INT AS
$$
SELECT my_schema.a() + 1
$$ LANGUAGE SQL;

------------------------------------------------------------------------------------------------------------------------
-- tests/input/sql/my_schema/schema.sql
-- name: my_other_schema

DROP SCHEMA IF EXISTS my_other_schema CASCADE;
CREATE SCHEMA IF NOT EXISTS my_other_schema;

------------------------------------------------------------------------------------------------------------------------
-- tests/input/sql/my_schema/functions/a.sql
-- name: my_other_schema.a
-- dropped_by: my_other_schema
-- requires: my_schema.b

CREATE FUNCTION my_other_schema.a() RETURNS INT AS
$$
SELECT my_schema.b() + 1
$$ LANGUAGE SQL IMMUTABLE
                PARALLEL SAFE;

------------------------------------------------------------------------------------------------------------------------
-- tests/input/sql/my_other_schema/functions/c.sql
-- name: my_schema.c
-- dropped_by: my_schema
-- requires: my_schema.b
-- requires: my_other_schema.a

CREATE FUNCTION my_schema.c() RETURNS INT AS
$$
SELECT my_schema.b() + my_other_schema.a() + 1
$$ LANGUAGE SQL;
```



            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "topcat",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "file,dependency,topological,graph,concatenation",
    "author": "josha@jci.dev",
    "author_email": "Josha Inglis <joshainglis@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/e1/a9/26990ea2f3042d2e4efa21f146ffc21aeaebbe67ffd8d0f8abb3dd4ef8c4/topcat-0.1.2.tar.gz",
    "platform": null,
    "description": "# topcat\n\n**top**ological con**cat**enation of files\n\n## Description\n\n`topcat` is a simple tool to concatenate files in a topological order. It is useful when you have a set of files that\ndepend on each other and you want to concatenate them in the right order.\n\nFor my use case this is SQL files.\n\nI like to treat my SQL files as a set of functions and views that depend on each other. I like to keep them in separate\nfiles and concatenate them in the right order to create a single file that I can run in my database.\n\n## Installation\n\npip:\n\n```sh\npip install topcat\n```\n\npoetry:\n\n```sh\npoetry add topcat\n```\n\n## Usage\n\n### The quick version\n\n```sh\ntopcat -i /path/to/input -o /path/to/output.sql\n```\n\nWhere `/path/to/input` is the directory containing the files to concatenate and `/path/to/output.sql` will be where the\nconcatenated file will be written.\n\n### The long version\n\n```sh\nUSAGE:\n    topcat [FLAGS] [OPTIONS] --output <FILE>\n\nFLAGS:\n        --dry        Only print the output, do not write to file.\n    -h, --help       Prints help information\n    -V, --version    Prints version information\n    -v, --verbose    Print debug information\n\nOPTIONS:\n        --comment-str <comment-str>\n            The string used to denote a comment. eg '--' [default: --]\n\n        --ensure-each-file-ends-with <ensure-each-file-ends-with-str>\n            Add this string to the end of files if it does not exist. eg ';' [default: ;]\n\n    -x, --exclude <PATTERN>...                                           Exclude files matching given glob pattern\n        --file-separator-str <file-separator-str>\n            Add this between each concatenated file in the output. eg '---' [default:\n            ------------------------------------------------------------------------------------------------------------------------]\n    -n, --include <PATTERN>...                                           Only include files matching glob pattern\n    -i, --input_dir <DIR>...\n            Path to directory containing files to be concatenated\n\n    -o, --output <FILE>                                                  Path to generate combined output file\n```\n\nSome quirks here:\n\n- `-i` is the input directory. You can have multiple input directories. This is useful if you have a set of files in\n  different directories that depend on each other.\n- `-o` is the output file. This is where the concatenated file will be written.\n- `-x` and `-n` are used to exclude and include files respectively. These are glob patterns. For example `-x\n  **/tests/*` will exclude all files in any `tests` directory. `-n **/functions/*` will **only** include files in the\n  `functions` directory. You can use these together to include and exclude files as you need. You can use these multiple\n  times.\n- `--comment-str` is the string used to denote a comment. This is used to find the `name`, `requires`, `dropped_by` and\n  `exists` comments in the files. The default is `--`. In SQL this is `--` but in other languages it might be `//`\n  or `#`.\n- `--ensure-each-file-ends-with` is the string to add to the end of each file if it doesn't exist. This is useful for\n  SQL\n  files where you might want to ensure each file ends with a `;`. The default is `;`.\n- `--file-separator-str` is the string to add between each concatenated file in the output. The default is a long line\n  of\n  dashes. This is just visually useful to see where one file ends and the next begins.\n- `--dry` will only print the output, it will not write to the output file.\n- `-v` will print debug information and a `.dot` format of the dependency graph.\n\n## What a file needs to include to be concatenated\n\n### `name`\n\nThe only requirement for a file to be included in the concatenation is that it needs to have a `name` comment at the top\nof the file.\n\nThis can be anything you want, but it needs to be unique. This is used to define a node in the dependency graph.\n\nFor example:\n\n```postgresql\n-- name: my_schema\n```\n\n### `requires`\n\nIf a file requires another file to be concatenated before it, you can add a `requires` comment to the file.\nAn alias for `requires` is `dropped_by`. I use `dropped_by` in SQL files for clarity to show that the DDL in the file\ngets dropped so I don't need to use `CREATE OR REPLACE FUNCTION` or the like.\n\nFor example:\n\n```postgresql\n-- name: my_schema.b\n-- dropped_by: my_schema\n-- requires: my_schema.a\n```\n\n### `exists`\n\n`exists` is for soft dependencies. For example in plpgsql functions, the body isn't parsed until the function is called.\nSo any dependent objects you can't use `requires` for, you can use `exists` to ensure the file is included in the\nconcatenated file but order of creation doesn't matter.\n\nFor example:\n\n```postgresql\n-- name: my_schema.b\n-- dropped_by: my_schema\n-- requires: my_schema.a\n-- exists: my_schema.c\n```\n\n## Example\n\nLets say you have a directory with the following files:\n\n```\n\nsql\n\u251c\u2500\u2500 my_other_schema\n\u2502 \u251c\u2500\u2500 functions\n\u2502 \u2502 \u251c\u2500\u2500 a.sql\n\u2502 \u2502 \u251c\u2500\u2500 b.sql\n\u2502 \u2502 \u2514\u2500\u2500 c.sql\n\u2502 \u2514\u2500\u2500 schema.sql\n\u2514\u2500\u2500 my_schema\n\u251c\u2500\u2500 functions\n\u2502 \u2514\u2500\u2500 a.sql\n\u2514\u2500\u2500 schema.sql\n\n```\n\nAnd the content of the files is:\n\n`sql/my_schema/schema.sql`:\n\n```postgresql\n-- name: my_schema\n\nDROP SCHEMA IF EXISTS my_schema CASCADE;\nCREATE SCHEMA IF NOT EXISTS my_schema;\n```\n\n`sql/my_schema/functions/a.sql`:\n\n```postgresql\n-- name: my_schema.a\n-- dropped_by: my_schema\n\nCREATE FUNCTION my_schema.a() RETURNS INT AS\n$$\nSELECT 1;\n$$ LANGUAGE SQL IMMUTABLE\n                PARALLEL SAFE;\n```\n\n`sql/my_schema/functions/b.sql`:\n\n```postgresql\n-- name: my_schema.b\n-- dropped_by: my_schema\n-- requires: my_schema.a\n\nCREATE FUNCTION my_schema.b() RETURNS INT AS\n$$\nSELECT my_schema.a() + 1\n$$ LANGUAGE SQL;\n```\n\n`sql/my_schema/functions/c.sql`:\n\n```postgresql\n-- name: my_schema.c\n-- dropped_by: my_schema\n-- requires: my_schema.b\n\nCREATE FUNCTION my_schema.c() RETURNS INT AS\n$$\nSELECT my_schema.b() + 1\n$$ LANGUAGE SQL IMMUTABLE\n                PARALLEL SAFE;\n```\n\n`sql/my_other_schema/schema.sql`:\n\n```postgresql\n-- name: my_other_schema\n\nDROP SCHEMA IF EXISTS my_schema CASCADE;\nCREATE SCHEMA IF NOT EXISTS my_schema;\n```\n\n`sql/my_other_schema/functions/a.sql`:\n\n```postgresql\n-- name: my_other_schema.a\n-- dropped_by: my_other_schema\n-- requires: my_schema.b\n\nCREATE FUNCTION my_other_schema.a() RETURNS INT AS\n$$\nSELECT my_schema.b() + 1\n$$ LANGUAGE SQL IMMUTABLE\n                PARALLEL SAFE;\n```\n\nSo the dependency graph looks like:\n![](https://github.com/joshainglis/topcat/raw/main/docs/assets/graph.png)\n\nNow you can run `topcat` to concatenate the files in the right order:\n\n```sh\ntopcat -i tests/input/sql -o tests/output/sql/output.sql\n```\n\nThe content of `output.sql` will be:\n\n```postgresql\n-- This file was generated by topcat. To regenerate run:\n--\n-- topcat -i tests/input/sql -o tests/output/sql/output.sql -v\n\n------------------------------------------------------------------------------------------------------------------------\n-- tests/input/sql/my_other_schema/schema.sql\n-- name: my_schema\n\nDROP SCHEMA IF EXISTS my_schema CASCADE;\nCREATE SCHEMA IF NOT EXISTS my_schema;\n\n------------------------------------------------------------------------------------------------------------------------\n-- tests/input/sql/my_other_schema/functions/a.sql\n-- name: my_schema.a\n-- dropped_by: my_schema\n\nCREATE FUNCTION my_schema.a() RETURNS INT AS\n$$\nSELECT 1;\n$$ LANGUAGE SQL;\n\n------------------------------------------------------------------------------------------------------------------------\n-- tests/input/sql/my_other_schema/functions/b.sql\n-- name: my_schema.b\n-- dropped_by: my_schema\n-- requires: my_schema.a\n\nCREATE FUNCTION my_schema.b() RETURNS INT AS\n$$\nSELECT my_schema.a() + 1\n$$ LANGUAGE SQL;\n\n------------------------------------------------------------------------------------------------------------------------\n-- tests/input/sql/my_schema/schema.sql\n-- name: my_other_schema\n\nDROP SCHEMA IF EXISTS my_other_schema CASCADE;\nCREATE SCHEMA IF NOT EXISTS my_other_schema;\n\n------------------------------------------------------------------------------------------------------------------------\n-- tests/input/sql/my_schema/functions/a.sql\n-- name: my_other_schema.a\n-- dropped_by: my_other_schema\n-- requires: my_schema.b\n\nCREATE FUNCTION my_other_schema.a() RETURNS INT AS\n$$\nSELECT my_schema.b() + 1\n$$ LANGUAGE SQL IMMUTABLE\n                PARALLEL SAFE;\n\n------------------------------------------------------------------------------------------------------------------------\n-- tests/input/sql/my_other_schema/functions/c.sql\n-- name: my_schema.c\n-- dropped_by: my_schema\n-- requires: my_schema.b\n-- requires: my_other_schema.a\n\nCREATE FUNCTION my_schema.c() RETURNS INT AS\n$$\nSELECT my_schema.b() + my_other_schema.a() + 1\n$$ LANGUAGE SQL;\n```\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A tool for concatenating files in topological order",
    "version": "0.1.2",
    "project_urls": {
        "Repository": "https://github.com/joshainglis/topcat"
    },
    "split_keywords": [
        "file",
        "dependency",
        "topological",
        "graph",
        "concatenation"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a0693c70f1e21971619a4f17f28446ee4afa8eac7cc1daf9bcaaa2b8b87bb8c4",
                "md5": "7142678ce9a20609e116a0901e896393",
                "sha256": "c477956bba53242add7958ff3be20ff56631ad72c2218789a5cc9d1493c57dca"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
            "has_sig": false,
            "md5_digest": "7142678ce9a20609e116a0901e896393",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 980291,
            "upload_time": "2024-03-13T23:56:10",
            "upload_time_iso_8601": "2024-03-13T23:56:10.287056Z",
            "url": "https://files.pythonhosted.org/packages/a0/69/3c70f1e21971619a4f17f28446ee4afa8eac7cc1daf9bcaaa2b8b87bb8c4/topcat-0.1.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "18bd9b32d5b712281061bdef40c181e536aa0b7f3a9834c29f91ebbe36873208",
                "md5": "2ee819d989f4d97edd0d1e97b1442a44",
                "sha256": "2d0dd9e52defb5d90d4a666fa07934b1ac6052e568acd7ecba6ec35e70adff7a"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-macosx_10_12_x86_64.whl",
            "has_sig": false,
            "md5_digest": "2ee819d989f4d97edd0d1e97b1442a44",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 502448,
            "upload_time": "2024-03-13T23:56:12",
            "upload_time_iso_8601": "2024-03-13T23:56:12.237509Z",
            "url": "https://files.pythonhosted.org/packages/18/bd/9b32d5b712281061bdef40c181e536aa0b7f3a9834c29f91ebbe36873208/topcat-0.1.2-py3-none-macosx_10_12_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7130f4522f829d3487f1f030c04a34b8150caaa28d1add8b067f8c37b04cf9f1",
                "md5": "d0126f31f633b3c8f3117cc195d566c4",
                "sha256": "fb99e1f7ef0c08e9246a48beab0fb4c0f64913aaa2b9fcb7149bf14072cb11f9"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "has_sig": false,
            "md5_digest": "d0126f31f633b3c8f3117cc195d566c4",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 483213,
            "upload_time": "2024-03-13T23:56:13",
            "upload_time_iso_8601": "2024-03-13T23:56:13.477620Z",
            "url": "https://files.pythonhosted.org/packages/71/30/f4522f829d3487f1f030c04a34b8150caaa28d1add8b067f8c37b04cf9f1/topcat-0.1.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "38fb5a495f3df4d7861cceae56d7708affcb64bff23fbb2e765df99ae2763fd2",
                "md5": "8cef727468308d25bfe145a3e09fdaaf",
                "sha256": "e0098db0f63ed7d1eba3765580d463509ba9cd47967a16dc9cb88b517f6ddbe4"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",
            "has_sig": false,
            "md5_digest": "8cef727468308d25bfe145a3e09fdaaf",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 479511,
            "upload_time": "2024-03-13T23:56:14",
            "upload_time_iso_8601": "2024-03-13T23:56:14.651470Z",
            "url": "https://files.pythonhosted.org/packages/38/fb/5a495f3df4d7861cceae56d7708affcb64bff23fbb2e765df99ae2763fd2/topcat-0.1.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6e66755c551a3cd3ea300f3bff4f674e67e1ca698f20423e637f43c2b5321bf9",
                "md5": "1e5e738e940ca675e8bc381010a6546b",
                "sha256": "f8563a6e1b01cac8f9667af850caf7b79d2ef91ed3d2a4d5d00c9161ff695276"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",
            "has_sig": false,
            "md5_digest": "1e5e738e940ca675e8bc381010a6546b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 562856,
            "upload_time": "2024-03-13T23:56:16",
            "upload_time_iso_8601": "2024-03-13T23:56:16.709853Z",
            "url": "https://files.pythonhosted.org/packages/6e/66/755c551a3cd3ea300f3bff4f674e67e1ca698f20423e637f43c2b5321bf9/topcat-0.1.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "577eee89e565fd77c0d487e7ced07e40838af0cd61e634d96f462c61c6f9d900",
                "md5": "8763cf5b06e94e1bdbfb8850fa49ffcd",
                "sha256": "ff4f3b0fd77c953f601fe2d4e01f2f8c113bdc6275695c48f2bdcb309491171e"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
            "has_sig": false,
            "md5_digest": "8763cf5b06e94e1bdbfb8850fa49ffcd",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 653691,
            "upload_time": "2024-03-13T23:56:20",
            "upload_time_iso_8601": "2024-03-13T23:56:20.049565Z",
            "url": "https://files.pythonhosted.org/packages/57/7e/ee89e565fd77c0d487e7ced07e40838af0cd61e634d96f462c61c6f9d900/topcat-0.1.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8192bdfc99dba2dfbbc00c05270c2f45986b5e4504ca7b8b8bf24bfa5b0ca071",
                "md5": "f07a621e63ca8a0e27751af1484de28e",
                "sha256": "c9da09281175b486888d60c58296745181bf0abd020230a7fc9d98ae436a254d"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",
            "has_sig": false,
            "md5_digest": "f07a621e63ca8a0e27751af1484de28e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 673365,
            "upload_time": "2024-03-13T23:56:18",
            "upload_time_iso_8601": "2024-03-13T23:56:18.473009Z",
            "url": "https://files.pythonhosted.org/packages/81/92/bdfc99dba2dfbbc00c05270c2f45986b5e4504ca7b8b8bf24bfa5b0ca071/topcat-0.1.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "eb3560ce0a09d3e0b045e9c40c62c2e53f347eff0fa5d915a5038a2fe13ce236",
                "md5": "69d3c6c82b5a4009b9cc1d5827559515",
                "sha256": "eab20d2eed818968a3711e5dd9bca47369b349c46889e3dee82ea233dcd5c7c0"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",
            "has_sig": false,
            "md5_digest": "69d3c6c82b5a4009b9cc1d5827559515",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 604220,
            "upload_time": "2024-03-13T23:56:21",
            "upload_time_iso_8601": "2024-03-13T23:56:21.674829Z",
            "url": "https://files.pythonhosted.org/packages/eb/35/60ce0a09d3e0b045e9c40c62c2e53f347eff0fa5d915a5038a2fe13ce236/topcat-0.1.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a072c70e25af6aea8fb77133ba240e341b6f7c57aa82e7263d0090dea2f675a6",
                "md5": "e58ecc83885982ea796e6ebca9fe3531",
                "sha256": "f34e61a13576eef37b32981fa64ee5d3a666988e7e939ee4c12a0e295c6cb9bc"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "e58ecc83885982ea796e6ebca9fe3531",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 517148,
            "upload_time": "2024-03-13T23:56:22",
            "upload_time_iso_8601": "2024-03-13T23:56:22.851441Z",
            "url": "https://files.pythonhosted.org/packages/a0/72/c70e25af6aea8fb77133ba240e341b6f7c57aa82e7263d0090dea2f675a6/topcat-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5d1fda7057059a6c6a79776f56eb0d57bac66216356d0c19cb47b04ba939603f",
                "md5": "d495140e5de9db37b05efc40b1963956",
                "sha256": "17976f07e6a3586c8f2749e9b27ebbc0bce9d7e1e335948443ac1046f92e8292"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-musllinux_1_2_aarch64.whl",
            "has_sig": false,
            "md5_digest": "d495140e5de9db37b05efc40b1963956",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 517370,
            "upload_time": "2024-03-13T23:56:25",
            "upload_time_iso_8601": "2024-03-13T23:56:25.081525Z",
            "url": "https://files.pythonhosted.org/packages/5d/1f/da7057059a6c6a79776f56eb0d57bac66216356d0c19cb47b04ba939603f/topcat-0.1.2-py3-none-musllinux_1_2_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8d0d9f6549190c627e99e9117d87475fd195a1125246f3f680a7b0abd7d6eb1b",
                "md5": "5db7d056479889bce90fe2715bf90ee8",
                "sha256": "887eb4086fda17d7d14cbb0659223ecdd3bd235119cd19cf8d9c440500554ac4"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-musllinux_1_2_armv7l.whl",
            "has_sig": false,
            "md5_digest": "5db7d056479889bce90fe2715bf90ee8",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 501394,
            "upload_time": "2024-03-13T23:56:26",
            "upload_time_iso_8601": "2024-03-13T23:56:26.886866Z",
            "url": "https://files.pythonhosted.org/packages/8d/0d/9f6549190c627e99e9117d87475fd195a1125246f3f680a7b0abd7d6eb1b/topcat-0.1.2-py3-none-musllinux_1_2_armv7l.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1ad36c536d5d63c8d53dc00d04af8c3bcc11badf7f9417dfd2193f63d8ad6b7b",
                "md5": "41b623e8a1ba0b52ff6f3dc78408cbed",
                "sha256": "d01d05c847a97643610bad3e6bfa4fa62c97f13585c27b79d8384060e433c119"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-musllinux_1_2_i686.whl",
            "has_sig": false,
            "md5_digest": "41b623e8a1ba0b52ff6f3dc78408cbed",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 570286,
            "upload_time": "2024-03-13T23:56:28",
            "upload_time_iso_8601": "2024-03-13T23:56:28.668695Z",
            "url": "https://files.pythonhosted.org/packages/1a/d3/6c536d5d63c8d53dc00d04af8c3bcc11badf7f9417dfd2193f63d8ad6b7b/topcat-0.1.2-py3-none-musllinux_1_2_i686.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4c7535e6dc868b61b6ce2e66fbb42d811ef34af99f6e301e88eb255bc483a8d2",
                "md5": "491d551d80f630e38eca74354ed203d4",
                "sha256": "ce5ca0ba63520dfe366bafc41eff71c093820def82428b074fb1d72a6dcd8ca3"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-musllinux_1_2_x86_64.whl",
            "has_sig": false,
            "md5_digest": "491d551d80f630e38eca74354ed203d4",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 564148,
            "upload_time": "2024-03-13T23:56:30",
            "upload_time_iso_8601": "2024-03-13T23:56:30.503504Z",
            "url": "https://files.pythonhosted.org/packages/4c/75/35e6dc868b61b6ce2e66fbb42d811ef34af99f6e301e88eb255bc483a8d2/topcat-0.1.2-py3-none-musllinux_1_2_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "80ab4d492c829072849f240517f44fdb1c3e921c6bffb3259c0ea94ae3722c89",
                "md5": "833a362d4372dc1a6e0ad3f623fb254b",
                "sha256": "3149b6e7182cf7176b446b576cd8e1b866fa1020c4d94a94972b5e982c4b9b08"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-win32.whl",
            "has_sig": false,
            "md5_digest": "833a362d4372dc1a6e0ad3f623fb254b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 411480,
            "upload_time": "2024-03-13T23:56:32",
            "upload_time_iso_8601": "2024-03-13T23:56:32.723386Z",
            "url": "https://files.pythonhosted.org/packages/80/ab/4d492c829072849f240517f44fdb1c3e921c6bffb3259c0ea94ae3722c89/topcat-0.1.2-py3-none-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "98c1563a99311487c2c0d1574d42369b2d5b955bc73f6cac0f2db53e08bf6515",
                "md5": "7f836932671e9fc3664aabdab534ce8d",
                "sha256": "3e74ed01794edebf7db50873ab4dd0505a4bb7e39ad4afc1482c4115008f4a48"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "7f836932671e9fc3664aabdab534ce8d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 425702,
            "upload_time": "2024-03-13T23:56:33",
            "upload_time_iso_8601": "2024-03-13T23:56:33.864479Z",
            "url": "https://files.pythonhosted.org/packages/98/c1/563a99311487c2c0d1574d42369b2d5b955bc73f6cac0f2db53e08bf6515/topcat-0.1.2-py3-none-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "70b807c571d2a44744c4b2abc64c2a21da541f48f75e8004dcd05be94f67ea5b",
                "md5": "aefc0a503fb2d465cfab34a68e185e54",
                "sha256": "e886d83d934ea99037b4535f28ebd48c135ed74e33592a0bca573b63847d51a2"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2-py3-none-win_arm64.whl",
            "has_sig": false,
            "md5_digest": "aefc0a503fb2d465cfab34a68e185e54",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 402323,
            "upload_time": "2024-03-13T23:56:35",
            "upload_time_iso_8601": "2024-03-13T23:56:35.557643Z",
            "url": "https://files.pythonhosted.org/packages/70/b8/07c571d2a44744c4b2abc64c2a21da541f48f75e8004dcd05be94f67ea5b/topcat-0.1.2-py3-none-win_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e1a926990ea2f3042d2e4efa21f146ffc21aeaebbe67ffd8d0f8abb3dd4ef8c4",
                "md5": "16d2ccec5a163aeed911a0ef34d88078",
                "sha256": "812aab5e2465b079f1eda38695149fc6207b804dad140243cd5bd73cca71a8e7"
            },
            "downloads": -1,
            "filename": "topcat-0.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "16d2ccec5a163aeed911a0ef34d88078",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 115223,
            "upload_time": "2024-03-13T23:56:36",
            "upload_time_iso_8601": "2024-03-13T23:56:36.596849Z",
            "url": "https://files.pythonhosted.org/packages/e1/a9/26990ea2f3042d2e4efa21f146ffc21aeaebbe67ffd8d0f8abb3dd4ef8c4/topcat-0.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-13 23:56:36",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "joshainglis",
    "github_project": "topcat",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "topcat"
}
        
Elapsed time: 0.27219s