{ "info": { "author": "Tiago Tresoldi", "author_email": "tresoldi@shh.mpg.de", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries" ], "description": "# Ngesh, simulation of random phylogenetic trees with characters\n\n[![Build Status](https://travis-ci.org/tresoldi/ngesh.svg?branch=master)](https://travis-ci.org/tresoldi/ngesh)\n[![codecov](https://codecov.io/gh/tresoldi/ngesh/branch/master/graph/badge.svg)](https://codecov.io/gh/tresoldi/ngesh)\n[![PyPI](https://img.shields.io/pypi/v/ngesh.svg)](https://pypi.org/project/ngesh)\n[![DOI](https://zenodo.org/badge/178537103.svg)](https://zenodo.org/badge/latestdoi/178537103)\n\n`ngesh` is a Python library for simulating random phylogenetic trees and\nrelated data (characters, states, branch length, etc.).\nIt is intended for benchmarking phylogenetic methods, especially in\nhistorical linguistics, and for providing dummy trees\nfor their development and debugging. The generation of\nrandom phylogenetic trees also goes by the name of \"simulation methods\nfor phylogenetic trees\" or just \"phylogenetic tree simulation\".\n\n*Please remember that `ngesh` is a work-in-progress and a library intended to\nbe a simple drop-in for cases where random trees are needed; for complex\nmethods, see the alternatives listed below or consult the\nbibliographic references.*\n\nIn detail, with `ngesh`:\n\n* trees can be generated according to user-specified birth and death ratios (and\nthe death ratio can be set to zero, resulting in a birth-only tree)\n* speciation events default to two descendants, but the number of descendants\ncan be randomly drawn from a user-defined Poisson process (allowing\nto model hard politomies)\n* trees will have random topologies and, if necessary, random branch-lengths\n* trees can be limited in terms of number of extant leaves, evolution time\n(as related to the birth and death parameters), or both\n* non-extant leaves can be pruned from birth-death trees\n* character evolution can be simulated in relation to branch lengths,\nwith user-specified ratios for mutation and horizontal gene transfer,\nwith different rates of change for each character\n* trees can be generated from user-provided seeds, so that the random\ngeneration can be maintained across executions (and, in most cases, the\nexecution should be reproducible *also* on different machines and different\nvestions of Python)\n* nodes can optionally receive unique labels, either sequential ones\n(like \"L01\", \"L02\", and \"L03\"),\nrandom human-readable names (like \"Sume\", \"Fekobir\", and \"Tukok\"),\nor random biological names approximating the\nbinomial nomenclature standard (like \"Sburas wioris\", \"Zurbata ceglaces\",\nand \"Spellis spusso\")\n* trees can be returned as [ETE](http://etetoolkit.org/) tree objects or\nexported in a variety of formats, such as Newick trees, ASCII representation,\ntabular textual listings, etc.\n\n### Changelog\n\nVersion 0.3:\n\n- General improvements to code quality\n- Full reproducibility from seeds for the pseudo-random generators,\n allowing string, ints, and floats\n- Changes for further integration with `abzu` and `alteruphono` for\n simulating linguistic data\n\n## How does ngesh work?\n\nFor each tree, an `event_rate` is computed from the sum of the `birth` and\n`death` rates. At each iteration, which takes place after an\nrandom expovariant time from the `event_rate`, one of the extant nodes is\nselected for an \"event\": either a birth or a death from the\nproportion of each rate. All other extant leaves have their distances\nupdated with the event time.\n\nThe random labels follow the expected methods for random text generation\nfrom a set of patterns, taking care to generate names as universally\nreadable (if not pronounceable) as possible.\n\n*missing on character generation*\n\n## Installation\n\nIn any standard Python environment, `ngesh` can be installed with:\n\n```\npip install ngesh\n```\n\nThe `pip` installation will also fetch the dependencies `ete3` and\n`numpy`, if necessary.\n\n## How to use\n\nYou can test your installation from the command line with the `ngesh` command, which\nwill return a different random small birth-death tree in Newick format each time it\nis called:\n\n```\n$ ngesh\n(Saorus getes:1.31562,((Voces earas:1.07567,(Dallao spettus:0.703609,Sburas wioris:0.703609)1:0.372063)1:0.464667,(Zurbaza ceglaces:0.527431,(Amduo vizoris:0.345862,Uras wiurus:0.345862)1:0.18551)1:1.00897)1:2.1707);\n\n$ ngesh\n((Ollio zavis:0.698453,(Spectuo sicui:0.596731,((Ronis mivulis:0.0431014,Vaporus conomattas:0.0431014)1:0.413634,Rizarus urrus:0.456735)1:0.139996)1:0.101722)1:3.17827,(Deses mepus:2.22061,(Ovegpuves wiumoras:1.88469,(Easas ecdebus:0.201891,Muggas lupas:0.201891)1:1.6828)1:0.335918)1:1.65611);\n```\n\nThe same command line tool can refer to values provided in a textual\nconfiguration file. Here, we generate the Nexus data for a\nreproducible Yule tree (note the `12345` seed)\nwith a birth ratio of 0.75, at least 8 leaves with `\"human\"` labels,\nand 10 presence/absence characters:\n\n```\n$ cat my_tree.conf \n[Config]\nlabels=human\nbirth=0.666\ndeath=0.0\noutput=nexus\nmin_leaves=8\nnum_chars=10\n\n$ ngesh -c mine.conf --seed 12345\n#NEXUS\n\nbegin data;\n dimensions ntax=15 nchar=25;\n format datatype=standard missing=? gap=-;\n matrix\nForo 1011000101010010100100100\nMeno 1100100101010010010010001\nVuea 1100110001010100001001001\nVegevo 1100100101010010010010100\nBufuri 1100110001010100001001001\nNovake 1100110001010100001001001\nFonulip 1100110001010100001001001\nOmih 1101001001010011000100100\nOnegro 1101000011010010001100100\nRolsoa 1100100100110010010100100\nWigu 1101001001010010001100100\nTeozu 1101001001010011000100010\nKabu 1100100101001010010100100\nTimebbed 1100100101010010010010100\nOkuna 1100110001010100001001001\n ;\nend;\n```\n\nParameters set in a configuration file can be overridden at the command line.\nThe ASCII representation of the topology of the same tree can be obtained\nwith:\n\n```\n$ ngesh -c mine.conf --seed 12345 -o ascii\n\n /-Omih\n |\n /-| /-Onegro\n | | /-|\n | \\-| \\-Wigu\n | |\n | \\-Teozu\n |\n /-| /-Kabu\n | | |\n | | | /-Novake\n | | | |\n | | | /-| /-Okuna\n | | | | | /-|\n | \\-| | \\-| \\-Fonulip\n | | /-| |\n | | | | \\-Bufuri\n | | | |\n--| | /-| \\-Vuea\n | | | |\n | | | | /-Meno\n | \\-| \\-|\n | | \\-Rolsoa\n | |\n | | /-Vegevo\n | \\-|\n | \\-Timebbed\n |\n \\-Foro\n```\n\nThe package is, however, designed to be used as a library. If you have\nPyQt5 installed (which is not listed as a dependency), the following code\nwill pop up the ETE Tree Viewer on a random tree:\n\n```\npython3 -c \"import ngesh ; ngesh.display_random_tree()\"\n```\n\n![random tree](https://raw.githubusercontent.com/tresoldi/ngesh/master/doc/tree001.png){width=100%}\n\nThe main functions for generation are `gen_tree()`, which returns a random\ntree topology, and `add_characters()`, which simulates character evolution\nin a provided tree. As they are separate tasks, it is possible to just\ngenerate a random tree or to simulate character evolution in an user\nprovided tree.\n\nThe full documentation is available in the functions docstring (which\ncan be visualized with `print(ngesh.gen_tree.__doc__)` and\n`print(ngesh.add_characters.__doc__)`) or\n[directly in the source code](https://github.com/tresoldi/ngesh/blob/master/ngesh/random_tree.py).\nThe code snipped below shows a basic tree generation, character evolution,\nand output flow; the parameters for generation are the same listed in\nthe docstrings and in the following below.\n\n```\n$ ipython3\n\nIn [1]: import ngesh\n\nIn [2]: tree = ngesh.gen_tree(1.0, 0.5, max_time=3.0, labels=\"human\")\n\nIn [3]: print(tree)\n\n /-Butobfa\n /-|\n | | /-Defomze\n | \\-|\n | \\-Gegme\n--|\n | /-Bo\n | /-|\n | | \\-Peoni\n \\-|\n | /-Riuzo\n \\-|\n \\-Hoale\n\nIn [4]: tree = ngesh.add_characters(tree, 10, 3.0, 1.0)\n\nIn [5]: print(ngesh.tree2nexus(tree))\n#NEXUS\n\nbegin data;\n dimensions ntax=7 nchar=15;\n format datatype=standard missing=? gap=-;\n matrix\nHoale 100111101101110\nButobfa 101011101110101\nDefomze 101011110110101\nRiuzo 100111101101110\nPeoni 110011101110110\nBo 110011101110110\nGegme 101011101110101\n ;\nend;\n```\n\n### Integrating with other software\n\nIntegration is easy due to the various export functions. For example, it\nis possible to generate random trees with characters for which we know\nall details on evolution and parameters, and generate Nexus files that\ncan be fed to phylogenetic software such as\n[MrBayes](http://nbisweden.github.io/MrBayes/) or\n[BEAST2](https://www.beast2.org/)\nto either check how they perform or\nhow good is our generation in terms of real data.\n\nLet's simulate phylogenetic data for an analysis using BEAST2 through\n[BEASTling](https://github.com/lmaurits/BEASTling). We start with\na birth-death tree (lambda=0.9, mu=0.3), with at least 15 leaves, and 100\ncharacters whose evolution is modelled with the default parameters\nand a string seed `\"jena\"` for reproducibility; the tree data is exported\nin `\"wordlist\"` format:\n\n```\n$ cat examples/example_ngesh.conf \n[Config]\nlabels=human\nbirth=0.9\ndeath=0.3\noutput=nexus\nmin_leaves=15\nnum_chars=100\n\n$ ngesh -c examples/example.conf --seed jena > examples/example.csv\n\n$ head examples/example.csv \nLanguage_ID,Feature_ID,Value\nDotare,feature_0,0\nDotare,feature_1,1\nDotare,feature_2,2\nDotare,feature_3,3\nDotare,feature_4,4\nDotare,feature_5,5\nDotare,feature_6,6\nDotare,feature_7,7\nDotare,feature_8,8\n```\n\nWe can now use a minimal BEASTling configuration and generate an XML\ninput for BEAST2. Let's assume we want to test how well our pipeline\nperforms when assuming a Yule tree when the data actually includes\nextinct taxa. The results here presented are not expected to perfect,\nas we will use\na short chain length to make it faster and a model which is different\nfrom the assumptions used for generation (besides the fact of the\ndefault parameters for\nhorizontal gene transfer being a bit too aggressive).\n\n```\n$ cat examples/example_beastling.conf \n[admin]\nbasename=example\n[MCMC]\nchainlength=500000\n[model example]\nmodel=covarion\ndata=example.csv\n\n$ beastling example_beastling.conf \n\n$ beast example.xml \n```\n\nWe can proceed normally here: use BEAST2's `treeannotator` (or similar\nsoftware) to generate a summary tree,\nwhich we store in `examples/summary.nex`,\nand plot the results with `figtree` (or, again, similar software).\n\nLet's plot our summary tree and compare the results with the\nactual topology (which we can regenerate with the earlier seed).\n\n![summary tree](https://raw.githubusercontent.com/tresoldi/ngesh/master/doc/summary.nex.png){width=100%}\n\n```\n$ ngesh -c examples/example_ngesh.conf --seed jena --output newick > examples/example.nw\n```\n\n![original tree](https://raw.githubusercontent.com/tresoldi/ngesh/master/doc/example.nw.png){width=100%}\n\nThe results are not excellent given the limits we set for quick demonstration,\nbut it still capture major information and subgroupings (as clearer by\nthe radial layout below) -- manual data exploration show that at least some\nof the errors, including the group in the first split, are due to horizontal\ngene transfer. For an analysis of\nthe inference performance we would need to improve the parameters above\nand repeat the analysis on a range of random trees, including studying the\nlog of character changes (including borrowings) involved in this particular\nrandom tree.\n\n![summary tree radial](https://raw.githubusercontent.com/tresoldi/ngesh/master/doc/summary.nex2.png){width=100%}\n\n*TODO: Compare trees (Robinson-Foulds symmetric difference?)*\n\nThe files used and generated in this example\ncan be found in the `/examples` directory.\n\n## Parameters for tree generation\n\nThe parameters for tree generation, as also given by `ngesh -h`, are:\n\n* `birth`: The tree birth rate (l)\n* `death`: The tree death rate (mu)\n* `max_time`: The stopping criterion for maximum evolution time\n* `min_leaves`: The stopping criterion for minimum number of leaves\n* `labels`: The model for textual generation of random labels\n(`None`, `\"enum\"` for a simple enumeration, `\"human\"` for randomly\ngenerated names, and `\"bio\"` for randomly generated specie names)\n* `num_chars`: The number of characters to be simulated\n* `k_mut`: The character mutation gamma `k` parameter\n* `th_mut`: The character mutation gamma `th` parameter\n* `k_hgt`: The character HGT gamma `k` parameter\n* `th_hgt`: The character HGT gamma `th` parameter\n* `e`: The character general mutation `e` parameter\n\n## What does \"ngesh\" mean?\n\nTechnically it is just an unique name, but it was derived from one of the Sumerian words\nfor \"tree\", [\u011de\u0161](http://psd.museum.upenn.edu/epsd/epsd/e2052.html), albeit\nwith an uncommon transcription. The name comes from the library once being\na module of a larger system for simulating language evolution and benchmarking\nrelated tools, called [Enki](https://en.wikipedia.org/wiki/Enki) after the\nSumerian god of (among many other things) language and mischief.\n\nThe intended pronounciation, as in the most accepted reconstructions, is /\u014be\u0283/. \nBut don't strees over it: it is just a unique name.\n\n## Alternatives\n\nThere are many tools for simulating phylogenetic processes in order to obtain\nrandom phylogenetic trees. The most complete is probably the R package\n[`TreeSim`](https://CRAN.R-project.org/package=TreeSim)\nby Tanja Stadler, which includes many flexible tree simulation functions. In\nR, one can also use the `rtree()` function from package `ape` and the\n`birthdeath.tree()` one from package `geiger`, as well as manually randomizing taxon\nplacement in cladograms.\n\nIn Python, some code similar to `ngesh` and which served as initial inspiration\nis provided by Marc-Rolland Noutahi on the blog post\n[How to simulate a phylogenetic tree ? (part 1)](https://mrnoutahi.com/2017/12/05/How-to-simulate-a-tree/).\n\nA number of on-line tools are also available at the time of writing:\n\n* [T-Rex (Tree and reticulogram REConstruction](http://www.trex.uqam.ca/index.php?action=randomtreegenerator&project=trex)\nat the Universit\u00e9 du Qu\u00e9bec \u00e0 Montr\u00e9al (UQAM)\n* [Anvi'o Server](https://anvi-server.org/meren/random_phylogenetic_tree_w500_nodes) can\nbe used on-line as a wrapper to T-Rex above\n* [phyloT](https://phylot.biobyte.de/), which by randomly sampling taxonomic names,\nidentifiers or protein accessions can be used for the same purpose\n\n## TODO\n\n* Shorter-term\n * Write better documentation of function parameters\n * Add all still unavailable parameters to the command line tool (e.g.,\n setting hard politomies)\n * Automatically generate developer documentation (possibly with Sphinx)\n * Allow generation of unlabelled trees from the command-line (a text\n generation model is currently mandatory)\n * Look for default parameters that are more closely related to\n linguistic trees (or, at least, to the Indo-European one)\n * Check if all outputs are complete (e.g., characters are currently\n missing in the Newick format)\n * Add a command-line option (or a new tool) that allows to write the\n output to one file and the reference tree to a second one (possibly\n with the log of character evolution)\n * Check for alternatives for the exponential correction of a character\n resistance to mutation (e.g. Zipf law), including separating mutation\n and borrowing rates\n * Allow to exclude non extant taxa from horizontal gene transfer\n events\n * Add stopping criterion on the global number of nodes (in complement\n to the number of *extant* nodes, currently implemented), either absolute\n or as a range\n\n* Longer-term\n * Simulation of data problems (incomplete sampling, errors in\n sequencing/cognate judgment, etc.)\n * Variable birth/death ratios\n * Rewrite the random text generation functions, possibly as actual\n Python generators\n * Consider replacing or complementing `expovariate()` in birth/death\n events with actual random Poisson sampling, allowing additional models\n * Build a simple website\n * Implement parallel character evolution as controlled by a parameter\n * Rewrite functions with too many arguments to accept dictionaries of\n parameters\n * Implement more models for random character generation, especially those\n frm genetics (first candidate, a General Time Reversable model with\n a proportion of invariable sites and a gamma-shaped distribution of\n rates across sites)\n * Simulate a \"donation power\" for taxa, making borrowing events globally\n more likely from a given donor (analogous to cultural influence in\n linguistics)\n * Allow to guarantee that borrowing events will always result in\n altered states (it is currently possible that an event will borrow\n an equal state for a given character, especially considering that we\n favor borrowing from closer taxa)\n * Implement character simulation for other datatypes, particularly from\n genetics (currently only standard binary presence/absence)\n\n## Gallery\n\n![random tree](https://raw.githubusercontent.com/tresoldi/ngesh/master/doc/tree001.png){width=100%}\n![random tree](https://raw.githubusercontent.com/tresoldi/ngesh/master/doc/tree002.png){width=100%}\n![random tree](https://raw.githubusercontent.com/tresoldi/ngesh/master/doc/tree003.png){width=100%}\n\n## How to cite\n\nIf you use `ngesh`, please cite it as:\n\n> Tresoldi, Tiago (2019). Ngesh, a tool for simulating random phylogenetic trees.\nVersion 0.3. Jena. Available at: https://github.com/tresoldi/ngesh\n\nIn BibTeX:\n\n```\n@misc{Tresoldi2019ngesh,\n author = {Tresoldi, Tiago},\n title = {Ngesh, a tool for simulating random phylogenetic trees. Version 0.3},\n howpublished = {\\url{https://github.com/tresoldi/ngesh}},\n address = {Jena},\n year = {2019},\n doi = {10.5281/zenodo.2619311},\n}\n```\n\n## References\n\n* Bailey, N. T. J. (1964). *The elements of stochastic processes with applications to the natural sciences*. John Wiley & Sons.\n\n* Foote, M., J. P. Hunter, C. M. Janis, and J. J. Sepkoski Jr. (1999). *Evolutionary and preservational constraints on origins of biologic groups: Divergence times of eutherian mammals*. Science 283:1310\u20131314.\n\n* Harmon, Luke J (2019). *Phylogenetic Comparative Methods -- learning from trees*.\nAvailable at: [https://lukejharmon.github.io/pcm/chapter10_birthdeath/](https://lukejharmon.github.io/pcm/chapter10_birthdeath/). Access date: 2019-03-31.\n\n* Noutahi, Marc-Rolland (2017). *How to simulate a phylogenetic tree? (part 1)*. Available at:\n[https://mrnoutahi.com/2017/12/05/How-to-simulate-a-tree/](https://mrnoutahi.com/2017/12/05/How-to-simulate-a-tree/). Access date: 2019-03-31\n\n* Stadler, Tanja (2011). *Simulating Trees with a Fixed Number of Extant Species*. Systematic Biology 60.5:676-684. DOI: [https://doi.org/10.1093/sysbio/syr029](https://doi.org/10.1093/sysbio/syr029)\n\n## Author\n\nTiago Tresoldi (tresoldi@shh.mpg.de)\n\nThe author was supported during development by the \n[ERC Grant #715618](https://cordis.europa.eu/project/rcn/206320/factsheet/en)\nfor the project [CALC](http://calc.digling.org)\n(Computer-Assisted Language Comparison: Reconciling Computational and Classical\nApproaches in Historical Linguistics), led by\n[Johann-Mattis List](http://www.lingulist.de).\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://github.com/tresoldi/ngesh", "keywords": "random phylogenetic tree,phylogenetics", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "ngesh", "package_url": "https://pypi.org/project/ngesh/", "platform": "", "project_url": "https://pypi.org/project/ngesh/", "project_urls": { "Homepage": "https://github.com/tresoldi/ngesh" }, "release_url": "https://pypi.org/project/ngesh/0.3/", "requires_dist": [ "abzu", "ete3", "numpy", "six" ], "requires_python": "", "summary": "Simulate random phylogenetic trees", "version": "0.3" }, "last_serial": 5994545, "releases": { "0.1.1": [ { "comment_text": "", "digests": { "md5": "a992b0eeb05fa35fb26cec07c77e141c", "sha256": "a541dea51fff29fe78cdf8937984802caa6061a60c4c8543cb3655a6949e985c" }, "downloads": -1, "filename": "ngesh-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "a992b0eeb05fa35fb26cec07c77e141c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 14804, "upload_time": "2019-03-31T09:59:43", "url": "https://files.pythonhosted.org/packages/bf/a4/18a8c49022a8bbaf9fdfe95e0b89b3d3d94d42b0464477ce1c51226b65e1/ngesh-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "92c5caa842b0d452e35095801dba10f4", "sha256": "0fa2a0a0427a418f87a74d6b6fa227ed9e084bc8aa083885d918f0416b2e4042" }, "downloads": -1, "filename": "ngesh-0.1.1.tar.gz", "has_sig": false, "md5_digest": "92c5caa842b0d452e35095801dba10f4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17112, "upload_time": "2019-03-31T09:59:45", "url": "https://files.pythonhosted.org/packages/ee/33/62aa5b886febd402a79135c7f7f04224473a068df67ae15aaaf82aeec8e8/ngesh-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "0084f6e8973419624e933af4da9980dd", "sha256": "0a758b2242b74261100eb1dfa4cd5ff121b9fadcd6e6954be735eb759d809e4a" }, "downloads": -1, "filename": "ngesh-0.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "0084f6e8973419624e933af4da9980dd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 14948, "upload_time": "2019-03-31T10:24:31", "url": "https://files.pythonhosted.org/packages/77/d9/b61c274a8a7e10775d9f452af27fb3df783f7f188f69e049fa5598064321/ngesh-0.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e72c9fa7fbfb0bbbfa202f4f9cb63bd5", "sha256": "765872bf59e7e8409d95425fe613dcb24b1f300dde8f8649deb437045309b7bf" }, "downloads": -1, "filename": "ngesh-0.1.2.tar.gz", "has_sig": false, "md5_digest": "e72c9fa7fbfb0bbbfa202f4f9cb63bd5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17392, "upload_time": "2019-03-31T10:24:33", "url": "https://files.pythonhosted.org/packages/3e/33/49ed2463117d6f430a5a221d55ec79b8c65847cefafc8300bf6bf3ee5bd6/ngesh-0.1.2.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "6c8b86c8de6c4e2e3e1b41acaa67b917", "sha256": "2e508842013055899420f59dd1eeccb5b8f94b3d33c75479e7c99a07e3762522" }, "downloads": -1, "filename": "ngesh-0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "6c8b86c8de6c4e2e3e1b41acaa67b917", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22553, "upload_time": "2019-04-16T17:27:27", "url": "https://files.pythonhosted.org/packages/3a/ce/99fce094d3202a4934c39f538a9e3f3d749399f75d03a0e77bcb0bf51cc3/ngesh-0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "de9467284024cb1f5658daa647b36767", "sha256": "15d21c3b6a76880f3376e2017ecae5919fdb5121388ec16896059fec153cf648" }, "downloads": -1, "filename": "ngesh-0.2.tar.gz", "has_sig": false, "md5_digest": "de9467284024cb1f5658daa647b36767", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29691, "upload_time": "2019-04-16T17:27:29", "url": "https://files.pythonhosted.org/packages/26/5d/e6d3c15e65cf339bb494236f16a924bb52ee2fbcc3b6d1027444edb59c3a/ngesh-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "4c9d6792d43ec33956b53d8794f8b01f", "sha256": "5d8762888a4d17621baef897ab8ecd34d4bf7154bc96586be221372b53a236d3" }, "downloads": -1, "filename": "ngesh-0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "4c9d6792d43ec33956b53d8794f8b01f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 23130, "upload_time": "2019-10-18T09:07:43", "url": "https://files.pythonhosted.org/packages/a5/5e/b8fe42e90a8fe2ee5158446dfa2f671eb06f56fdcc63144f82af548112f7/ngesh-0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "815ae933148d6ad1aec14e2083a86765", "sha256": "2ed3b8ecd1b7a65a2c28ce6fbc7a8e9057222fd9dace395e6c744f54a7e9579a" }, "downloads": -1, "filename": "ngesh-0.3.tar.gz", "has_sig": false, "md5_digest": "815ae933148d6ad1aec14e2083a86765", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28169, "upload_time": "2019-10-18T09:07:46", "url": "https://files.pythonhosted.org/packages/b7/e9/005e0a317246f6ce2dec1759d75a25d47c077322231c3340f4bf611b246b/ngesh-0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4c9d6792d43ec33956b53d8794f8b01f", "sha256": "5d8762888a4d17621baef897ab8ecd34d4bf7154bc96586be221372b53a236d3" }, "downloads": -1, "filename": "ngesh-0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "4c9d6792d43ec33956b53d8794f8b01f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 23130, "upload_time": "2019-10-18T09:07:43", "url": "https://files.pythonhosted.org/packages/a5/5e/b8fe42e90a8fe2ee5158446dfa2f671eb06f56fdcc63144f82af548112f7/ngesh-0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "815ae933148d6ad1aec14e2083a86765", "sha256": "2ed3b8ecd1b7a65a2c28ce6fbc7a8e9057222fd9dace395e6c744f54a7e9579a" }, "downloads": -1, "filename": "ngesh-0.3.tar.gz", "has_sig": false, "md5_digest": "815ae933148d6ad1aec14e2083a86765", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28169, "upload_time": "2019-10-18T09:07:46", "url": "https://files.pythonhosted.org/packages/b7/e9/005e0a317246f6ce2dec1759d75a25d47c077322231c3340f4bf611b246b/ngesh-0.3.tar.gz" } ] }