{ "info": { "author": "Rafael Viotti", "author_email": "rviotti@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.5", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.0", "Programming Language :: Python :: 3.1", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development" ], "description": "# sh2py\n\nsh2py is a shell to Python command line mapper. In other words, it is the\neasiest way to expose Python functions to the shell. Main features:\n\n* Very small code size. A single Python module. About a hundred lines of code.\n* The public API consists of a Python class, `CommandLineMapper`; plus two\n methods: `add` and `run`.\n* No external dependencies.\n* Support for Python 2 and 3.\n\n## Installation\n\n pip install sh2py\n\n## Basic Use\n\nExpose a single Python function. Consider the snippet below.\n\n```python\nfrom sh2py import CommandLineMapper\n\ndef myfunc(arg1, arg2, arg3='val'):\n print(arg1)\n print(arg2)\n print(arg3)\n\nif __name__ == '__main__':\n cli = CommandLineMapper()\n\n cli.add(myfunc)\n\n cli.run()\n```\n\nThe last three instructions demonstrate the basic operation of the API.\n\n1. Instantiate the `CommandLineMapper`.\n\n2. Register the function you want to expose, using the `CommandLineMapper.add`\nmethod.\n\n3. Call `CommandLineMapper.run`. It will process the command line,\n``sys.argv``, and invoke the matching function.\n\nSuppose the snippet above is saved as `myscript.py`.\n\n $ python myscript.py val1 val2 arg3=val3\n val1\n val2\n val3\n\nThe output reveals that the shell command above actually called\n`myfunc('val1', 'val2', arg3='val3')`. A couple of notes.\n\n1. Only one function was exposed via `CommandLineMapper.add`, so its name could\nbe omitted from the command line. If exposing more than one function, it is\nrecommended to pass its name as the first program argument, otherwise the first\nexposed function will be called. See next section.\n\n2. There is no type validation/coercion. The **run** method will only pass\nstrings on actual function calls.\n\n## Multiple Commands\n\nIf your script is large, you can organize it as a suite of sub-commands. Create\none function for each command you expect to handle and register all of them\nwith `CommandLineMapper.add`. Consider the code below.\n\n```python\nfrom sh2py import CommandLineMapper\n\ndef subcommand1(*args1, **kwargs1):\n pass\n\ndef subcommand2(*args2, **kwargs2):\n pass\n\nif __name__ == '__main__':\n cli = CommandLineMapper()\n\n cli.add(subcommand1)\n cli.add(subcommand2)\n\n cli.run()\n```\n\nYou can then specify which function to run via command line. For example, to\ninvoke `subcommand2` with arguments `val1` and `val2`, type the following.\n\n python mysuite.py subcommand2 val1 val2\n\nNotice that the `subcommand2` entry itself is extracted from the argument\nline. The remainder of the line is processed as usual. In this case, `args2`\nis `['val1', 'val2']`.\n\n## Complete example\n\nHere is a complete example.\n\n```python\nfrom sys import exit, stderr\nfrom time import sleep\nfrom random import sample\n\nfrom sh2py import HALT, CommandLineMapper\n\ndef hello(case='', shuffle='no', pace='0'):\n '''\n Emits a \"Hello, world!\" greeting message on standard error.\n\n Usage:\n\n python hello.py help\n python hello.py [case=upper/lower] [shuffle=yes/no] [pace=0]\n\n Arguments:\n\n help, print this usage help and exit;\n case=upper/lower, convert the message to uppercase, or lowercase;\n shuffle=yes/no, shuffle the letters of the message;\n pace=0, pace at which the letters are shown, in miliseconds.\n\n By default, there is no case conversion and no shuffling. Also, the pace is\n zero, so the entire message is shown immediately on standard error.\n '''\n\n if case in ['', 'upper', 'lower'] and shuffle in ['yes', 'no']:\n if pace.isdigit():\n greet = ['Hello', 'world']\n delay = int(pace)\n\n if shuffle == 'yes':\n greet[0] = ''.join(sample(greet[0], len(greet[0])))\n greet[1] = ''.join(sample(greet[1], len(greet[1])))\n\n greet = '{}, {}!'.format(*greet)\n\n if case == 'upper':\n greet = greet.upper()\n\n elif case == 'lower':\n greet = greet.lower()\n\n if delay == 0:\n print(greet, file=stderr)\n\n else:\n for x in greet:\n stderr.write(x)\n\n stderr.flush()\n\n sleep(delay / 1000.0)\n\n print(file=stderr)\n\n else:\n return HALT\n\n else:\n return HALT\n\nif __name__ == '__main__':\n cli = CommandLineMapper()\n\n cli.add(hello)\n\n if cli.run() is HALT:\n print(hello.__doc__, file=stderr)\n\n exit(1)\n```\n\nObserve that the `hello` function does not have a `help` argument, but the\n**docstring** says different. The `help` argument is automatically recognized\nand, when used, will print the **docstring** of the default, `hello`, function.\nA default help text will be printed if a function does not supply a\n**docstring**.\n\nThe call to `CommandLineMapper.run` will return `HALT` if a command is\ninvoked with an invalid syntax. Your functions can also use it to signal error\nconditions. This allows the program to exit with a non-zero status, or trigger\nsome error handling function.\n\n## Q&A\n\nQ. I want POSIX arguments.\n\nA. Wrong tool. There are plenty of Python command line parsing utilities\nsupporting POSIX. Try one of them.\n\n* Argparse/Optparse/Getopt. Built into Python. Complex.\n* [Compago](https://github.com/jmohr/compago). Very nice, but\n unmaintained. Also, does not run on Python 3.\n* [Docopt](http://docopt.org/).\n* [Clint](https://github.com/kennethreitz/clint).\n* [Click](http://click.pocoo.org/3/).\n\nQ. I need type coercion.\n\nA. Implement it yourself, or use some third party library.\n\nQ. I can use Python itself as a command line interpreter. Why all of this?\n\nA. Yes you can. In this case all of this becomes irrelevant. I prefer not to,\nthat is one of the reasons I wrote this tool. Another is that everything else\nis too complex. YMMV.\n\nQ. Why not use `sys.argv` directly.\n\nA. Good question. I do this a lot of times. Actually, if your script is small\nenough and requires zero, one, or maybe two positional parameters, there is no\nneed for command line processing tools. Write a couple of conditionals and\nprint a simple help message in case of errors.\n\n", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/viotti/sh2py/tarball/0.1.0", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/viotti/sh2py", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "sh2py", "package_url": "https://pypi.org/project/sh2py/", "platform": "", "project_url": "https://pypi.org/project/sh2py/", "project_urls": { "Download": "https://github.com/viotti/sh2py/tarball/0.1.0", "Homepage": "https://github.com/viotti/sh2py" }, "release_url": "https://pypi.org/project/sh2py/0.1.0/", "requires_dist": null, "requires_python": "", "summary": "Python command line mapper", "version": "0.1.0" }, "last_serial": 3322298, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "ba28660b55ea28e185d5254114a80e6f", "sha256": "aa63a2b50b17f090099f38154dda7ca8cd97e5c33a7c751668636ec3a8b50716" }, "downloads": -1, "filename": "sh2py-0.1.0.tar.gz", "has_sig": false, "md5_digest": "ba28660b55ea28e185d5254114a80e6f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5928, "upload_time": "2017-11-10T14:18:47", "url": "https://files.pythonhosted.org/packages/82/dd/c06ff580116598106c8b33f854e1d956c457719b4475c88b860ee1b4a173/sh2py-0.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ba28660b55ea28e185d5254114a80e6f", "sha256": "aa63a2b50b17f090099f38154dda7ca8cd97e5c33a7c751668636ec3a8b50716" }, "downloads": -1, "filename": "sh2py-0.1.0.tar.gz", "has_sig": false, "md5_digest": "ba28660b55ea28e185d5254114a80e6f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5928, "upload_time": "2017-11-10T14:18:47", "url": "https://files.pythonhosted.org/packages/82/dd/c06ff580116598106c8b33f854e1d956c457719b4475c88b860ee1b4a173/sh2py-0.1.0.tar.gz" } ] }