detools


Namedetools JSON
Version 0.51.1 PyPI version JSON
download
home_pagehttps://github.com/eerimoq/detools
SummaryBinary delta encoding tools.
upload_time2022-12-28 20:23:15
maintainer
docs_urlNone
authorErik Moqvist
requires_python
licenseBSD
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            |nala|_

About
=====

Binary `delta encoding`_ in Python 3.6+ and C.

Based on http://www.daemonology.net/bsdiff/ and `HDiffPatch`_, with
the following features:

- bsdiff, hdiffpatch and match-blocks algorithms.

- `sequential`_, hdiffpatch or `in-place`_ (resumable) patch types.

- BZ2, LZ4, LZMA, `Zstandard`_, `heatshrink`_ or CRLE compression.

- Sequential patches allow streaming.

- Maximum file size is 2 GB for the bsdiff algorithm. There is
  practically no limit for the hdiffpatch and match-blocks algorithms.

- `Incremental apply patch`_ implemented in C, suitable for memory
  constrained embedded devices. Only the sequential patch type is
  supported.

- `SA-IS`_ or divsufsort instead of qsufsort for bsdiff.

- Optional experimental data format aware algorithm for potentially
  smaller patches. I don't recommend anyone to use this functionality
  as the gain is small in relation to memory usage and code
  complexity!

  There is a risk this functionality uses patent
  https://patents.google.com/patent/EP1988455B1/en. Anyway, this
  patent expires in August 2019 as I understand it.

  Supported data formats:

  - ARM Cortex-M4

  - AArch64

Project homepage: https://github.com/eerimoq/detools

Documentation: http://detools.readthedocs.org/en/latest

Installation
============

.. code-block:: python

    pip install detools

Statistics
==========

Patch sizes, memory usage (RSS) and elapsed times when creating a
patch from Python-3.7.3.tar (79M) to Python-3.8.1.tar (84M) for
various algorithm, patch type and compression combinations.

See `tests/benchmark.sh`_ for details on how the data was collected.

+--------------+------------+--------+------------+------+---------+
| Algorithm    | Patch type | Compr. | Patch size |  RSS |    Time |
+==============+============+========+============+======+=========+
| bsdiff       | sequential | lzma   |       3,5M | 662M | 0:24.29 |
+--------------+------------+--------+------------+------+---------+
| bsdiff       | sequential | none   |        86M | 646M | 0:15.20 |
+--------------+------------+--------+------------+------+---------+
| hdiffpatch   | hdiffpatch | lzma   |       2,4M | 523M | 0:13.74 |
+--------------+------------+--------+------------+------+---------+
| hdiffpatch   | hdiffpatch | none   |       7,2M | 523M | 0:10.24 |
+--------------+------------+--------+------------+------+---------+
| match-blocks | sequential | lzma   |       2,9M | 273M | 0:08.57 |
+--------------+------------+--------+------------+------+---------+
| match-blocks | sequential | none   |        84M | 273M | 0:01.72 |
+--------------+------------+--------+------------+------+---------+
| match-blocks | hdiffpatch | lzma   |       2,6M | 212M | 0:06.07 |
+--------------+------------+--------+------------+------+---------+
| match-blocks | hdiffpatch | none   |       9,7M | 212M | 0:01.30 |
+--------------+------------+--------+------------+------+---------+

Same as above, but for MicroPython ESP8266 binary releases (from 604k
to 615k).

+--------------+------------+--------+------------+------+---------+
| Algorithm    | Patch type | Compr. | Patch size |  RSS |    Time |
+==============+============+========+============+======+=========+
| bsdiff       | sequential | lzma   |        71K |  46M | 0:00.64 |
+--------------+------------+--------+------------+------+---------+
| bsdiff       | sequential | none   |       609K |  27M | 0:00.33 |
+--------------+------------+--------+------------+------+---------+
| hdiffpatch   | hdiffpatch | lzma   |        65K |  42M | 0:00.37 |
+--------------+------------+--------+------------+------+---------+
| hdiffpatch   | hdiffpatch | none   |       123K |  25M | 0:00.32 |
+--------------+------------+--------+------------+------+---------+
| match-blocks | sequential | lzma   |       194K |  46M | 0:00.44 |
+--------------+------------+--------+------------+------+---------+
| match-blocks | sequential | none   |       606K |  25M | 0:00.22 |
+--------------+------------+--------+------------+------+---------+
| match-blocks | hdiffpatch | lzma   |       189K |  43M | 0:00.38 |
+--------------+------------+--------+------------+------+---------+
| match-blocks | hdiffpatch | none   |       313K |  24M | 0:00.19 |
+--------------+------------+--------+------------+------+---------+

