{ "info": { "author": "Brian Williams", "author_email": "briancmwilliams@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6" ], "description": "# actappliance #\n\n### Use case ###\nThis repo abstracts the type of connection you are making to an actifio appliance. You can write a test or use case one\nway ane execute over SSH or RESTful connections. \n\nThe primary idea being that all sent commands can look like CLI as it is shorter and more people are familiar with it,\nwhile the responses look like the RESTful API's JSON returns as they are easier to parse.\nIt also allows direct commands using either connection with the same contract of CLI like requests and RESTful like\nresponses for the case where the call is unreliable unusable for whatever reason (CLI permissions, arbitrary outputs). \n\n# Functionality of Library #\n\nFirst create your appliance/sky/uds object:\n\n> a = Appliance(ip_address=, hostname=) # hostname or ip_address required\n> ex. a = Appliance(ip_address=8.8.8.8)\n\nWith default settings it will try to send RESTful calls for all cmd methods.\n\n```\n>>> a.a.cmd('udsinfo lsversion')\n{u'status': 0, u'result': [{u'version': u'7.0.0.68595', u'component': u'CDS', u'installed': u'2016-03-07 12:14:37'}, {u'version': u'7.0.0.68595', u'component': u'psrv-revision', u'installed': u'2016-03-07 12:14:37'}]}\n```\nNote: You will likely see debug messages if your log levels aren't set!\n\nIf you store the return the object has additional methods like parse and raise_for_error.\n```\n>>> act_response = a.a.cmd('udsinfo lsversion')\n>>> act_response.parse()\n{u'version': u'7.0.0.68595', u'component': u'CDS', u'installed': u'2016-03-07 12:14:37'}\n```\n\n### Parse ###\nThe parse method tries to simplify interactions with our RESTful responses. It only returns dictionaries and strings. It\nwill never return a list! In the case above you can see it returned the first relevant dictionary it found. If the info\nyou desire was the version of the psrv-revision component you would use m_k='component' (search key is component), \nm_v='psrv-revision' (matching value is psrv-revision). Those two inputs in action:\n```\n>>> act_response.parse(m_k='component', m_v='psrv-revision')\n{u'version': u'7.0.0.68595', u'component': u'psrv-revision', u'installed': u'2016-03-07 12:14:37'}\n```\nHowever we wanted the version not the whole dicitonary so we would add k='version' (search for key version in the dict \nand return the corresponding value).\nThe full command and result:\n```\n>>> act_response\n{u'status': 0, 'errorcode': 8675309, 'errormessage': 'Something went wrong', u'result': [{u'version': u'7.0.0.68595', u'component': u'CDS', u'installed': u'2016-03-07 12:14:37'}, {u'version': u'7.0.0.68595', u'component': u'psrv-revision', u'installed': u'2016-03-07 12:14:37'}]}\n>>> act_response.parse(m_k='component', m_v='psrv-revision', k='version')\nu'7.0.0.68595'\n```\nHere we can see the use of parse is to simplify basic parsing of appliance responses.\n\n* Advanced example\nIf you have used parse for a while, you probably have come to understand how it functions. Overreliance on parse may\nlead to writing code like the following:\n\n`ids = [act_response.parse(backups, k='id', index=backup) for backup in range(len(backups))]`\n\nThe above is considered ugly. When doing something like the above rewriting it to avoid using parse, but instead perform\n it's action. The following has an identical result to the above line:\n\n`ids = [data['id'] for data in backups['result']]`\n\nIf you want to avoid list comprehensions you could do the following\n\n```\nids = []\nfor data in backup['results']:\n ids.append(data['id'])\n```\n\n### Raise_for_error ###\nThe raise_for_error method does self inspection of the dictionary to determine if an Actifio related error occurred.\nThese errors do not include connection errors like failing to authenticate and get a valid REST sessionid. These are\nspecifically for errors that are bubbled up to the user when interacting with an Actifio appliance. The response objects\nhave two attributes \"errormessage\" and \"errorcode\" which you can use to handle errors that should not end the test.\n\n* Basic example\n```\n>>> r = self.a.cmd('udsinfo lsversion -l')\n>>> r.raise_for_status()\nResponse: {u'errorcode': 10010, u'errormessage': u'invalid option: l'}\n```\n\nThis raised an error because -l is not a valid option for \"udsinfo lsversion\". The error object itself has direct access\nto errorcode and errormessage. You can handle these exceptions as needed:\n```\n>>> from actappliance.act_errors import ACTError\n>>> try:\n... r.raise_for_error()\n... except ACTError as e:\n... if e.errorcode == 10010:\n... # handle or allow this error\n... print(\"I am allowing this error\")\n... else:\n... raise\n```\n\nAn alternative way to handle this would be to catch the specific error:\n```\n>>> from actappliance.act_errors import act_errors\n>>> try:\n... r.raise_for_error()\n... except act_errors[10010]:\n... # handle or allow this error\n... print(\"I am allowing this error\")\n```\n\n\nNote: If your command needs to specifically be rest OR ssh and cannot function or is an inaccurate test if sent the \nother way use the specific methods instead of cmd.\n\n### Have fun!\n![Lots of fun](http://i.imgur.com/fzhEnP0.png)\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Brian-Williams/actappliance", "keywords": "automation testing", "license": "", "maintainer": "", "maintainer_email": "", "name": "act-appliance", "package_url": "https://pypi.org/project/act-appliance/", "platform": "", "project_url": "https://pypi.org/project/act-appliance/", "project_urls": { "Homepage": "https://github.com/Brian-Williams/actappliance" }, "release_url": "https://pypi.org/project/act-appliance/0.8.2/", "requires_dist": [ "requests", "paramiko", "bitpermissions", "asyncssh", "aiohttp", "pytest (>=2.9.0); extra == 'test'", "flake8; extra == 'test'", "tenacity; extra == 'test'" ], "requires_python": "", "summary": "An abstraction utility for actifio appliances", "version": "0.8.2" }, "last_serial": 4843446, "releases": { "0.8.1": [ { "comment_text": "", "digests": { "md5": "755a22bf0fd8ca1d5789272196d2239c", "sha256": "e5fb2cabcdf87afd6c58fc33d697a27243d839152430161c4352fa2eb24fff23" }, "downloads": -1, "filename": "act_appliance-0.8.1-py3-none-any.whl", "has_sig": false, "md5_digest": "755a22bf0fd8ca1d5789272196d2239c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 31082, "upload_time": "2018-09-18T17:29:29", "url": "https://files.pythonhosted.org/packages/4c/d6/4fea4d9549dddf35209581e2b30369dc34bbbaa844a339af3e8f7defad8b/act_appliance-0.8.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cdd5b58fdd3d18069061214a6e5d310e", "sha256": "5b990d13cfa64c0bd882c74910add67a819ee3a805f0cc638330cc3869fb4592" }, "downloads": -1, "filename": "act_appliance-0.8.1.tar.gz", "has_sig": false, "md5_digest": "cdd5b58fdd3d18069061214a6e5d310e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24002, "upload_time": "2018-09-18T17:29:31", "url": "https://files.pythonhosted.org/packages/d5/ac/63dd5436a1f5a7314c6c7dd09bac2274bd8091310da588a04b67cec7f046/act_appliance-0.8.1.tar.gz" } ], "0.8.2": [ { "comment_text": "", "digests": { "md5": "171941233e99d59a19baafd0cf2d6080", "sha256": "5f55f24b01408de10e1b434689d54df1908a3aba8e37b98a408188df554839c8" }, "downloads": -1, "filename": "act_appliance-0.8.2-py3-none-any.whl", "has_sig": false, "md5_digest": "171941233e99d59a19baafd0cf2d6080", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 31101, "upload_time": "2019-02-20T03:09:20", "url": "https://files.pythonhosted.org/packages/0d/6a/bbbba2cf88ed1fdfdc62766037f66a1ee494743c14f26f54952aaa6a10a3/act_appliance-0.8.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8a6a75d7599819b383c0de93cfc32908", "sha256": "7fe4efa167888dbde771382cf8375766656c024daf8fc749c30a3671e667aa65" }, "downloads": -1, "filename": "act_appliance-0.8.2.tar.gz", "has_sig": false, "md5_digest": "8a6a75d7599819b383c0de93cfc32908", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24046, "upload_time": "2019-02-20T03:09:22", "url": "https://files.pythonhosted.org/packages/68/76/8ae7073bbdc5163a98b06221fcc4765c509f32daf9c8e8586c296cd36a08/act_appliance-0.8.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "171941233e99d59a19baafd0cf2d6080", "sha256": "5f55f24b01408de10e1b434689d54df1908a3aba8e37b98a408188df554839c8" }, "downloads": -1, "filename": "act_appliance-0.8.2-py3-none-any.whl", "has_sig": false, "md5_digest": "171941233e99d59a19baafd0cf2d6080", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 31101, "upload_time": "2019-02-20T03:09:20", "url": "https://files.pythonhosted.org/packages/0d/6a/bbbba2cf88ed1fdfdc62766037f66a1ee494743c14f26f54952aaa6a10a3/act_appliance-0.8.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8a6a75d7599819b383c0de93cfc32908", "sha256": "7fe4efa167888dbde771382cf8375766656c024daf8fc749c30a3671e667aa65" }, "downloads": -1, "filename": "act_appliance-0.8.2.tar.gz", "has_sig": false, "md5_digest": "8a6a75d7599819b383c0de93cfc32908", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24046, "upload_time": "2019-02-20T03:09:22", "url": "https://files.pythonhosted.org/packages/68/76/8ae7073bbdc5163a98b06221fcc4765c509f32daf9c8e8586c296cd36a08/act_appliance-0.8.2.tar.gz" } ] }