{ "info": { "author": "Alin-Marian Iuga", "author_email": "alin.m.iga@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha" ], "description": "# Locust Backpack\n\nThe **Locust Backpack** is a Locustio load testing framework extension that aims to simplify writing load test scripts while also adding some functionality and awesome quirks.\n\nThe main idea behind the module is \"Endpoints as objects\". \nThis means less hardcoding, fewer decision blocks, smaller chances for mistakes and bugs, less stress and more fun.\n\n\n## Getting Started\n\nStarting to use the **Backpack** is simple. After placing the module in your working directory, import it from the Locust script:\n```\nimport locust_backpack as Backpack\n```\nAt this point, you are a proud user of the Locust Backpack. Time to put it to work.\n\n\n\n## Initialization\nAs mentioned earlier, the **Backpack** ideology is \"Endpoints as objects\". Thus, we have to create objects from all the endpoints which will later be used in the load test.\n\nThis can be done outside the TaskSet child class, in a different file, or just wherever we prefer.\n\nThe master class holding the endpoint data is **LocustEndpoint**. Each individual endpoint has to be initialized with an instance of this class, accepting the following parameters:\n```\nLocustEndpoint(self, endpoint, methods, name=None, headers=None, body=None)\n```\n\n| Argument |Description |Default|\n|----------------|-------------------------------|-----------------------------|\n|**endpoint (str)**|`string representing the actual endpoint`|`N/A`|\n|**methods (str or list)**|`string or list containing all the methods the endpoint supports`|`N/A`|\n|**name (str)** |`string representing a friendly or a debug name for the endpoint. This is the name the endpoint will have on the Locust UI`|`name = endpoint`|\n|**headers(dict)**|`the headers this endpoint will use`|`{}`|\n|**body(dict)**|`the body this endpoint will use`|`{}`|\n\n>Note: The values passed when initializing a LocustEndpoint are not permanent. These can be modified anytime during the test !\n\nExamples:\n\n**Only the mandatory parameters:**\n\n```\nTeamInit = Backpack.LocustEndpoint('/public/team/v1/init', 'post')\n```\n```\nPvP2Init = Backpack.LocustEndpoint('/public/pvp2/v1/init', ['post', 'get'])\n```\n\n**Passing a custom name**\n\n```\nResetSession = Backpack.LocustEndpoint('/public/session/v1/cheat/reset','post',\n name=\"/public/session/v1/cheat/reset::newUser\")\n```\n\n**Passing a body**\n\n```\nSessionStart = Backpack.LocustEndpoint('/public/session/v1/start', 'post',\n name=\"/public/session/v1/start::newUser\", \n body={\"device_type\": \"test\",\n \"device_id\": \"test\", \n \"version\": 320, \n \"language\": \"RO\", \n \"gender\": 1, \n \"name\": \"load_test\", \n \"platform\": 1})\n```\t\n\n\nOnce all our LocustEndpoints are created, we need access to the TaskSet in order to be able to make requests using Locust. This can be achieved in two ways:\n\nLooping through a list of all endpoints and applying their _attach()_ method to the current context:\n\n```\nfor endp in [TeamInit, ResetSession, SessionStart, PvP2Init, EventInit]:\n endp.attach(self)\n```\n\nCalling the Backpack method _Unzip()_ which does the same as above but saves you from providing a list of LocustEndpoints\n\n```\nBackpack.Unzip(self)\n```\n\n\n\n# Making Requests\n\n### Simple Request\n\nRemember ```self.client.post(...)``` ? Forget about it.\n\nLocust Backpack exposes a much simpler way of making a request and tracking it's result:\n```\nTeamInit.Request()\n``` \nor \n```\nTeamInit.Request('post')\n```\n\nCalling _Request()_ without a parameter will use the endpoint's passed method when initializing the LocustEndpoint. Specifying a method will use that method from the method pool.\n\n> Note: If **LocustEndpoint** was initialized with a list of methods and _Request()_ is called without arguments, a **MissingMethodException** will be thrown !\n\nBut what happens under the hood when we ```LocustEndpoint.Request()``` ?\n>* A self.client.method(*args) request is made, following the Locust style and using the default or provided method\n>* A status code check is performed, registering the request.success or request.failure for Locust\n>* A Result object is created, containing all the request information\n\n---\n\n### Simple-Chaining Dependent Requests\n\nWhat if we want to connect multiple requests, but we want each subsequent request to be made only if the previous one succeeds? It couldn't be any easier!\n\n```\nResetSession + SessionStart\n``` \n_...seriously, that's all..._\n\nThe above is translated to:\n>* Make a request to **ResetSession**\n>* Check the result of **ResetSession**\n>* If **ResetSession** is successful, make a request to **SessionStart**\n\nOf course, any number of requests can be chained:\n```\nTeamInit + ResetSession + SessionStart + EventInit\n```\nLet's say ```TeamInit``` fails in the above scenario. In such case, no request following it will be performed because the dependency chain has failed from that point.\n\n> Note: Simple-Chaining has no wait time between requests. If successful, each request will be made instantly after the previous one\n\n> Note: Simple-Chaining only support LocustEndpoints that were declared with a single method\n---\n### Advanced-Chaining Dependent Requests\n\nTo address the limitations of Simple-Chaining, Advanced-Chaining was created.\nAdvanced-Chaining is defined by the backpack class _Chain()_ as such:\n```\nChain(self, endpoints, independent=False, wait=0)\n```\n\n| Argument |Description |Default|\n|----------------|-------------------------------|-----------------------------|\n|**endpoints (list of tuples )**|`list of tuples containing an endpoint and it's method`|`N/A`|\n|**independent(bool)**|`wether or not the provided endpoints depend on the success of the previous one`|`False`|\n|**wait(int)** |`integer representing how much time to wait between making the provided requests`|`0`|\n\n\n\nExample:\n```\nBackpack.Chain([(PvP2Init, 'get'), (PvP2Init, 'post')], wait=2)\n```\n\n\n\n# Scenarios\n\nWhat if there was an easy way to build and run a scenario? Well there isn't one way to do it, but multiple.\n\n\n### Simple Scenario\n\nThe most basic way of building a scenario is the backpack's _Scenario()_ class.\n\n```Scenario(self, endpoints, wait=1, runtime=None, independent_requests=False)```\n\n| Argument |Description |Default|\n|----------------|-------------------------------|-----------------------------|\n|**endpoints (list of tuples )**|`list of tuples containing an endpoint and it's method`|`N/A`|\n|**wait(int)**|`integer representing how much time to wait(sec) between making the provided requests`|`1`|\n|**runtime(int)** |`integer representing the runtime(sec) of the scenario`|`None`|\n|**independent_requests(bool)**|`wether or not the provided endpoints depend on the success of the previous one`|`False`|\n\nExample:\n```\nscenario_endpoints = [(TeamInit, 'post'), (ResetSession, 'post'),\n (SessionStart, 'post'), (PvP2Init, 'get'),\n (PvP2Init, 'post'), (EventInit, 'post')]\n```\n\n```\nSCENARIO = backpack.Scenario(scenario_endpoints, runtime=10, independent_requests=True)\n```\n\nBut this will not run the Scenario yet! Two methods are available for running the scenario:\n\n```\nSCENARIO.run()\n```\nOr if you would like to run the scenario only once, regardless of runtime:\n```\nSCENARIO.run_once()\n```\n\n---\n### Weighted Scenario\nMaybe we want to add a chance for endpoints when running a scenario.\nFor that purpose, _WeightedScenario()_ comes into play. Subclassing the Simple Scenario, there are only two minor differences between them:\n\n>* WeightedScenario() does not have an independent_requests argument\n>* The tuples passed to WeightedScenario() have a 3rd element representing an int between 1-100 which is that chance for that request to be made (100 meaning 100% chance)\n\nExample:\n```\nscenario_endpoints = [(TeamInit, 'post', 100), (ResetSession, 'post', 20),\n (SessionStart, 'post', 100), (PvP2Init, 'get', 75), \n (PvP2Init, 'post', 15), (EventInit, 'post', 50)]\n\nSCENARIO_2 = Backpack.WeightedScenario(scenario_endpoints, runtime=15)\n\nSCENARIO_2.run()\n```\nor \n```\nSCENARIO.run_once()\n```\n\n---\n### Sequenced Scenario (WIP)\nOne other way of building a scenario is using the _Backpack.SequenceScenario()_ feature\n\nWhat this scenario builder has special is it's ability to receive a list-of-lists-of-tuples or a list-of-tuples-of-lists-of-tuples.\n\nExample:\n\nFirst, we define some sequences. These are lists of tuples containing the LocustEndpoint, it's method and an **optional** weight/chance\n\n```\nsequence_1 = [(TeamInit, 'post', 10), (ResetSession, 'post', 20)]\nsequence_2 = [(SessionStart, 'post', 30), (PvP2Init, 'get', 20)]\nsequence_3 = [(PvP2Init, 'post', 50), (EventInit, 'post', 80)]\n```\n\nThen we build the sequenced scenario by passing the sequences above and an **optional** weight/chance\n\n```\nSCENARIO_3 = Backpack.SequenceScenario([sequence_1, sequence_2, sequence_3])\n```\nOR\n```\nSCENARIO_3 = Backpack.SequenceScenario([(sequence_1, 40), (sequence_2, 70), (sequence_3, 25)])\n```\n\nThen we can finally call the _run()_ method:\n\n```\nSCENARIO_3.run()\n``` \nor \n```\nSCENARIO_3.run_once()\n```\n\n# The Result Object\nWhenever a LocustEndpoint makes a request, a _Result_ object is created. Every subsequent request to that LocustEndpoint overwrites the previous Result object.\n\nThis Result object holds information about the latest request to it's endpoint and has a few useful attributes as well:\n\n```\nLocustEndpoint.Result.success # Equals True if request is successful\nLocustEndpoint.Result.failure # Equals True if request has failed\nLocustEndpoint.Result.status_code # Equals the status code of the request\nLocustEndpoint.Result.response # Contains the bare response of the request\n```\n\n```\nLocustEndpoint.Result.json() # Tries to return the json-formatted response \n```\n\n\n# Dependency building\nThe Locust Backpack is a deep one, with many pockets. \n\nLet's assume we have an endpoint that needs an element from the response of another endpoint. Of course, we could parse the response and assign that specific key/element to the other endpoint, but why go through all that trouble every time?\n\nFor example, let's say we have an endpoint ```EventInit``` that needs the key ```'player'``` from another endpoint ```SessionStart```\n\nWe can permanently declare this dependency anywhere in the Locust script with the following:\n\n```\nEventInit >> DEPENDS_ON('player') >> SessionStart\n```\n\nOnce this is done, every successful request to ```SessionStart``` will assign it's ```player``` key to ```EventInit```'s body, making ```EventInit``` use it in future requests.\n\n\n# Other features\nDon't think that's all. This backpack is prepared for long journeys.\n\n---\n## Sealing and Unsealing\n\nEach LocustEndpoint has sealing and unsealing features which can be activated and deactivated with\n\n```\nEventInit.seal\n```\n```\nEventInit.unseal\n```\n\nSealing an endpoint means that the endpoint will be unable to make any further requests until being unsealed.\n\nThis does not interfere in any way with the script logic, but once a sealed endpoint request is reached, the request part is skipped and that endpoint's latest Result will be set to a silent fail (not registered anywhere)\n\nThere is also a way of sealing and unsealing all LocustEndpoints at once:\n\n```\nBackpack.SealAll()\n```\n```\nBackpack.UnsealAll()\n```\n\n---\n## Check a Request's Success\n\nAside from using the _Result()_ object to access all information regarding the latest request, including the success with ```EventInit.Result.success```, we can use a simpler and quicker way:\n\nMore specifically, we can check for the _truthness_ of a LocustEndpoint instance\n```\nif EventInit: # Your code\n```\n\nIn other words, the following two methods have the exact same result:\n```\nif EventInit.Result.success: # Code\n```\n```\nif EventInit: # Code\n```\n\n---\n## Mass Assignation\n\nAs already mentioned, attributes of a LocustEndpoint can be changed anytime. But what if you want to modify or create a variable for all (or more than one) LocustEndpoints?\n\nThis is achieved using _Backpack.SetGlobal()_\n\n| Argument |Description |Default |\n|----------------|-------------------------------|-----------------------------|\n|**variable (str)**|`the variable that will be modified or created`|`N/A`|\n|**value (anything)**|`value of variable`|`N/A`|\n|**selective (list)** |`integer representing the runtime(sec) of the scenario`|`All LocustEndpoints`|\n\nExample:\n\n**Setting the same header for all LocustEndpoints**\n```\nBackpack.SetGlobal('headers', auth_header)\n```\n\n**Or just for specific LocustEndpoints**\n```\nBackpack.SetGlobal('headers', auth_header, selective=[EventInit, TeamInit])\n```\n\n---\n## Zipping (WIP)\n\nEvery unzipped backpack should be zipped back. It would be a pitty to lose anything from it.\n\nTo that effect, the Backpack function _Zip()_ was created.\n\nCalling ```Backpack.Zip()``` from anywhere within your current test will save all the test data to a folder within your workspace.\n\nZip() will:\n>* Check if the Locust address \"http://localhost:8089/\" is accessible\n>* Download the Locust .csv files\n>* Build a clone of the Locust stats page\n>* Use seaborn to plot the test details\n>* Nicely save everything to a datestamped folder in your current working directory\n\n> Note! Due to the fact that all zipping operations are done on a localhost URL, _Zip()_ should only be called by the Locust Master\n\n\n\n## Flow Chart of a LocustEndpoint Request\n\n```mermaid\ngraph TB\n\nA(LocustEndpoint) -- Request --> B(TaskSet.client.method)\nB -- status_check --> C(Request Result)\nC -- request.success --> D(LocustEndpoint.Result)\nD --> F(Resolve dependencies)\nC -- request.failure --> E(LocustEndpoint.Result)\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "locustio-backpack", "package_url": "https://pypi.org/project/locustio-backpack/", "platform": "", "project_url": "https://pypi.org/project/locustio-backpack/", "project_urls": null, "release_url": "https://pypi.org/project/locustio-backpack/0.3.0/", "requires_dist": [ "pandas (==0.23.4)", "setuptools (==41.0.1)", "wget (==3.2)", "numpy (==1.15.4)", "gevent (==1.3.7)", "matplotlib (==2.2.4)", "requests (==2.21.0)", "locustio (==0.9.0)" ], "requires_python": ">=2.7", "summary": "Locust Framework Extension", "version": "0.3.0" }, "last_serial": 5330964, "releases": { "0.2": [ { "comment_text": "", "digests": { "md5": "441d2b42030d465d2289e97108059501", "sha256": "01a443cddb3365eab82571b9e46ed2bfe3bc5db3cf4fe2e3492585f9ce474245" }, "downloads": -1, "filename": "locustio_backpack-0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "441d2b42030d465d2289e97108059501", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 16036, "upload_time": "2019-05-14T11:14:17", "url": "https://files.pythonhosted.org/packages/26/db/dc71ef467eeb4d0e4a872ea1ec44e4a1417606d31739748f7f9e42aee083/locustio_backpack-0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "eb4bba1d7c6c28eb508615b6100bf2dd", "sha256": "0a53b7a8aa676f25bfafb3b97697f1c262b5e6c1352cebc45ba4eadcc68d170f" }, "downloads": -1, "filename": "locustio-backpack-0.2.tar.gz", "has_sig": false, "md5_digest": "eb4bba1d7c6c28eb508615b6100bf2dd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 14426, "upload_time": "2019-05-14T11:14:20", "url": "https://files.pythonhosted.org/packages/93/0d/4721d3e79c274696c730b45c115554c2b2b39e01b2496ee0b4e44c4cb0dc/locustio-backpack-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "01c2357307b69b30e28fa911637463cc", "sha256": "d588d65abda5dfb199e45e6477e66977ff1dfb3c55553469bd5d337eff2e5b41" }, "downloads": -1, "filename": "locustio_backpack-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "01c2357307b69b30e28fa911637463cc", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 18252, "upload_time": "2019-05-21T04:54:06", "url": "https://files.pythonhosted.org/packages/a6/a6/224b2c2ae1b8e4c627b23619de9b999f44757888b539480cbefefa58645b/locustio_backpack-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cfcbb5f6da146598f2c92f75c72fac66", "sha256": "285f5c9d95fd06aa99eed509b2f0a720d514ad66ef5e047dfca28dcaa79a821b" }, "downloads": -1, "filename": "locustio-backpack-0.2.1.tar.gz", "has_sig": false, "md5_digest": "cfcbb5f6da146598f2c92f75c72fac66", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 20594, "upload_time": "2019-05-21T04:54:08", "url": "https://files.pythonhosted.org/packages/0f/e0/baa07efb5c6a6144b2b269cd6c1258e9214179af59c0a32343bcf35bfe46/locustio-backpack-0.2.1.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "dcfd0176e37a8c8bbb5db3fe5458db3f", "sha256": "e3091f7925ed518022b8a70f19900b058f9b5f86b4844c14c48ad4d9a3fe9873" }, "downloads": -1, "filename": "locustio_backpack-0.2.5-py3-none-any.whl", "has_sig": false, "md5_digest": "dcfd0176e37a8c8bbb5db3fe5458db3f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 21124, "upload_time": "2019-05-29T07:19:18", "url": "https://files.pythonhosted.org/packages/80/fb/c874d1bea73418bb1f2973d1c10e603cc1f2dbddfb7eae3725a5253f27a5/locustio_backpack-0.2.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1eb9c79ddf235fdf10995b0ed394d715", "sha256": "5ff6e057fa170babf3183865c0d889488285abc7474aad3c1e98a6c6bf210323" }, "downloads": -1, "filename": "locustio-backpack-0.2.5.tar.gz", "has_sig": false, "md5_digest": "1eb9c79ddf235fdf10995b0ed394d715", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 22861, "upload_time": "2019-05-29T07:19:19", "url": "https://files.pythonhosted.org/packages/4a/79/e8bc73a0a7e61150d01d846e234fcad8a56c2b845320ec729020d274fd00/locustio-backpack-0.2.5.tar.gz" } ], "0.2.6": [ { "comment_text": "", "digests": { "md5": "c3038f3fe2159c7d6f01f2182cb02950", "sha256": "f0fda188be5f47e053379b07c8d8b0cc361fbf591d89004540776601f14cd863" }, "downloads": -1, "filename": "locustio_backpack-0.2.6-py3-none-any.whl", "has_sig": false, "md5_digest": "c3038f3fe2159c7d6f01f2182cb02950", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 21120, "upload_time": "2019-05-29T07:23:05", "url": "https://files.pythonhosted.org/packages/17/e4/12f02949c6ed0860e4930b2dd54f846561c71679cc55c3a49feba3f01c94/locustio_backpack-0.2.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e9838bd95f2b324763680138279e0154", "sha256": "4429340e7fb9ae10a90086c9105820909c4ef4fc4ff159dba556d6496976435b" }, "downloads": -1, "filename": "locustio-backpack-0.2.6.tar.gz", "has_sig": false, "md5_digest": "e9838bd95f2b324763680138279e0154", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 18334, "upload_time": "2019-05-29T07:23:06", "url": "https://files.pythonhosted.org/packages/4c/2d/b142857bd4913447db98a98d613c42146bb36049cc01ee875bf4e6a6f3a4/locustio-backpack-0.2.6.tar.gz" } ], "0.2.7": [ { "comment_text": "", "digests": { "md5": "0003451a4e088eb11d0024b34fcdcb3b", "sha256": "c95b4856e57937ca3be3bcfd50c839a48e67e4c677661f588393b72b7e21ebaa" }, "downloads": -1, "filename": "locustio_backpack-0.2.7-py3-none-any.whl", "has_sig": false, "md5_digest": "0003451a4e088eb11d0024b34fcdcb3b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 21129, "upload_time": "2019-05-29T07:25:26", "url": "https://files.pythonhosted.org/packages/dd/dc/fd74494271a9052388f159deb87581e710b7abc162e1e1ab3528a1ecdc7c/locustio_backpack-0.2.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2bd8119e9f42b5940cf26bb9601d894d", "sha256": "84b5d9f752dc66d8aa7326bcf4db9b80a3286d7c481fdad963e6ed8cfb46258c" }, "downloads": -1, "filename": "locustio-backpack-0.2.7.tar.gz", "has_sig": false, "md5_digest": "2bd8119e9f42b5940cf26bb9601d894d", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 18350, "upload_time": "2019-05-29T07:25:28", "url": "https://files.pythonhosted.org/packages/0a/55/d6d70e57b3669424c0ddb493328f6ffec4f9adfa82be6c66488c7a397d5e/locustio-backpack-0.2.7.tar.gz" } ], "0.2.8": [ { "comment_text": "", "digests": { "md5": "917f64f2ac1021d49cecea1825fff473", "sha256": "e14a6dfaee172dd43de18d377a6d26282d9b3bf2c0f8e86a4453b2732bdcde13" }, "downloads": -1, "filename": "locustio_backpack-0.2.8-py3-none-any.whl", "has_sig": false, "md5_digest": "917f64f2ac1021d49cecea1825fff473", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 21132, "upload_time": "2019-05-29T07:27:06", "url": "https://files.pythonhosted.org/packages/cf/c5/4fe9cbc0085072491f983345172f4a5933c408d24e52fbb9c7a9ecd2ef36/locustio_backpack-0.2.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d2a5843781136ab2c0e1e7f8d33da7d8", "sha256": "aa1afc9dc1cf159fde310292600693dc4ad3feef0a05e32dca886f8b7a34ebbd" }, "downloads": -1, "filename": "locustio-backpack-0.2.8.tar.gz", "has_sig": false, "md5_digest": "d2a5843781136ab2c0e1e7f8d33da7d8", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 18378, "upload_time": "2019-05-29T07:27:07", "url": "https://files.pythonhosted.org/packages/51/58/2d88cc8399dc73462b916046ed478bdaa4c9ba560500ea1f77314a8b8bf5/locustio-backpack-0.2.8.tar.gz" } ], "0.2.9": [ { "comment_text": "", "digests": { "md5": "7bba2a95c1910a3307b776b42f865350", "sha256": "bd1b86dcceb63007cb93b9cdd0fa0d1aa49dd6887de9654566bc3e0b107bed02" }, "downloads": -1, "filename": "locustio_backpack-0.2.9-py3-none-any.whl", "has_sig": false, "md5_digest": "7bba2a95c1910a3307b776b42f865350", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 21128, "upload_time": "2019-05-29T07:29:14", "url": "https://files.pythonhosted.org/packages/c3/b2/cbec2fcaa21836f5cc935ea0a3caaced37d9464bb56a097c128b62e7fe11/locustio_backpack-0.2.9-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "dd84943cad00f157b651a5fa256b1f23", "sha256": "d101b14caa01815c2a2cd34ccf60aa0159f14e5d40000a7f1d87833bc6f3121f" }, "downloads": -1, "filename": "locustio-backpack-0.2.9.tar.gz", "has_sig": false, "md5_digest": "dd84943cad00f157b651a5fa256b1f23", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 18362, "upload_time": "2019-05-29T07:29:16", "url": "https://files.pythonhosted.org/packages/5e/09/9298bb1df587485cc494cc9be5bc5e72f2c24b51f93390561987f31c5b53/locustio-backpack-0.2.9.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "9cf1c88490506719690c1747939e7f16", "sha256": "5b2431299fc52a762e66b5a068882072fa149ba29840e1a910b2858f3442fd04" }, "downloads": -1, "filename": "locustio_backpack-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "9cf1c88490506719690c1747939e7f16", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 21106, "upload_time": "2019-05-29T07:45:17", "url": "https://files.pythonhosted.org/packages/40/97/17abeccb19fb6f9affce12f8aeee23fe751d734963e636babfd329e2ed1b/locustio_backpack-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "419abf39d95fd0086c4cad02fc61292c", "sha256": "f9431a5d681085c456cc9d49f84bd95995e01a2cd9bfd44bb3b740139c7fd5aa" }, "downloads": -1, "filename": "locustio-backpack-0.3.0.tar.gz", "has_sig": false, "md5_digest": "419abf39d95fd0086c4cad02fc61292c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 18344, "upload_time": "2019-05-29T07:45:18", "url": "https://files.pythonhosted.org/packages/70/cd/6b8a85e547609035d71869c79943d0c1c6d9f486b4eda281ec2f19d70dce/locustio-backpack-0.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9cf1c88490506719690c1747939e7f16", "sha256": "5b2431299fc52a762e66b5a068882072fa149ba29840e1a910b2858f3442fd04" }, "downloads": -1, "filename": "locustio_backpack-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "9cf1c88490506719690c1747939e7f16", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 21106, "upload_time": "2019-05-29T07:45:17", "url": "https://files.pythonhosted.org/packages/40/97/17abeccb19fb6f9affce12f8aeee23fe751d734963e636babfd329e2ed1b/locustio_backpack-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "419abf39d95fd0086c4cad02fc61292c", "sha256": "f9431a5d681085c456cc9d49f84bd95995e01a2cd9bfd44bb3b740139c7fd5aa" }, "downloads": -1, "filename": "locustio-backpack-0.3.0.tar.gz", "has_sig": false, "md5_digest": "419abf39d95fd0086c4cad02fc61292c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 18344, "upload_time": "2019-05-29T07:45:18", "url": "https://files.pythonhosted.org/packages/70/cd/6b8a85e547609035d71869c79943d0c1c6d9f486b4eda281ec2f19d70dce/locustio-backpack-0.3.0.tar.gz" } ] }