Example usage
=============

Examples in C are found in `c`_.

Command line tool
-----------------

The create patch subcommand
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Create a patch ``foo.patch`` from ``tests/files/foo/old`` to
``tests/files/foo/new``.

.. code-block:: text

   $ detools create_patch tests/files/foo/old tests/files/foo/new foo.patch
   Successfully created 'foo.patch' in 0.01 seconds!
   $ ls -l foo.patch
   -rw-rw-r-- 1 erik erik 127 feb  2 10:35 foo.patch

Create the same patch as above, but without compression.

.. code-block:: text

   $ detools create_patch --compression none \
         tests/files/foo/old tests/files/foo/new foo-no-compression.patch
   Successfully created 'foo-no-compression.patch' in 0 seconds!
   $ ls -l foo-no-compression.patch
   -rw-rw-r-- 1 erik erik 2792 feb  2 10:35 foo-no-compression.patch

Create a hdiffpatch patch ``foo-hdiffpatch.patch``.

.. code-block:: text

   $ detools create_patch --algorithm hdiffpatch --patch-type hdiffpatch \
         tests/files/foo/old tests/files/foo/new foo-hdiffpatch.patch
   Successfully created patch 'foo-hdiffpatch.patch' in 0.01 seconds!
   $ ls -l foo-hdiffpatch.patch
   -rw-rw-r-- 1 erik erik 146 feb  2 10:37 foo-hdiffpatch.patch

Lower memory usage with ``--algorithm match-blocks`` algorithm. Mainly
useful for big files. Creates slightly bigger patches than ``bsdiff``
and ``hdiffpatch``.

.. code-block:: text

   $ detools create_patch --algorithm match-blocks \
         tests/files/foo/old tests/files/foo/new foo-hdiffpatch-64.patch
   Successfully created patch 'foo-hdiffpatch-64.patch' in 0.01 seconds!
   $ ls -l foo-hdiffpatch-64.patch
   -rw-rw-r-- 1 erik erik 404 feb  8 11:03 foo-hdiffpatch-64.patch

Non-sequential but smaller patch with ``--patch-type hdiffpatch``.

.. code-block:: text

   $ detools create_patch \
         --algorithm match-blocks --patch-type hdiffpatch \
         tests/files/foo/old tests/files/foo/new foo-hdiffpatch-sequential.patch
   Successfully created 'foo-hdiffpatch-sequential.patch' in 0.01 seconds!
   $ ls -l foo-hdiffpatch-sequential.patch
   -rw-rw-r-- 1 erik erik 389 feb  8 11:05 foo-hdiffpatch-sequential.patch

The create in-place patch subcommand
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Create an in-place patch ``foo-in-place.patch``.

.. code-block:: text

   $ detools create_patch_in_place --memory-size 3000 --segment-size 500 \
         tests/files/foo/old tests/files/foo/new foo-in-place.patch
   Successfully created 'foo-in-place.patch' in 0.01 seconds!
   $ ls -l foo-in-place.patch
   -rw-rw-r-- 1 erik erik 672 feb  2 10:36 foo-in-place.patch

The create bsdiff patch subcommand
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Create a bsdiff patch ``foo-bsdiff.patch``, compatible with the
original bsdiff program.

.. code-block:: text

   $ detools create_patch_bsdiff \
         tests/files/foo/old tests/files/foo/new foo-bsdiff.patch
   Successfully created 'foo-bsdiff.patch' in 0 seconds!
   $ ls -l foo-bsdiff.patch
   -rw-rw-r-- 1 erik erik 261 feb  2 10:36 foo-bsdiff.patch

The apply patch subcommand
^^^^^^^^^^^^^^^^^^^^^^^^^^

Apply the patch ``foo.patch`` to ``tests/files/foo/old`` to create
``foo.new``.

