{ "info": { "author": "Sri Kadimisetty", "author_email": "s@sri.io", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Terminals" ], "description": "[action_hero_logo]: ./art/logo.svg\n![Action Hero Logo][action_hero_logo]\n\n\n[![codecov](https://codecov.io/gh/kadimisetty/action-hero/branch/master/graph/badge.svg)](https://codecov.io/gh/kadimisetty/action-hero)\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/action-hero?style=flat-square)\n![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)\n![PyPI - License](https://img.shields.io/pypi/l/action-hero?style=flat-square)\n[![Build Status](https://travis-ci.org/kadimisetty/action-hero.svg?branch=master)](https://travis-ci.org/kadimisetty/action-hero)\n\n\n####\n\n`action_hero` is a python package that helps you \n__manage user arguments in command line applications using `argparse`__ \n\n\n## Introduction\n> __Introduction__ \u00b7 [Quick Usage](#quick-usage) \u00b7 [Help & FAQ](#help-and-faq) \u00b7 [Catalog](#catalog) \u00b7 [Development](#development)\n\n##### _Argparse, Parsers, Actions? What now??_ \ud83e\udd37\u200d\u2642\ufe0f\n\n
\n\n
1. argparse
\n
argparse is a python standard library module used to build command line interfaces.\n\u2693\ufe0e\n
\n\n
2. ArgumentParser
\n
argparse.ArgumentParser parses user arguments by inspecting\nthe command line, converting each argument to an appropriate type and finally\ninvoking an appropriate argparse.Action\n\u2693\ufe0e\n
\n\n\n
3. Action
\n
argparse.Action objects are used by\nArgumentParser to represent information needed to parse arguments\nfrom the command line.\n\u2693\ufe0e\n
\n\n\n
4. action_hero \ud83d\udca5
\n
action_hero provides many such custom actions to deal with\naccepting user arguments in your command line application. They are subclasses\nof argparse.Action and fit in with the rest of you\nargparse code.
\n\n
For example, the FileIsWritableAction automatically\nverifies that all file paths accepted as arguments are indeed writable,\ninforming the user if they aren't. This saves you the trouble of doing\nthat check yourself. Nice, no? Browse the catalog for\nmore custom actions.
\n\n
\n\nTherefore __`argparse`__ + __`action_hero`__ = \ud83e\udde8\n\n\n## Quick Usage\n> [Introduction](#introduction) \u00b7 __Quick Usage__ \u00b7 [Help & FAQ](#help-and-faq) \u00b7 [Catalog](#catalog) \u00b7 [Development](#development)\n\n__1. Installation__: Use `pip` for installation\n\n```python \npip install action_hero\n```\n\n__2. Quick Usage__: Import an action and specify it when adding an argument to your parser.\n\n```python \nfrom action_hero import FileIsReadableAction\n...\nparser.add_argument(\"--file\", action=FileIsReadableAction)\n...\n```\n\n__3. Full Example__: CLI program that counts number of lines of a file. \n\n```python\n# examples/line_counter.py\nimport argparse\n\nfrom action_hero import FileIsReadableAction\n\n\nif __name__ == \"__main__\":\n # Create parser\n parser = argparse.ArgumentParser()\n\n # Add user argument \"file\"\n parser.add_argument(\"--file\", action=FileIsReadableAction)\n\n # Parse user arguments\n args = parser.parse_args()\n\n if args.file:\n # Count lines in file\n with open(args.file) as f:\n # print(f\"{args.file} has {len(f.readlines())} lines\")\n print(\"{} has {} lines\".format(args.file, len(f.readlines())))\n else:\n # Print usage when no arguments were supplied\n parser.print_usage()\n```\n\nRun `line_counter.py` on the command line\n\n```bash\n$ ls\nline_counter.py mary.md\n\n$ python line_counter.py --file mary.md\nmary.md has 39 lines\n\n$ python line_counter.py\nusage: line_counter.py [-h] [--file FILE]\n\n$ python line_counter.py --file nofile.md\nusage: line_counter.py [-h] [--file FILE]\nline_counter.py: error: argument --file: File is not readable\n```\n\n**Note**: _Supported Python versions 3.6 upwards._\n\n## Help and FAQ\n> [Introduction](#introduction) \u00b7 [Quick Usage](#quick-usage) \u00b7 __Help & FAQ__ \u00b7 [Catalog](#catalog) \u00b7 [Development](#development)\n\n### Accepting `action_values`\nThere are times your action requires an additional value. For instance, when your argument accepts only filenames with `md` or `markdown` extensions. You can use the `FilenameHasExtension` action for this and pass in the extensions to check for via `action_values`, like so \u2014 \n\n```python\nparser.add_argument(\n \"--file\", \n action=FilenameHasExtension, \n action_values=[\"md\", \"markdown\"]\n)\n\n```\n\nUnless otherwise mentioned, `action_values` should be provided as a non-empty\nlist of strings. e.g.\n`action_values = [\"md\", \"markdown\"]`.\n\n\n### Pipelining multiple actions\n\nThe `PipelineAction` allows you to run multiple actions as a pipeline. Pass in\nyour pipeline of actions as a list to `action_values`. If one of the actions\nyou're passing in has it's own `action_values`, put that one as a tuple, like\nsuch: `(FilenameHasExtension, [\"md\", \"markdown\"])`. Here's an example of\npipelining actions for `--file` \n\n1. File has extensions `md` or `markdown`\n2. File exists\n\n```python\nparser.add_argument(\n \"--file\", \n action=PipelineAction, \n action_values=[\n (FilenameHasExtension, [\"md\", \"markdown\"]),\n FileExistsAction\n ]\n)\n```\n\nAnother helpful feature, this action provides is the _order of error\nreporting_. In the above example, if the supplied argument file did not have\nthe markdown extensions, the error message would reflect that and exit. After\nthe user redoes the entry with a valid filename the next action in the pipeline\napplies `FileExistsAction` which check for existence. If the file does not\nexist, an error message about file not existing will be shown and exits\nallowing the user to try again.\n\nThis behavior can save you a lot of manual condition checks later on. For\nexample, here's how to check for an existing, writable, non-empty, markdown\nfile \u2014\n\n```python\nparser.add_argument(\n \"--file\", \n action=PipelineAction, \n action_values=[\n FileExistsAction, \n FileIsWritableAction,\n FileIsNotEmptyAction,\n (FilenameHasExtension, [\"md\", \"markdown\"])\n]\n```\n\n### Exceptions in this module\nYou'll come across two different exceptions in `action_hero`.\n\n1. __`ValueError`__: These are intended for you, the CLI developer. You'd want\n to fix any underlying issue that causes them before releasing your CLI.\n e.g. when `action_values` is an empty list.\n\n2. __`argparse.ArgumentError`__: These are intended for your CLI's users, so\n they might use the messages as hints to provide corrent command line\n options.\n\n### Not capturing user argument exceptions\n`argparse.ArgumentParser` has a slightly unconventional approach to handling\n`argparse.ArgumentError`s. Upon encountering one, it prints argument usage\ninformation, error and exits. I mention this, so you don't setup a `try/except`\naround `parser.parse_args()` to capture that exception. \n\nIn order to maintain consistency with the rest of your `argparse` code,\nexceptions in `action_hero` are also of type `argparse.ArgumentError` and\ncauses system exit as well. More information can be found in [PEP\n389](https://www.python.org/dev/peps/pep-0389/#id46). Since this is\nexpected behavior, I recommend you allow exception and let it display usage\ninformation and exit.\n\n### On arguments accepting multiple values\nJust like any other `argparse.Action` each `action_hero.Action` handles\nmultiple arguments and provides relevant error messages.\n\n### FAQ\n
\n
What do I need to know to use action_hero in my command line application?
\n
Vanilla argparse knowledge should do it.
\n\n
Where can I find information about argparse?
\n
argparse is part of the Python standard library.
\n\n
Is action_hero tied to the argparse module?
\n
Yes (but technically no \u2014 any project that can use an argpoarse.Action should work as long as it handles the argparse.ArgumentError exception)
\n\n
What type are the user argument exceptions?
\n
argparse.ArgumentError{\"helpful error message\"}, just like any other argparse.Action
\n\n
There was no mention of humans! Does this work for humans?
\n
Yes, it works for humans :)
\n
\n\n\n## Catalog\n> [Introduction](#introduction) \u00b7 [Quick Usage](#quick-usage) \u00b7 [Help & FAQ](#help-and-faq) \u00b7 __Catalog__ \u00b7 [Development](#development)\n\n\n1. __Special__ actions:\n\n| Action | Description | `action_values` |\n| --- | --- | --- |\n| __`PipelineAction`__ | Run multiple actions as a pipeline | Actions to run as a pipeline. e.g. `[FileExistsAction, FileIsWritableAction]`. ([Read more about this](#pipelining-multiple-actions)) |\n\n2. __Path, Directory and File__ related actions:\n\n| Action | Description | `action_values` |\n| --- | --- | --- |\n| __`DirectoryDoesNotExistAction`__ | Check if directory does not exist | |\n| __`DirectoryExistsAction`__ | Check if directory exists | |\n| __`DirectoryIsExecutableAction`__ | Check if directory is executable | |\n| __`DirectoryIsNotExecutableAction`__ | Check if directory is not executable | |\n| __`DirectoryIsNotReadableAction`__ | Check if directory is not readable | |\n| __`DirectoryIsNotWritableAction`__ | Check if directory is not writable | |\n| __`DirectoryIsReadableAction`__ | Check if directory is readable | |\n| __`DirectoryIsValidAction`__ | Check directory is valid | |\n| __`DirectoryIsWritableAction`__ | Check if directory is writable | |\n| __`EnsureDirectoryAction`__ | Ensure directory exists and create it if it doesnt | |\n| __`EnsureFileAction`__ | Ensure file exists and create it if it doesnt | |\n| __`FileDoesNotExistAction`__ | Check if file doesnt exist | |\n| __`FileExistsAction`__ | Check if file exists | |\n| __`FileIsEmptyAction`__ | Check if file is empty | |\n| __`FileIsExecutableAction`__ | Check if file is executable | |\n| __`FileIsNotEmptyAction`__ | Check if file is not empty | |\n| __`FileIsNotExecutableAction`__ | Check if file is not executable | |\n| __`FileIsNotReadableAction`__ | Check if file is not readable | |\n| __`FileIsNotWritableAction`__ | Check if file is not writable | |\n| __`FileIsReadableAction`__ | Check if file is readable | |\n| __`FileIsValidAction`__ | Check file is valid | |\n| __`FileIsWritableAction`__ | Check if file is writable | |\n| __`FilenameHasExtension`__ | Check if file has specified extension | Extensions to check against. e.g. `[\"md\", \"markdown\"]` |\n| __`PathDoesNotExistsAction`__ | Check if path does not exist | |\n| __`PathExistsAction`__ | Check if path exists | |\n| __`PathIsExecutableAction`__ | Check if path is executable | |\n| __`PathIsNotExecutableAction`__ | Check if path is not executable | |\n| __`PathIsNotReadableAction`__ | Check if path is not writable | |\n| __`PathIsNotWritableAction`__ | Check if path is not writable | |\n| __`PathIsReadableAction`__ | Check if path is readable | |\n| __`PathIsValidAction`__ | Check if path is valid | |\n| __`PathIsWritableAction`__ | Check if path is writable | |\n| __`ResolvePathAction`__ | Resolves path to canonical path removing symbolic links if present | |\n\n\n3. __Network__ related actions:\n\n| Action | Description | `action_values` |\n| --- | --- | --- |\n| __`IPIsValidIPAddressAction`__ | Check if ip is valid ipv4 or ipv6 address | |\n| __`IPIsValidIPv4AddressAction`__ | Check if ip address is valid ipv4 address | |\n| __`IPIsValidIPv6AddressAction`__ | Check if ip address is valid ipv6 address | |\n| __`URLIsNotReachableAction`__ | Check if URL is not reachable | |\n| __`URLIsReachableAction`__ | Check if URL is reachable | |\n| __`URLWithHTTPResponseStatusCodeAction`__ | Check if upplied URL responds with expected HTTP response status code | [Status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) to check against. e.g. `[\"200\", \"201\", \"202\", \"204\"]` |\n\n\n4. __Type__ related actions:\n\n| Action | Description | `action_values` |\n| --- | --- | --- |\n| __`IsConvertibleToFloatAction`__ | Check if value is convertible to float | |\n| __`IsConvertibleToIntAction`__ | Check if value is convertible to int | |\n| __`IsConvertibleToUUIDAction`__ | Checks if value is convertible to UUID | |\n| __`IsFalsyAction`__ | Checks if value is falsy | |\n| __`IsTruthyAction`__ | Checks if value is truthy | |\n\n5. __Email__ related actions:\n\n| Action | Description | `action_values` |\n| --- | --- | --- |\n| __`EmailIsValidAction`__ | Checks if email address is valid | |\n\n6. __Range__ related actions:\n\n| Action | Description | `action_values` |\n| --- | --- | --- |\n\n7. __Miscellaneous__ other actions:\n\n| Action | Description | `action_values` |\n| --- | --- | --- |\n| __`ChoicesAction`__ | Allow argument to only be from passed in choices | Choices e.g. `[\"red\", \"blue\", \"green\"]` |\n\n## Development\n> [Introduction](#introduction) \u00b7 [Quick Usage](#quick-usage) \u00b7 [Help & FAQ](#help-and-faq) \u00b7 [Catalog](#catalog) \u00b7 __Development__\n\n### Notes\n- __Formatting__-: _PEP8 only. Please format with black using `black_linelength=79`_\n- __License__: _The MIT License_\n- __Image Attributions__: _Karate by Alex Auda Samora from the Noun Project_\n\n### Roadmap\n1. Configurable exception type. e.g. ValueError/ArgumentError etc.\n2. More Actions.\n3. Reference with Sphinx docs + github pages on a seperate branch.\n4. More examples.\n5. Proper repo things.\n\n> If you like action hero please give it a quick star \u2b50\ufe0f \n> It helps with visibility and will be much appreciated! \n> Thank you for using `action_hero`\n\n\n", "description_content_type": "text/plain", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/kadimisetty/action-hero", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "action-hero", "package_url": "https://pypi.org/project/action-hero/", "platform": "", "project_url": "https://pypi.org/project/action-hero/", "project_urls": { "Homepage": "https://github.com/kadimisetty/action-hero" }, "release_url": "https://pypi.org/project/action-hero/0.6.3/", "requires_dist": [ "requests" ], "requires_python": ">=3.5.0", "summary": "Argparse Actions that pack a punch!", "version": "0.6.3" }, "last_serial": 5643123, "releases": { "0.6.1": [ { "comment_text": "", "digests": { "md5": "5812d5d18cb1a10879a6b6f6d536f634", "sha256": "e43954a7faa83e107e8ed47793fa1a3fddb04afb4d8102e6be1233ab0943d1a8" }, "downloads": -1, "filename": "action_hero-0.6.1-py3-none-any.whl", "has_sig": false, "md5_digest": "5812d5d18cb1a10879a6b6f6d536f634", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6.0", "size": 18750, "upload_time": "2019-08-05T11:36:20", "url": "https://files.pythonhosted.org/packages/a5/3d/23b4764f6a58db643acc19e32a98657d47743ebbf7e4dc51a63341fed4f8/action_hero-0.6.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "557c0847b4a6916cee9b6ab56d3ff54f", "sha256": "32524885c7b222ca33f628fdb786a8c5c378a7db26e3c9e16caf5b05124b2de4" }, "downloads": -1, "filename": "action-hero-0.6.1.tar.gz", "has_sig": false, "md5_digest": "557c0847b4a6916cee9b6ab56d3ff54f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 35652, "upload_time": "2019-08-05T11:36:23", "url": "https://files.pythonhosted.org/packages/22/5c/b6a1c4dd6375eb6a0a315675c47684e69ad62f8da1259e4a2788789f1a77/action-hero-0.6.1.tar.gz" } ], "0.6.2": [ { "comment_text": "", "digests": { "md5": "498d052a4edc1e59179af1bcbefceeb9", "sha256": "0f0a815cd8fe8136cdac07af087d446e8746e517be5edd5922ea7ff592004e9a" }, "downloads": -1, "filename": "action_hero-0.6.2-py3-none-any.whl", "has_sig": false, "md5_digest": "498d052a4edc1e59179af1bcbefceeb9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6.0", "size": 20034, "upload_time": "2019-08-06T06:41:15", "url": "https://files.pythonhosted.org/packages/a0/6c/ccec780ec9afbb3d9c245f68dee47c3e737308ef1b14cc6bc20dd7e7ebae/action_hero-0.6.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "90cf5b9ee3fe35130408a35a6b7d5c51", "sha256": "1b7f401dbc810eb16c4d3ccdcb330d6ca7f3c093771f56b639f25f2de42b00ca" }, "downloads": -1, "filename": "action-hero-0.6.2.tar.gz", "has_sig": false, "md5_digest": "90cf5b9ee3fe35130408a35a6b7d5c51", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 37730, "upload_time": "2019-08-06T06:41:17", "url": "https://files.pythonhosted.org/packages/9b/04/2157eb5e8e9e476cb237ebb259845295a0f3f8392d46aefa67a82d53c6d1/action-hero-0.6.2.tar.gz" } ], "0.6.3": [ { "comment_text": "", "digests": { "md5": "770e8a9aac03422afb31a7e4eec8072d", "sha256": "7d5f5b93a463f27b398cad2c736d6c73d2bcc1d672a2c6f52d177b3a91683ecd" }, "downloads": -1, "filename": "action_hero-0.6.3-py3-none-any.whl", "has_sig": false, "md5_digest": "770e8a9aac03422afb31a7e4eec8072d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5.0", "size": 20018, "upload_time": "2019-08-07T05:02:23", "url": "https://files.pythonhosted.org/packages/47/5a/bb280f2edd0f02be69809704646be92d2763b8092b6b78849b74131264d7/action_hero-0.6.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2220673f0372ea3907f665b1c72e2ec1", "sha256": "81b96384fa29f02d9c41bdb4380829ae85422d9bc794d7b51529205bcb66482c" }, "downloads": -1, "filename": "action-hero-0.6.3.tar.gz", "has_sig": false, "md5_digest": "2220673f0372ea3907f665b1c72e2ec1", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.0", "size": 36578, "upload_time": "2019-08-07T05:02:32", "url": "https://files.pythonhosted.org/packages/7c/61/09fe9703b9a5795c6696c3d1151d42ebc683fd62ec4a450367b1b26668f6/action-hero-0.6.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "770e8a9aac03422afb31a7e4eec8072d", "sha256": "7d5f5b93a463f27b398cad2c736d6c73d2bcc1d672a2c6f52d177b3a91683ecd" }, "downloads": -1, "filename": "action_hero-0.6.3-py3-none-any.whl", "has_sig": false, "md5_digest": "770e8a9aac03422afb31a7e4eec8072d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5.0", "size": 20018, "upload_time": "2019-08-07T05:02:23", "url": "https://files.pythonhosted.org/packages/47/5a/bb280f2edd0f02be69809704646be92d2763b8092b6b78849b74131264d7/action_hero-0.6.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2220673f0372ea3907f665b1c72e2ec1", "sha256": "81b96384fa29f02d9c41bdb4380829ae85422d9bc794d7b51529205bcb66482c" }, "downloads": -1, "filename": "action-hero-0.6.3.tar.gz", "has_sig": false, "md5_digest": "2220673f0372ea3907f665b1c72e2ec1", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.0", "size": 36578, "upload_time": "2019-08-07T05:02:32", "url": "https://files.pythonhosted.org/packages/7c/61/09fe9703b9a5795c6696c3d1151d42ebc683fd62ec4a450367b1b26668f6/action-hero-0.6.3.tar.gz" } ] }