{ "info": { "author": "mpkocher natechols", "author_email": "mkocher@pacificbiosciences.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Topic :: Software Development :: Bug Tracking" ], "description": "pbcommand High Level Overview\n=============================\n\nco-owners:\n\n[mpkocher](https://github.com/mpkocher)\n\n[natechols](https://github.com/natechols)\n\nPacBio Officially Supported Library. Note the APIs are still in flux and not yet 1.0.0.\n\n[Full Docs](http://pbcommand.readthedocs.org/en/latest/)\n\n[![Circle CI](https://circleci.com/gh/PacificBiosciences/pbcommand.svg?style=svg)](https://circleci.com/gh/PacificBiosciences/pbcommand)\n\nPacBio library for common utils, models, and tools to interface with pbsmrtpipe workflow engine.\n\nTo integrate with the pbsmrtpipe workflow engine you must to be able to generate a **Tool Contract** and to be able to run from a **Resolved Tool Contract**.\n\nA **Tool Contract** contains the metadata of the exe, such as the file types of inputs, outputs and options.\n\nExample [Tool Contract Json](https://github.com/PacificBiosciences/pbcommand/blob/master/tests/data/dev_example_dev_txt_app_tool_contract.json) (and [Avro Schema](https://github.com/PacificBiosciences/pbcommand/blob/master/pbcommand/schemas/tool_contract.avsc))\n\nExample [Resolved Tool Contract Json](https://github.com/PacificBiosciences/pbcommand/blob/master/tests/data/resolved_tool_contract_dev_app.json) (and [Avro Schema](https://github.com/PacificBiosciences/pbcommand/blob/master/pbcommand/schemas/resolved_tool_contract.avsc))\n\nThere are two principle use cases, first wrapping/calling python functions that have been defined in external python packages, or scripts. Second, creating a CLI tool that supports emitting tool contracts, running resolved tool contracts and complete argparse style CLI.\n\nExample from **pbcommand.cli.examples**\n\n```python\n\nimport sys\nimport logging\n\nfrom pbcommand.models import FileTypes\nfrom pbcommand.cli import registry_builder, registry_runner\n\nlog = logging.getLogger(__name__)\n\nregistry = registry_builder(\"pbcommand\", \"python -m pbcommand.cli.examples.dev_quick_hello_world \")\n\n\ndef _example_main(input_files, output_files, **kwargs):\n # Simple Function that should imported from your library code\n # write mock output files for testing purposes, otherwise the End-to-End test will fail\n xs = output_files if isinstance(output_files, (list, tuple)) else [output_files]\n for x in xs:\n with open(x, 'w') as writer:\n writer.write(\"Mock data\\n\")\n return 0\n\n\n@registry(\"dev_qhello_world\", \"0.2.1\", FileTypes.FASTA, FileTypes.FASTA, nproc=1, options=dict(alpha=1234))\ndef run_rtc(rtc):\n return _example_main(rtc.task.input_files[0], rtc.task.output_files[0], nproc=rtc.task.nproc)\n\n\n@registry(\"dev_fastq2fasta\", \"0.1.0\", FileTypes.FASTQ, FileTypes.FASTA)\ndef run_rtc(rtc):\n return _example_main(rtc.task.input_files[0], rtc.task.output_files[0])\n\n\nif __name__ == '__main__':\n sys.exit(registry_runner(registry, sys.argv[1:]))\n\n```\n\nA driver is the commandline interface that the workflow engine will call.\n\nThe driver will be called with \"${exe} /path/to/resolved_tool_contract.json\"\n\nThe tool contracts can be emitted to a directory and used in [pbsmrtpipe](https://github.com/PacificBiosciences/pbsmrtpipe).\n\n```bash\n$> python -m pbcommand.cli.examples.dev_quick_hello_world -o /path/to/my-tool-contracts\n```\n\n\nCreating a Full Commandline Tool with TC/RTC and argparse support\n-----------------------------------------------------------------\n\nThree Steps\n- define Parser\n- add running from argparse and running from Resolved ToolContract funcs to call your main\n- add call to driver\n\nImport or define your main function.\n\n```python\ndef run_my_main(fasta_in, fasta_out, min_length):\n # do stuff. Main should return an int exit code\n return 0\n```\n\nDefine a function that will add inputs, outputs and options to your parser.\n\n```python\nfrom pbcommand.models import FileTypes\n\n\ndef add_args_and_options(p):\n # FileType, label, name, description\n p.add_input_file_type(FileTypes.FASTA, \"fasta_in\", \"Fasta File\", \"PacBio Spec'ed fasta file\")\n # File Type, label, name, description, default file name\n p.add_output_file_type(FileTypes.FASTA, \"fasta_out\", \"Filtered Fasta file\", \"Filtered Fasta file\", \"filter.fasta\")\n # Option id, label, default value, name, description\n # for the argparse, the read-length will be translated to --read-length and (accessible via args.read_length)\n p.add_int(\"pbcommand.task_options.dev_read_length\", \"read-length\", 25, \"Length filter\", \"Min Sequence Length filter\")\n return p\n```\n\nDefine Parser\n\n```python\nfrom pbcommand.models import TaskTypes, SymbolTypes, get_pbparser\n\n\ndef get_contract_parser():\n tool_id = \"example_namespace.tasks.my_id\"\n version = \"0.1.0\" # or reuse __version__\n display_name = \"My Example Tool\"\n # Number of processors to use, can also be SymbolTypes.MAX_NPROC\n nproc = 1\n # Log file, tmp dir, tmp file. See ResourceTypes in models, ResourceTypes.TMP_DIR\n resource_types = ()\n # Commandline exe to call \"{exe}\" /path/to/resolved-tool-contract.json\n driver_exe = \"python -m pbcommand.cli.example.dev_app --resolved-tool-contract \"\n desc = \"Dev app for Testing that supports emitting tool contracts\"\n is_distributed = False \n # set to True if you want your task to be submitted to the cluster manager (e.g., SGE) if \n # one is provided to the workflow engine.\n p = get_pbparser(tool_id, version, display_name, desc, driver_exe, is_distributed=is_distributed, nproc=nproc, resource_types=resource_types)\n add_args_and_options(p)\n return p\n```\n \n\nDefine a Wrapping layer to call your main from both the tool contract and raw argparse IO layer\n\n```python\ndef _args_runner(args):\n # this is the args from parser.parse_args()\n # the properties of args are defined as \"labels\" in the add_args_and_options func.\n return run_my_main(args.fasta_in, args.fasta_out, args.read_length)\n\n \ndef _resolved_tool_contract_runner(resolved_tool_contract):\n \"\"\"\n :type resolved_tool_contract: pbcommand.models.ResolvedToolContract\"\"\"\n rtc = resolved_tool_contract\n # all options are referenced by globally namespaced id. This allows tools to use other tools options\n # e.g., pbalign to use blasr defined options.\n return run_my_main(rtc.task.input_files[0], rtc.task.outputs[0], rtc.task.options[\"pbcommand.task_options.dev_read_length\"])\n```\n \n \n \n \nAdd running layer\n\n```python\nimport sys\nimport logging\nfrom pbcommand.utils import setup_log\nfrom pbcommand.cli import pbparser_runner\n\nlog = logging.getLogger(__name__)\n\n\ndef main(argv=sys.argv):\n # New interface that supports running resolved tool contracts\n log.info(\"Starting {f} version {v} pbcommand example dev app\".format(f=__file__, v=\"0.1.0\"))\n return pbparser_runner(argv[1:], \n get_contract_parser(), \n _args_runner, # argparse runner func\n _resolved_tool_contract_runner, # tool contract runner func\n log, # log instance\n setup_log # setup log func\n )\nif __name__ == '__main__':\n sys.exit(main())\n```\n\nNow you can run your tool via the argparse standard interface as well as emitting a **Tool Contract** to stdout from the commandline interface.\n\n```sh\n> python -m 'pbcommand.cli.examples.dev_app' --emit-tool-contract\n```\n\nAnd you can run the tool from a **Resolved Tool Contract**\n\n```sh\n> python -m pbcommand.cli.example.dev_app --resolved-tool-contract /path/to/resolved_contract.json\n```\n\nSee the dev apps in [\"pbcommand.cli.examples\"](https://github.com/PacificBiosciences/pbcommand/blob/master/pbcommand/cli/examples/dev_app.py) for a complete application (They require pbcore to be installed).\n\nIn addition to TC/RTC support, there's a complete argparse support for the task options. An example of **help** is shown below.\n\n```sh\n(pbcommand_test)pbcommand $> python -m 'pbcommand.cli.examples.dev_app' --help\nusage: dev_app.py [-h] [-v] [--versions] [--emit-tool-contract]\n [--resolved-tool-contract RESOLVED_TOOL_CONTRACT]\n [--log-level LOG_LEVEL] [--debug]\n [--read-length READ_LENGTH]\n fasta_in fasta_out\n\nDev app for Testing that supports emitting tool contracts\n\npositional arguments:\n fasta_in PacBio Spec'ed fasta file\n fasta_out Filtered Fasta file\n\noptional arguments:\n -h, --help show this help message and exit\n -v, --version show program's version number and exit\n --versions Show versions of individual components (default: None)\n --emit-tool-contract Emit Tool Contract to stdout (default: False)\n --resolved-tool-contract RESOLVED_TOOL_CONTRACT\n Run Tool directly from a PacBio Resolved tool contract\n (default: None)\n --log-level LOG_LEVEL\n Set log level (default: 10)\n --debug Debug to stdout (default: False)\n --read-length READ_LENGTH\n Min Sequence Length filter (default: 25)\n```", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/PacificBiosciences/pbcommand/tarball/0.3.29", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/PacificBiosciences/pbcommand", "keywords": "workflow,pacbio", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "pbcommand", "package_url": "https://pypi.org/project/pbcommand/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/pbcommand/", "project_urls": { "Download": "https://github.com/PacificBiosciences/pbcommand/tarball/0.3.29", "Homepage": "https://github.com/PacificBiosciences/pbcommand" }, "release_url": "https://pypi.org/project/pbcommand/0.3.29/", "requires_dist": null, "requires_python": "", "summary": "Library and Tools for interfacing to PacBio pbsmrtpipe workflow engine.", "version": "0.3.29" }, "last_serial": 5575769, "releases": { "0.1.10": [ { "comment_text": "", "digests": { "md5": "2436554ef6b2a4205a2769d82f972c4f", "sha256": "173032b43dac66527f4d8e0afea9d086960b732af7df0e438407a6b6a904067a" }, "downloads": -1, "filename": "pbcommand-0.1.10.tar.gz", "has_sig": false, "md5_digest": "2436554ef6b2a4205a2769d82f972c4f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26696, "upload_time": "2015-07-18T21:12:20", "url": "https://files.pythonhosted.org/packages/d6/8c/38d052167a14bc4344c2853eef96a706517c1f926219ae688680940202f0/pbcommand-0.1.10.tar.gz" } ], "0.1.12": [ { "comment_text": "", "digests": { "md5": "7a5a31733eacd716dc4122947ee9d293", "sha256": "6c89c92e47f6570f1d879b46e45c4f1474766f30e1404028d2531d01db526873" }, "downloads": -1, "filename": "pbcommand-0.1.12.tar.gz", "has_sig": false, "md5_digest": "7a5a31733eacd716dc4122947ee9d293", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31354, "upload_time": "2015-07-22T00:23:26", "url": "https://files.pythonhosted.org/packages/28/51/38dca717b29d54c3dbaf02b0f05c9c747fa61d766d9e8e2b702c3ccd2415/pbcommand-0.1.12.tar.gz" } ], "0.1.14": [ { "comment_text": "", "digests": { "md5": "f0297d3956a7d76036972ad5a62e47a6", "sha256": "a322094a380a9e0f33a668318f32cc5956dc212cce8dda7198083b098739342b" }, "downloads": -1, "filename": "pbcommand-0.1.14.tar.gz", "has_sig": false, "md5_digest": "f0297d3956a7d76036972ad5a62e47a6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32198, "upload_time": "2015-07-24T02:14:31", "url": "https://files.pythonhosted.org/packages/27/22/5a651c7c25246be8c0e9db309fbbab358e9f7345797d42663e540fb17117/pbcommand-0.1.14.tar.gz" } ], "0.1.18": [ { "comment_text": "", "digests": { "md5": "fc8b5bb04cea586cc2d595653add7023", "sha256": "d7572c814192eb94d106225d5e51e7f2997a4bbb2a336c577f2aac7d761249cc" }, "downloads": -1, "filename": "pbcommand-0.1.18.tar.gz", "has_sig": false, "md5_digest": "fc8b5bb04cea586cc2d595653add7023", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 36480, "upload_time": "2015-07-28T04:30:13", "url": "https://files.pythonhosted.org/packages/15/45/8cbaa407738c2115dfbb1953e48e4cf3556e21797e188b0b65636083da92/pbcommand-0.1.18.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "2d0b45068e6a1a7382d90a6e0e82acdb", "sha256": "526e3ac30a1ae929f9e41e9dc51ae0da95d1c6352262fe636a97f9276c47640a" }, "downloads": -1, "filename": "pbcommand-0.1.4.tar.gz", "has_sig": false, "md5_digest": "2d0b45068e6a1a7382d90a6e0e82acdb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22036, "upload_time": "2015-07-10T20:14:09", "url": "https://files.pythonhosted.org/packages/4f/b7/7fbc9876458b0df745e81a0c8bb4aa9600b4e26c84d9f6a2232efce69936/pbcommand-0.1.4.tar.gz" } ], "0.1.7": [ { "comment_text": "", "digests": { "md5": "a7fa2fc8754796ec59f1e428cba405e8", "sha256": "5670639efb0eb2d86f35f7442f3cebd720f8ae4a339768b1b2fa8ca787ffcd3b" }, "downloads": -1, "filename": "pbcommand-0.1.7.tar.gz", "has_sig": false, "md5_digest": "a7fa2fc8754796ec59f1e428cba405e8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25383, "upload_time": "2015-07-16T02:50:01", "url": "https://files.pythonhosted.org/packages/4b/aa/7fc2ff30404bd589b5a2262203893bd7de87f1dc447b0cee382a83120598/pbcommand-0.1.7.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "e0684adb8aa296256d6dc1aa01a82d8d", "sha256": "20ae4e46df7ac260e43d6712408f2c1bb63efcb5ed32dc4762c802e99d372bce" }, "downloads": -1, "filename": "pbcommand-0.2.0.tar.gz", "has_sig": false, "md5_digest": "e0684adb8aa296256d6dc1aa01a82d8d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39791, "upload_time": "2015-07-30T23:21:45", "url": "https://files.pythonhosted.org/packages/08/30/bb2f15a39f2e3ce40063f6649cb2014c250fa866454c6992cd456e023e48/pbcommand-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "7e57fe05d5fe22db52e3d972944be42f", "sha256": "5e175787f6f6db8f9a63446a54fa330d1fc51fc1e1423b47a0dd599ba7ea0871" }, "downloads": -1, "filename": "pbcommand-0.2.1.tar.gz", "has_sig": false, "md5_digest": "7e57fe05d5fe22db52e3d972944be42f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40823, "upload_time": "2015-08-06T05:16:33", "url": "https://files.pythonhosted.org/packages/b6/13/8aaed2693763db4fc3cbc8b7dbe269de01f2fe021aade2a641273aed0e3d/pbcommand-0.2.1.tar.gz" } ], "0.2.16": [ { "comment_text": "", "digests": { "md5": "fb039c509153299440f0b32977d0ea2a", "sha256": "ba5c4a4068dd8922b90e3235f058bffe32a7a2ab292c6f16462b3e8dc369eff5" }, "downloads": -1, "filename": "pbcommand-0.2.16.tar.gz", "has_sig": false, "md5_digest": "fb039c509153299440f0b32977d0ea2a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 51434, "upload_time": "2015-10-05T21:09:07", "url": "https://files.pythonhosted.org/packages/bc/0d/7d08ab894ad652e5500f0a1582ed4178f3d6a10ab934bfbda45823157e52/pbcommand-0.2.16.tar.gz" } ], "0.2.17": [ { "comment_text": "", "digests": { "md5": "b546db428f74671ff0d279e023d6654f", "sha256": "4f895a84c3020bc9b93c88ef7ef729b4a3abd3ae0b2370e9cab1ca393f8249be" }, "downloads": -1, "filename": "pbcommand-0.2.17.tar.gz", "has_sig": false, "md5_digest": "b546db428f74671ff0d279e023d6654f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 51639, "upload_time": "2015-11-10T22:58:24", "url": "https://files.pythonhosted.org/packages/49/e1/58f2aa97c6692414d9069bdb365bef0ecb4a7c84ecb81746f5f4618665a3/pbcommand-0.2.17.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "25d0dcca7c4b6d7c5a403b41f206c2ba", "sha256": "147d22fd5243eed3af7590388026166f7587b6fc33288f28f1894e3c3e2e1204" }, "downloads": -1, "filename": "pbcommand-0.2.3.tar.gz", "has_sig": false, "md5_digest": "25d0dcca7c4b6d7c5a403b41f206c2ba", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43140, "upload_time": "2015-08-10T15:37:01", "url": "https://files.pythonhosted.org/packages/69/8b/61b8b0ebb3bb20203ca4ef923150d4c45e18d0ea6a5e2c4dcda9d7e5a052/pbcommand-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "43e32edea122d94923ce800156933ebb", "sha256": "12e43000f66f4dccb4d377cf7ac99baac4352f75824cb17741b5ab0f9201aa0f" }, "downloads": -1, "filename": "pbcommand-0.2.4.tar.gz", "has_sig": false, "md5_digest": "43e32edea122d94923ce800156933ebb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45350, "upload_time": "2015-08-11T20:26:28", "url": "https://files.pythonhosted.org/packages/5a/28/f70806d06790a247d4a8c52404790c6165fd4480f79b5c91896a0044352c/pbcommand-0.2.4.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "bbcb2f2c61be157d9d98595b2186d87b", "sha256": "a4470cbb9d15b28f08a5b0507c9db1dc9ed7dac11db663de1c00e38e0df6d8b6" }, "downloads": -1, "filename": "pbcommand-0.2.5.tar.gz", "has_sig": false, "md5_digest": "bbcb2f2c61be157d9d98595b2186d87b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45352, "upload_time": "2015-08-12T14:58:40", "url": "https://files.pythonhosted.org/packages/76/eb/4a322b66e58794e15fbe8f445b462901ea495395028c0378d8b3999bea3c/pbcommand-0.2.5.tar.gz" } ], "0.2.7": [ { "comment_text": "", "digests": { "md5": "c660d2b11dd73e5ba212a9e4851f4e27", "sha256": "8ee30ff2266bf90aa67de07276d54033971a859035b10988384ecc096d0a7e2e" }, "downloads": -1, "filename": "pbcommand-0.2.7.tar.gz", "has_sig": false, "md5_digest": "c660d2b11dd73e5ba212a9e4851f4e27", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45898, "upload_time": "2015-08-13T03:34:03", "url": "https://files.pythonhosted.org/packages/94/c2/b2c292a3d6ba7df66bef6bea256b77fc00e58baeb8a4910698ec0a7bef26/pbcommand-0.2.7.tar.gz" } ], "0.2.8": [ { "comment_text": "", "digests": { "md5": "1966cde728689a70d6a93aff9d44013d", "sha256": "46bf8b4a2fe2735fd0d38fede3982d3b181bc35ad2bebe8946b77da80a2257eb" }, "downloads": -1, "filename": "pbcommand-0.2.8.tar.gz", "has_sig": false, "md5_digest": "1966cde728689a70d6a93aff9d44013d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47467, "upload_time": "2015-08-14T00:44:05", "url": "https://files.pythonhosted.org/packages/01/be/8bbd8983e4ce780e6ac030f9e23dc2aa6ddcff4896e7ac2b2dbe8325e8fa/pbcommand-0.2.8.tar.gz" } ], "0.3.18": [ { "comment_text": "", "digests": { "md5": "4cd7ebcc539f82c3a10d4c30071a1f2d", "sha256": "37ed5ff9e3ba2c661e7ec27487c88fd8b43649524076ee837a33fb04b40fdfad" }, "downloads": -1, "filename": "pbcommand-0.3.18.tar.gz", "has_sig": false, "md5_digest": "4cd7ebcc539f82c3a10d4c30071a1f2d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 76140, "upload_time": "2016-03-03T19:01:27", "url": "https://files.pythonhosted.org/packages/54/cf/c1c2b0dcd593293cf994f960448efdaaac6163264a96554751cf52216999/pbcommand-0.3.18.tar.gz" } ], "0.3.20": [], "0.3.21": [ { "comment_text": "", "digests": { "md5": "54dcc26eef0a98a0a2ebc98544aeacbd", "sha256": "94f3268eee43d936432f6e962849a80927dfdc93c89d028d502f0c24ecff6ff6" }, "downloads": -1, "filename": "pbcommand-0.3.21.tar.gz", "has_sig": false, "md5_digest": "54dcc26eef0a98a0a2ebc98544aeacbd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 76985, "upload_time": "2016-03-09T16:02:26", "url": "https://files.pythonhosted.org/packages/7b/21/e8ab40ea18549743ead0495614cacd0e923b25dbd577afc37011c34d181b/pbcommand-0.3.21.tar.gz" } ], "0.3.29": [ { "comment_text": "", "digests": { "md5": "f1b3c2b6039d6bf7cf166bd5df6f3cd8", "sha256": "e26a8e9959d6992b0e1ff2254445c008c8e32d74d5128242e918538cf2adda9c" }, "downloads": -1, "filename": "pbcommand-0.3.29.tar.gz", "has_sig": false, "md5_digest": "f1b3c2b6039d6bf7cf166bd5df6f3cd8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 80758, "upload_time": "2016-06-14T22:43:37", "url": "https://files.pythonhosted.org/packages/ed/10/8cb0bb4586a11ddac7383634ad48b095692313b97f1153f0e77e1b70eacc/pbcommand-0.3.29.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f1b3c2b6039d6bf7cf166bd5df6f3cd8", "sha256": "e26a8e9959d6992b0e1ff2254445c008c8e32d74d5128242e918538cf2adda9c" }, "downloads": -1, "filename": "pbcommand-0.3.29.tar.gz", "has_sig": false, "md5_digest": "f1b3c2b6039d6bf7cf166bd5df6f3cd8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 80758, "upload_time": "2016-06-14T22:43:37", "url": "https://files.pythonhosted.org/packages/ed/10/8cb0bb4586a11ddac7383634ad48b095692313b97f1153f0e77e1b70eacc/pbcommand-0.3.29.tar.gz" } ] }