.. code-block:: text

   $ detools apply_patch tests/files/foo/old foo.patch foo.new
   Successfully created 'foo.new' in 0 seconds!
   $ ls -l foo.new
   -rw-rw-r-- 1 erik erik 2780 feb  2 10:38 foo.new

The in-place apply patch subcommand
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Apply the in-place patch ``foo-in-place.patch`` to ``foo.mem``.

.. code-block:: text

   $ cp tests/files/foo/in-place-3000-500.mem foo.mem
   $ detools apply_patch_in_place foo.mem foo-in-place.patch
   Successfully created 'foo.mem' in 0 seconds!
   $ ls -l foo.mem
   -rw-rw-r-- 1 erik erik 3000 feb  2 10:40 foo.mem

The bsdiff apply patch subcommand
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Apply the patch ``foo-bsdiff.patch`` to ``tests/files/foo/old`` to
create ``foo.new``.

.. code-block:: text

   $ detools apply_patch_bsdiff tests/files/foo/old foo-bsdiff.patch foo.new
   Successfully created 'foo.new' in 0 seconds!
   $ ls -l foo.new
   -rw-rw-r-- 1 erik erik 2780 feb  2 10:41 foo.new

The patch info subcommand
^^^^^^^^^^^^^^^^^^^^^^^^^

Print information about the patch ``foo.patch``.

.. code-block:: text

   $ detools patch_info foo.patch
   Type:               sequential
   Patch size:         127 bytes
   To size:            2.71 KiB
   Patch/to ratio:     4.6 % (lower is better)
   Diff/extra ratio:   9828.6 % (higher is better)
   Size/data ratio:    0.3 % (lower is better)
   Compression:        lzma

   Number of diffs:    2
   Total diff size:    2.69 KiB
   Average diff size:  1.34 KiB
   Median diff size:   1.34 KiB

   Number of extras:   2
   Total extra size:   28 bytes
   Average extra size: 14 bytes
   Median extra size:  14 bytes

Contributing
============

#. Fork the repository.

#. Install prerequisites.

   .. code-block:: text

      pip install -r requirements.txt

#. Implement the new feature or bug fix.

#. Implement test case(s) to ensure that future changes do not break
   legacy.

#. Run the tests.

   .. code-block:: text

      make test

#. Create a pull request.

.. |nala| image:: https://img.shields.io/badge/nala-test-blue.svg
.. _nala: https://github.com/eerimoq/nala

.. _SA-IS: https://sites.google.com/site/yuta256/sais

.. _HDiffPatch: https://github.com/sisong/HDiffPatch

.. _Incremental apply patch: https://github.com/eerimoq/detools/tree/master/c

.. _delta encoding: https://en.wikipedia.org/wiki/Delta_encoding

.. _heatshrink: https://github.com/atomicobject/heatshrink

.. _Zstandard: https://facebook.github.io/zstd

.. _sequential: https://detools.readthedocs.io/en/latest/#id1

.. _in-place: https://detools.readthedocs.io/en/latest/#id3

.. _c: https://github.com/eerimoq/detools/tree/master/c

