{ "info": { "author": "Max Williams", "author_email": "futuresharks@gmail.com", "bugtrack_url": null, "classifiers": [ "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Quality Assurance", "Topic :: Software Development :: Testing", "Topic :: Software Development :: Testing :: Traffic Generation" ], "description": "# invokust\n\nA tool for running [Locust](http://locust.io/) load tests from within Python without the need to use the locust command line. This gives more flexibility for automation such as QA/CI/CD tests and also makes it possible to run locust on [AWS Lambda](https://aws.amazon.com/lambda/) for ultimate scalability.\n\n## Installation\n\nInstall via pip:\n\n```\npip3 install invokust\n```\n\n## Examples\n\nRunning a load test using a locust file:\n\n```python\nimport invokust\n\nsettings = invokust.create_settings(\n locustfile='locustfile_example.py',\n host='http://example.com',\n num_clients=1,\n hatch_rate=1,\n run_time='3m'\n )\n\nloadtest = invokust.LocustLoadTest(settings)\nloadtest.run()\nloadtest.stats()\n'{\"num_requests_fail\": 0, \"num_requests\": 10, \"success\": {\"/\": {\"median_response_time\": 210, \"total_rpm\": 48.13724156297892, \"request_type\": \"GET\", \"min_response_time\": 210, \"response_times\": {\"720\": 1, \"210\": 7, \"820\": 1, \"350\": 1}, \"num_requests\": 10, \"response_time_percentiles\": {\"65\": 210, \"95\": 820, \"75\": 350, \"85\": 720, \"55\": 210}, \"total_rps\": 0.802287359382982, \"max_response_time\": 824, \"avg_response_time\": 337.2}}, \"locust_host\": \"http://example.com\", \"fail\": {}, \"num_requests_success\": 10}'\n```\n\nRunning a load test without locust file:\n\n```python\nimport invokust\n\nfrom locust import HttpLocust, TaskSet, task\n\nclass Task(TaskSet):\n @task()\n def get_home_page(self):\n '''\n Gets /\n '''\n self.client.get(\"/\")\n\nclass WebsiteUser(HttpLocust):\n task_set = Task\n\nsettings = invokust.create_settings(\n classes=[WebsiteUser],\n host='http://example.com',\n num_clients=1,\n hatch_rate=1,\n run_time='3m'\n )\n\nloadtest = invokust.LocustLoadTest(settings)\nloadtest.run()\nloadtest.stats()\n'{\"num_requests_fail\": 0, \"num_requests\": 10, \"success\": {\"/\": {\"median_response_time\": 330, \"total_rpm\": 40.53552561950598, \"request_type\": \"GET\", \"min_response_time\": 208, \"response_times\": {\"230\": 1, \"1000\": 1, \"780\": 1, \"330\": 1, \"1100\": 1, \"210\": 3, \"790\": 1, \"670\": 1}, \"num_requests\": 10, \"response_time_percentiles\": {\"65\": 780, \"95\": 1100, \"75\": 790, \"85\": 1000, \"55\": 670}, \"total_rps\": 0.6755920936584331, \"max_response_time\": 1111, \"avg_response_time\": 552.8}}, \"locust_host\": \"http://example.com\", \"fail\": {}, \"num_requests_success\": 10}'\n```\n\n## Running Locust on AWS Lambda\n\n\"Lambda\"Locust\n\n[AWS Lambda](https://aws.amazon.com/lambda/) is a great tool for load testing as it is very cheap (or free) and highly scalable.\n\nThere are many load testing tools such as [ab](https://httpd.apache.org/docs/2.4/programs/ab.html) and [wrk](https://github.com/wg/wrk). Then there are other cloud based load testing options such as [BlazeMeter](https://www.blazemeter.com/) or [Loader](https://loader.io/) and some more DIY solutions that use AWS Lambda too such as [Goad](https://goad.io/) or [serverless-artillery](https://github.com/Nordstrom/serverless-artillery). But these all have the same drawback: They are too simplistic. They can perform simple GET or POST requests but can't accurately emulate more complex behaviour. e.g. browsing a website, selecting random items, filling a shopping cart and checking out. But with [Locust](http://locust.io/) this is possible.\n\nIncluded is an example function for running Locust on AWS Lambda, `lambda_locust.py`.\n\n### Creating a Lambda function\n\nThe process for running a locust test on Lambda involves [creating a zip file](http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html) of the locust load test, creating a Lambda function and then triggering the function.\n\nInstall invokust (and its dependencies) python packages locally:\n\n```\npip3 install invokust --target=python-packages\n```\n\nOr if running on a Mac (python packages need to be compiled for 64 bit Linux) you can use docker:\n\n```\ndocker run -it --volume=$PWD/python-packages:/python-packages python:3.6 bash -c \"pip install invokust --target=/python-packages\"\n```\n\nCreate the zip file:\n\n```\nzip -q -r lambda_locust.zip lambda_locust.py locustfile_example.py python-packages\n```\n\nThen create the Lambda function using using the AWS CLI:\n\n```\naws lambda create-function --function-name lambda_locust --timeout 300 --runtime python3.6 --role arn:aws:iam::9999999999:role/lambda_basic_execution --handler lambda_locust.handler --zip-file fileb://lambda_locust.zip\n```\n\nOr [Terraform](https://www.terraform.io/) and the example [main.tf](main.tf) file:\n\n```\nterraform apply\n...\n```\n\n### Invoking the function\n\nThe Locust settings can be passed to the Lambda function or can be set from environment variables. The environment variables are:\n\n - LOCUST_LOCUSTFILE: Locust file to use for the load test\n - LOCUST_CLASSES: Names of locust classes to use for the load test (instead of a locustfile). If more than one, separate with comma.\n - LOCUST_HOST: The host to run the load test against\n - LOCUST_NUM_CLIENTS: Number of clients to simulate\n - LOCUST_HATCH_RATE: Number of clients per second to start\n - LOCUST_RUN_TIME: The time the test should run for.\n\n[AWS CLI](https://aws.amazon.com/cli/) example with Locust settings in a payload:\n\n```\naws lambda invoke --function-name lambda_locust --invocation-type RequestResponse --payload '{\"locustfile\": \"locustfile_example.py\", \"host\":\"https://example.com\", \"num_requests\":\"20\", \"num_clients\": \"1\", \"hatch_rate\": \"1\", \"run_time\":\"3m\"}' output.txt\n{\n \"StatusCode\": 200\n}\ncat output.txt\n\"{\\\"success\\\": {\\\"GET_/\\\": {\\\"request_type\\\": \\\"GET\\\", \\\"num_requests\\\": 20, \\\"min_response_time\\\": 86, \\\"median_response_time\\\": 93 ...\n```\n\nPython boto3 example:\n\n```python\nimport json\nfrom boto3.session import Session\nfrom botocore.client import Config\n\nsession = Session()\nconfig = Config(connect_timeout=10, read_timeout=310)\nclient = session.client('lambda', config=config)\n\nlambda_payload = {\n 'locustfile': 'locustfile_example.py',\n 'host': 'https://example.com',\n 'num_clients': '1',\n 'hatch_rate': 1,\n 'run_time':'3m'\n}\n\nresponse = client.invoke(FunctionName='lambda_locust', Payload=json.dumps(lambda_payload))\njson.loads(response['Payload'].read())\n'{\"success\": {\"GET_/\": {\"request_type\": \"GET\", \"num_requests\": 20, \"min_response_time\": 87, \"median_response_time\": 99, \"avg_response_time\": 97.35 ...\n```\n\n### Running a real load test\n\nLambda function execution time is limited to a maximum of 5 minutes. To run a real load test the function will need to be invoked repeatedly and likely in parallel to generate enough load. To manage this there is a class called `LambdaLoadTest` that can manage invoking the function in parallel loops and collecting the statistics.\n\n```python\nimport logging\nfrom invokust.aws_lambda import LambdaLoadTest\n\nlogging.basicConfig(level=logging.INFO)\n\nlambda_payload = {\n 'locustfile': 'locustfile_example.py',\n 'host': 'https://example.com',\n 'num_clients': '1',\n 'hatch_rate': 1,\n 'run_time':'3m'\n}\n\nload_test = LambdaLoadTest(\n lambda_function_name='lambda_locust',\n threads=2,\n ramp_time=0,\n time_limit=30,\n lambda_payload=lambda_payload\n)\n\nload_test.run()\nINFO:root:\nStarting load test\nFunction: lambda_locust\nRamp time: 0\nThreads: 2\nLambda payload: {'locustfile': 'locustfile_example.py', 'host': 'https://example.com', 'run_time': '30s', 'num_clients': '1', 'hatch_rate': 1, 'run_time':'3m'}\n\nINFO:root:thread started\nINFO:root:threads: 1, rpm: 0, run_time: 0, requests_total: 0, request_fail_ratio: 0, invocation_error_ratio: 0\nINFO:root:threads: 1, rpm: 0, run_time: 3, requests_total: 0, request_fail_ratio: 0, invocation_error_ratio: 0\nINFO:root:thread started\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 2982, sleeping: 0\nINFO:root:threads: 2, rpm: 368, run_time: 6, requests_total: 20, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 2896, sleeping: 0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3023, sleeping: 0\nINFO:root:threads: 2, rpm: 770, run_time: 9, requests_total: 60, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3041, sleeping: 0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3071, sleeping: 0\nINFO:root:threads: 2, rpm: 768, run_time: 12, requests_total: 100, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3031, sleeping: 0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 2965, sleeping: 0\nINFO:root:threads: 2, rpm: 782, run_time: 15, requests_total: 140, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 2957, sleeping: 0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3069, sleeping: 0\nINFO:root:threads: 2, rpm: 779, run_time: 18, requests_total: 180, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3015, sleeping: 0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3018, sleeping: 0\nINFO:root:threads: 2, rpm: 771, run_time: 21, requests_total: 220, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3055, sleeping: 0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3015, sleeping: 0\nINFO:root:threads: 2, rpm: 771, run_time: 24, requests_total: 260, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3007, sleeping: 0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3012, sleeping: 0\nINFO:root:threads: 2, rpm: 779, run_time: 27, requests_total: 300, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3029, sleeping: 0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3037, sleeping: 0\nINFO:root:threads: 2, rpm: 773, run_time: 30, requests_total: 340, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3078, sleeping: 0\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3100, sleeping: 0\nINFO:root:threads: 2, rpm: 758, run_time: 33, requests_total: 380, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\nINFO:root:Time limit reached\nINFO:root:Waiting for threads to exit...\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 2965, sleeping: 0\nINFO:root:thread finished\nINFO:invokust.aws_lambda.lambda_load_test:Invocation complete. Requests (errors): 20 (0), execution time: 3033, sleeping: 0\nINFO:root:thread finished\n\nload_test.get_summary_stats()\n{'lambda_invocation_count': 21, 'total_lambda_execution_time': 63399, 'requests_total': 420, 'request_fail_ratio': 0.0, 'invocation_error_ratio': 0.0}\n```\n\nThere is also an example CLI tool for running a load test, `invokr.py`:\n\n```\n$ ./invokr.py --function_name=lambda_locust --locust_file=locustfile_example.py --locust_host=https://example.com --threads=1 --time_limit=30 --locust_requests=20\n2017-05-22 20:16:22,432 INFO MainThread\nStarting load test\nFunction: lambda_locust\nRamp time: 0\nThreads: 1\nLambda payload: {'locustfile': 'locustfile_example.py', 'host': 'https://example.com', 'num_requests': 20, 'num_clients': 20, 'hatch_rate': 10, 'run_time':'3m'}\n\n2017-05-22 20:16:22,432 INFO thread_1 thread started\n2017-05-22 20:16:22,436 INFO MainThread threads: 1, rpm: 0, run_time: 0, requests_total: 0, request_fail_ratio: 0, invocation_error_ratio: 0\n2017-05-22 20:16:25,440 INFO MainThread threads: 1, rpm: 0, run_time: 3, requests_total: 0, request_fail_ratio: 0, invocation_error_ratio: 0\n2017-05-22 20:16:27,983 INFO thread_1 Invocation complete. Requests (errors): 20 (0), execution time: 5186, sleeping: 0\n2017-05-22 20:16:28,446 INFO MainThread threads: 1, rpm: 216, run_time: 6, requests_total: 20, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:31,448 INFO MainThread threads: 1, rpm: 216, run_time: 9, requests_total: 20, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:32,860 INFO thread_1 Invocation complete. Requests (errors): 20 (0), execution time: 4798, sleeping: 0\n2017-05-22 20:16:34,453 INFO MainThread threads: 1, rpm: 246, run_time: 12, requests_total: 40, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:37,454 INFO MainThread threads: 1, rpm: 246, run_time: 15, requests_total: 40, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:38,110 INFO thread_1 Invocation complete. Requests (errors): 20 (0), execution time: 5176, sleeping: 0\n2017-05-22 20:16:40,458 INFO MainThread threads: 1, rpm: 229, run_time: 18, requests_total: 60, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:43,072 INFO thread_1 Invocation complete. Requests (errors): 20 (0), execution time: 4882, sleeping: 0\n2017-05-22 20:16:43,464 INFO MainThread threads: 1, rpm: 242, run_time: 21, requests_total: 80, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:46,466 INFO MainThread threads: 1, rpm: 242, run_time: 24, requests_total: 80, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:48,237 INFO thread_1 Invocation complete. Requests (errors): 20 (0), execution time: 5041, sleeping: 0\n2017-05-22 20:16:49,467 INFO MainThread threads: 1, rpm: 232, run_time: 27, requests_total: 100, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:52,468 INFO MainThread threads: 1, rpm: 232, run_time: 30, requests_total: 100, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:53,347 INFO thread_1 Invocation complete. Requests (errors): 20 (0), execution time: 5041, sleeping: 0\n2017-05-22 20:16:55,468 INFO MainThread threads: 1, rpm: 235, run_time: 33, requests_total: 120, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:55,468 INFO MainThread Time limit reached\n2017-05-22 20:16:55,468 INFO MainThread Waiting for threads to exit...\n2017-05-22 20:16:58,666 INFO thread_1 Invocation complete. Requests (errors): 20 (0), execution time: 5209, sleeping: 0\n2017-05-22 20:16:58,667 INFO thread_1 thread finished\n2017-05-22 20:16:59,484 INFO MainThread Load test finished. lambda_invocation_count: 7, total_lambda_execution_time: 35333, requests_total: 140, request_fail_ratio: 0.0, invocation_error_ratio: 0.0\n2017-05-22 20:16:59,484 INFO MainThread Aggregated results: {'success': {'GET_/': {'median_response_time': 285.7142857142857, 'total_rps': 19.753860147907517, 'avg_response_time': 615.4214285714286, 'max_response_time': 1703, 'min_response_time': 100, 'response_times': {'1100': 6, '1400': 9, '120': 2, '140': 14, '960': 3, '180': 9, '160': 11, '260': 6, '300': 3, '1200': 6, '340': 3, '200': 12, '1700': 2, '220': 9, '1300': 10, '380': 3, '440': 5, '240': 5, '1000': 2, '480': 2, '1600': 2, '1500': 9, '100': 1, '360': 1, '540': 1, '940': 1, '280': 1, '320': 1, '400': 1}, 'total_rpm': 1185.231608874451}}, 'fail': {}, 'num_requests': 140, 'num_requests_fail': 0, 'num_requests_success': 140, 'total_time': 35333, 'invocations': 7, 'approximate_cost': 7.4824e-05}\n2017-05-22 20:16:59,484 INFO MainThread Exiting...\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "https://github.com/FutureSharks/invokust/archive/0.41.tar.gz", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/FutureSharks/invokust", "keywords": "testing,loadtest,lamba,locust", "license": "GPLv2", "maintainer": "", "maintainer_email": "", "name": "invokust", "package_url": "https://pypi.org/project/invokust/", "platform": "", "project_url": "https://pypi.org/project/invokust/", "project_urls": { "Download": "https://github.com/FutureSharks/invokust/archive/0.41.tar.gz", "Homepage": "https://github.com/FutureSharks/invokust" }, "release_url": "https://pypi.org/project/invokust/0.52/", "requires_dist": [ "locustio (==0.9.0)", "boto3", "pyzmq", "numpy" ], "requires_python": "", "summary": "A small wrapper for locust to allow running load tests from within Python or on AWS Lambda", "version": "0.52" }, "last_serial": 4992275, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "90fed5af6fdb989289b8946cd8bcefdb", "sha256": "3bfd59a0d94bb6cbc46d7edadaa166c8fae4dbe5b5a611a2b778014eaf507e76" }, "downloads": -1, "filename": "invokust-0.1.tar.gz", "has_sig": false, "md5_digest": "90fed5af6fdb989289b8946cd8bcefdb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3027, "upload_time": "2017-04-02T14:48:35", "url": "https://files.pythonhosted.org/packages/4f/93/f1e822aad172d5cc6489ff0bc14ee8ab6dfe4000422e0a4b06b18dc0e183/invokust-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "7bf2261f7648099724c1eed875bbe9ef", "sha256": "231ff2a4242c51dc23875770650327de68970e38f5d188296fc4a106090a15ff" }, "downloads": -1, "filename": "invokust-0.2.tar.gz", "has_sig": false, "md5_digest": "7bf2261f7648099724c1eed875bbe9ef", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3125, "upload_time": "2017-04-20T17:19:36", "url": "https://files.pythonhosted.org/packages/8f/48/86586453d555ff94b2569f8bd1973880349183b1449f1087ff0ae6cacfae/invokust-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "36a26f7bda59baf742a8d63e3949b06b", "sha256": "273fb257e449ccf9cb412d49eab1530d8308bfe22bd2d8446d396bd65bbfb081" }, "downloads": -1, "filename": "invokust-0.3.tar.gz", "has_sig": false, "md5_digest": "36a26f7bda59baf742a8d63e3949b06b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3127, "upload_time": "2017-04-20T17:23:15", "url": "https://files.pythonhosted.org/packages/e4/91/b953f8638e402a26f4db60269fc347e9447443a1b811484446a250afd5a0/invokust-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "4519ff0c815c86aa73e74d0f53749e86", "sha256": "d5fc3a5c04fc723916e8fa63bd38e154b8522f463afc533dde362424f86a977f" }, "downloads": -1, "filename": "invokust-0.4.tar.gz", "has_sig": false, "md5_digest": "4519ff0c815c86aa73e74d0f53749e86", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7328, "upload_time": "2017-05-22T18:37:05", "url": "https://files.pythonhosted.org/packages/94/b9/c90cd057b126f66a47449120d0cadd83d35371038a998684571cd1730ac8/invokust-0.4.tar.gz" } ], "0.41": [ { "comment_text": "", "digests": { "md5": "b895628275004b902af93f5f5db5baa7", "sha256": "7df9839316b8c27071c1f53ebe02bf6ab48ece46b5e529fc63a669327f9ecb4e" }, "downloads": -1, "filename": "invokust-0.41.tar.gz", "has_sig": false, "md5_digest": "b895628275004b902af93f5f5db5baa7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7351, "upload_time": "2017-05-24T17:58:21", "url": "https://files.pythonhosted.org/packages/85/81/46e8ac72b3755ff0455618eaea1521565567ba64bcee592b53e51644f40d/invokust-0.41.tar.gz" } ], "0.42": [ { "comment_text": "", "digests": { "md5": "50cc9294d07a6243753a5a768df893a7", "sha256": "5b778bb65cb755f4123b9735cc5e17ced796434b6004c6d4c028ca028318c7dd" }, "downloads": -1, "filename": "invokust-0.42.tar.gz", "has_sig": false, "md5_digest": "50cc9294d07a6243753a5a768df893a7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7432, "upload_time": "2017-06-12T13:38:39", "url": "https://files.pythonhosted.org/packages/2c/be/03964dd304191ff67c6cb86b97501d68de5d7aaeb109e76c30761b08c2df/invokust-0.42.tar.gz" } ], "0.43": [ { "comment_text": "", "digests": { "md5": "1b67cc472d670bf506602afb9e229ca1", "sha256": "5452ca825414ec9165f0853c471063544d82b15ef8db72d75ec380ab2b320d95" }, "downloads": -1, "filename": "invokust-0.43.tar.gz", "has_sig": false, "md5_digest": "1b67cc472d670bf506602afb9e229ca1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7363, "upload_time": "2017-06-15T10:41:33", "url": "https://files.pythonhosted.org/packages/a8/3c/f6d03fdfe6163f434892fd188f52ff8ae1f753e3d7a3ccae4f48104e989a/invokust-0.43.tar.gz" } ], "0.44": [ { "comment_text": "", "digests": { "md5": "6cb50cff2cd1bd70e937c5126503311d", "sha256": "b2fa446583306ce79ca45b3ad91c83589df9ac1d456af6be8c39bb34f2052741" }, "downloads": -1, "filename": "invokust-0.44.tar.gz", "has_sig": false, "md5_digest": "6cb50cff2cd1bd70e937c5126503311d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7377, "upload_time": "2017-06-27T10:22:24", "url": "https://files.pythonhosted.org/packages/6b/6f/385a030dfb479f7e063305933b8be9b02c511bb8058d26268f2b9c5422dc/invokust-0.44.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "46f260630dcecc7d2eaa3bbd3982d09c", "sha256": "f352b08e67e78f753d081403b0260ce0c4bfa9ef18a6492b2ec2cb4b478671b6" }, "downloads": -1, "filename": "invokust-0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "46f260630dcecc7d2eaa3bbd3982d09c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11123, "upload_time": "2019-03-27T11:33:53", "url": "https://files.pythonhosted.org/packages/73/91/f0a7bc132d4b487cab504d9be4c2057905111bfb69abc25fbd34cd0af0ce/invokust-0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bf1a160f306b5e78e799350f6b5c31a1", "sha256": "84ea4f37dc0ab629ae230ad10044cfceb20c46a6acea5541cf47d868f58f41b5" }, "downloads": -1, "filename": "invokust-0.5.tar.gz", "has_sig": false, "md5_digest": "bf1a160f306b5e78e799350f6b5c31a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11534, "upload_time": "2019-03-27T11:24:58", "url": "https://files.pythonhosted.org/packages/99/6b/ccfc167ff07975ddc62d016e9207a75f3d6e1cef01051d76969bf50ce20a/invokust-0.5.tar.gz" } ], "0.51": [ { "comment_text": "", "digests": { "md5": "401af2c6ddb851fa93c17ec0684076dd", "sha256": "732bad1d064fdeabff68253a53bab3e4b3a3bc0baf1f3a529e08145f27da55ff" }, "downloads": -1, "filename": "invokust-0.51-py3-none-any.whl", "has_sig": false, "md5_digest": "401af2c6ddb851fa93c17ec0684076dd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11167, "upload_time": "2019-03-27T11:38:59", "url": "https://files.pythonhosted.org/packages/4e/19/e7174d921a3813c501a9418353dd8a3c67f9c2fbdafd81b0c3b26730122d/invokust-0.51-py3-none-any.whl" } ], "0.52": [ { "comment_text": "", "digests": { "md5": "6dfd88121ee4b7ce655fdf76cdd3fa26", "sha256": "80c75c8f57e2d751f347055d5e2a65534b14ef6a8a99ce62c81fd5109438554a" }, "downloads": -1, "filename": "invokust-0.52-py3-none-any.whl", "has_sig": false, "md5_digest": "6dfd88121ee4b7ce655fdf76cdd3fa26", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15105, "upload_time": "2019-03-27T11:41:13", "url": "https://files.pythonhosted.org/packages/23/5a/bf7daadf2aebe9ac7654bcc79071176402116b1d1ef423880db5872326f4/invokust-0.52-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "6dfd88121ee4b7ce655fdf76cdd3fa26", "sha256": "80c75c8f57e2d751f347055d5e2a65534b14ef6a8a99ce62c81fd5109438554a" }, "downloads": -1, "filename": "invokust-0.52-py3-none-any.whl", "has_sig": false, "md5_digest": "6dfd88121ee4b7ce655fdf76cdd3fa26", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15105, "upload_time": "2019-03-27T11:41:13", "url": "https://files.pythonhosted.org/packages/23/5a/bf7daadf2aebe9ac7654bcc79071176402116b1d1ef423880db5872326f4/invokust-0.52-py3-none-any.whl" } ] }