{ "info": { "author": "Richard Campen", "author_email": "richard@campen.co", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: End Users/Desktop", "Intended Audience :: Science/Research", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering :: Bio-Informatics" ], "description": "mothur-py\r\n=========\r\n\r\nCopyright \u00a9 2018, Richard Campen. All rights reserved.\r\n\r\nSee LICENSE.txt for full license conditions.\r\n\r\n--------------\r\n\r\nDescription\r\n~~~~~~~~~~~\r\n\r\nA python wrapper for the command line version of the bioinformatics tool\r\n`mothur `__.\r\n\r\nSee the change log at the end of this ReadMe for a full list of changes.\r\n\r\nMothur-py was inspired by the\r\n`ipython-mothurmagic `__\r\nmodule, but with an intention to provide a more general python wrapper\r\nthat would work outside of the IPython/Jupyter notebook environment, as\r\nwell as provide support for mothur's ``current`` keyword functionality.\r\n\r\n**Note:** This module has only been tested with mothur v1.39.5 and\r\npython 3. It should in theory work with older versions of mothur, but\r\nthe older the version the less likely as this module relies upon some of\r\nthe more recent mothur commands/output to function properly.\r\n\r\n--------------\r\n\r\nInstallation\r\n~~~~~~~~~~~~\r\n\r\nTo install the latest release version you can just\r\n``pip install mothur-py``. To install the most up to date code you\r\nshould download/clone this repository and create a binary distribution\r\nusing ``python setup.py bdist_wheel`` that will create a .whl file in\r\nthe ``dist`` folder. You can then install mothur-py with pip from the\r\n.whl file using ``pip install ``. The advantage of this\r\nmethod over just running ``python setup.py install`` is that you can\r\neasily remove or update the package via pip.\r\n\r\n--------------\r\n\r\nBasic Usage\r\n~~~~~~~~~~~\r\n\r\n**NOTE:** mothur-py expects mothur to be installed in the users PATH\r\nenvironment variable. If this is not the case you will need to tell it\r\nwhere to find the mothur executable. See the configuration section of\r\nthe README for details.\r\n\r\nUse of this module revolves around the ``Mothur`` class that catches\r\nmethod calls and passes them off to mothur to be run as commands. An\r\ninstance of the ``Mothur`` class needs to be created before running any\r\ncommands:\r\n\r\n::\r\n\r\n # create instance of Mothur class\r\n from mothur_py import Mothur\r\n m = Mothur()\r\n\r\nCommands in mothur can then be executed as methods of the ``Mothur``\r\nclass instance using the same names you would use within the command\r\nline version of mothur:\r\n\r\n::\r\n\r\n # run the mothur help command\r\n m.help()\r\n\r\nCommand parameters can either be passed as python native types (i.e.\r\nstrings, integers, floats, booleans, lists) *or* as strings that match\r\nthe format that mothur would expect:\r\n\r\n::\r\n\r\n # running make contigs using str input for file parameter, and int for processor paramenter\r\n m.make.contigs(file='basic_usage.files', processors=2)\r\n\r\n # running summary.single, passing calculators as mothur formatted list\r\n m.summary.single(shared='basic_usage.shared', calc='nseqs-sobs-coverage-shannon-simpson')\r\n\r\n # running summary.single, passing calculators as python list also works\r\n m.summary.single(shared='basic_usage.shared', calc=['nseqs', 'sobs', 'coverage', 'shannon', 'simpson'])\r\n\r\nThe ``Mothur`` object saves a record of the current directories and\r\nfiles and the output files from mothur after executing each command.\r\nThese are stored as dictionary attributes of the ``Mothur`` object:\r\n\r\n::\r\n\r\n # run a command\r\n m.summary.seqs(fasta='basic_usage.fasta')\r\n\r\n # display current mothur files\r\n print(m.current_files)\r\n\r\n # read in the output file from summary.seqs()\r\n with open(m.output_files['summary'][0], 'r') as in_handle:\r\n in_handle.read()\r\n\r\n**NOTE:** Due to the possibility of multiple output files with the same\r\nextension the output files are saved as lists within the attribute\r\ndictionaries with the file extension as the key. This issue does not\r\noccur for current files and dirs so they are stored as the actual\r\nvalues, not as lists of the values, with the key being the type of file\r\naccording to mothur (usually the same as the file extension).\r\n\r\n**NOTE:** Each successive execution of a mothur command will update the\r\ncurrent files and dirs, but will completely overwrite the saved output\r\nfiles. This is so that you have access to the current files generated\r\nmore than one command ago, but do not get access to output from more\r\nthan one command ago, which would be confusing.\r\n\r\nThere is also implementation of the ``current`` keyword used in the\r\ncommand line version of mothur:\r\n\r\n::\r\n\r\n # run the mothur summary.seqs command using the 'current' option\r\n # NOTE: current is being passed as a string\r\n m.summary.seqs(fasta='current')\r\n \r\n # like the command line version, you don't even need to specify \r\n # the 'current' keyword for some commands\r\n m.summary.seqs() \r\n\r\nBehind the scenes, the ``current`` keyword is enabled by appending the\r\nusers command with the ``get.current()`` command to list the current\r\ndirectories and files being used by mothur, parsing of the output to\r\nextract this information, and prepending future commands with\r\n``set.dir()`` and ``set.current()`` to tell mothur what these should be.\r\nThis is necessary as each call to mothur is executed as a separate\r\nmothur session and therefore mothur can not store this information\r\nitself.\r\n\r\n--------------\r\n\r\nConfiguration\r\n~~~~~~~~~~~~~\r\n\r\nThe ``Mothur`` class stores configuration options for how mothur is\r\nexecuted. These options include ``mothur_path`` to tell mothur-py where\r\nto find the mothur executable, ``verbosity`` to control how much output\r\nthere is, ``mothur_seed`` to control the seed used by mothur for random\r\nnumber generation, ``logfile_name`` to set the name of the mothur\r\nlogfile, ``suppress_logfile`` which suppresses the creation of the\r\nmothur logfile, and ``line_limit`` which sets the limit on how many\r\nlines of stdout will be printed.\r\n\r\nThe default for ``mothur_path`` is ``mothur`` which will only work if\r\nmothur is in your PATH environment variable. If it is not then you will\r\nneed to specify where to find the mothur executable, including the name\r\nof the executable itself:\r\n\r\n::\r\n\r\n # configure mothur with executable in current directory on Windows\r\n m = Mothur(mothur_path='mothur.exe')\r\n\r\n # configure mothur with executable in current directory on Linux\r\n m = Mothur(mothur_path='./mothur')\r\n\r\n # configure mothur with executable in alternate directory on Windows\r\n m = Mothur(mothur_path='\\\\path\\\\to\\\\mothur.exe')\r\n\r\nFailure to correctly configure the ``mothur_path`` will usually result\r\nin a PermissionError:\r\n\r\n::\r\n\r\n m = Mothur(mothur_path='/not/a/real/path/to/mothur')\r\n Traceback (most recent call last):\r\n File \"\", line 1, in \r\n File \".../mothur_py/core.py\", line 199, in __call__\r\n p = Popen([self.root_object.mothur_path, '#%s' % commands_str], stdout=PIPE, stderr=STDOUT)\r\n File \"/usr/lib/python3.5/subprocess.py\", line 947, in __init__\r\n restore_signals, start_new_session)\r\n File \"/usr/lib/python3.5/subprocess.py\", line 1551, in _execute_child\r\n raise child_exception_type(errno_num, err_msg)\r\n PermissionError: [Errno 13] Permission denied\r\n\r\nWhen ``verbosity`` is set to ``0`` (default) there is no output printed,\r\n``1`` prints the normal output as would be seen with command line\r\nexecution (minus the header that contains the mothur version and runtime\r\ninformation), and ``2`` displays all output including the commands being\r\nexecuted behind the scenes to enable the ``current`` keyword to work.\r\nThe default option is ``0``, with ``1`` being useful when you want to\r\nsee the standard mothur output, and ``2`` being useful for debugging\r\npurposes.\r\n\r\nIf ``mothur_seed`` is set to a valid integer then this number will be\r\npassed to mothur to be used for random number generation. This is\r\nimplemented by adding the ``seed=`` named parameter to\r\neach mothur command. By default no seed is set (``mothur_seed=None``).\r\nNot all commands will accept having a seed set. For these commands you\r\nmay need to set the ``mothur_seed`` parameter to ``None`` for the\r\nexecution of that command, e.g.:\r\n\r\n::\r\n\r\n m = Mothur(mothur_seed=12345)\r\n\r\n # summary.seqs() allows setting the seed so this will run fine\r\n m.summary.seqs(fasta='current')\r\n\r\n # help() does not accept having the seed set so need to alter that value temporarily, otherwise an error will occur\r\n seed = m.mothur_seed\r\n m.mothur_seed = None\r\n m.help()\r\n m.mothur_seed = seed\r\n\r\nThe ``logfile_name`` option allows the user to specify the name of the\r\nmothur generated logfile. The logfile will store the output from all\r\nmothur commands executed for the Mothur object it is configured for.\r\nWhen set to ``None`` (default) a random logfile name is generated for\r\nthe mothur object in the format\r\n``mothur.py..logfile``.\r\n\r\n**Note:** When copying mothur objects it is important to then specify\r\ndifferent logfiles for them otherwise they may attempt to use the same\r\nlogfile. Additionally, if ``suppress_logfile`` is true, the logfile will\r\nbe suppressed even if it has been given a name by the user.\r\n\r\nThe ``supress_logfile`` option is useful when you don't want the log\r\nfiles, such as when running in an Jupyter (nee IPython) notebook with\r\n``verbosity=1``, in which case you already have a record of mothur's\r\noutput and the mothur logfiles are superfluous. Default setting is\r\n``False``.\r\n\r\n**Note:** Currently, due to the way that mothur creates the logfiles, a\r\nlogfile will always be created BUT it will be cleaned up upon successful\r\nexecution if ``suppress_logfile=True``. However, if mothur fails to\r\nsuccessfully execute, i.e. execution hangs or is interrupted, the\r\nlogfile will not be cleaned up. For relevant discussion of this\r\nbehaviour in mothur see\r\n`here `__ and\r\n`here `__.\r\n\r\nThe ``line_limit`` option is useful when the full stdout is not wanted,\r\nor when printing it will be problematic, such as when stdout is\r\nexcessive and causes memory issues in the Jupyter (nee IPython) notebook\r\nenvironment. Setting ``line_limit`` to ``-1`` (default) imposes no line\r\nlimit, while any positive integer (or zero) imposes a line limit that\r\ncauses stdout to no longer be printed once the limit is reaches. If the\r\nline limit is reached then a warning is printed to notify the user.\r\n\r\n**Note:** Only lines related to the user specified command count towards\r\nthe line limit, therefore commands running in the background (viewable\r\nwith verbosity == 2) do not count towards this limit. Additionally, when\r\nverbosity == 2 the additional commands that enable the ``current``\r\nkeyword functionality that are executed after the users command are\r\nstill displayed, even if the line limit has been reached. Setting a line\r\nlimit does not change what is printed to the logfile.\r\n\r\nYou can also instantiate the ``Mothur`` object with your desired\r\nconfiguration options.\r\n\r\n::\r\n\r\n m = Mothur(verbosity=1, mothur_seed=543210, suppress_logfile=True, line_limit=1000)\r\n\r\n--------------\r\n\r\nAdvanced Usage\r\n~~~~~~~~~~~~~~\r\n\r\nThe current files and current directories for use in mothur are stored\r\nin dictionary attributes of the ``Mothur`` instance, ``current_files``\r\nand ``current_dirs`` respectively. These values can be passed to mothur\r\ncommands, e.g:\r\n\r\n::\r\n\r\n # passing current fasta file to summary.seqs()\r\n m.summary.seqs(fasta=m.current_files['fasta'])\r\n \r\n\r\nThe ``current`` keyword is actually just a shortcut for this\r\nfunctionality so it will always be easier to just pass ``'current'``.\r\nHowever, this demonstrates that the parameters of the mothur commands\r\ncan accept any variable as long as it will resolve to something that\r\nmothur accepts. In the above example, the dictionary value resolves to a\r\nstring that is the path to the ``.fasta`` file. As a better example of\r\npassing python variables as mothur command parameters, you could perform\r\nclassification of sequences at multiple defined cutoffs as follows:\r\n\r\n::\r\n\r\n from copy import deepcopy\r\n\r\n # init results container\r\n mothur_objs = dict()\r\n\r\n # iterate over list off possible cutoff values\r\n for cutoff in [70, 80, 90]:\r\n\r\n # make a copy of the original mothur object so we do not make unwanted modifications to the original\r\n m_copy = deepcopy(m)\r\n \r\n # save outputs to different folders, but keep input the same\r\n output_dir = 'cutoff_%s' % cutoff\r\n m_copy.set.dir(output=output_dir, input='.')\r\n m_copy.classify.seqs(fasta='current', count='current', reference='reference.fasta', taxonomy='referenece.tax',\r\n cutoff=cutoff)\r\n \r\n # save to results container\r\n mothur_objs[cutoff] = m_copy\r\n \r\n\r\nThis may be a convoluted example, but it demonstrates the functionality\r\nwell. One note of caution with this approach is that depending on the\r\nmothur command and the parameter you are changing, you may be\r\noverwriting your output files as you go. This is the reason for saving\r\neach output to a different folder in the above example. We also create\r\nmultiple copies of the original mothur object and use those for the\r\ncommand instead so we can continue to use the ``current`` keyword\r\ndownstream and have it refer to the correct files:\r\n\r\n::\r\n\r\n # using the results container from above\r\n for m_ in mothur_objs.values():\r\n \r\n # run remove.lineage() on each mothur object created previously to remove unwanted taxa\r\n # because we saved each classify.seqs command to a different mothur object we can safely use the 'current'\r\n # keyword here and know that it refers to the correct file\r\n m_.remove.lineage(fasta='current', count='current', taxonomy='current, taxon='unknown')\r\n\r\nYou can also instantiate a ``Mothur`` instance with predefined current\r\nfile and directory dictionaries:\r\n\r\n::\r\n\r\n m = Mothur(current_files=my_predefined_files_dict, current_dirs=my_predefined_files_dict)\r\n\r\nThis can be convenient for saving and loading the state of a mothur\r\nobject to/from file as such:\r\n\r\n::\r\n\r\n import json\r\n\r\n # save state of mothur object, m, to json file\r\n with open('mothur_object.json', 'w') as out_handle:\r\n json.dump(vars(m), out_handle)\r\n\r\n # can reload mothur object from the json file\r\n with open('mothur_object.json', 'r') as in_handle:\r\n m = Mothur(**json.load(in_handle))\r\n\r\n--------------\r\n\r\nChange Log\r\n~~~~~~~~~~\r\n\r\n*v0.4.0*\r\n^^^^^^^^\r\n\r\nNew features: \\* Added a line limit configuration option to limit the\r\namount of stdout printed to screen. Helps with potential memory issues\r\nwhen outputting in Jupyter (nee IPython) notebook\r\n\r\nBig fixes: \\* Current files/dirs and output are now only set after\r\nsuccessful execution to prevent them being changed when mothur errors\r\n\r\nChanges: \\* Added lines of text specifying transition from user input\r\nfunctions from background functions enabling the current keyword\r\nfunctionality when verbosity == 2 \\* For verbosity == 1, now does not\r\nprint redundant warning/error text at the end of stdout \\* Split utility\r\nfunctions out into their own file (``mothur_py.utils``) \\* Refined\r\n``__str__`` and ``__repr__`` for Mothur and MothurCommand\r\n\r\n*v0.3.1*\r\n^^^^^^^^\r\n\r\nNew features: \\* Allow setting the name of the mothur logfile via\r\nconfiguration of the Mothur object\r\n\r\nBug fixes: \\* Changed strings to match to detect errors and warnings\r\nfrom mothur in stdout \\* Now check both top level and output directories\r\nwhen removing logfile\r\n\r\n*v0.3.0*\r\n^^^^^^^^\r\n\r\nChanges: \\* The ``output_files`` attribute now stores the full file path\r\nfor each output file, rather than just the file name as was done\r\npreviously.\r\n\r\n*v0.2.5*\r\n^^^^^^^^\r\n\r\nNew features: \\* Added configuration option for path to the mothur\r\nexecutable, thereby adding support for any mothur executable location\r\n(previously mothur had to be in users PATH environment variable).\r\n\r\n*v0.2.4*\r\n^^^^^^^^\r\n\r\nNew features: \\* Enabled passing python native types as command\r\nparameters, which are then converted to mothur compatible types as\r\nneeded \\* Added parsing and saving of the output files generated by the\r\nlast run mothur command \\* Improved documentation and examples\r\n\r\n*v0.2.3*\r\n^^^^^^^^\r\n\r\nBug fixes: \\* Fixed current files not being saved correctly to the\r\nmothur obejct after execution\r\n\r\n*v0.2.2*\r\n^^^^^^^^\r\n\r\nChanges: \\* No longer return the mothur object. If it is desired to\r\nstore the altered object as a copy then the deepcopy function in the\r\ncopy package should be used\r\n\r\nBug fixes: \\* Fixed verbosity level affecting the parsing of current\r\nfiles/dirs from stdout \\* Only update the current files/dirs for the\r\nmothur object once execution of mothur ends successfully \\* Fixed calls\r\nto unimplemented dunder methods (i.e. **deepcopy**) being parsed as\r\nmothur commands\r\n\r\nNew features: \\* Can set the seed that mothur uses for its random number\r\ngeneration \\* Added more unittests\r\n\r\n*v0.2.1*\r\n^^^^^^^^\r\n\r\nBug fixes: \\* Fixed bug where python failed to raise an error if mothur\r\ndid\r\n\r\nNew features: \\* Use of an invalid command now raises an error in\r\npython, halting execution. Previously this would fail silently.\r\n\r\n*v0.2.0*\r\n^^^^^^^^\r\n\r\nChanges: \\* Renamed project from Rhea to mothur\\_py to avoid confusion\r\nwith the R package for 16S amplicon analysis. Mothur class now needs to\r\nbe imported from mothur\\_py instead.\r\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/campenr/mothur-py", "keywords": "mothur bioinformatics", "license": "Modified BSD License", "maintainer": "", "maintainer_email": "", "name": "mothur-py", "package_url": "https://pypi.org/project/mothur-py/", "platform": "", "project_url": "https://pypi.org/project/mothur-py/", "project_urls": { "Homepage": "https://github.com/campenr/mothur-py" }, "release_url": "https://pypi.org/project/mothur-py/0.4.0/", "requires_dist": null, "requires_python": "", "summary": "Python wrapper for the bioinformatics tool mothur", "version": "0.4.0" }, "last_serial": 3670659, "releases": { "0.2.0": [ { "comment_text": "", "digests": { "md5": "2b173f07a1b27b015842e81e81ed9177", "sha256": "70831e06b6c23011de4aae702d4dc73488a47aa576818c2d0eeee4a0e7125d4c" }, "downloads": -1, "filename": "mothur_py-0.2.0.tar.gz", "has_sig": false, "md5_digest": "2b173f07a1b27b015842e81e81ed9177", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19849, "upload_time": "2017-10-02T13:50:26", "url": "https://files.pythonhosted.org/packages/1f/e5/b34621cccac74f6d4d6f095b4bf92d7741b994e930cf4c30d3a88e81ef2e/mothur_py-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "3825897fa134abfc9c483c8e866bad5b", "sha256": "ec832bc8ecdc0e97a2f817106f7fc31e209234096b3cea68db8e2e1d7924e405" }, "downloads": -1, "filename": "mothur_py-0.2.1.tar.gz", "has_sig": false, "md5_digest": "3825897fa134abfc9c483c8e866bad5b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19985, "upload_time": "2017-10-06T01:37:27", "url": "https://files.pythonhosted.org/packages/92/1a/e1ac79d965667e4947542a5c7f01b4d8393abb10d0399e3ab40c779b4bef/mothur_py-0.2.1.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "68ea850cce29e43c993c90edfe285e0e", "sha256": "9d597c3a33b8e72333b52dc71b5b87d5843bdf17a641ba4949da921e6a8b786c" }, "downloads": -1, "filename": "mothur_py-0.2.3.tar.gz", "has_sig": false, "md5_digest": "68ea850cce29e43c993c90edfe285e0e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20388, "upload_time": "2017-10-20T11:36:45", "url": "https://files.pythonhosted.org/packages/34/ed/1f25a5eb4917d5d01880e7d464394f05c919d356cc7fcebf184dcb30dff6/mothur_py-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "897a3bbd93bfb127ca5693d498587e26", "sha256": "ed9f23252da05de88f235e687c689c92782c012007dff9113dc38b1493d6d49a" }, "downloads": -1, "filename": "mothur_py-0.2.4.tar.gz", "has_sig": false, "md5_digest": "897a3bbd93bfb127ca5693d498587e26", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22498, "upload_time": "2017-11-02T00:03:51", "url": "https://files.pythonhosted.org/packages/0d/38/29cb88993b616d5c2dbd3d0b1717d3efe73e12a6f2b81df670ffbaf90ca1/mothur_py-0.2.4.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "f98800210f5a3cb3af346fc401763a60", "sha256": "8d2036c095ee26c0ceec0e375c3a7ffc354a631a3f7b15e6e92ab19a7e585409" }, "downloads": -1, "filename": "mothur_py-0.2.5.tar.gz", "has_sig": false, "md5_digest": "f98800210f5a3cb3af346fc401763a60", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23557, "upload_time": "2017-11-09T13:37:45", "url": "https://files.pythonhosted.org/packages/1b/11/f39dd4dd3deb53497e126819bb3274d9e91d0c5fc46ab03000810cee795e/mothur_py-0.2.5.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "221bc3cacc196ebc8787058d967c79c8", "sha256": "3ca3c46f6691a4f84fd6c6a05908171d1aa3429723c8b17e70d80db8efd94501" }, "downloads": -1, "filename": "mothur_py-0.3.0.tar.gz", "has_sig": false, "md5_digest": "221bc3cacc196ebc8787058d967c79c8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24333, "upload_time": "2017-12-10T18:51:28", "url": "https://files.pythonhosted.org/packages/97/f6/700e9b7e43435bf494dde4328235b05591aa370bccbf9b14c7f6131773e1/mothur_py-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "c75234cc112383ae78e3eea7acb9c83f", "sha256": "ef9bbd740bc7a201d0f3f41ab13df8a0e870cfc460cc8e16476aa52a90e23d5e" }, "downloads": -1, "filename": "mothur_py-0.3.1.tar.gz", "has_sig": false, "md5_digest": "c75234cc112383ae78e3eea7acb9c83f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25140, "upload_time": "2018-02-02T22:45:03", "url": "https://files.pythonhosted.org/packages/1b/d3/74a3c23de0e56c2850c5802bc4513f0be9fe1c3c0f0f0f1179715842a43a/mothur_py-0.3.1.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "4bd6947735aa19a87a87d857be26d8a3", "sha256": "c6a41219fe3d995395ac03f69b748c7205dbafc6301e6472f13e53dfd40d5f98" }, "downloads": -1, "filename": "mothur_py-0.4.0.tar.gz", "has_sig": false, "md5_digest": "4bd6947735aa19a87a87d857be26d8a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26722, "upload_time": "2018-03-14T22:41:41", "url": "https://files.pythonhosted.org/packages/0b/9a/769363e46d01b8f45498a0a85c0f1ec59bf7a7618dbcc03cbb9181d76b10/mothur_py-0.4.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4bd6947735aa19a87a87d857be26d8a3", "sha256": "c6a41219fe3d995395ac03f69b748c7205dbafc6301e6472f13e53dfd40d5f98" }, "downloads": -1, "filename": "mothur_py-0.4.0.tar.gz", "has_sig": false, "md5_digest": "4bd6947735aa19a87a87d857be26d8a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26722, "upload_time": "2018-03-14T22:41:41", "url": "https://files.pythonhosted.org/packages/0b/9a/769363e46d01b8f45498a0a85c0f1ec59bf7a7618dbcc03cbb9181d76b10/mothur_py-0.4.0.tar.gz" } ] }