{ "info": { "author": "Robert Bricheno", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# Client of redundant servers\n\n[![Build Status](https://travis-ci.org/rbricheno/client_of_redundant_servers.svg?branch=master)](https://travis-ci.org/rbricheno/client_of_redundant_servers)\n[![codecov](https://codecov.io/gh/rbricheno/client_of_redundant_servers/branch/master/graph/badge.svg)](https://codecov.io/gh/rbricheno/client_of_redundant_servers)\n[![PyPI version](https://badge.fury.io/py/client-of-redundant-servers.svg)](https://badge.fury.io/py/client-of-redundant-servers)\n\nGeneric client of redundant servers. A simple framework to make requests of unreliable servers.\nThrows an exception if no servers are available, otherwise returns a result from the first server that doesn't fail.\nSupports round-robin, fixed, and random orders of servers.\n\nThe intention is that you can use this to glue together things that are otherwise slightly tedious, \nusing your own client classes which inherit from ClientOfRedundantServers.\n\n\n## Installation\n```\npip install client-of-redundant-servers\n```\n\n\n## Usage\n\nSay you have some web servers, all serving the same content, and you want to get a file from any one.\nYou don't care which server responds, but you don't want to have to manually look for failures and try again.\n\n`client_of_redundant_servers` lets you write things like this:\n\n```python\nimport requests\nimport client_of_redundant_servers as cors\nfrom collections import OrderedDict\n\n\nclass ClientOfRedundantWebServers(cors.ClientOfRedundantServers):\n def __init__(self, url_list: list):\n # Super().__init__ wants a dict, but this example is so simple that\n # a list can be used to create an OrderedDict of None.\n url_dict = OrderedDict((url, None) for url in url_list)\n super().__init__(url_dict)\n\n def _get_file_func(self, url):\n try:\n r = requests.get(url)\n # Check for errors that didn't raise a requests.exception\n if not r.ok:\n raise cors.CurrentServerFailed\n return r\n except requests.exceptions.RequestException:\n raise cors.CurrentServerFailed\n\n def get_file(self):\n return self.request(self._get_file_func)\n\n\n# Only picking on Ubuntu because it is widely mirrored.\nurls = [\"http://badserver.example.com/badfile\",\n \"http://www.mirrorservice.org/sites/cdimage.ubuntu.com/cdimage/releases/16.04/release/SHA256SUMS\",\n \"http://nl.archive.ubuntu.com/ubuntu-cdimages/16.04/release/SHA256SUMS\"]\n\nclient = ClientOfRedundantWebServers(urls)\ntry:\n r = client.get_file()\n print(r.text)\n print(\"*****\")\n print(\"Retrieved from : \" + r.url)\nexcept cors.AllAvailableServersFailed:\n print(\"Error! No servers were available to service the request.\")\n```\n\nIf you run that, you'll see that the client tries to retrieve the file from `badserver`,\nwhich fails, so it continues to try the next available server.\n\nSee the \"examples\" directory for some examples that might be useful.\nCurrently there's a RADIUS client using [pyrad](https://github.com/wichert/pyrad)\nand an Active Directory LDAP client using [ldap3](https://github.com/cannatag/ldap3).\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/rbricheno/client_of_redundant_servers", "keywords": "redundant client radius ldap", "license": "", "maintainer": "", "maintainer_email": "", "name": "client-of-redundant-servers", "package_url": "https://pypi.org/project/client-of-redundant-servers/", "platform": "", "project_url": "https://pypi.org/project/client-of-redundant-servers/", "project_urls": { "Bug Reports": "https://github.com/rbricheno/client_of_redundant_servers/issues", "Homepage": "https://github.com/rbricheno/client_of_redundant_servers", "Source": "https://github.com/rbricheno/client_of_redundant_servers" }, "release_url": "https://pypi.org/project/client-of-redundant-servers/0.6/", "requires_dist": null, "requires_python": ">=3", "summary": "Client of redundant servers", "version": "0.6" }, "last_serial": 3861118, "releases": { "0.3": [ { "comment_text": "", "digests": { "md5": "8f33c28645c626a564918574e6752ddd", "sha256": "2f2a5dde4af8f76abc84599cd99295677810401467d91eedf08d9c4f828d1b81" }, "downloads": -1, "filename": "client_of_redundant_servers-0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "8f33c28645c626a564918574e6752ddd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 9104, "upload_time": "2018-04-30T11:00:55", "url": "https://files.pythonhosted.org/packages/89/27/3178bb5975298d8ad3e2478fe04b0772a46f7caffe101d7ac83b1901c292/client_of_redundant_servers-0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "82eb7b9e4471771dc682613a1d1f71a9", "sha256": "b91703b9db8cb7a86ec514e512a8f082c8d7003249c52a403db3501a71aa3234" }, "downloads": -1, "filename": "client_of_redundant_servers-0.3.tar.gz", "has_sig": false, "md5_digest": "82eb7b9e4471771dc682613a1d1f71a9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 6431, "upload_time": "2018-04-30T11:00:56", "url": "https://files.pythonhosted.org/packages/cf/d0/09ac7f8a4ffc8932bd6ea4acac82f1da49b4244702706462e168f25c1a50/client_of_redundant_servers-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "28682ee9c7e6d5c0ff5270bce94282c6", "sha256": "8c88708495c6d19f86ed883d2d48d0333c0db6937a9852790d50a5eff42d1f5f" }, "downloads": -1, "filename": "client_of_redundant_servers-0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "28682ee9c7e6d5c0ff5270bce94282c6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 9299, "upload_time": "2018-05-11T16:00:08", "url": "https://files.pythonhosted.org/packages/e2/8b/9300718b56338e0286eb0a9f9f2e92e1f2c6f32dc788a9e0bfc6e732527c/client_of_redundant_servers-0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "50cc970de261546486f25cca0d8ea99c", "sha256": "35149ff42cf9c9ad776e096355aadffc8c536d02c36382bf94a4f87c48b00aef" }, "downloads": -1, "filename": "client_of_redundant_servers-0.4.tar.gz", "has_sig": false, "md5_digest": "50cc970de261546486f25cca0d8ea99c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 6589, "upload_time": "2018-05-11T16:00:09", "url": "https://files.pythonhosted.org/packages/90/8f/06428be2387956c4450bc677311dc7337259c7e553a7f4d03c95de923cb1/client_of_redundant_servers-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "6ecb66acd1bb6774aaad263a9dfdcfc7", "sha256": "192108b8450bee9949ea52864c992ea9eeee98e235d70538c6248dd42a232621" }, "downloads": -1, "filename": "client_of_redundant_servers-0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "6ecb66acd1bb6774aaad263a9dfdcfc7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 9369, "upload_time": "2018-05-14T13:36:59", "url": "https://files.pythonhosted.org/packages/9f/cd/3ac65f2658c15cff1b09c4ba2d709a789f2376e4112f9e881539f4e3f73a/client_of_redundant_servers-0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7b2455e3598c586bae9c064091cef82e", "sha256": "12b7c070541f99634b519f19cffa8985c73fd722a9382d572b4cbb2a9ab62616" }, "downloads": -1, "filename": "client_of_redundant_servers-0.5.tar.gz", "has_sig": false, "md5_digest": "7b2455e3598c586bae9c064091cef82e", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 6726, "upload_time": "2018-05-14T13:37:01", "url": "https://files.pythonhosted.org/packages/75/46/e3f889ee89172891fa215bb967174b38b2e980e0606fc914b702c01251dd/client_of_redundant_servers-0.5.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "213a354cea022678b8d6a199fd354757", "sha256": "3beff3504c4fdce736d76d00470ce1ec00026a79faab353d340eb3b2b0e4cbcb" }, "downloads": -1, "filename": "client_of_redundant_servers-0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "213a354cea022678b8d6a199fd354757", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 9435, "upload_time": "2018-05-14T14:20:03", "url": "https://files.pythonhosted.org/packages/d9/d4/1b34b9dbcf2e315ef4552c6cd4f78c9258a60dbb0b3267a6dfad0ea5accd/client_of_redundant_servers-0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0aeeb6b5cbed62bb1790c2db3dec3cf4", "sha256": "1ef476736c022b067d4498f14fb06cd0ac5a67f3c00de7d3cfc004de43dfc5b4" }, "downloads": -1, "filename": "client_of_redundant_servers-0.6.tar.gz", "has_sig": false, "md5_digest": "0aeeb6b5cbed62bb1790c2db3dec3cf4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 6768, "upload_time": "2018-05-14T14:20:04", "url": "https://files.pythonhosted.org/packages/01/9b/06ec1c7d8e5602e0bce37e18beac6c8fe9eef5c113b17c0c63ee9e13269a/client_of_redundant_servers-0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "213a354cea022678b8d6a199fd354757", "sha256": "3beff3504c4fdce736d76d00470ce1ec00026a79faab353d340eb3b2b0e4cbcb" }, "downloads": -1, "filename": "client_of_redundant_servers-0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "213a354cea022678b8d6a199fd354757", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 9435, "upload_time": "2018-05-14T14:20:03", "url": "https://files.pythonhosted.org/packages/d9/d4/1b34b9dbcf2e315ef4552c6cd4f78c9258a60dbb0b3267a6dfad0ea5accd/client_of_redundant_servers-0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0aeeb6b5cbed62bb1790c2db3dec3cf4", "sha256": "1ef476736c022b067d4498f14fb06cd0ac5a67f3c00de7d3cfc004de43dfc5b4" }, "downloads": -1, "filename": "client_of_redundant_servers-0.6.tar.gz", "has_sig": false, "md5_digest": "0aeeb6b5cbed62bb1790c2db3dec3cf4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 6768, "upload_time": "2018-05-14T14:20:04", "url": "https://files.pythonhosted.org/packages/01/9b/06ec1c7d8e5602e0bce37e18beac6c8fe9eef5c113b17c0c63ee9e13269a/client_of_redundant_servers-0.6.tar.gz" } ] }