.. _tests/benchmark.sh: https://github.com/eerimoq/detools/tree/master/tests/benchmark.sh

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/eerimoq/detools",
    "name": "detools",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "",
    "author": "Erik Moqvist",
    "author_email": "erik.moqvist@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/26/26/145687cee2ed9dfdcfba04d289193f6d23fd41392cdfe45fcebb587d5d33/detools-0.51.1.tar.gz",
    "platform": null,
    "description": "|nala|_\n\nAbout\n=====\n\nBinary `delta encoding`_ in Python 3.6+ and C.\n\nBased on http://www.daemonology.net/bsdiff/ and `HDiffPatch`_, with\nthe following features:\n\n- bsdiff, hdiffpatch and match-blocks algorithms.\n\n- `sequential`_, hdiffpatch or `in-place`_ (resumable) patch types.\n\n- BZ2, LZ4, LZMA, `Zstandard`_, `heatshrink`_ or CRLE compression.\n\n- Sequential patches allow streaming.\n\n- Maximum file size is 2 GB for the bsdiff algorithm. There is\n  practically no limit for the hdiffpatch and match-blocks algorithms.\n\n- `Incremental apply patch`_ implemented in C, suitable for memory\n  constrained embedded devices. Only the sequential patch type is\n  supported.\n\n- `SA-IS`_ or divsufsort instead of qsufsort for bsdiff.\n\n- Optional experimental data format aware algorithm for potentially\n  smaller patches. I don't recommend anyone to use this functionality\n  as the gain is small in relation to memory usage and code\n  complexity!\n\n  There is a risk this functionality uses patent\n  https://patents.google.com/patent/EP1988455B1/en. Anyway, this\n  patent expires in August 2019 as I understand it.\n\n  Supported data formats:\n\n  - ARM Cortex-M4\n\n  - AArch64\n\nProject homepage: https://github.com/eerimoq/detools\n\nDocumentation: http://detools.readthedocs.org/en/latest\n\nInstallation\n============\n\n.. code-block:: python\n\n    pip install detools\n\nStatistics\n==========\n\nPatch sizes, memory usage (RSS) and elapsed times when creating a\npatch from Python-3.7.3.tar (79M) to Python-3.8.1.tar (84M) for\nvarious algorithm, patch type and compression combinations.\n\nSee `tests/benchmark.sh`_ for details on how the data was collected.\n\n+--------------+------------+--------+------------+------+---------+\n| Algorithm    | Patch type | Compr. | Patch size |  RSS |    Time |\n+==============+============+========+============+======+=========+\n| bsdiff       | sequential | lzma   |       3,5M | 662M | 0:24.29 |\n+--------------+------------+--------+------------+------+---------+\n| bsdiff       | sequential | none   |        86M | 646M | 0:15.20 |\n+--------------+------------+--------+------------+------+---------+\n| hdiffpatch   | hdiffpatch | lzma   |       2,4M | 523M | 0:13.74 |\n+--------------+------------+--------+------------+------+---------+\n| hdiffpatch   | hdiffpatch | none   |       7,2M | 523M | 0:10.24 |\n+--------------+------------+--------+------------+------+---------+\n| match-blocks | sequential | lzma   |       2,9M | 273M | 0:08.57 |\n+--------------+------------+--------+------------+------+---------+\n| match-blocks | sequential | none   |        84M | 273M | 0:01.72 |\n+--------------+------------+--------+------------+------+---------+\n| match-blocks | hdiffpatch | lzma   |       2,6M | 212M | 0:06.07 |\n+--------------+------------+--------+------------+------+---------+\n| match-blocks | hdiffpatch | none   |       9,7M | 212M | 0:01.30 |\n+--------------+------------+--------+------------+------+---------+\n\nSame as above, but for MicroPython ESP8266 binary releases (from 604k\nto 615k).\n\n+--------------+------------+--------+------------+------+---------+\n| Algorithm    | Patch type | Compr. | Patch size |  RSS |    Time |\n+==============+============+========+============+======+=========+\n| bsdiff       | sequential | lzma   |        71K |  46M | 0:00.64 |\n+--------------+------------+--------+------------+------+---------+\n| bsdiff       | sequential | none   |       609K |  27M | 0:00.33 |\n+--------------+------------+--------+------------+------+---------+\n| hdiffpatch   | hdiffpatch | lzma   |        65K |  42M | 0:00.37 |\n+--------------+------------+--------+------------+------+---------+\n| hdiffpatch   | hdiffpatch | none   |       123K |  25M | 0:00.32 |\n+--------------+------------+--------+------------+------+---------+\n| match-blocks | sequential | lzma   |       194K |  46M | 0:00.44 |\n+--------------+------------+--------+------------+------+---------+\n| match-blocks | sequential | none   |       606K |  25M | 0:00.22 |\n+--------------+------------+--------+------------+------+---------+\n| match-blocks | hdiffpatch | lzma   |       189K |  43M | 0:00.38 |\n+--------------+------------+--------+------------+------+---------+\n| match-blocks | hdiffpatch | none   |       313K |  24M | 0:00.19 |\n+--------------+------------+--------+------------+------+---------+\n\nExample usage\n=============\n\nExamples in C are found in `c`_.\n\nCommand line tool\n-----------------\n\nThe create patch subcommand\n^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nCreate a patch ``foo.patch`` from ``tests/files/foo/old`` to\n``tests/files/foo/new``.\n\n.. code-block:: text\n\n   $ detools create_patch tests/files/foo/old tests/files/foo/new foo.patch\n   Successfully created 'foo.patch' in 0.01 seconds!\n   $ ls -l foo.patch\n   -rw-rw-r-- 1 erik erik 127 feb  2 10:35 foo.patch\n\nCreate the same patch as above, but without compression.\n\n.. code-block:: text\n\n   $ detools create_patch --compression none \\\n         tests/files/foo/old tests/files/foo/new foo-no-compression.patch\n   Successfully created 'foo-no-compression.patch' in 0 seconds!\n   $ ls -l foo-no-compression.patch\n   -rw-rw-r-- 1 erik erik 2792 feb  2 10:35 foo-no-compression.patch\n\nCreate a hdiffpatch patch ``foo-hdiffpatch.patch``.\n\n.. code-block:: text\n\n   $ detools create_patch --algorithm hdiffpatch --patch-type hdiffpatch \\\n         tests/files/foo/old tests/files/foo/new foo-hdiffpatch.patch\n   Successfully created patch 'foo-hdiffpatch.patch' in 0.01 seconds!\n   $ ls -l foo-hdiffpatch.patch\n   -rw-rw-r-- 1 erik erik 146 feb  2 10:37 foo-hdiffpatch.patch\n\nLower memory usage with ``--algorithm match-blocks`` algorithm. Mainly\nuseful for big files. Creates slightly bigger patches than ``bsdiff``\nand ``hdiffpatch``.\n\n.. code-block:: text\n\n   $ detools create_patch --algorithm match-blocks \\\n         tests/files/foo/old tests/files/foo/new foo-hdiffpatch-64.patch\n   Successfully created patch 'foo-hdiffpatch-64.patch' in 0.01 seconds!\n   $ ls -l foo-hdiffpatch-64.patch\n   -rw-rw-r-- 1 erik erik 404 feb  8 11:03 foo-hdiffpatch-64.patch\n\nNon-sequential but smaller patch with ``--patch-type hdiffpatch``.\n\n.. code-block:: text\n\n   $ detools create_patch \\\n         --algorithm match-blocks --patch-type hdiffpatch \\\n         tests/files/foo/old tests/files/foo/new foo-hdiffpatch-sequential.patch\n   Successfully created 'foo-hdiffpatch-sequential.patch' in 0.01 seconds!\n   $ ls -l foo-hdiffpatch-sequential.patch\n   -rw-rw-r-- 1 erik erik 389 feb  8 11:05 foo-hdiffpatch-sequential.patch\n\nThe create in-place patch subcommand\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nCreate an in-place patch ``foo-in-place.patch``.\n\n.. code-block:: text\n\n   $ detools create_patch_in_place --memory-size 3000 --segment-size 500 \\\n         tests/files/foo/old tests/files/foo/new foo-in-place.patch\n   Successfully created 'foo-in-place.patch' in 0.01 seconds!\n   $ ls -l foo-in-place.patch\n   -rw-rw-r-- 1 erik erik 672 feb  2 10:36 foo-in-place.patch\n\nThe create bsdiff patch subcommand\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nCreate a bsdiff patch ``foo-bsdiff.patch``, compatible with the\noriginal bsdiff program.\n\n.. code-block:: text\n\n   $ detools create_patch_bsdiff \\\n         tests/files/foo/old tests/files/foo/new foo-bsdiff.patch\n   Successfully created 'foo-bsdiff.patch' in 0 seconds!\n   $ ls -l foo-bsdiff.patch\n   -rw-rw-r-- 1 erik erik 261 feb  2 10:36 foo-bsdiff.patch\n\nThe apply patch subcommand\n^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nApply the patch ``foo.patch`` to ``tests/files/foo/old`` to create\n``foo.new``.\n\n.. code-block:: text\n\n   $ detools apply_patch tests/files/foo/old foo.patch foo.new\n   Successfully created 'foo.new' in 0 seconds!\n   $ ls -l foo.new\n   -rw-rw-r-- 1 erik erik 2780 feb  2 10:38 foo.new\n\nThe in-place apply patch subcommand\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nApply the in-place patch ``foo-in-place.patch`` to ``foo.mem``.\n\n.. code-block:: text\n\n   $ cp tests/files/foo/in-place-3000-500.mem foo.mem\n   $ detools apply_patch_in_place foo.mem foo-in-place.patch\n   Successfully created 'foo.mem' in 0 seconds!\n   $ ls -l foo.mem\n   -rw-rw-r-- 1 erik erik 3000 feb  2 10:40 foo.mem\n\nThe bsdiff apply patch subcommand\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nApply the patch ``foo-bsdiff.patch`` to ``tests/files/foo/old`` to\ncreate ``foo.new``.\n\n.. code-block:: text\n\n   $ detools apply_patch_bsdiff tests/files/foo/old foo-bsdiff.patch foo.new\n   Successfully created 'foo.new' in 0 seconds!\n   $ ls -l foo.new\n   -rw-rw-r-- 1 erik erik 2780 feb  2 10:41 foo.new\n\nThe patch info subcommand\n^^^^^^^^^^^^^^^^^^^^^^^^^\n\nPrint information about the patch ``foo.patch``.\n\n.. code-block:: text\n\n   $ detools patch_info foo.patch\n   Type:               sequential\n   Patch size:         127 bytes\n   To size:            2.71 KiB\n   Patch/to ratio:     4.6 % (lower is better)\n   Diff/extra ratio:   9828.6 % (higher is better)\n   Size/data ratio:    0.3 % (lower is better)\n   Compression:        lzma\n\n   Number of diffs:    2\n   Total diff size:    2.69 KiB\n   Average diff size:  1.34 KiB\n   Median diff size:   1.34 KiB\n\n   Number of extras:   2\n   Total extra size:   28 bytes\n   Average extra size: 14 bytes\n   Median extra size:  14 bytes\n\nContributing\n============\n\n#. Fork the repository.\n\n#. Install prerequisites.\n\n   .. code-block:: text\n\n      pip install -r requirements.txt\n\n#. Implement the new feature or bug fix.\n\n#. Implement test case(s) to ensure that future changes do not break\n   legacy.\n\n#. Run the tests.\n\n   .. code-block:: text\n\n      make test\n\n#. Create a pull request.\n\n.. |nala| image:: https://img.shields.io/badge/nala-test-blue.svg\n.. _nala: https://github.com/eerimoq/nala\n\n.. _SA-IS: https://sites.google.com/site/yuta256/sais\n\n.. _HDiffPatch: https://github.com/sisong/HDiffPatch\n\n.. _Incremental apply patch: https://github.com/eerimoq/detools/tree/master/c\n\n.. _delta encoding: https://en.wikipedia.org/wiki/Delta_encoding\n\n.. _heatshrink: https://github.com/atomicobject/heatshrink\n\n.. _Zstandard: https://facebook.github.io/zstd\n\n.. _sequential: https://detools.readthedocs.io/en/latest/#id1\n\n.. _in-place: https://detools.readthedocs.io/en/latest/#id3\n\n.. _c: https://github.com/eerimoq/detools/tree/master/c\n\n.. _tests/benchmark.sh: https://github.com/eerimoq/detools/tree/master/tests/benchmark.sh\n",
    "bugtrack_url": null,
    "license": "BSD",
    "summary": "Binary delta encoding tools.",
    "version": "0.51.1",
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "90a18ada6f596437412bf2d05687a4df",
                "sha256": "8ed02e1f5c79492685d9e6ad6efbf164a810bdc3d4f151813cc25e2c27be3d89"
            },
            "downloads": -1,
            "filename": "detools-0.51.1.tar.gz",
            "has_sig": false,
            "md5_digest": "90a18ada6f596437412bf2d05687a4df",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 11069549,
            "upload_time": "2022-12-28T20:23:15",
            "upload_time_iso_8601": "2022-12-28T20:23:15.275536Z",
            "url": "https://files.pythonhosted.org/packages/26/26/145687cee2ed9dfdcfba04d289193f6d23fd41392cdfe45fcebb587d5d33/detools-0.51.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-12-28 20:23:15",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "eerimoq",
    "github_project": "detools",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "detools"
}
        
Elapsed time: 0.02157s