{ "info": { "author": "Cyril Roelandt", "author_email": "tipecaml@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3 :: Only" ], "description": "# Universal Packaging Tool (upt)\n\nA unified CLI tool that converts a package from a language-specific package\nmanager (such as PyPI or NPM) to an almost ready-to-use package for Free\nUnix-based operating systems (such as a GNU/Linux distribution or \\*BSD).\n\n\n## Installing\nPlease note that Python 3.6 or newer is required to run upt.\n\nYou may install upt from PyPI:\n\n $ pip install upt\n\nYou may also install it from the Git repository or a tarball:\n\n $ python setup.py install\n\nBy itself, upt is useless. It requires frontends and or backends to provide\nuseful features. See the list of available frontends/backends at the end of this\ndocument. You may install them by running:\n\n $ pip install upt-pypi\n $ pip install upt-openbsd\n $ pip install ...\n\nYou may also install upt and all its frontends by running:\n\n $ pip install upt[frontends]\n\nYou may also install upt and all its backends by running:\n\n $ pip install upt[backends]\n\nYou may also install upt and all of its frontends and backends by running:\n\n $ pip install upt[frontends,backends]\n\n\n## Usage\nYou may get help by running:\n\n $ upt --help\n\nUpt gathers data about a package using a **frontend** and writes a package\ndefinition using a **backend**. You may list all installed frontends and\nbackends by running:\n\n```\n$ upt list-frontends\ncpan\npypi\n$ upt list-backends\nguix\nopenbsd\n```\n\nTo package [the requests library from\nPyPI](https://pypi.python.org/pypi/requests) for [GNU\nGuix](https://www.gnu.org/s/guix), just write:\n\n $ upt package --frontend pypi --backend guix requests\n\nOr, using shorter options:\n\n $ upt package -f pypi -b guix requests\n\nYou may also want to recursively package all of its requirements:\n\n $ upt package -f pypi -b guix -r requests\n\nThe package definition will be written to the standard output.\n\n\n## Under the hood\nThere are two kinds of places from where packages may be installed:\n\n- language specific package repositories (CPAN, CRAN, CTAN, Hackage, NPM, PyPI,\n RubyGems, etc.)\n- traditional, language agnostic package managers (apt for Debian, dnf for\n Fedora, Nix, Guix, pkgsrc, the OpenBSD ports, etc.)\n\nPackages available on the former are usually also packaged in the latter ones.\nSince packaging is a tedious and repetitive task, packagers have written tools\nto assist them in this endeavor: Guix has \"guix import\", a collection of scripts\nthat parse CPAN, PyPI and other language specific package repositories and\ngenerate a Guix package definition; Debian has tools such as pypi2deb,\nnpm2deb... The same goes for RPM-based distributions, and other operating\nsystems.\n\nLet's talk about PyPI. It seems that (almost) every single distribution has (or\nwill have) a tool that parses PyPI. Whatever the distribution may be (Debian,\nFedora, Guix...), parsing PyPI is basically always the same thing: it is just\nreading a JSON document. This code is not shared among distributions though,\nwhich means that they all end up writing the same kind of code. The same is true\nfor other language specific package managers.\n\nThe distribution specific code is usually not even shared among the various\ntools provided by said distribution. Writing an OpenBSD port always involve\ncreating a directory, writing the maintainer's name to a Makefile, etc. These\noperations are common to all packages: they should not be rewritten over and\nover by every single tool OpenBSD developers may end up using. The same is true\nfor Debian: creating a Debian package involves a lot of operations that are not\ntruly specific to the piece of software being packaged.\n\nWe may also note that all these tools come with their own interface: packagers\nworking with more than one package repository and/or more than one distribution\ntherefore have to use different interfaces to perform similar tasks.\n\nThe Universal Packaging Tool (upt) aims at providing package maintainers with a\nunified CLI that harnesses the power of a modular infrastructure, meant to\nfactorize as much code as possible. Upt is the \"core\" of the project. It exposes\na CLI and a small Python library that defines an internal representation for\npackages. Two kind of objects have to talk to upt:\n\n- frontends, which parse a package repository and return information about a\n given package using upt's internal representation;\n- backends, which turn the internal representation of a package into a valid\n package definition for a language agnostic package manager.\n\nThis is basically what other common tools do: the [GCC\ncompiler](https://gcc.gnu.org/) has frontends for languages and backends for CPU\narchitectures. Similarly, [pandoc](https://pandoc.org/) can convert files from\none markup language to another using various frontends and backends.\n\n```\n | | | |\n Package | upt | upt | upt | Package\n Repositories | Frontends | | Backends | Definitions\n | | | |\n +------+ | +----------+ | +-----+ | +-------------+ | +----------+\n | | | | | | | | | | | | | |\n | PyPI |------|->| upt-pypi |-|->| |-|->| upt-guix |-|->| Guix pkg |\n | | | | | | | | | | | | | |\n +------+ | +----------+ | | | | +-------------+ | +----------+\n | | | upt | | |\n +------+ | +----------+ | | | | +-------------+ | +----------+\n | | | | | | | | | | | | | |\n | CPAN |------|->| upt-cpan |-|->| |-|->| upt-openbsd |-|->| Makefile |\n | | | | | | | | | | | | | |\n +------+ | +----------+ | +-----+ | +-------------+ | +----------+\n | | | |\n```\n\nHere we can see that using the [upt-pypi](https://pypi.python.org/pypi/upt-pypi)\nand [upt-cpan](https://pypi.python.org/pypi/upt-cpan) frontends, upt is able to\nretrieve information about packages hosted on [CPAN](https://www.cpan.org/) and\n[PyPI](https://pypi.python.org/). Then, using the\n[upt-guix](https://pypi.python.org/pypi/upt-guix) backend, it can generate a\npackage definition suitable for [GNU Guix](https://www.gnu.org/s/guix); using\nthe [upt-openbsd](https://pypi.python.org/pypi/upt-openbsd) backend, it can\ngenerate a Makefile suitable for [OpenBSD](https://www.openbsd.org)'s ports.\n\nUsing this modular approach, we solved our two issues:\n\n- We will only ever need *one* PyPI parser, *one* CPAN parser, etc.\n- We will only have one backend per distribution. Backends will not be truly\n language-agnostic: the build systems will not be the same for Python packages\n and Ruby packages, for instance. Still, a lot of code may be factorized: the\n creation of the required directories, the writing of some common metadata...\n\nLast but not least, frontends and backends are not part of the upt core project.\nEvery backend, every frontend is a separate project, living in its own\nrepository, written by its own team. This way, nobody has control over the full\nproject, and different communities may make different technical choices (testing\ntools, coding standards, version control systems...) without having to impose\nthem upon everyone else.\n\n\n## Contributing to upt\nYou may contribute by sending patches to tipecaml@gmail.com or by opening a pull\nrequest.\n\nYour patches should not break anything, so, prior to sending them, be sure to\nrun:\n\n $ tox -eflake8\n $ tox -epy36\n\nYou may also want to contribute to one of the frontends/backends: they are\nseparate projects, so you should not send your patches to upt.\n\n\n## Adding frontends or backends\n\n### New frontend/backend using cookiecutter\n\nYou may create the whole directory structure for a new frontend/backend using\n[cookiecutter](https://github.com/audreyr/cookiecutter). This will also write\nsome code and create a first git commit including everything you need to get\nstarted. Simply type:\n\n $ cookiecutter https://framagit.org/upt/cookiecutter-upt\n\nAnd answer the questions prompted on the screen. The next two sections describe\nthe structure of a frontend and a backend.\n\n### Adding a frontend\nYour setup.cfg should use an entry point, like this:\n\n```\n# Taken from the upt-rubygems project\n[options.entry_points]\nupt.frontends =\n rubygems = upt_rubygems.upt_rubygems:RubyGemsFrontend\n```\n\nAlternatively, if you want to use setup.py:\n\n```\nsetup(\n ...\n entry_points = { \n 'upt.frontends': [\n 'rubygems=upt_rubygems.upt_rubygems:RubyGemsFrontend',\n ] \n },\n ...\n)\n```\n\nLet us now look at the implementation of a frontend:\n\n```\n...\nimport upt\n...\nclass MyFrontEndPackage(upt.Package):\n pass\n\n\nclass MyFrontendParser(upt.Parser):\n name = 'myfrontend'\n\n def parse(self, pkg_name):\n ...\n return MyFrontendPackage(pkg_name,\n version=..., # A string, such as '1.2.3'\n homepage=..., # A string\n summary=..., # A string containing a short description\n description=..., # A string, containing a longer description\n # upt.PackageRequirement takes two arguments:\n # - the name of the package\n # - a version specifier, as defined in\n # https://www.python.org/dev/peps/pep-0440/#version-specifiers\n requirements={\n 'config': [\n upt.PackageRequirement('config-dep', '==1.4'),\n ...\n ],\n 'build': [\n upt.PackageRequirement('build-dep', '>1.2'),\n ...\n ],\n 'run': [\n upt.PackageRequirement('runtime-dep', ''),\n ...\n ],\n 'test': [\n upt.PackageRequirement('test-dep', '<=2.3'),\n ...\n ]\n },\n # The license(s) used by this package, as instances of\n # upt.License. The upt project provides a lot of licenses in\n # the upt.licenses module. Use help(upt.licenses) to see the\n # whole list.\n # If you may not determine the nature of a licenses, you should\n # return upt.UnknownLicense().\n # The list of licenses may be empty.\n licenses=[\n upt.licenses.BSDThreeClauseLicense(),\n upt.UnknownLicense(),\n ],\n archives=[\n upt.Archive('http://example.com/foo.tar.gz', size=1234,\n md5='md5', rmd160='rmd160', sha256='sha256')\n ]\n )\n\n```\n\nThe most interesting method here is MyFrontendParser.parse. It must return a\nupt.Package object (you may define a subclass such as MyFrontendPackage if you\nwish). Only the package name and its version must be passed to the constructor,\nall other fields are optional.\n\n### Adding a backend\nYour setup.cfg should use an entry point, like this:\n\n```\n[options.entry_points]\n# Taken from upt-openbsd\nupt.backends =\n openbsd = upt_openbsd.upt_openbsd:OpenBSD\n```\n\nAlternatively, if you want to use setup.py:\n\n```\nsetup(\n ...\n entry_points = { \n 'upt.backends': [\n 'openbsd=upt_openbsd.upt_openbsd:OpenBSD',\n ] \n },\n ...\n)\n```\n\nLet us now look at the implementation of a backend:\n\n```\n...\nimport upt\n...\nclass MyBackend(upt.Backend):\n # The name of the backend: this is what will be seen in the output of\n # \"upt --list-backends\".\n name = 'mybackend'\n\n # Should you wish to use the \"--recursive\" flag, in order to recursively\n # package all dependencies of your package, you must define the following\n # method, which returns a list of all versions of a given package currently\n # packaged in your backend.\n def package_versions(self, package_name):\n \"\"\"Return a list of available versions of PACKAGE_NAME\"\"\"\n raise NotImplementedError\n\n # Alternatively, you could redefine the following method to have complete\n # control over the decision to package (or not package) the given\n # requirement:\n # def needs_requirement(self, req, phase):\n\n def create_package(self, upt_pkg, output=None):\n # Parameters:\n # - upt_pkg: an instance of upt_pkg. See the \"Adding a frontend\"\n # section for more info on its fields.\n # - output: currently unused, will always be None.\n\n # Do whatever you need to generate a valid \"package definition\" for\n # your package manager. Note that \"upt_pkg.frontend\" contains the name\n # of the frontend that was used: it should be helpful with the\n # language-specific parts of your backend.\n ...\n\n # Currently, all backends write the \"package definition\" to stdout.\n print(...)\n```\n\n\n### Logging\nWhether you are writing a frontend or a backend, you can use a logger provided\nby upt by running:\n\n```\nimport logging\n...\nlogger = logging.getLogger('upt')\n```\n\nSee the [logging module\ndocumentation](https://docs.python.org/3/library/logging.html) for more info on\nhow to use this logger.\n\n\n## Known frontends and backends\n### Supported frontends\n\n- [upt-cpan](https://pypi.python.org/pypi/upt-cpan) a frontend for\n [CPAN](https://www.cpan.org/)\n- [upt-pypi](https://pypi.python.org/pypi/upt-pypi) a frontend for\n [PyPI](https://pypi.python.org/)\n- [upt-rubygems](https://pypi.python.org/pypi/upt-rubygems) a frontend for\n [RubyGems](https://rubygems.org/)\n\nPlease tell us about your frontends!\n\n### Supported backends\n\n- [upt-fedora](https://pypi.python.org/pypi/upt-fedora) a backend for\n [Fedora](https://getfedora.org/)\n- [upt-freebsd](https://pypi.python.org/pypi/upt-freebsd) a backend for\n [FreeBSD](https://www.freebsd.org/)\n- [upt-guix](https://pypi.python.org/pypi/upt-guix) a backend for [GNU\n Guix](https://www.gnu.org/s/guix)\n- [upt-nix](https://pypi.python.org/pypi/upt-nix) a backend for\n [Nix](https://nixos.org/nix/)\n- [upt-openbsd](https://pypi.python.org/pypi/upt-openbsd) a backend for\n [OpenBSD](https://www.openbsd.org)\n\nPlease tell us about your backends!\n\n### Compatibility\n\n| | upt-cpan | upt-pypi | upt-rubygems |\n|-------------|----------|----------|--------------|\n| upt-fedora | OK | OK | OK |\n| upt-freebsd | OK | OK | KO |\n| upt-guix | OK | OK | OK |\n| upt-nix | OK | OK | KO |\n| upt-openbsd | OK | OK | OK |\n\n\n## Similar projects\n\n### Generic tools\n[fpm](https://github.com/jordansissel/fpm) (Effing package management) is a tool\nquite similar to upt. It can turn packages from PyPI/RubyGems/etc. into packages\nfor Debian/Fedora/etc. It features a unified command-line interface, a common\nbehaviour for all target distributions, and a modular design.\n\nThe main difference with upt is that it does not generate the \"source\" of a\npackage, but rather an installable package: it will generate a deb file rather\nthan a debian/ directory, an rpm file rather than a spec file, etc. See [this\ncomment on the bug\ntracker](https://github.com/jordansissel/fpm/issues/1507#issuecomment-411390171)\nfor more information.\n\n### Per-distribution tools\nHere are some tools used to turn a package from a language-specific archive to\na package suitable for a general purpose package manager. We can see that [GNU\nGuix](https://www.gnu.org/s/guix), [NetBSD](https://www.netbsd.org/) and\n[OpenBSD](https://www.openbsd.org) decided to write a single tool, thus having\na unified CLI to access all upstream packages.\n\n| | Debian | Fedora | Guix | FreeBSD | NetBSD | OpenBSD |\n|------|--------------| ---------|-------------|----------|---------|---------|\n| CPAN | dh-make-perl | cpan2rpm | guix import | ? | url2pkg | PortGen |\n| NPM | npm2deb | npm2rpm | N/A | ? | url2pkg | ? |\n| PyPI | pypi2deb | pyp2rpm | guix import | pytoport | url2pkg | PortGen | \n| Ruby | gem2deb | gem2rpm | guix import | ? | url2pkg | PortGen |\n\n\n## License\nThis project is distributed under the [3-Clause BSD\nLicense](https://opensource.org/licenses/BSD-3-Clause). See the LICENSE file.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://framagit.org/upt/upt", "keywords": "", "license": "BSD-3-Clause", "maintainer": "", "maintainer_email": "", "name": "upt", "package_url": "https://pypi.org/project/upt/", "platform": "", "project_url": "https://pypi.org/project/upt/", "project_urls": { "Homepage": "https://framagit.org/upt/upt" }, "release_url": "https://pypi.org/project/upt/0.10.3/", "requires_dist": [ "packaging", "spdx-lookup", "upt-fedora ; extra == 'backends'", "upt-freebsd ; extra == 'backends'", "upt-guix ; extra == 'backends'", "upt-nix ; extra == 'backends'", "upt-openbsd ; extra == 'backends'", "upt-cpan ; extra == 'frontends'", "upt-pypi ; extra == 'frontends'", "upt-rubygems ; extra == 'frontends'" ], "requires_python": "", "summary": "Package software from any package manager to any distribution", "version": "0.10.3" }, "last_serial": 5615081, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "3b17d0caeff27a6cc903cc1178281848", "sha256": "38fffcf0a531315083a72bf077d568eecd0583fc016d412bc749129454f5b4a6" }, "downloads": -1, "filename": "upt-0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "3b17d0caeff27a6cc903cc1178281848", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12041, "upload_time": "2018-02-17T00:10:16", "url": "https://files.pythonhosted.org/packages/3d/d9/695836d7473da225924b3c952c262052bb7fac4decb97ee0d6a6abbf13e2/upt-0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "caf7f38daede2df14cfc5e45a5d90da9", "sha256": "5fe76723b198562015897aedd7326e177c0ab1c2afbba7be1f945c564c068e98" }, "downloads": -1, "filename": "upt-0.1.tar.gz", "has_sig": false, "md5_digest": "caf7f38daede2df14cfc5e45a5d90da9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7283, "upload_time": "2018-02-17T00:10:05", "url": "https://files.pythonhosted.org/packages/b6/61/77bbc10df5085909fb936abc1b823050b2cb836e4e7f4b235d130a0aa815/upt-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "ddf83508ef3d5fc422c273484fc5f46c", "sha256": "c7ffb570575e97a96c7e8a8a4ee22dd81992dad87a9803dd2bb005965ddf2561" }, "downloads": -1, "filename": "upt-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "ddf83508ef3d5fc422c273484fc5f46c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12079, "upload_time": "2018-02-17T00:26:53", "url": "https://files.pythonhosted.org/packages/41/ff/6e6db5313744ad46c4172324fdffa975fad026b56f7536d607179a6636a3/upt-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5a8bf137132f03abb3113aa4d5ec5ec7", "sha256": "e674e771a235434fc90449a60e2e2869e784201094a53ff0267e1260ac886523" }, "downloads": -1, "filename": "upt-0.1.1.tar.gz", "has_sig": false, "md5_digest": "5a8bf137132f03abb3113aa4d5ec5ec7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7294, "upload_time": "2018-02-17T00:26:55", "url": "https://files.pythonhosted.org/packages/02/e6/c28e79ceded78617d4cc772a87f3d64c997cb4537afa3bf56615e89c0019/upt-0.1.1.tar.gz" } ], "0.10": [ { "comment_text": "", "digests": { "md5": "72a9f206a5d516503b7bbc80c69323ed", "sha256": "61a03da73f8956773fa61040f2ae34c46d34b94a4e327d4c8d8383ec4d07a6c8" }, "downloads": -1, "filename": "upt-0.10-py3-none-any.whl", "has_sig": false, "md5_digest": "72a9f206a5d516503b7bbc80c69323ed", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 24364, "upload_time": "2019-07-21T18:02:37", "url": "https://files.pythonhosted.org/packages/95/18/992c19b1f5affc34404185aede747abf4bd9d69533db4519be7bd2f83f83/upt-0.10-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8cc4fb28bf43c7ee6e043a92107bc7c5", "sha256": "2a5659d3e1929581ef3fc89a8a7858d655bbb838d67b8410fbcdfe6a846b19d3" }, "downloads": -1, "filename": "upt-0.10.tar.gz", "has_sig": false, "md5_digest": "8cc4fb28bf43c7ee6e043a92107bc7c5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26610, "upload_time": "2019-07-21T18:02:39", "url": "https://files.pythonhosted.org/packages/f7/81/0fb5c7f6cc277be4f828f2c665449b3f530849b335dff57463db707c7ebb/upt-0.10.tar.gz" } ], "0.10.1": [ { "comment_text": "", "digests": { "md5": "b661bda739a6ec3582dbdb09f7a49548", "sha256": "c6768adb698158c644d30ee02b29fb3bc6b43e8046c66aa01f6d5298cfdd0049" }, "downloads": -1, "filename": "upt-0.10.1-py3-none-any.whl", "has_sig": false, "md5_digest": "b661bda739a6ec3582dbdb09f7a49548", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 24423, "upload_time": "2019-07-21T19:06:39", "url": "https://files.pythonhosted.org/packages/71/91/254b3fc18c51c0066e38d71a3290a997617339b5bd4a734a65419d0a45d3/upt-0.10.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8494affbf1045910a8ce288887e94695", "sha256": "1578c4173a65242a6fd2b33b0f024bf5d19f7b18f120320d5e758bed69840422" }, "downloads": -1, "filename": "upt-0.10.1.tar.gz", "has_sig": false, "md5_digest": "8494affbf1045910a8ce288887e94695", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26634, "upload_time": "2019-07-21T19:06:41", "url": "https://files.pythonhosted.org/packages/ce/82/64640eb39bcef5e39560612c6b05d65aab8bc196850039c100396d574806/upt-0.10.1.tar.gz" } ], "0.10.2": [ { "comment_text": "", "digests": { "md5": "db46fa608df3ca61a329b9fa36bc4694", "sha256": "a0a58b543312c998b74ec738241418ce9d570d60a9c05621589725ec73967b28" }, "downloads": -1, "filename": "upt-0.10.2-py3-none-any.whl", "has_sig": false, "md5_digest": "db46fa608df3ca61a329b9fa36bc4694", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 24427, "upload_time": "2019-07-28T02:04:02", "url": "https://files.pythonhosted.org/packages/ac/11/2b35c22aec6c17eba3ecb920c2fc89f938cb83445fc6af4d21fd9fe50dbb/upt-0.10.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0600f0d39df144c32ea912581c01599b", "sha256": "3b1ea43af5c528471fa26aaa2f67a1412851cd3552dde3e9c28a28c287716d22" }, "downloads": -1, "filename": "upt-0.10.2.tar.gz", "has_sig": false, "md5_digest": "0600f0d39df144c32ea912581c01599b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28482, "upload_time": "2019-07-28T02:04:04", "url": "https://files.pythonhosted.org/packages/7a/3c/2e221cb2a658672a6c4eca362b4353cfbbb5919acbb22292af52cdb239a4/upt-0.10.2.tar.gz" } ], "0.10.3": [ { "comment_text": "", "digests": { "md5": "c5216e4395f9422a27a4692c7d981826", "sha256": "cc2211977226d1a3807cb17729b0633c96aeeb215e61692233be42f9aa0f99a9" }, "downloads": -1, "filename": "upt-0.10.3-py3-none-any.whl", "has_sig": false, "md5_digest": "c5216e4395f9422a27a4692c7d981826", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 24426, "upload_time": "2019-07-31T19:03:14", "url": "https://files.pythonhosted.org/packages/9f/c4/1339aa5fc9cd90c50d34cb487009d61878609d755638c924095253e273f0/upt-0.10.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4a1944030b269e606476c6cf17e01f4d", "sha256": "e08fcea114cf71ed98dd5f9085c40892301b22ebba9448d2940be77737596258" }, "downloads": -1, "filename": "upt-0.10.3.tar.gz", "has_sig": false, "md5_digest": "4a1944030b269e606476c6cf17e01f4d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28655, "upload_time": "2019-07-31T19:03:16", "url": "https://files.pythonhosted.org/packages/e0/76/693147981894b8d6447c298e277a0cea184760d43cda1272af2c74937882/upt-0.10.3.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "99e0c85b4fb763ec09627461a75d6df0", "sha256": "11da461d1e5abb67b65dd752b2f7c8e4aebf6f1cc3ec482af9550e3799e3b937" }, "downloads": -1, "filename": "upt-0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "99e0c85b4fb763ec09627461a75d6df0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16473, "upload_time": "2018-02-21T03:05:10", "url": "https://files.pythonhosted.org/packages/42/d3/d529bea73c2131e42af6821531b56fa1d12a2859ece93cfcff29a4fec99f/upt-0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "93885692926064ac3c07d750ad1b1653", "sha256": "0303f7910dc1c8cc8d0588805446ca76d08dc9b2364c648949b5b1d0ec555fb1" }, "downloads": -1, "filename": "upt-0.2.tar.gz", "has_sig": false, "md5_digest": "93885692926064ac3c07d750ad1b1653", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12470, "upload_time": "2018-02-21T03:05:12", "url": "https://files.pythonhosted.org/packages/47/3f/b17af919ca6972ae1e011372baf9626b5a707b51b4db1b42864b14649e2b/upt-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "bdc0111040ee39081c763cb42627f774", "sha256": "e680c86d4ecc199175ff0944ae6844c46741a77653afd4ed989b33d754283a29" }, "downloads": -1, "filename": "upt-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "bdc0111040ee39081c763cb42627f774", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16934, "upload_time": "2018-03-04T21:21:03", "url": "https://files.pythonhosted.org/packages/09/ee/e340029464b9c83a067435c2589185a0c9e817bbce5114da183464883631/upt-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2611ae78cab027dd068834a47d575f96", "sha256": "1cfceb7e4f03fee9a694c4a6a27271af81e6bf78c5401a5925b852fb616b64c8" }, "downloads": -1, "filename": "upt-0.2.1.tar.gz", "has_sig": false, "md5_digest": "2611ae78cab027dd068834a47d575f96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12725, "upload_time": "2018-03-04T21:21:05", "url": "https://files.pythonhosted.org/packages/00/86/28166caa701b863597ea1e497163aa894013b76368f2c357f4d585660962/upt-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "d1d89f05f677d09450d4172b293eb088", "sha256": "964e861af2a817da2f6dd8ade33b555897673cbe862f1f9364b2ff41d668b462" }, "downloads": -1, "filename": "upt-0.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "d1d89f05f677d09450d4172b293eb088", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16997, "upload_time": "2018-03-04T21:46:00", "url": "https://files.pythonhosted.org/packages/4a/41/2e3e69d35503634fd700f3a65a579b86da4a0b562fe0a19bcf65370435c4/upt-0.2.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "809f18b60d897476b614c5ef92a0ab37", "sha256": "e4b5f51d9fa99aa0173bd183e3f9b837cbcc484586883b14bb8ad4db32fbc28e" }, "downloads": -1, "filename": "upt-0.2.2.tar.gz", "has_sig": false, "md5_digest": "809f18b60d897476b614c5ef92a0ab37", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12813, "upload_time": "2018-03-04T21:46:02", "url": "https://files.pythonhosted.org/packages/c2/0c/8e7dbf9df281a4ea22899f3b8d174ab498f3b954dffc04ab154b4168e095/upt-0.2.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "d79eef788a6cc77c4b9a854dd45f3076", "sha256": "7b8b25283ba0ffc51680c62f4f9a16d5734b2a92d8381ab1df58f29bef3b32a5" }, "downloads": -1, "filename": "upt-0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "d79eef788a6cc77c4b9a854dd45f3076", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 19183, "upload_time": "2018-03-13T01:26:01", "url": "https://files.pythonhosted.org/packages/32/a3/b59afd5466ece42ec7942692f910a3d759f72baf992fa7f9a5590174a5b0/upt-0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "50c76e0336bcddea663cad4439251492", "sha256": "8ae8ec689649059346de8125973a03c1cab8b925d91436c4200b7cc351b462c2" }, "downloads": -1, "filename": "upt-0.3.tar.gz", "has_sig": false, "md5_digest": "50c76e0336bcddea663cad4439251492", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14180, "upload_time": "2018-03-13T01:26:03", "url": "https://files.pythonhosted.org/packages/3a/5e/02e2481d247d0fb4448b08ec582785eff1bf1087a8d9e631b7c5d9f6cf72/upt-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "471b99415859ea5edb13e913c8d8a126", "sha256": "56f61c16e91f4a6721e58afebb9cb194a86d4e03571f79f0631989b2949a47b7" }, "downloads": -1, "filename": "upt-0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "471b99415859ea5edb13e913c8d8a126", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 20962, "upload_time": "2018-03-20T01:41:45", "url": "https://files.pythonhosted.org/packages/0f/0e/098686df04f2338ac8cf64efc7eacafc8994163d64000d6b09bc284d148d/upt-0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9d85e9a1e4d6425f32d28efabb6a89c0", "sha256": "f7eb5e02730b71c7a365b9629b4a212966fab5f414832f6f69c761ea554134be" }, "downloads": -1, "filename": "upt-0.4.tar.gz", "has_sig": false, "md5_digest": "9d85e9a1e4d6425f32d28efabb6a89c0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15295, "upload_time": "2018-03-20T01:41:47", "url": "https://files.pythonhosted.org/packages/79/65/a3aef62003d6e48909c22e01732487c9e2ec9d39853a00ff86ec2fe9e9ca/upt-0.4.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "e5197b2bef18e1892dcde25746991f02", "sha256": "a229806c033588f9c6f5a28bde8c0ef7bd6468d577ec93fe300c0c849f829a97" }, "downloads": -1, "filename": "upt-0.4.1-py3-none-any.whl", "has_sig": false, "md5_digest": "e5197b2bef18e1892dcde25746991f02", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21343, "upload_time": "2018-08-13T00:25:31", "url": "https://files.pythonhosted.org/packages/3b/51/824ba283dfa598a544ad04e2773231714f615953176db90ca93a70d4f58f/upt-0.4.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a8b82c16394af03d8bf50deca1980824", "sha256": "3d249b821ebec3c8e92373ee19e6bdc5cea00a96a3783fd85a8adba62c53af80" }, "downloads": -1, "filename": "upt-0.4.1.tar.gz", "has_sig": false, "md5_digest": "a8b82c16394af03d8bf50deca1980824", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15551, "upload_time": "2018-08-13T00:25:32", "url": "https://files.pythonhosted.org/packages/8e/d9/8e540d160b92b862d0cef05deb87934b8eb2b8b88de57259c4c11380f459/upt-0.4.1.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "442d698baa7f29b1593e454ed3d8e078", "sha256": "5c8b99166517696e81b35aee992864fd2644b298af98f0e0ef84252575423f87" }, "downloads": -1, "filename": "upt-0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "442d698baa7f29b1593e454ed3d8e078", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22628, "upload_time": "2018-10-04T18:15:53", "url": "https://files.pythonhosted.org/packages/f6/55/77ff3e7adf997074f81eabe00bf0b034ebb295f4965a7b986e1a66012aa7/upt-0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ea7da2fdc5e01cb40a132bf7b2684a40", "sha256": "dbb8c79470ac15223c50f2adb5b01ff8a59e77790f225133bbedd0e7ada86f4f" }, "downloads": -1, "filename": "upt-0.5.tar.gz", "has_sig": false, "md5_digest": "ea7da2fdc5e01cb40a132bf7b2684a40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16670, "upload_time": "2018-10-04T18:15:54", "url": "https://files.pythonhosted.org/packages/48/ac/1cdf39ded76a99cd04cb7323f79d8f62894839b3d6a8be5ac77eb5f55694/upt-0.5.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "c56e47790633e21f62b129e393d90116", "sha256": "71eedcc8c083b30f64732fbbd03d67705667e8586d7b5f01d0860bc0c164ba22" }, "downloads": -1, "filename": "upt-0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "c56e47790633e21f62b129e393d90116", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 20219, "upload_time": "2019-02-08T02:49:38", "url": "https://files.pythonhosted.org/packages/33/7f/8aeac6cafcf7ccefd220d474508fa8a9ad24f615d8a58109e01e7297257a/upt-0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5d608573557e69fe6b265de2199665c2", "sha256": "707b79dd699f5bdd68ef2eeb66bacfe2f86e0c93f99ad3a5c48b1b6a799b222b" }, "downloads": -1, "filename": "upt-0.6.tar.gz", "has_sig": false, "md5_digest": "5d608573557e69fe6b265de2199665c2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23609, "upload_time": "2019-02-08T02:49:40", "url": "https://files.pythonhosted.org/packages/85/91/545f02d019f64af6c135b680c660a17f54b1d81afa9ebcc2b19999159d3b/upt-0.6.tar.gz" } ], "0.7": [ { "comment_text": "", "digests": { "md5": "207a2268e5ebe333915828910b8ed089", "sha256": "ebddeff369e0d1982479b8c7bb2b18f713a91cb46a6bfb703862bda63039e184" }, "downloads": -1, "filename": "upt-0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "207a2268e5ebe333915828910b8ed089", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 20652, "upload_time": "2019-04-28T20:59:04", "url": "https://files.pythonhosted.org/packages/7c/7f/1045bd1a3b37568d316a6a3c0263b23fc60b081c992537fef61964b38aa8/upt-0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "eba229d8da2607c8bce2f567c75d8dd7", "sha256": "7de9a0cc9d55c175b611ed748ee7ea572ec308411934769e2e647d1d26ba2eea" }, "downloads": -1, "filename": "upt-0.7.tar.gz", "has_sig": false, "md5_digest": "eba229d8da2607c8bce2f567c75d8dd7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24223, "upload_time": "2019-04-28T20:59:08", "url": "https://files.pythonhosted.org/packages/f8/dd/6867d803067ad54fdd06f2602a1c6f0d947152565bb29edac1e9c0c2a4f7/upt-0.7.tar.gz" } ], "0.8": [ { "comment_text": "", "digests": { "md5": "17d9c53d516020f0df5c659c2e0e75a0", "sha256": "04dc9a058b4c1db7f7b6eb67ee3d257b28e653ff858fa7f21cd8254d1a842a03" }, "downloads": -1, "filename": "upt-0.8-py3-none-any.whl", "has_sig": false, "md5_digest": "17d9c53d516020f0df5c659c2e0e75a0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21145, "upload_time": "2019-06-15T01:57:18", "url": "https://files.pythonhosted.org/packages/72/e0/42d4fcd1c55bd13356bfed945d143999d976d522c1451a895e2f64171bdc/upt-0.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "de07b0b52ab7e365df35561bb379e459", "sha256": "ecb4b8da0e2e6a5f6926dc41cc45fd3923e8dfb6a9a8aafaa9149b5144d8898c" }, "downloads": -1, "filename": "upt-0.8.tar.gz", "has_sig": false, "md5_digest": "de07b0b52ab7e365df35561bb379e459", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25792, "upload_time": "2019-06-15T01:57:20", "url": "https://files.pythonhosted.org/packages/a2/d8/5bff77dffb3ab1bbb8e97ceeecbba216f0cd005e6f8b4a6e36950433d18c/upt-0.8.tar.gz" } ], "0.9": [ { "comment_text": "", "digests": { "md5": "e45fc7866d0b1fbcb198af1965be58e8", "sha256": "e1668b0b37af1f2bf2d36b7c0a8bc7b28705bfa88546dda1da9c1ec5e9d03cd3" }, "downloads": -1, "filename": "upt-0.9-py3-none-any.whl", "has_sig": false, "md5_digest": "e45fc7866d0b1fbcb198af1965be58e8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21264, "upload_time": "2019-06-18T23:20:26", "url": "https://files.pythonhosted.org/packages/8b/b2/cfb7dfb5cc04efd4bae92ae7ad655a2c934555add8983f8ccb4c51278efc/upt-0.9-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "348d4d5da568463468bde0329a62b1a3", "sha256": "b967cda25e8e5a634a450886e98ebeaf5aa51220e8888a17a34d78d001f96035" }, "downloads": -1, "filename": "upt-0.9.tar.gz", "has_sig": false, "md5_digest": "348d4d5da568463468bde0329a62b1a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25969, "upload_time": "2019-06-18T23:20:28", "url": "https://files.pythonhosted.org/packages/63/89/07765f09eace4b96cd0872a2c81736940d1f0f7388f76dbc55cfb33209ce/upt-0.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c5216e4395f9422a27a4692c7d981826", "sha256": "cc2211977226d1a3807cb17729b0633c96aeeb215e61692233be42f9aa0f99a9" }, "downloads": -1, "filename": "upt-0.10.3-py3-none-any.whl", "has_sig": false, "md5_digest": "c5216e4395f9422a27a4692c7d981826", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 24426, "upload_time": "2019-07-31T19:03:14", "url": "https://files.pythonhosted.org/packages/9f/c4/1339aa5fc9cd90c50d34cb487009d61878609d755638c924095253e273f0/upt-0.10.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4a1944030b269e606476c6cf17e01f4d", "sha256": "e08fcea114cf71ed98dd5f9085c40892301b22ebba9448d2940be77737596258" }, "downloads": -1, "filename": "upt-0.10.3.tar.gz", "has_sig": false, "md5_digest": "4a1944030b269e606476c6cf17e01f4d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28655, "upload_time": "2019-07-31T19:03:16", "url": "https://files.pythonhosted.org/packages/e0/76/693147981894b8d6447c298e277a0cea184760d43cda1272af2c74937882/upt-0.10.3.tar.gz" } ] }