From ff75c135438df60d0703cab934f3f4d1aa7726e5 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 4 Oct 2019 23:12:20 +0800 Subject: [PATCH 01/28] change: remove unused imports --- httprunner/api.py | 1 - httprunner/built_in.py | 6 +++--- httprunner/client.py | 5 +++-- httprunner/loader.py | 5 ++--- httprunner/locusts.py | 1 - httprunner/report.py | 5 +++-- httprunner/response.py | 3 +-- httprunner/utils.py | 1 - httprunner/validator.py | 2 +- tests/api_server.py | 2 ++ tests/base.py | 3 ++- tests/debugtalk.py | 22 +++++++++++++++++++++- tests/test_apiserver.py | 3 --- tests/test_client.py | 1 - tests/test_context.py | 4 ++-- tests/test_loader.py | 2 +- tests/test_response.py | 1 + tests/test_utils.py | 2 +- 18 files changed, 43 insertions(+), 26 deletions(-) diff --git a/httprunner/api.py b/httprunner/api.py index 43a6cf0c..10323132 100644 --- a/httprunner/api.py +++ b/httprunner/api.py @@ -1,6 +1,5 @@ # encoding: utf-8 -import os import unittest from httprunner import (__version__, exceptions, loader, logger, parser, diff --git a/httprunner/built_in.py b/httprunner/built_in.py index 7f26e8ea..821304ca 100644 --- a/httprunner/built_in.py +++ b/httprunner/built_in.py @@ -5,7 +5,6 @@ Built-in dependent functions used in YAML/JSON testcases. """ import datetime -import json import os import random import re @@ -13,10 +12,11 @@ import string import time import filetype -from httprunner.compat import basestring, builtin_str, integer_types, str -from httprunner.exceptions import ParamsError from requests_toolbelt import MultipartEncoder +from httprunner.compat import basestring, builtin_str, integer_types +from httprunner.exceptions import ParamsError + PWD = os.getcwd() diff --git a/httprunner/client.py b/httprunner/client.py index 60018e86..bd6766c3 100644 --- a/httprunner/client.py +++ b/httprunner/client.py @@ -4,12 +4,13 @@ import time import requests import urllib3 -from httprunner import logger -from httprunner.utils import lower_dict_keys, omit_long_data from requests import Request, Response from requests.exceptions import (InvalidSchema, InvalidURL, MissingSchema, RequestException) +from httprunner import logger +from httprunner.utils import lower_dict_keys, omit_long_data + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) diff --git a/httprunner/loader.py b/httprunner/loader.py index bf93b81e..b4735ad1 100644 --- a/httprunner/loader.py +++ b/httprunner/loader.py @@ -1,5 +1,3 @@ -import collections -import copy import csv import importlib import io @@ -8,7 +6,8 @@ import os import sys import yaml -from httprunner import built_in, exceptions, logger, parser, utils, validator + +from httprunner import built_in, exceptions, logger, utils, validator try: # PyYAML version >= 5.1 diff --git a/httprunner/locusts.py b/httprunner/locusts.py index 38f6b7fa..0d0cab45 100644 --- a/httprunner/locusts.py +++ b/httprunner/locusts.py @@ -6,7 +6,6 @@ import os import sys from httprunner.logger import color_print -from httprunner import loader def parse_locustfile(file_path): diff --git a/httprunner/report.py b/httprunner/report.py index 15877b4c..c01a9aae 100644 --- a/httprunner/report.py +++ b/httprunner/report.py @@ -10,10 +10,11 @@ from collections import Iterable from datetime import datetime import requests -from httprunner import __version__, loader, logger -from httprunner.compat import basestring, bytes, json, numeric_types from jinja2 import Template, escape +from httprunner import __version__, logger +from httprunner.compat import basestring, bytes, json, numeric_types + def get_platform(): return { diff --git a/httprunner/response.py b/httprunner/response.py index 5ab5ac33..9cbadc1d 100644 --- a/httprunner/response.py +++ b/httprunner/response.py @@ -1,13 +1,12 @@ # encoding: utf-8 -import json import re + import jsonpath from httprunner import exceptions, logger, utils from httprunner.compat import OrderedDict, basestring, is_py2 - text_extractor_regexp_compile = re.compile(r".*\(.*\).*") diff --git a/httprunner/utils.py b/httprunner/utils.py index 97c01958..133329f3 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -7,7 +7,6 @@ import itertools import json import os.path import re -import string from datetime import datetime from httprunner import exceptions, logger diff --git a/httprunner/validator.py b/httprunner/validator.py index 60c15cd1..36f085a2 100644 --- a/httprunner/validator.py +++ b/httprunner/validator.py @@ -7,11 +7,11 @@ import types from httprunner import exceptions, logger - """ validate data format TODO: refactor with JSON schema validate """ + def is_testcase(data_structure): """ check if data_structure is a testcase. diff --git a/tests/api_server.py b/tests/api_server.py index 0b20c5d9..d3a370d4 100644 --- a/tests/api_server.py +++ b/tests/api_server.py @@ -4,6 +4,7 @@ import json from functools import wraps from flask import Flask, make_response, request + from httprunner.built_in import gen_random_string try: @@ -53,6 +54,7 @@ def get_sign(*args): sign = hmac.new(sign_key, content, hashlib.sha1).hexdigest() return sign + def gen_md5(*args): return hashlib.md5("".join(args).encode('utf-8')).hexdigest() diff --git a/tests/base.py b/tests/base.py index 82198842..9e1e09b2 100644 --- a/tests/base.py +++ b/tests/base.py @@ -3,9 +3,10 @@ import time import unittest import requests + from tests.api_server import FLASK_APP_PORT, HTTPBIN_HOST, HTTPBIN_PORT from tests.api_server import app as flask_app -from tests.api_server import gen_md5, gen_random_string, get_sign, httpbin_app +from tests.api_server import gen_random_string, get_sign, httpbin_app def run_flask(): diff --git a/tests/debugtalk.py b/tests/debugtalk.py index dd89e8be..7006ddf8 100644 --- a/tests/debugtalk.py +++ b/tests/debugtalk.py @@ -1,4 +1,3 @@ -import json import os import random import string @@ -8,12 +7,15 @@ from tests.api_server import HTTPBIN_SERVER, gen_md5, get_sign BASE_URL = "http://127.0.0.1:5000" + def get_httpbin_server(): return HTTPBIN_SERVER + def get_base_url(): return BASE_URL + def get_default_request(): return { "base_url": BASE_URL, @@ -22,9 +24,11 @@ def get_default_request(): } } + def sum_two(m, n): return m + n + def sum_status_code(status_code, expect_sum): """ sum status code digits e.g. 400 => 4, 201 => 3 @@ -35,34 +39,42 @@ def sum_status_code(status_code, expect_sum): assert sum_value == expect_sum + def is_status_code_200(status_code): return status_code == 200 + os.environ["TEST_ENV"] = "PRODUCTION" + def skip_test_in_production_env(): """ skip this test in production environment """ return os.environ["TEST_ENV"] == "PRODUCTION" + def get_user_agent(): return ["iOS/10.1", "iOS/10.2"] + def gen_app_version(): return [ {"app_version": "2.8.5"}, {"app_version": "2.8.6"} ] + def get_account(): return [ {"username": "user1", "password": "111111"}, {"username": "user2", "password": "222222"} ] + def get_account_in_tuple(): return [("user1", "111111"), ("user2", "222222")] + def gen_random_string(str_len): random_char_list = [] for _ in range(str_len): @@ -72,12 +84,15 @@ def gen_random_string(str_len): random_string = ''.join(random_char_list) return random_string + def setup_hook_add_kwargs(request): request["key"] = "value" + def setup_hook_remove_kwargs(request): request.pop("key") + def teardown_hook_sleep_N_secs(response, n_secs): """ sleep n seconds after request """ @@ -86,12 +101,15 @@ def teardown_hook_sleep_N_secs(response, n_secs): else: time.sleep(n_secs) + def hook_print(msg): print(msg) + def modify_request_json(request, os_platform): request["json"]["os_platform"] = os_platform + def setup_hook_httpntlmauth(request): if "httpntlmauth" in request: from requests_ntlm import HttpNtlmAuth @@ -99,6 +117,7 @@ def setup_hook_httpntlmauth(request): request["auth"] = HttpNtlmAuth( auth_account["username"], auth_account["password"]) + def alter_response(response): response.status_code = 500 response.headers["Content-Type"] = "html/text" @@ -108,6 +127,7 @@ def alter_response(response): "key": 123 } + def alter_response_error(response): # NameError not_defined_variable diff --git a/tests/test_apiserver.py b/tests/test_apiserver.py index 1887ae1a..5d144349 100644 --- a/tests/test_apiserver.py +++ b/tests/test_apiserver.py @@ -1,6 +1,3 @@ -import random -import requests - from tests.base import ApiServerUnittest diff --git a/tests/test_client.py b/tests/test_client.py index 63ee4bb7..755c9397 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1,5 +1,4 @@ from httprunner.client import HttpSession -from httprunner.compat import bytes from tests.api_server import HTTPBIN_SERVER from tests.base import ApiServerUnittest diff --git a/tests/test_context.py b/tests/test_context.py index 6659ef24..67367c97 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -1,8 +1,8 @@ import os -import time from httprunner import context, exceptions, loader, parser, runner -from tests.base import ApiServerUnittest, gen_md5, gen_random_string +from tests.api_server import gen_md5 +from tests.base import ApiServerUnittest, gen_random_string class TestContext(ApiServerUnittest): diff --git a/tests/test_loader.py b/tests/test_loader.py index be22a520..21268074 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -2,7 +2,7 @@ import os import unittest -from httprunner import exceptions, loader, validator +from httprunner import exceptions, loader class TestFileLoader(unittest.TestCase): diff --git a/tests/test_response.py b/tests/test_response.py index f73825f4..633bb6e7 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -1,4 +1,5 @@ import requests + from httprunner import built_in, exceptions, loader, response from httprunner.compat import basestring, bytes from tests.api_server import HTTPBIN_SERVER diff --git a/tests/test_utils.py b/tests/test_utils.py index 58138424..5a32588f 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,7 +2,7 @@ import io import os import shutil -from httprunner import exceptions, loader, parser, utils +from httprunner import exceptions, loader, utils from tests.base import ApiServerUnittest From f0cd396e40c5ba15e36461f85feea88b14771935 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 14:21:23 +0800 Subject: [PATCH 02/28] 2.2.7 change: move debugging cli to __main__.py --- httprunner/__init__.py | 2 +- httprunner/__main__.py | 27 +++++++++++++++++++++++++++ httprunner/cli.py | 27 --------------------------- 3 files changed, 28 insertions(+), 28 deletions(-) create mode 100644 httprunner/__main__.py diff --git a/httprunner/__init__.py b/httprunner/__init__.py index 7fbb6af4..ef770dc2 100644 --- a/httprunner/__init__.py +++ b/httprunner/__init__.py @@ -1,4 +1,4 @@ -__version__ = "2.2.6" +__version__ = "2.2.7" __description__ = "One-stop solution for HTTP(S) testing." __all__ = ["__version__", "__description__"] diff --git a/httprunner/__main__.py b/httprunner/__main__.py new file mode 100644 index 00000000..1f1c95e0 --- /dev/null +++ b/httprunner/__main__.py @@ -0,0 +1,27 @@ +import os +import sys + +from httprunner.cli import main_hrun, main_locust + +if __name__ == "__main__": + """ debugging mode + """ + if len(sys.argv) == 0: + sys.exit(1) + + sys.path.insert(0, os.getcwd()) + cmd = sys.argv.pop(1) + + if cmd in ["hrun", "httprunner", "ate"]: + main_hrun() + elif cmd in ["locust", "locusts"]: + main_locust() + else: + from httprunner.logger import color_print + color_print("Miss debugging type.", "RED") + example = "\n".join([ + "e.g.", + "python -m httprunner hrun /path/to/testcase_file", + "python -m httprunner locusts -f /path/to/testcase_file" + ]) + color_print(example, "yellow") diff --git a/httprunner/cli.py b/httprunner/cli.py index 8bd7b553..67555da7 100644 --- a/httprunner/cli.py +++ b/httprunner/cli.py @@ -186,30 +186,3 @@ def main_locust(): locusts.run_locusts_with_processes(sys.argv, processes_count) else: locusts.start_locust_main() - - -if __name__ == "__main__": - """ debugging mode - """ - import sys - import os - - if len(sys.argv) == 0: - exit(0) - - sys.path.insert(0, os.getcwd()) - cmd = sys.argv.pop(1) - - if cmd in ["hrun", "httprunner", "ate"]: - main_hrun() - elif cmd in ["locust", "locusts"]: - main_locust() - else: - from httprunner.logger import color_print - color_print("Miss debugging type.", "RED") - example = "\n".join([ - "e.g.", - "python -m httprunner.cli hrun /path/to/testcase_file", - "python -m httprunner.cli locusts -f /path/to/testcase_file" - ]) - color_print(example, "yellow") From 705bade1a03d40952cbfab56dcfd1dea193842d7 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 15:01:12 +0800 Subject: [PATCH 03/28] change: log version before running --- httprunner/api.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/httprunner/api.py b/httprunner/api.py index 10323132..cfcd9145 100644 --- a/httprunner/api.py +++ b/httprunner/api.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - import unittest from httprunner import (__version__, exceptions, loader, logger, parser, @@ -9,7 +7,7 @@ from httprunner import (__version__, exceptions, loader, logger, parser, class HttpRunner(object): def __init__(self, failfast=False, save_tests=False, report_template=None, report_dir=None, - log_level="INFO", log_file=None, report_file=None): + log_level="INFO", log_file=None, report_file=None): """ initialize HttpRunner. Args: @@ -22,7 +20,6 @@ class HttpRunner(object): """ logger.setup_logger(log_level, log_file) - logger.log_info("HttpRunner version: {}".format(__version__)) self.exception_stage = "initialize HttpRunner()" kwargs = { @@ -273,6 +270,7 @@ class HttpRunner(object): dict: valid testcase/testsuite data """ + logger.log_info("HttpRunner version: {}".format(__version__)) if validator.is_testcase_path(path_or_tests): return self.run_path(path_or_tests, dot_env_path, mapping) elif validator.is_testcases(path_or_tests): From 890f2796c06199db13c5528463307f8164116b68 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 15:42:47 +0800 Subject: [PATCH 04/28] change: split locust main from httprunner cli --- httprunner/__main__.py | 25 +------- httprunner/cli.py | 133 ++++++++--------------------------------- httprunner/locusts.py | 91 +++++++++++++++++++++++++++- pyproject.toml | 10 ++-- 4 files changed, 121 insertions(+), 138 deletions(-) diff --git a/httprunner/__main__.py b/httprunner/__main__.py index 1f1c95e0..7cc58a3b 100644 --- a/httprunner/__main__.py +++ b/httprunner/__main__.py @@ -1,27 +1,6 @@ -import os import sys -from httprunner.cli import main_hrun, main_locust +from httprunner.cli import main if __name__ == "__main__": - """ debugging mode - """ - if len(sys.argv) == 0: - sys.exit(1) - - sys.path.insert(0, os.getcwd()) - cmd = sys.argv.pop(1) - - if cmd in ["hrun", "httprunner", "ate"]: - main_hrun() - elif cmd in ["locust", "locusts"]: - main_locust() - else: - from httprunner.logger import color_print - color_print("Miss debugging type.", "RED") - example = "\n".join([ - "e.g.", - "python -m httprunner hrun /path/to/testcase_file", - "python -m httprunner locusts -f /path/to/testcase_file" - ]) - color_print(example, "yellow") + sys.exit(main()) diff --git a/httprunner/cli.py b/httprunner/cli.py index 67555da7..75a1fa53 100644 --- a/httprunner/cli.py +++ b/httprunner/cli.py @@ -1,18 +1,20 @@ -# encoding: utf-8 +import argparse +import sys + +from httprunner import __description__, __version__ +from httprunner.api import HttpRunner +from httprunner.compat import is_py2 +from httprunner.logger import color_print +from httprunner.utils import (create_scaffold, get_python2_retire_msg, + prettify_json_file) +from httprunner.validator import validate_json_file -def main_hrun(): +def main(): """ API test: parse command line options and run commands. """ - import sys - import argparse - from httprunner.logger import color_print - from httprunner import __description__, __version__ - from httprunner.api import HttpRunner - from httprunner.compat import is_py2 - from httprunner.validator import validate_json_file - from httprunner.utils import (create_scaffold, get_python2_retire_msg, - prettify_json_file) + if is_py2: + color_print(get_python2_retire_msg(), "YELLOW") parser = argparse.ArgumentParser(description=__description__) parser.add_argument( @@ -57,24 +59,26 @@ def main_hrun(): args = parser.parse_args() - if is_py2: - color_print(get_python2_retire_msg(), "YELLOW") + if len(sys.argv) == 1: + # no argument passed + parser.print_help() + return 0 if args.version: color_print("{}".format(__version__), "GREEN") - exit(0) + return 0 if args.validate: validate_json_file(args.validate) - exit(0) + return 0 if args.prettify: prettify_json_file(args.prettify) - exit(0) + return 0 project_name = args.startproject if project_name: create_scaffold(project_name) - exit(0) + return 0 runner = HttpRunner( failfast=args.failfast, @@ -85,6 +89,7 @@ def main_hrun(): log_file=args.log_file, report_file=args.report_file ) + try: for path in args.testcase_paths: runner.run(path, dot_env_path=args.dot_env_path) @@ -93,96 +98,10 @@ def main_hrun(): raise if runner.summary and runner.summary["success"]: - sys.exit(0) + return 0 else: - sys.exit(1) + return 1 -def main_locust(): - """ Performance test with locust: parse command line options and run commands. - """ - try: - # monkey patch ssl at beginning to avoid RecursionError when running locust. - from gevent import monkey; monkey.patch_ssl() - import multiprocessing - import sys - from httprunner import logger - from httprunner import locusts - except ImportError: - msg = "Locust is not installed, install first and try again.\n" - msg += "install command: pip install locustio" - print(msg) - exit(1) - - sys.argv[0] = 'locust' - if len(sys.argv) == 1: - sys.argv.extend(["-h"]) - - if sys.argv[1] in ["-h", "--help", "-V", "--version"]: - locusts.start_locust_main() - sys.exit(0) - - # set logging level - if "-L" in sys.argv: - loglevel_index = sys.argv.index('-L') + 1 - elif "--loglevel" in sys.argv: - loglevel_index = sys.argv.index('--loglevel') + 1 - else: - loglevel_index = None - - if loglevel_index and loglevel_index < len(sys.argv): - loglevel = sys.argv[loglevel_index] - else: - # default - loglevel = "WARNING" - - logger.setup_logger(loglevel) - - # get testcase file path - try: - if "-f" in sys.argv: - testcase_index = sys.argv.index('-f') + 1 - elif "--locustfile" in sys.argv: - testcase_index = sys.argv.index('--locustfile') + 1 - else: - testcase_index = None - - assert testcase_index and testcase_index < len(sys.argv) - except AssertionError: - print("Testcase file is not specified, exit.") - sys.exit(1) - - testcase_file_path = sys.argv[testcase_index] - sys.argv[testcase_index] = locusts.parse_locustfile(testcase_file_path) - - if "--processes" in sys.argv: - """ locusts -f locustfile.py --processes 4 - """ - if "--no-web" in sys.argv: - logger.log_error("conflict parameter args: --processes & --no-web. \nexit.") - sys.exit(1) - - processes_index = sys.argv.index('--processes') - - processes_count_index = processes_index + 1 - - if processes_count_index >= len(sys.argv): - """ do not specify processes count explicitly - locusts -f locustfile.py --processes - """ - processes_count = multiprocessing.cpu_count() - logger.log_warning("processes count not specified, use {} by default.".format(processes_count)) - else: - try: - """ locusts -f locustfile.py --processes 4 """ - processes_count = int(sys.argv[processes_count_index]) - sys.argv.pop(processes_count_index) - except ValueError: - """ locusts -f locustfile.py --processes -P 8888 """ - processes_count = multiprocessing.cpu_count() - logger.log_warning("processes count not specified, use {} by default.".format(processes_count)) - - sys.argv.pop(processes_index) - locusts.run_locusts_with_processes(sys.argv, processes_count) - else: - locusts.start_locust_main() +if __name__ == '__main__': + sys.exit(main()) diff --git a/httprunner/locusts.py b/httprunner/locusts.py index 0d0cab45..c079c504 100644 --- a/httprunner/locusts.py +++ b/httprunner/locusts.py @@ -1,11 +1,21 @@ # encoding: utf-8 +try: + # monkey patch ssl at beginning to avoid RecursionError when running locust. + from gevent import monkey + monkey.patch_ssl() +except ImportError: + msg = "Locust is not installed, install first and try again.\n" + msg += "install command: pip install locustio" + print(msg) + import sys + sys.exit(1) import io import multiprocessing import os import sys -from httprunner.logger import color_print +from httprunner import logger def parse_locustfile(file_path): @@ -14,7 +24,7 @@ def parse_locustfile(file_path): if file_path is a YAML/JSON file, convert it to locustfile """ if not os.path.isfile(file_path): - color_print("file path invalid, exit.", "RED") + logger.color_print("file path invalid, exit.", "RED") sys.exit(1) file_suffix = os.path.splitext(file_path)[1] @@ -24,7 +34,7 @@ def parse_locustfile(file_path): locustfile_path = gen_locustfile(file_path) else: # '' or other suffix - color_print("file type should be YAML/JSON/Python, exit.", "RED") + logger.color_print("file type should be YAML/JSON/Python, exit.", "RED") sys.exit(1) return locustfile_path @@ -85,3 +95,78 @@ def run_locusts_with_processes(sys_argv, processes_count): start_master(sys_argv) except KeyboardInterrupt: manager.shutdown() + + +def main(): + """ Performance test with locust: parse command line options and run commands. + """ + sys.argv[0] = 'locust' + if len(sys.argv) == 1: + sys.argv.extend(["-h"]) + + if sys.argv[1] in ["-h", "--help", "-V", "--version"]: + start_locust_main() + + def get_arg_index(*target_args): + for arg in target_args: + if arg not in sys.argv: + continue + + return sys.argv.index(arg) + 1 + + return None + + # set logging level + loglevel_index = get_arg_index("-L", "--loglevel") + if loglevel_index and loglevel_index < len(sys.argv): + loglevel = sys.argv[loglevel_index] + else: + # default + loglevel = "WARNING" + + logger.setup_logger(loglevel) + + # get testcase file path + try: + testcase_index = get_arg_index("-f", "--locustfile") + assert testcase_index and testcase_index < len(sys.argv) + except AssertionError: + print("Testcase file is not specified, exit.") + sys.exit(1) + + testcase_file_path = sys.argv[testcase_index] + sys.argv[testcase_index] = parse_locustfile(testcase_file_path) + + if "--processes" in sys.argv: + """ locusts -f locustfile.py --processes 4 + """ + if "--no-web" in sys.argv: + logger.log_error("conflict parameter args: --processes & --no-web. \nexit.") + sys.exit(1) + + processes_index = sys.argv.index('--processes') + processes_count_index = processes_index + 1 + if processes_count_index >= len(sys.argv): + """ do not specify processes count explicitly + locusts -f locustfile.py --processes + """ + processes_count = multiprocessing.cpu_count() + logger.log_warning("processes count not specified, use {} by default.".format(processes_count)) + else: + try: + """ locusts -f locustfile.py --processes 4 """ + processes_count = int(sys.argv[processes_count_index]) + sys.argv.pop(processes_count_index) + except ValueError: + """ locusts -f locustfile.py --processes -P 8888 """ + processes_count = multiprocessing.cpu_count() + logger.log_warning("processes count not specified, use {} by default.".format(processes_count)) + + sys.argv.pop(processes_index) + run_locusts_with_processes(sys.argv, processes_count) + else: + start_locust_main() + + +if __name__ == '__main__': + main() diff --git a/pyproject.toml b/pyproject.toml index db5bae3a..0f4534ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "httprunner" -version = "2.2.6" +version = "2.2.7" description = "One-stop solution for HTTP(S) testing." license = "Apache-2.0" readme = "README.md" @@ -39,10 +39,10 @@ coveralls = "^1.8" contextlib2 = "^0.5.5" [tool.poetry.scripts] -hrun = "httprunner.cli:main_hrun" -ate = "httprunner.cli:main_hrun" -httprunner = "httprunner.cli:main_hrun" -locusts = "httprunner.cli:main_locust" +hrun = "httprunner.cli:main" +ate = "httprunner.cli:main" +httprunner = "httprunner.cli:main" +locusts = "httprunner.locusts:main" [build-system] requires = ["poetry>=0.12"] From 22eb592eec7898a277e0a081d3a9488d91f336a6 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 16:40:47 +0800 Subject: [PATCH 05/28] feat: make locusts as httprunner plugin --- httprunner/api.py | 28 ----- httprunner/plugins/__init__.py | 0 httprunner/plugins/locusts/README.md | 100 ++++++++++++++++++ .../locusts/__init__.py} | 31 +++++- httprunner/plugins/locusts/__main__.py | 6 ++ .../locusts}/locustfile_template | 8 +- pyproject.toml | 2 +- tests/test_api.py | 18 +--- tests/test_plugins/__init__.py | 0 tests/test_plugins/test_locusts.py | 19 ++++ 10 files changed, 158 insertions(+), 54 deletions(-) create mode 100644 httprunner/plugins/__init__.py create mode 100644 httprunner/plugins/locusts/README.md rename httprunner/{locusts.py => plugins/locusts/__init__.py} (88%) create mode 100644 httprunner/plugins/locusts/__main__.py rename httprunner/{templates => plugins/locusts}/locustfile_template (94%) create mode 100644 tests/test_plugins/__init__.py create mode 100644 tests/test_plugins/test_locusts.py diff --git a/httprunner/api.py b/httprunner/api.py index cfcd9145..a8c6f140 100644 --- a/httprunner/api.py +++ b/httprunner/api.py @@ -283,31 +283,3 @@ class HttpRunner(object): """ get test reuslt summary. """ return self._summary - - -def prepare_locust_tests(path): - """ prepare locust testcases - - Args: - path (str): testcase file path. - - Returns: - list: locust tests data - - [ - testcase1_dict, - testcase2_dict - ] - - """ - tests_mapping = loader.load_tests(path) - testcases = parser.parse_tests(tests_mapping) - - locust_tests = [] - - for testcase in testcases: - testcase_weight = testcase.get("config", {}).pop("weight", 1) - for _ in range(testcase_weight): - locust_tests.append(testcase) - - return locust_tests diff --git a/httprunner/plugins/__init__.py b/httprunner/plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/httprunner/plugins/locusts/README.md b/httprunner/plugins/locusts/README.md new file mode 100644 index 00000000..514ea9bb --- /dev/null +++ b/httprunner/plugins/locusts/README.md @@ -0,0 +1,100 @@ +# locusts + +## Usage + +```shell script +$ locusts -f xxx.yml +``` + +```shell script +$ python3 -m plugins.locusts + +Usage: locust [options] [LocustClass [LocustClass2 ... ]] + +Options: + -h, --help show this help message and exit + -H HOST, --host=HOST Host to load test in the following format: + http://10.21.32.33 + --web-host=WEB_HOST Host to bind the web interface to. Defaults to '' (all + interfaces) + -P PORT, --port=PORT, --web-port=PORT + Port on which to run web host + -f LOCUSTFILE, --locustfile=LOCUSTFILE + Python module file to import, e.g. '../other.py'. + Default: locustfile + --csv=CSVFILEBASE, --csv-base-name=CSVFILEBASE + Store current request stats to files in CSV format. + --master Set locust to run in distributed mode with this + process as master + --slave Set locust to run in distributed mode with this + process as slave + --master-host=MASTER_HOST + Host or IP address of locust master for distributed + load testing. Only used when running with --slave. + Defaults to 127.0.0.1. + --master-port=MASTER_PORT + The port to connect to that is used by the locust + master for distributed load testing. Only used when + running with --slave. Defaults to 5557. Note that + slaves will also connect to the master node on this + port + 1. + --master-bind-host=MASTER_BIND_HOST + Interfaces (hostname, ip) that locust master should + bind to. Only used when running with --master. + Defaults to * (all available interfaces). + --master-bind-port=MASTER_BIND_PORT + Port that locust master should bind to. Only used when + running with --master. Defaults to 5557. Note that + Locust will also use this port + 1, so by default the + master node will bind to 5557 and 5558. + --heartbeat-liveness=HEARTBEAT_LIVENESS + set number of seconds before failed heartbeat from + slave + --heartbeat-interval=HEARTBEAT_INTERVAL + set number of seconds delay between slave heartbeats + to master + --expect-slaves=EXPECT_SLAVES + How many slaves master should expect to connect before + starting the test (only when --no-web used). + --no-web Disable the web interface, and instead start running + the test immediately. Requires -c and -r to be + specified. + -c NUM_CLIENTS, --clients=NUM_CLIENTS + Number of concurrent Locust users. Only used together + with --no-web + -r HATCH_RATE, --hatch-rate=HATCH_RATE + The rate per second in which clients are spawned. Only + used together with --no-web + -t RUN_TIME, --run-time=RUN_TIME + Stop after the specified amount of time, e.g. (300s, + 20m, 3h, 1h30m, etc.). Only used together with --no- + web + -L LOGLEVEL, --loglevel=LOGLEVEL + Choose between DEBUG/INFO/WARNING/ERROR/CRITICAL. + Default is INFO. + --logfile=LOGFILE Path to log file. If not set, log will go to + stdout/stderr + --print-stats Print stats in the console + --only-summary Only print the summary stats + --no-reset-stats [DEPRECATED] Do not reset statistics once hatching has + been completed. This is now the default behavior. See + --reset-stats to disable + --reset-stats Reset statistics once hatching has been completed. + Should be set on both master and slaves when running + in distributed mode + -l, --list Show list of possible locust classes and exit + --show-task-ratio print table of the locust classes' task execution + ratio + --show-task-ratio-json + print json data of the locust classes' task execution + ratio + -V, --version show program's version number and exit + --exit-code-on-error=EXIT_CODE_ON_ERROR + sets the exit code to post on error +``` + +## tests + +```shell script +$ python -m plugins.locusts.test_main +``` diff --git a/httprunner/locusts.py b/httprunner/plugins/locusts/__init__.py similarity index 88% rename from httprunner/locusts.py rename to httprunner/plugins/locusts/__init__.py index c079c504..d16c3673 100644 --- a/httprunner/locusts.py +++ b/httprunner/plugins/locusts/__init__.py @@ -15,7 +15,7 @@ import multiprocessing import os import sys -from httprunner import logger +from httprunner import logger, loader, parser def parse_locustfile(file_path): @@ -46,7 +46,6 @@ def gen_locustfile(testcase_file_path): locustfile_path = 'locustfile.py' template_path = os.path.join( os.path.dirname(os.path.realpath(__file__)), - "templates", "locustfile_template" ) @@ -168,5 +167,29 @@ def main(): start_locust_main() -if __name__ == '__main__': - main() +def prepare_locust_tests(path): + """ prepare locust testcases + + Args: + path (str): testcase file path. + + Returns: + list: locust tests data + + [ + testcase1_dict, + testcase2_dict + ] + + """ + tests_mapping = loader.load_tests(path) + testcases = parser.parse_tests(tests_mapping) + + locust_tests = [] + + for testcase in testcases: + testcase_weight = testcase.get("config", {}).pop("weight", 1) + for _ in range(testcase_weight): + locust_tests.append(testcase) + + return locust_tests diff --git a/httprunner/plugins/locusts/__main__.py b/httprunner/plugins/locusts/__main__.py new file mode 100644 index 00000000..488e253d --- /dev/null +++ b/httprunner/plugins/locusts/__main__.py @@ -0,0 +1,6 @@ +import sys + +from httprunner.plugins.locusts import main + +if __name__ == "__main__": + main() diff --git a/httprunner/templates/locustfile_template b/httprunner/plugins/locusts/locustfile_template similarity index 94% rename from httprunner/templates/locustfile_template rename to httprunner/plugins/locusts/locustfile_template index 410a6fe5..b3389b62 100644 --- a/httprunner/templates/locustfile_template +++ b/httprunner/plugins/locusts/locustfile_template @@ -1,13 +1,13 @@ import logging import random -import zmq -from httprunner.exceptions import MyBaseError, MyBaseFailure -from httprunner.api import prepare_locust_tests -from httprunner.runner import Runner from locust import HttpLocust, TaskSet, task from locust.events import request_failure +from httprunner.exceptions import MyBaseError, MyBaseFailure +from httprunner.runner import Runner +from httprunner.plugins.locusts import prepare_locust_tests + logging.getLogger().setLevel(logging.CRITICAL) logging.getLogger('locust.main').setLevel(logging.INFO) logging.getLogger('locust.runners').setLevel(logging.INFO) diff --git a/pyproject.toml b/pyproject.toml index 0f4534ef..8280e744 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,7 @@ contextlib2 = "^0.5.5" hrun = "httprunner.cli:main" ate = "httprunner.cli:main" httprunner = "httprunner.cli:main" -locusts = "httprunner.locusts:main" +locusts = "httprunner.plugins.locusts:main" [build-system] requires = ["poetry>=0.12"] diff --git a/tests/test_api.py b/tests/test_api.py index 9cf176f3..1f84a8b8 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -2,10 +2,9 @@ import os import re import shutil import time -import unittest from httprunner import exceptions, loader, parser -from httprunner.api import HttpRunner, prepare_locust_tests +from httprunner.api import HttpRunner from tests.api_server import HTTPBIN_SERVER from tests.base import ApiServerUnittest @@ -788,18 +787,3 @@ class TestApi(ApiServerUnittest): results.records[1]["name"], "create user and check result." ) - - -class TestLocust(unittest.TestCase): - - def test_prepare_locust_tests(self): - path = os.path.join( - os.getcwd(), 'tests/locust_tests/demo_locusts.yml') - locust_tests = prepare_locust_tests(path) - self.assertEqual(len(locust_tests), 2 + 3) - name_list = [ - "create user 1000 and check result.", - "create user 1001 and check result." - ] - self.assertIn(locust_tests[0]["config"]["name"], name_list) - self.assertIn(locust_tests[4]["config"]["name"], name_list) diff --git a/tests/test_plugins/__init__.py b/tests/test_plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_plugins/test_locusts.py b/tests/test_plugins/test_locusts.py new file mode 100644 index 00000000..10bc736a --- /dev/null +++ b/tests/test_plugins/test_locusts.py @@ -0,0 +1,19 @@ +import os +import unittest + +from httprunner.plugins.locusts import prepare_locust_tests + + +class TestLocust(unittest.TestCase): + + def test_prepare_locust_tests(self): + path = os.path.join( + os.getcwd(), 'tests/locust_tests/demo_locusts.yml') + locust_tests = prepare_locust_tests(path) + self.assertEqual(len(locust_tests), 2 + 3) + name_list = [ + "create user 1000 and check result.", + "create user 1001 and check result." + ] + self.assertIn(locust_tests[0]["config"]["name"], name_list) + self.assertIn(locust_tests[4]["config"]["name"], name_list) From c0a66e494bb95852f44929e3009631af0eb439d4 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 17:06:05 +0800 Subject: [PATCH 06/28] change: rename folder, templates => static --- README.md | 2 +- httprunner/report.py | 10 ++++------ httprunner/{templates => static}/qrcode.jpg | Bin .../{templates => static}/report_template.html | 0 pyproject.toml | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) rename httprunner/{templates => static}/qrcode.jpg (100%) rename httprunner/{templates => static}/report_template.html (100%) diff --git a/README.md b/README.md index c932b118..7b5f1311 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ HttpRunner is rich documented. 关注 HttpRunner 的微信公众号,第一时间获得最新资讯。 -![](httprunner/templates/qrcode.jpg) +![](httprunner/static/qrcode.jpg) [Requests]: http://docs.python-requests.org/en/master/ [unittest]: https://docs.python.org/3/library/unittest.html diff --git a/httprunner/report.py b/httprunner/report.py index c01a9aae..34ac9c6b 100644 --- a/httprunner/report.py +++ b/httprunner/report.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - import io import os import platform @@ -9,8 +7,8 @@ from base64 import b64encode from collections import Iterable from datetime import datetime -import requests from jinja2 import Template, escape +from requests.cookies import RequestsCookieJar from httprunner import __version__, logger from httprunner.compat import basestring, bytes, json, numeric_types @@ -150,7 +148,7 @@ def __stringify_request(request_data): # class instance, e.g. MultipartEncoder() value = repr(value) - elif isinstance(value, requests.cookies.RequestsCookieJar): + elif isinstance(value, RequestsCookieJar): value = value.get_dict() request_data[key] = value @@ -209,7 +207,7 @@ def __stringify_response(response_data): # class instance, e.g. MultipartEncoder() value = repr(value) - elif isinstance(value, requests.cookies.RequestsCookieJar): + elif isinstance(value, RequestsCookieJar): value = value.get_dict() response_data[key] = value @@ -283,7 +281,7 @@ def render_html_report(summary, report_template=None, report_dir=None, report_fi if not report_template: report_template = os.path.join( os.path.abspath(os.path.dirname(__file__)), - "templates", + "static", "report_template.html" ) logger.log_debug("No html report template specified, use default.") diff --git a/httprunner/templates/qrcode.jpg b/httprunner/static/qrcode.jpg similarity index 100% rename from httprunner/templates/qrcode.jpg rename to httprunner/static/qrcode.jpg diff --git a/httprunner/templates/report_template.html b/httprunner/static/report_template.html similarity index 100% rename from httprunner/templates/report_template.html rename to httprunner/static/report_template.html diff --git a/pyproject.toml b/pyproject.toml index 8280e744..06e947e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules" ] -include = ["CHANGELOG.md", "httprunner/templates/*"] +include = ["CHANGELOG.md", "httprunner/static/*"] [tool.poetry.dependencies] python = "~2.7 || ^3.5" From 7446199fb327f6841c727b7e4774c1e0a498f1c7 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 17:12:43 +0800 Subject: [PATCH 07/28] feat: add Python 3.8 --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c10a5ae7..27a688c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,10 +5,11 @@ python: - 3.5 - 3.6 matrix: - include: + include: # Required for Python 3.7+ - python: 3.7 - dist: xenial # Required for Python 3.7 - sudo: true # Required for Python 3.7 + dist: xenial + - python: 3.8 + dist: xenial install: - pip install poetry - poetry install -vvv From 44fc0fdeb3bcfe328c909cda16c7d58eced526c7 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 17:46:45 +0800 Subject: [PATCH 08/28] fix: add locustio to dev dependencies --- pyproject.toml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 06e947e2..0a9ba469 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,22 +21,23 @@ include = ["CHANGELOG.md", "httprunner/static/*"] [tool.poetry.dependencies] python = "~2.7 || ^3.5" -requests = "^2.14" -requests-toolbelt = "^0.8.0" +requests = "*" +requests-toolbelt = "*" pyyaml = "^5.1" -jinja2 = "^2.10" -har2case = "^0.3.1" -colorama = "^0.4.1" -colorlog = "^4.0" -filetype = "^1.0" +jinja2 = "*" +har2case = "*" +colorama = "*" +colorlog = "*" +filetype = "*" future = { version = "^0.17.1", python = "~2.7" } -jsonpath = "^0.82" +jsonpath = "*" [tool.poetry.dev-dependencies] flask = "<1.0.0" -coverage = "^4.5" -coveralls = "^1.8" -contextlib2 = "^0.5.5" +coverage = "*" +coveralls = "*" +contextlib2 = "*" +locustio = "*" [tool.poetry.scripts] hrun = "httprunner.cli:main" From 75516ce6de9fb182069480072f8b91da6baf1235 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 18:25:43 +0800 Subject: [PATCH 09/28] feat: add poetry.lock --- .gitignore | 1 - poetry.lock | 627 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 627 insertions(+), 1 deletion(-) create mode 100644 poetry.lock diff --git a/.gitignore b/.gitignore index b7d995e7..495a27d3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,4 @@ logs .coverage locustfile.py site/ -poetry.lock reports \ No newline at end of file diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..4f55c34a --- /dev/null +++ b/poetry.lock @@ -0,0 +1,627 @@ +[[package]] +category = "main" +description = "Python package for providing Mozilla's CA Bundle." +name = "certifi" +optional = false +python-versions = "*" +version = "2019.9.11" + +[[package]] +category = "dev" +description = "Foreign Function Interface for Python calling C code." +marker = "sys_platform == \"win32\" and platform_python_implementation == \"CPython\"" +name = "cffi" +optional = false +python-versions = "*" +version = "1.13.1" + +[package.dependencies] +pycparser = "*" + +[[package]] +category = "main" +description = "Universal encoding detector for Python 2 and 3" +name = "chardet" +optional = false +python-versions = "*" +version = "3.0.4" + +[[package]] +category = "dev" +description = "Composable command line interface toolkit" +name = "click" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "7.0" + +[[package]] +category = "main" +description = "Cross-platform colored terminal text." +name = "colorama" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.4.1" + +[[package]] +category = "main" +description = "Log formatting with colors!" +name = "colorlog" +optional = false +python-versions = "*" +version = "4.0.2" + +[package.dependencies] +colorama = "*" + +[[package]] +category = "dev" +description = "Backports and enhancements for the contextlib module" +name = "contextlib2" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.6.0.post1" + +[[package]] +category = "dev" +description = "Code coverage measurement for Python" +name = "coverage" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <4" +version = "4.5.4" + +[[package]] +category = "dev" +description = "Show coverage stats online via coveralls.io" +name = "coveralls" +optional = false +python-versions = "*" +version = "1.8.2" + +[package.dependencies] +coverage = ">=3.6,<5.0" +docopt = ">=0.6.1" +requests = ">=1.0.0" + +[package.dependencies.urllib3] +extras = ["secure"] +python = "<3" +version = "*" + +[package.extras] +yaml = ["PyYAML (>=3.10)"] + +[[package]] +category = "dev" +description = "Pythonic argument parser, that will make you smile" +name = "docopt" +optional = false +python-versions = "*" +version = "0.6.2" + +[[package]] +category = "main" +description = "Infer file type and MIME type of any file/buffer. No external dependencies." +name = "filetype" +optional = false +python-versions = "*" +version = "1.0.5" + +[[package]] +category = "dev" +description = "A microframework based on Werkzeug, Jinja2 and good intentions" +name = "flask" +optional = false +python-versions = "*" +version = "0.12.4" + +[package.dependencies] +Jinja2 = ">=2.4" +Werkzeug = ">=0.7" +click = ">=2.0" +itsdangerous = ">=0.21" + +[[package]] +category = "main" +description = "Clean single-source support for Python 3 and 2" +marker = "python_version >= \"2.7\" and python_version < \"2.8\"" +name = "future" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "0.17.1" + +[[package]] +category = "dev" +description = "Coroutine-based network library" +name = "gevent" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "1.4.0" + +[package.dependencies] +cffi = ">=1.11.5" +greenlet = ">=0.4.14" + +[package.extras] +dnspython = ["dnspython", "idna"] +doc = ["repoze.sphinx.autointerface"] +events = ["zope.event", "zope.interface"] +test = ["zope.interface", "zope.event", "requests", "objgraph", "psutil", "futures", "mock", "coverage (>=5.0a3)", "coveralls (>=1.0)"] + +[[package]] +category = "dev" +description = "Lightweight in-process concurrent programming" +marker = "platform_python_implementation == \"CPython\"" +name = "greenlet" +optional = false +python-versions = "*" +version = "0.4.15" + +[[package]] +category = "main" +description = "Convert HAR(HTTP Archive) to YAML/JSON testcases for HttpRunner." +name = "har2case" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" +version = "0.3.1" + +[package.dependencies] +PyYAML = "*" + +[[package]] +category = "main" +description = "Internationalized Domain Names in Applications (IDNA)" +name = "idna" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.8" + +[[package]] +category = "dev" +description = "Various helpers to pass data to untrusted environments and back." +name = "itsdangerous" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.1.0" + +[[package]] +category = "main" +description = "A very fast and expressive template engine." +name = "jinja2" +optional = false +python-versions = "*" +version = "2.10.3" + +[package.dependencies] +MarkupSafe = ">=0.23" + +[package.extras] +i18n = ["Babel (>=0.8)"] + +[[package]] +category = "main" +description = "An XPath for JSON" +name = "jsonpath" +optional = false +python-versions = "*" +version = "0.82" + +[[package]] +category = "dev" +description = "Website load testing framework" +name = "locustio" +optional = false +python-versions = "*" +version = "0.11.0" + +[package.dependencies] +flask = ">=0.10.1" +gevent = ">=1.2.2" +msgpack = ">=0.4.2" +pyzmq = ">=16.0.2" +requests = ">=2.9.1" +six = ">=1.10.0" + +[[package]] +category = "main" +description = "Safely add untrusted strings to HTML/XML markup." +name = "markupsafe" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "1.1.1" + +[[package]] +category = "dev" +description = "MessagePack (de)serializer." +name = "msgpack" +optional = false +python-versions = "*" +version = "0.6.2" + +[[package]] +category = "dev" +description = "C parser in Python" +marker = "sys_platform == \"win32\" and platform_python_implementation == \"CPython\"" +name = "pycparser" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.19" + +[[package]] +category = "main" +description = "YAML parser and emitter for Python" +name = "pyyaml" +optional = false +python-versions = "*" +version = "5.1.2" + +[[package]] +category = "dev" +description = "Python bindings for 0MQ" +name = "pyzmq" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" +version = "18.1.0" + +[[package]] +category = "main" +description = "Python HTTP for Humans." +name = "requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.22.0" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<3.1.0" +idna = ">=2.5,<2.9" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] + +[[package]] +category = "main" +description = "A utility belt for advanced users of python-requests" +name = "requests-toolbelt" +optional = false +python-versions = "*" +version = "0.9.1" + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +category = "dev" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*" +version = "1.12.0" + +[[package]] +category = "main" +description = "HTTP library with thread-safe connection pooling, file post, and more." +name = "urllib3" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" +version = "1.25.6" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] + +[[package]] +category = "dev" +description = "The comprehensive WSGI web application library." +name = "werkzeug" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.16.0" + +[package.extras] +dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"] +termcolor = ["termcolor"] +watchdog = ["watchdog"] + +[metadata] +content-hash = "7b4557bc1f6b6d77027535d94b5cf225abe4679b57ddd8e0831cd52c4087900a" +python-versions = "~2.7 || ^3.5" + +[metadata.files] +certifi = [ + {file = "certifi-2019.9.11-py2.py3-none-any.whl", hash = "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"}, + {file = "certifi-2019.9.11.tar.gz", hash = "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50"}, +] +cffi = [ + {file = "cffi-1.13.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:9009e917d8f5ef780c2626e29b6bc126f4cb2a4d43ca67aa2b40f2a5d6385e78"}, + {file = "cffi-1.13.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:825ecffd9574557590e3225560a8a9d751f6ffe4a49e3c40918c9969b93395fa"}, + {file = "cffi-1.13.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:193697c2918ecdb3865acf6557cddf5076bb39f1f654975e087b67efdff83365"}, + {file = "cffi-1.13.1-cp27-cp27m-win32.whl", hash = "sha256:1ae14b542bf3b35e5229439c35653d2ef7d8316c1fffb980f9b7647e544baa98"}, + {file = "cffi-1.13.1-cp27-cp27m-win_amd64.whl", hash = "sha256:0ea23c9c0cdd6778146a50d867d6405693ac3b80a68829966c98dd5e1bbae400"}, + {file = "cffi-1.13.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec2fa3ee81707a5232bf2dfbd6623fdb278e070d596effc7e2d788f2ada71a05"}, + {file = "cffi-1.13.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:7cfcfda59ef1f95b9f729c56fe8a4041899f96b72685d36ef16a3440a0f85da8"}, + {file = "cffi-1.13.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:6fd58366747debfa5e6163ada468a90788411f10c92597d3b0a912d07e580c36"}, + {file = "cffi-1.13.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:9c77564a51d4d914ed5af096cd9843d90c45b784b511723bd46a8a9d09cf16fc"}, + {file = "cffi-1.13.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:728ec653964655d65408949b07f9b2219df78badd601d6c49e28d604efe40599"}, + {file = "cffi-1.13.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:a19089fa74ed19c4fe96502a291cfdb89223a9705b1d73b3005df4256976142e"}, + {file = "cffi-1.13.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:e22a00c0c81ffcecaf07c2bfb3672fa372c50e2bd1024ffee0da191c1b27fc71"}, + {file = "cffi-1.13.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:bb75ba21d5716abc41af16eac1145ab2e471deedde1f22c6f99bd9f995504df0"}, + {file = "cffi-1.13.1-cp35-cp35m-win32.whl", hash = "sha256:364f8404034ae1b232335d8c7f7b57deac566f148f7222cef78cf8ae28ef764e"}, + {file = "cffi-1.13.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fd82eb4694be712fcae03c717ca2e0fc720657ac226b80bbb597e971fc6928c2"}, + {file = "cffi-1.13.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:5ba86e1d80d458b338bda676fd9f9d68cb4e7a03819632969cf6d46b01a26730"}, + {file = "cffi-1.13.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:63424daa6955e6b4c70dc2755897f5be1d719eabe71b2625948b222775ed5c43"}, + {file = "cffi-1.13.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:33142ae9807665fa6511cfa9857132b2c3ee6ddffb012b3f0933fc11e1e830d5"}, + {file = "cffi-1.13.1-cp36-cp36m-win32.whl", hash = "sha256:e55b5a746fb77f10c83e8af081979351722f6ea48facea79d470b3731c7b2891"}, + {file = "cffi-1.13.1-cp36-cp36m-win_amd64.whl", hash = "sha256:47368f69fe6529f8f49a5d146ddee713fc9057e31d61e8b6dc86a6a5e38cecc1"}, + {file = "cffi-1.13.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:4895640844f17bec32943995dc8c96989226974dfeb9dd121cc45d36e0d0c434"}, + {file = "cffi-1.13.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:00d890313797d9fe4420506613384b43099ad7d2b905c0752dbcc3a6f14d80fa"}, + {file = "cffi-1.13.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a40ed527bffa2b7ebe07acc5a3f782da072e262ca994b4f2085100b5a444bbb2"}, + {file = "cffi-1.13.1-cp37-cp37m-win32.whl", hash = "sha256:6381a7d8b1ebd0bc27c3bc85bc1bfadbb6e6f756b4d4db0aa1425c3719ba26b4"}, + {file = "cffi-1.13.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1e389e069450609c6ffa37f21f40cce36f9be7643bbe5051ab1de99d5a779526"}, + {file = "cffi-1.13.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6381ab708158c4e1639da1f2a7679a9bbe3e5a776fc6d1fd808076f0e3145331"}, + {file = "cffi-1.13.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0cf9e550ac6c5e57b713437e2f4ac2d7fd0cd10336525a27224f5fc1ec2ee59a"}, + {file = "cffi-1.13.1-cp38-cp38-win32.whl", hash = "sha256:819f8d5197c2684524637f940445c06e003c4a541f9983fd30d6deaa2a5487d8"}, + {file = "cffi-1.13.1-cp38-cp38-win_amd64.whl", hash = "sha256:263242b6ace7f9cd4ea401428d2d45066b49a700852334fd55311bde36dcda14"}, + {file = "cffi-1.13.1.tar.gz", hash = "sha256:558b3afef987cf4b17abd849e7bedf64ee12b28175d564d05b628a0f9355599b"}, +] +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] +click = [ + {file = "Click-7.0-py2.py3-none-any.whl", hash = "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13"}, + {file = "Click-7.0.tar.gz", hash = "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"}, +] +colorama = [ + {file = "colorama-0.4.1-py2.py3-none-any.whl", hash = "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"}, + {file = "colorama-0.4.1.tar.gz", hash = "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d"}, +] +colorlog = [ + {file = "colorlog-4.0.2-py2.py3-none-any.whl", hash = "sha256:450f52ea2a2b6ebb308f034ea9a9b15cea51e65650593dca1da3eb792e4e4981"}, + {file = "colorlog-4.0.2.tar.gz", hash = "sha256:3cf31b25cbc8f86ec01fef582ef3b840950dea414084ed19ab922c8b493f9b42"}, +] +contextlib2 = [ + {file = "contextlib2-0.6.0.post1-py2.py3-none-any.whl", hash = "sha256:3355078a159fbb44ee60ea80abd0d87b80b78c248643b49aa6d94673b413609b"}, + {file = "contextlib2-0.6.0.post1.tar.gz", hash = "sha256:01f490098c18b19d2bd5bb5dc445b2054d2fa97f09a4280ba2c5f3c394c8162e"}, +] +coverage = [ + {file = "coverage-4.5.4-cp26-cp26m-macosx_10_12_x86_64.whl", hash = "sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28"}, + {file = "coverage-4.5.4-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c"}, + {file = "coverage-4.5.4-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce"}, + {file = "coverage-4.5.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe"}, + {file = "coverage-4.5.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888"}, + {file = "coverage-4.5.4-cp27-cp27m-win32.whl", hash = "sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc"}, + {file = "coverage-4.5.4-cp27-cp27m-win_amd64.whl", hash = "sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24"}, + {file = "coverage-4.5.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437"}, + {file = "coverage-4.5.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6"}, + {file = "coverage-4.5.4-cp33-cp33m-macosx_10_10_x86_64.whl", hash = "sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5"}, + {file = "coverage-4.5.4-cp34-cp34m-macosx_10_12_x86_64.whl", hash = "sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef"}, + {file = "coverage-4.5.4-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e"}, + {file = "coverage-4.5.4-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca"}, + {file = "coverage-4.5.4-cp34-cp34m-win32.whl", hash = "sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0"}, + {file = "coverage-4.5.4-cp34-cp34m-win_amd64.whl", hash = "sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1"}, + {file = "coverage-4.5.4-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7"}, + {file = "coverage-4.5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47"}, + {file = "coverage-4.5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025"}, + {file = "coverage-4.5.4-cp35-cp35m-win32.whl", hash = "sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e"}, + {file = "coverage-4.5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d"}, + {file = "coverage-4.5.4-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9"}, + {file = "coverage-4.5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755"}, + {file = "coverage-4.5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9"}, + {file = "coverage-4.5.4-cp36-cp36m-win32.whl", hash = "sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f"}, + {file = "coverage-4.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5"}, + {file = "coverage-4.5.4-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca"}, + {file = "coverage-4.5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650"}, + {file = "coverage-4.5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2"}, + {file = "coverage-4.5.4-cp37-cp37m-win32.whl", hash = "sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5"}, + {file = "coverage-4.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351"}, + {file = "coverage-4.5.4-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5"}, + {file = "coverage-4.5.4.tar.gz", hash = "sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c"}, +] +coveralls = [ + {file = "coveralls-1.8.2-py2.py3-none-any.whl", hash = "sha256:9bc5a1f92682eef59f688a8f280207190d9a6afb84cef8f567fa47631a784060"}, + {file = "coveralls-1.8.2.tar.gz", hash = "sha256:fb51cddef4bc458de347274116df15d641a735d3f0a580a9472174e2e62f408c"}, +] +docopt = [ + {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, +] +filetype = [ + {file = "filetype-1.0.5-py2.py3-none-any.whl", hash = "sha256:4967124d982a71700d94a08c49c4926423500e79382a92070f5ab248d44fe461"}, + {file = "filetype-1.0.5.tar.gz", hash = "sha256:17a3b885f19034da29640b083d767e0f13c2dcb5dcc267945c8b6e5a5a9013c7"}, +] +flask = [ + {file = "Flask-0.12.4-py2.py3-none-any.whl", hash = "sha256:6c02dbaa5a9ef790d8219bdced392e2d549c10cd5a5ba4b6aa65126b2271af29"}, + {file = "Flask-0.12.4.tar.gz", hash = "sha256:2ea22336f6d388b4b242bc3abf8a01244a8aa3e236e7407469ef78c16ba355dd"}, +] +future = [ + {file = "future-0.17.1.tar.gz", hash = "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8"}, +] +gevent = [ + {file = "gevent-1.4.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b7d3a285978b27b469c0ff5fb5a72bcd69f4306dbbf22d7997d83209a8ba917"}, + {file = "gevent-1.4.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:44089ed06a962a3a70e96353c981d628b2d4a2f2a75ea5d90f916a62d22af2e8"}, + {file = "gevent-1.4.0-cp27-cp27m-win32.whl", hash = "sha256:0e1e5b73a445fe82d40907322e1e0eec6a6745ca3cea19291c6f9f50117bb7ea"}, + {file = "gevent-1.4.0-cp27-cp27m-win_amd64.whl", hash = "sha256:74b7528f901f39c39cdbb50cdf08f1a2351725d9aebaef212a29abfbb06895ee"}, + {file = "gevent-1.4.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0ff2b70e8e338cf13bedf146b8c29d475e2a544b5d1fe14045aee827c073842c"}, + {file = "gevent-1.4.0-cp34-cp34m-macosx_10_14_x86_64.whl", hash = "sha256:0774babec518a24d9a7231d4e689931f31b332c4517a771e532002614e270a64"}, + {file = "gevent-1.4.0-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:d752bcf1b98174780e2317ada12013d612f05116456133a6acf3e17d43b71f05"}, + {file = "gevent-1.4.0-cp34-cp34m-win32.whl", hash = "sha256:3249011d13d0c63bea72d91cec23a9cf18c25f91d1f115121e5c9113d753fa12"}, + {file = "gevent-1.4.0-cp34-cp34m-win_amd64.whl", hash = "sha256:d1e6d1f156e999edab069d79d890859806b555ce4e4da5b6418616322f0a3df1"}, + {file = "gevent-1.4.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7d0809e2991c9784eceeadef01c27ee6a33ca09ebba6154317a257353e3af922"}, + {file = "gevent-1.4.0-cp35-cp35m-win32.whl", hash = "sha256:14b4d06d19d39a440e72253f77067d27209c67e7611e352f79fe69e0f618f76e"}, + {file = "gevent-1.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:53b72385857e04e7faca13c613c07cab411480822ac658d97fd8a4ddbaf715c8"}, + {file = "gevent-1.4.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:8d9ec51cc06580f8c21b41fd3f2b3465197ba5b23c00eb7d422b7ae0380510b0"}, + {file = "gevent-1.4.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2711e69788ddb34c059a30186e05c55a6b611cb9e34ac343e69cf3264d42fe1c"}, + {file = "gevent-1.4.0-cp36-cp36m-win32.whl", hash = "sha256:e5bcc4270671936349249d26140c267397b7b4b1381f5ec8b13c53c5b53ab6e1"}, + {file = "gevent-1.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9f7a1e96fec45f70ad364e46de32ccacab4d80de238bd3c2edd036867ccd48ad"}, + {file = "gevent-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:50024a1ee2cf04645535c5ebaeaa0a60c5ef32e262da981f4be0546b26791950"}, + {file = "gevent-1.4.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4bfa291e3c931ff3c99a349d8857605dca029de61d74c6bb82bd46373959c942"}, + {file = "gevent-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:ab4dc33ef0e26dc627559786a4fba0c2227f125db85d970abbf85b77506b3f51"}, + {file = "gevent-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:896b2b80931d6b13b5d9feba3d4eebc67d5e6ec54f0cf3339d08487d55d93b0e"}, + {file = "gevent-1.4.0-pp260-pypy_41-macosx_10_14_x86_64.whl", hash = "sha256:107f4232db2172f7e8429ed7779c10f2ed16616d75ffbe77e0e0c3fcdeb51a51"}, + {file = "gevent-1.4.0-pp260-pypy_41-win32.whl", hash = "sha256:28a0c5417b464562ab9842dd1fb0cc1524e60494641d973206ec24d6ec5f6909"}, + {file = "gevent-1.4.0.tar.gz", hash = "sha256:1eb7fa3b9bd9174dfe9c3b59b7a09b768ecd496debfc4976a9530a3e15c990d1"}, +] +greenlet = [ + {file = "greenlet-0.4.15-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99a26afdb82ea83a265137a398f570402aa1f2b5dfb4ac3300c026931817b163"}, + {file = "greenlet-0.4.15-cp27-cp27m-win32.whl", hash = "sha256:beeabe25c3b704f7d56b573f7d2ff88fc99f0138e43480cecdfcaa3b87fe4f87"}, + {file = "greenlet-0.4.15-cp27-cp27m-win_amd64.whl", hash = "sha256:9854f612e1b59ec66804931df5add3b2d5ef0067748ea29dc60f0efdcda9a638"}, + {file = "greenlet-0.4.15-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ac57fcdcfb0b73bb3203b58a14501abb7e5ff9ea5e2edfa06bb03035f0cff248"}, + {file = "greenlet-0.4.15-cp33-cp33m-win32.whl", hash = "sha256:d634a7ea1fc3380ff96f9e44d8d22f38418c1c381d5fac680b272d7d90883720"}, + {file = "greenlet-0.4.15-cp33-cp33m-win_amd64.whl", hash = "sha256:0d48200bc50cbf498716712129eef819b1729339e34c3ae71656964dac907c28"}, + {file = "greenlet-0.4.15-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:bcb530089ff24f6458a81ac3fa699e8c00194208a724b644ecc68422e1111939"}, + {file = "greenlet-0.4.15-cp34-cp34m-win32.whl", hash = "sha256:8b4572c334593d449113f9dc8d19b93b7b271bdbe90ba7509eb178923327b625"}, + {file = "greenlet-0.4.15-cp34-cp34m-win_amd64.whl", hash = "sha256:a9f145660588187ff835c55a7d2ddf6abfc570c2651c276d3d4be8a2766db490"}, + {file = "greenlet-0.4.15-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:51503524dd6f152ab4ad1fbd168fc6c30b5795e8c70be4410a64940b3abb55c0"}, + {file = "greenlet-0.4.15-cp35-cp35m-win32.whl", hash = "sha256:a19bf883b3384957e4a4a13e6bd1ae3d85ae87f4beb5957e35b0be287f12f4e4"}, + {file = "greenlet-0.4.15-cp35-cp35m-win_amd64.whl", hash = "sha256:853da4f9563d982e4121fed8c92eea1a4594a2299037b3034c3c898cb8e933d6"}, + {file = "greenlet-0.4.15-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:23d12eacffa9d0f290c0fe0c4e81ba6d5f3a5b7ac3c30a5eaf0126bf4deda5c8"}, + {file = "greenlet-0.4.15-cp36-cp36m-win32.whl", hash = "sha256:000546ad01e6389e98626c1367be58efa613fa82a1be98b0c6fc24b563acc6d0"}, + {file = "greenlet-0.4.15-cp36-cp36m-win_amd64.whl", hash = "sha256:d97b0661e1aead761f0ded3b769044bb00ed5d33e1ec865e891a8b128bf7c656"}, + {file = "greenlet-0.4.15-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:8041e2de00e745c0e05a502d6e6db310db7faa7c979b3a5877123548a4c0b214"}, + {file = "greenlet-0.4.15-cp37-cp37m-win32.whl", hash = "sha256:81fcd96a275209ef117e9ec91f75c731fa18dcfd9ffaa1c0adbdaa3616a86043"}, + {file = "greenlet-0.4.15-cp37-cp37m-win_amd64.whl", hash = "sha256:37c9ba82bd82eb6a23c2e5acc03055c0e45697253b2393c9a50cef76a3985304"}, + {file = "greenlet-0.4.15.tar.gz", hash = "sha256:9416443e219356e3c31f1f918a91badf2e37acf297e2fa13d24d1cc2380f8fbc"}, +] +har2case = [ + {file = "har2case-0.3.1-py2.py3-none-any.whl", hash = "sha256:84d3a5cc9fbb16e45372e7e880a936c59bbe8e9b66bad81927769e64f608e2af"}, + {file = "har2case-0.3.1.tar.gz", hash = "sha256:8f159ec7cba82ec4282f46af4a9dac89f65e62796521b2426d3c89c3c9fd8579"}, +] +idna = [ + {file = "idna-2.8-py2.py3-none-any.whl", hash = "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"}, + {file = "idna-2.8.tar.gz", hash = "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407"}, +] +itsdangerous = [ + {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, + {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, +] +jinja2 = [ + {file = "Jinja2-2.10.3-py2.py3-none-any.whl", hash = "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f"}, + {file = "Jinja2-2.10.3.tar.gz", hash = "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"}, +] +jsonpath = [ + {file = "jsonpath-0.82.tar.gz", hash = "sha256:46d3fd2016cd5b842283d547877a02c418a0fe9aa7a6b0ae344115a2c990fef4"}, +] +locustio = [ + {file = "locustio-0.11.0-py2.py3-none-any.whl", hash = "sha256:514562bb0040f18f7b3b74ed9beb943800030801058501c630c8b3fc02bafa27"}, + {file = "locustio-0.11.0.tar.gz", hash = "sha256:93404f831114791b0756325c53b08bff73f048eeb69688be657629feaa62b507"}, +] +markupsafe = [ + {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, + {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, +] +msgpack = [ + {file = "msgpack-0.6.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:774f5edc3475917cd95fe593e625d23d8580f9b48b570d8853d06cac171cd170"}, + {file = "msgpack-0.6.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:a06efd0482a1942aad209a6c18321b5e22d64eb531ea20af138b28172d8f35ba"}, + {file = "msgpack-0.6.2-cp27-cp27m-win32.whl", hash = "sha256:8a3ada8401736df2bf497f65589293a86c56e197a80ae7634ec2c3150a2f5082"}, + {file = "msgpack-0.6.2-cp27-cp27m-win_amd64.whl", hash = "sha256:b8b4bd3dafc7b92608ae5462add1c8cc881851c2d4f5d8977fdea5b081d17f21"}, + {file = "msgpack-0.6.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:24149a75643aeaa81ece4259084d11b792308a6cf74e796cbb35def94c89a25a"}, + {file = "msgpack-0.6.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:757bd71a9b89e4f1db0622af4436d403e742506dbea978eba566815dc65ec895"}, + {file = "msgpack-0.6.2-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:32fea0ea3cd1ef820286863a6202dcfd62a539b8ec3edcbdff76068a8c2cc6ce"}, + {file = "msgpack-0.6.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:db7ff14abc73577b0bcbcf73ecff97d3580ecaa0fc8724babce21fdf3fe08ef6"}, + {file = "msgpack-0.6.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:187794cd1eb73acccd528247e3565f6760bd842d7dc299241f830024a7dd5610"}, + {file = "msgpack-0.6.2-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:b24afc52e18dccc8c175de07c1d680bdf315844566f4952b5bedb908894bec79"}, + {file = "msgpack-0.6.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:355f7fd0f90134229eaeefaee3cf42e0afc8518e8f3cd4b25f541a7104dcb8f9"}, + {file = "msgpack-0.6.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:76df51492bc6fa6cc8b65d09efdb67cbba3cbfe55004c3afc81352af92b4a43c"}, + {file = "msgpack-0.6.2-cp36-cp36m-win32.whl", hash = "sha256:f0f47bafe9c9b8ed03e19a100a743662dd8c6d0135e684feea720a0d0046d116"}, + {file = "msgpack-0.6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:c6e5024fc0cdf7f83b6624850309ddd7e06c48a75fa0d1c5173de4d93300eb19"}, + {file = "msgpack-0.6.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:30b88c47e0cdb6062daed88ca283b0d84fa0d2ad6c273aa0788152a1c643e408"}, + {file = "msgpack-0.6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:229a0ccdc39e9b6c6d1033cd8aecd9c296823b6c87f0de3943c59b8bc7c64bee"}, + {file = "msgpack-0.6.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4abdb88a9b67e64810fb54b0c24a1fd76b12297b4f7a1467d85a14dd8367191a"}, + {file = "msgpack-0.6.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dedf54d72d9e7b6d043c244c8213fe2b8bbfe66874b9a65b39c4cc892dd99dd4"}, + {file = "msgpack-0.6.2-cp37-cp37m-win32.whl", hash = "sha256:0cc7ca04e575ba34fea7cfcd76039f55def570e6950e4155a4174368142c8e1b"}, + {file = "msgpack-0.6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:1904b7cb65342d0998b75908304a03cb004c63ef31e16c8c43fee6b989d7f0d7"}, + {file = "msgpack-0.6.2.tar.gz", hash = "sha256:ea3c2f859346fcd55fc46e96885301d9c2f7a36d453f5d8f2967840efa1e1830"}, +] +pycparser = [ + {file = "pycparser-2.19.tar.gz", hash = "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"}, +] +pyyaml = [ + {file = "PyYAML-5.1.2-cp27-cp27m-win32.whl", hash = "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8"}, + {file = "PyYAML-5.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"}, + {file = "PyYAML-5.1.2-cp34-cp34m-win32.whl", hash = "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9"}, + {file = "PyYAML-5.1.2-cp34-cp34m-win_amd64.whl", hash = "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696"}, + {file = "PyYAML-5.1.2-cp35-cp35m-win32.whl", hash = "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41"}, + {file = "PyYAML-5.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73"}, + {file = "PyYAML-5.1.2-cp36-cp36m-win32.whl", hash = "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299"}, + {file = "PyYAML-5.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b"}, + {file = "PyYAML-5.1.2-cp37-cp37m-win32.whl", hash = "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae"}, + {file = "PyYAML-5.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34"}, + {file = "PyYAML-5.1.2-cp38-cp38m-win32.whl", hash = "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9"}, + {file = "PyYAML-5.1.2-cp38-cp38m-win_amd64.whl", hash = "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681"}, + {file = "PyYAML-5.1.2.tar.gz", hash = "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4"}, +] +pyzmq = [ + {file = "pyzmq-18.1.0-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:856b2cdf7a1e2cbb84928e1e8db0ea4018709b39804103d3a409e5584f553f57"}, + {file = "pyzmq-18.1.0-cp27-cp27m-win32.whl", hash = "sha256:2762c45e289732d4450406cedca35a9d4d71e449131ba2f491e0bf473e3d2ff2"}, + {file = "pyzmq-18.1.0-cp27-cp27m-win_amd64.whl", hash = "sha256:fa4bad0d1d173dee3e8ef3c3eb6b2bb6c723fc7a661eeecc1ecb2fa99860dd45"}, + {file = "pyzmq-18.1.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:98fa3e75ccb22c0dc99654e3dd9ff693b956861459e8c8e8734dd6247b89eb29"}, + {file = "pyzmq-18.1.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:dd5995ae2e80044e33b5077fb4bc2b0c1788ac6feaf15a6b87a00c14b4bdd682"}, + {file = "pyzmq-18.1.0-cp34-cp34m-win32.whl", hash = "sha256:260c70b7c018905ec3659d0f04db735ac830fe27236e43b9dc0532cf7c9873ef"}, + {file = "pyzmq-18.1.0-cp34-cp34m-win_amd64.whl", hash = "sha256:021dba0d1436516092c624359e5da51472b11ba8edffa334218912f7e8b65467"}, + {file = "pyzmq-18.1.0-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cf0765822e78cf9e45451647a346d443f66792aba906bc340f4e0ac7870c169c"}, + {file = "pyzmq-18.1.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:e03fe5e07e70f245dc9013a9d48ae8cc4b10c33a1968039c5a3b64b5d01d083d"}, + {file = "pyzmq-18.1.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:05fd51edd81eed798fccafdd49c936b6c166ffae7b32482e4d6d6a2e196af4e6"}, + {file = "pyzmq-18.1.0-cp35-cp35m-win32.whl", hash = "sha256:22efa0596cf245a78a99060fe5682c4cd00c58bb7614271129215c889062db80"}, + {file = "pyzmq-18.1.0-cp35-cp35m-win_amd64.whl", hash = "sha256:85b869abc894672de9aecdf032158ea8ad01e2f0c3b09ef60e3687fb79418096"}, + {file = "pyzmq-18.1.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:dc398e1e047efb18bfab7a8989346c6921a847feae2cad69fedf6ca12fb99e2c"}, + {file = "pyzmq-18.1.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:9a22c94d2e93af8bebd4fcf5fa38830f5e3b1ff0d4424e2912b07651eb1bafb4"}, + {file = "pyzmq-18.1.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:b645a49376547b3816433a7e2d2a99135c8e651e50497e7ecac3bd126e4bea16"}, + {file = "pyzmq-18.1.0-cp36-cp36m-win32.whl", hash = "sha256:a7d3f4b4bbb5d7866ae727763268b5c15797cbd7b63ea17f3b0ec1067da8994b"}, + {file = "pyzmq-18.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:01636e95a88d60118479041c6aaaaf5419c6485b7b1d37c9c4dd424b7b9f1121"}, + {file = "pyzmq-18.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f4e37f33da282c3c319849877e34f97f0a3acec09622ec61b7333205bdd13b52"}, + {file = "pyzmq-18.1.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ea09a306144dff2795e48439883349819bef2c53c0ee62a3c2fae429451843bb"}, + {file = "pyzmq-18.1.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:343b9710a61f2b167673bea1974e70b5dccfe64b5ed10626798f08c1f7227e72"}, + {file = "pyzmq-18.1.0-cp37-cp37m-win32.whl", hash = "sha256:41bf96d5f554598a0632c3ec28e3026f1d6591a50f580df38eff0b8067efb9e7"}, + {file = "pyzmq-18.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:0463bd941b6aead494d4035f7eebd70035293dd6caf8425993e85ad41de13fa3"}, + {file = "pyzmq-18.1.0-pp271-pypy_41-macosx_10_14_x86_64.whl", hash = "sha256:2fc6cada8dc53521c1189596f1898d45c5f68603194d3a6453d6db4b27f4e12e"}, + {file = "pyzmq-18.1.0-pp371-pypy3_71-macosx_10_14_x86_64.whl", hash = "sha256:1fadc8fbdf3d22753c36d4172169d184ee6654f8d6539e7af25029643363c490"}, + {file = "pyzmq-18.1.0.tar.gz", hash = "sha256:93f44739db69234c013a16990e43db1aa0af3cf5a4b8b377d028ff24515fbeb3"}, +] +requests = [ + {file = "requests-2.22.0-py2.py3-none-any.whl", hash = "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"}, + {file = "requests-2.22.0.tar.gz", hash = "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4"}, +] +requests-toolbelt = [ + {file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"}, + {file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"}, +] +six = [ + {file = "six-1.12.0-py2.py3-none-any.whl", hash = "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c"}, + {file = "six-1.12.0.tar.gz", hash = "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"}, +] +urllib3 = [ + {file = "urllib3-1.25.6-py2.py3-none-any.whl", hash = "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398"}, + {file = "urllib3-1.25.6.tar.gz", hash = "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86"}, +] +werkzeug = [ + {file = "Werkzeug-0.16.0-py2.py3-none-any.whl", hash = "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4"}, + {file = "Werkzeug-0.16.0.tar.gz", hash = "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7"}, +] From 486f7f9061dd7dfa5cf82676cc484653e0401b83 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 19:09:18 +0800 Subject: [PATCH 10/28] change: update poetry.lock --- poetry.lock | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4f55c34a..bfdf0c65 100644 --- a/poetry.lock +++ b/poetry.lock @@ -9,7 +9,7 @@ version = "2019.9.11" [[package]] category = "dev" description = "Foreign Function Interface for Python calling C code." -marker = "sys_platform == \"win32\" and platform_python_implementation == \"CPython\"" +marker = "python_version < \"3\" and extra == \"secure\" or sys_platform == \"win32\" and platform_python_implementation == \"CPython\"" name = "cffi" optional = false python-versions = "*" @@ -90,6 +90,34 @@ version = "*" [package.extras] yaml = ["PyYAML (>=3.10)"] +[[package]] +category = "dev" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +marker = "python_version < \"3\" and extra == \"secure\"" +name = "cryptography" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "2.8" + +[package.dependencies] +cffi = ">=1.8,<1.11.3 || >1.11.3" +six = ">=1.4.1" + +[package.dependencies.enum34] +python = "<3" +version = "*" + +[package.dependencies.ipaddress] +python = "<3" +version = "*" + +[package.extras] +docs = ["sphinx (>=1.6.5,<1.8.0 || >1.8.0)", "sphinx-rtd-theme"] +docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +idna = ["idna (>=2.1)"] +pep8test = ["flake8", "flake8-import-order", "pep8-naming"] +test = ["pytest (>=3.6.0,<3.9.0 || >3.9.0,<3.9.1 || >3.9.1,<3.9.2 || >3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,<3.79.2 || >3.79.2)"] + [[package]] category = "dev" description = "Pythonic argument parser, that will make you smile" @@ -98,6 +126,15 @@ optional = false python-versions = "*" version = "0.6.2" +[[package]] +category = "dev" +description = "Python 3.4 Enum backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4" +marker = "python_version < \"3\" and extra == \"secure\"" +name = "enum34" +optional = false +python-versions = "*" +version = "1.1.6" + [[package]] category = "main" description = "Infer file type and MIME type of any file/buffer. No external dependencies." @@ -175,6 +212,15 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "2.8" +[[package]] +category = "dev" +description = "IPv4/IPv6 manipulation library" +marker = "python_version < \"3\" and extra == \"secure\" or python_version == \"2.7\" and extra == \"secure\"" +name = "ipaddress" +optional = false +python-versions = "*" +version = "1.0.23" + [[package]] category = "dev" description = "Various helpers to pass data to untrusted environments and back." @@ -240,12 +286,29 @@ version = "0.6.2" [[package]] category = "dev" description = "C parser in Python" -marker = "sys_platform == \"win32\" and platform_python_implementation == \"CPython\"" +marker = "python_version < \"3\" and extra == \"secure\" or sys_platform == \"win32\" and platform_python_implementation == \"CPython\"" name = "pycparser" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "2.19" +[[package]] +category = "dev" +description = "Python wrapper module around the OpenSSL library" +marker = "python_version < \"3\" and extra == \"secure\"" +name = "pyopenssl" +optional = false +python-versions = "*" +version = "19.0.0" + +[package.dependencies] +cryptography = ">=2.3" +six = ">=1.5.2" + +[package.extras] +docs = ["sphinx", "sphinx-rtd-theme"] +test = ["flaky", "pretend", "pytest (>=3.0.1)"] + [[package]] category = "main" description = "YAML parser and emitter for Python" @@ -307,6 +370,28 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" version = "1.25.6" +[package.dependencies] +[package.dependencies.certifi] +optional = true +version = "*" + +[package.dependencies.cryptography] +optional = true +version = ">=1.3.4" + +[package.dependencies.idna] +optional = true +version = ">=2.0.0" + +[package.dependencies.ipaddress] +optional = true +python = ">=2.7,<2.8" +version = "*" + +[package.dependencies.pyOpenSSL] +optional = true +version = ">=0.14" + [package.extras] brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] @@ -424,9 +509,38 @@ coveralls = [ {file = "coveralls-1.8.2-py2.py3-none-any.whl", hash = "sha256:9bc5a1f92682eef59f688a8f280207190d9a6afb84cef8f567fa47631a784060"}, {file = "coveralls-1.8.2.tar.gz", hash = "sha256:fb51cddef4bc458de347274116df15d641a735d3f0a580a9472174e2e62f408c"}, ] +cryptography = [ + {file = "cryptography-2.8-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8"}, + {file = "cryptography-2.8-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2"}, + {file = "cryptography-2.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad"}, + {file = "cryptography-2.8-cp27-cp27m-win32.whl", hash = "sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2"}, + {file = "cryptography-2.8-cp27-cp27m-win_amd64.whl", hash = "sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912"}, + {file = "cryptography-2.8-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d"}, + {file = "cryptography-2.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42"}, + {file = "cryptography-2.8-cp34-abi3-macosx_10_6_intel.whl", hash = "sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879"}, + {file = "cryptography-2.8-cp34-abi3-manylinux1_x86_64.whl", hash = "sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d"}, + {file = "cryptography-2.8-cp34-abi3-manylinux2010_x86_64.whl", hash = "sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9"}, + {file = "cryptography-2.8-cp34-cp34m-win32.whl", hash = "sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c"}, + {file = "cryptography-2.8-cp34-cp34m-win_amd64.whl", hash = "sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0"}, + {file = "cryptography-2.8-cp35-cp35m-win32.whl", hash = "sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf"}, + {file = "cryptography-2.8-cp35-cp35m-win_amd64.whl", hash = "sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793"}, + {file = "cryptography-2.8-cp36-cp36m-win32.whl", hash = "sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595"}, + {file = "cryptography-2.8-cp36-cp36m-win_amd64.whl", hash = "sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7"}, + {file = "cryptography-2.8-cp37-cp37m-win32.whl", hash = "sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff"}, + {file = "cryptography-2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f"}, + {file = "cryptography-2.8-cp38-cp38-win32.whl", hash = "sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e"}, + {file = "cryptography-2.8-cp38-cp38-win_amd64.whl", hash = "sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13"}, + {file = "cryptography-2.8.tar.gz", hash = "sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651"}, +] docopt = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] +enum34 = [ + {file = "enum34-1.1.6-py2-none-any.whl", hash = "sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79"}, + {file = "enum34-1.1.6-py3-none-any.whl", hash = "sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a"}, + {file = "enum34-1.1.6.tar.gz", hash = "sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"}, + {file = "enum34-1.1.6.zip", hash = "sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850"}, +] filetype = [ {file = "filetype-1.0.5-py2.py3-none-any.whl", hash = "sha256:4967124d982a71700d94a08c49c4926423500e79382a92070f5ab248d44fe461"}, {file = "filetype-1.0.5.tar.gz", hash = "sha256:17a3b885f19034da29640b083d767e0f13c2dcb5dcc267945c8b6e5a5a9013c7"}, @@ -492,6 +606,10 @@ idna = [ {file = "idna-2.8-py2.py3-none-any.whl", hash = "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"}, {file = "idna-2.8.tar.gz", hash = "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407"}, ] +ipaddress = [ + {file = "ipaddress-1.0.23-py2.py3-none-any.whl", hash = "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc"}, + {file = "ipaddress-1.0.23.tar.gz", hash = "sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2"}, +] itsdangerous = [ {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, @@ -563,6 +681,10 @@ msgpack = [ pycparser = [ {file = "pycparser-2.19.tar.gz", hash = "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"}, ] +pyopenssl = [ + {file = "pyOpenSSL-19.0.0-py2.py3-none-any.whl", hash = "sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6"}, + {file = "pyOpenSSL-19.0.0.tar.gz", hash = "sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200"}, +] pyyaml = [ {file = "PyYAML-5.1.2-cp27-cp27m-win32.whl", hash = "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8"}, {file = "PyYAML-5.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"}, From a25f2eddf3257b3627526787517792a43fbd3c05 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 19:43:26 +0800 Subject: [PATCH 11/28] fix: logger setup mupltiple times --- httprunner/logger.py | 46 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/httprunner/logger.py b/httprunner/logger.py index 62cb56c6..2887f309 100644 --- a/httprunner/logger.py +++ b/httprunner/logger.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - import logging import sys @@ -8,6 +6,9 @@ from colorlog import ColoredFormatter init(autoreset=True) +LOG_LEVEL = "INFO" +LOG_FILE_PATH = None + log_colors_config = { 'DEBUG': 'cyan', 'INFO': 'green', @@ -15,11 +16,27 @@ log_colors_config = { 'ERROR': 'red', 'CRITICAL': 'red', } -logger = logging.getLogger("httprunner") +loggers = {} def setup_logger(log_level, log_file=None): + global LOG_LEVEL + LOG_LEVEL = log_level + + if log_file: + global LOG_FILE_PATH + LOG_FILE_PATH = log_file + + +def get_logger(name=None): """setup logger with ColoredFormatter.""" + name = name or "httprunner" + if name in loggers: + return loggers[name] + + _logger = logging.getLogger(name) + + log_level = LOG_LEVEL level = getattr(logging, log_level.upper(), None) if not level: color_print("Invalid log level: %s" % log_level, "RED") @@ -29,21 +46,24 @@ def setup_logger(log_level, log_file=None): if level >= logging.INFO: sys.tracebacklimit = 0 + _logger.setLevel(level) + + if LOG_FILE_PATH: + handler = logging.FileHandler(LOG_FILE_PATH, encoding="utf-8") + else: + handler = logging.StreamHandler(sys.stdout) + formatter = ColoredFormatter( u"%(log_color)s%(bg_white)s%(levelname)-8s%(reset)s %(message)s", datefmt=None, reset=True, log_colors=log_colors_config ) - - if log_file: - handler = logging.FileHandler(log_file, encoding="utf-8") - else: - handler = logging.StreamHandler() - handler.setFormatter(formatter) - logger.addHandler(handler) - logger.setLevel(level) + _logger.addHandler(handler) + + loggers[name] = _logger + return _logger def coloring(text, color="WHITE"): @@ -59,9 +79,11 @@ def color_print(msg, color="WHITE"): def log_with_color(level): """ log with color by different level """ + _logger = get_logger() + def wrapper(text): color = log_colors_config[level.upper()] - getattr(logger, level.lower())(coloring(text, color)) + getattr(_logger, level.lower())(coloring(text, color)) return wrapper From 3b8d92bbcfd9174cbe5205ba07fce6047ae1c5b3 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 20:11:18 +0800 Subject: [PATCH 12/28] fix: log_with_color wrapper --- httprunner/logger.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/httprunner/logger.py b/httprunner/logger.py index 2887f309..ce2e4c97 100644 --- a/httprunner/logger.py +++ b/httprunner/logger.py @@ -79,10 +79,9 @@ def color_print(msg, color="WHITE"): def log_with_color(level): """ log with color by different level """ - _logger = get_logger() - def wrapper(text): color = log_colors_config[level.upper()] + _logger = get_logger() getattr(_logger, level.lower())(coloring(text, color)) return wrapper From 0ae33f89bb6e4743ab0361000e5f98e43173675c Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 20:12:11 +0800 Subject: [PATCH 13/28] feat: ignore .venv --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 495a27d3..55e509a6 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ logs .coverage locustfile.py site/ -reports \ No newline at end of file +reports +.venv \ No newline at end of file From d7276adb8327cfefd731667df0da40b974eeb408 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 20:19:58 +0800 Subject: [PATCH 14/28] fix: remove unused arguments --- httprunner/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/httprunner/client.py b/httprunner/client.py index bd6766c3..bc7cd07e 100644 --- a/httprunner/client.py +++ b/httprunner/client.py @@ -31,8 +31,8 @@ class HttpSession(requests.Session): This is a slightly extended version of `python-request `_'s :py:class:`requests.Session` class and mostly this class works exactly the same. """ - def __init__(self, *args, **kwargs): - super(HttpSession, self).__init__(*args, **kwargs) + def __init__(self): + super(HttpSession, self).__init__() self.init_meta_data() def init_meta_data(self): From 61b43e34297bf5f78ce863740cc0173ef54a10e8 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 21:59:44 +0800 Subject: [PATCH 15/28] change: remove unused file --- httprunner/plugins/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 httprunner/plugins/__init__.py diff --git a/httprunner/plugins/__init__.py b/httprunner/plugins/__init__.py deleted file mode 100644 index e69de29b..00000000 From 569cad5dda3b2b44f5ca08625c12ea4921dddecb Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 25 Oct 2019 23:42:02 +0800 Subject: [PATCH 16/28] change: locusts --- httprunner/compat.py | 1 - httprunner/plugins/locusts/README.md | 18 +- httprunner/plugins/locusts/__init__.py | 195 ------------------ httprunner/plugins/locusts/__main__.py | 4 +- httprunner/plugins/locusts/cli.py | 169 +++++++++++++++ ...stfile_template => locustfile_template.py} | 3 +- httprunner/plugins/locusts/utils.py | 29 +++ poetry.lock | 190 +---------------- pyproject.toml | 25 +-- tests/test_plugins/test_locusts.py | 2 +- 10 files changed, 228 insertions(+), 408 deletions(-) create mode 100644 httprunner/plugins/locusts/cli.py rename httprunner/plugins/locusts/{locustfile_template => locustfile_template.py} (90%) create mode 100644 httprunner/plugins/locusts/utils.py diff --git a/httprunner/compat.py b/httprunner/compat.py index 72716b22..e7e92ca3 100644 --- a/httprunner/compat.py +++ b/httprunner/compat.py @@ -7,7 +7,6 @@ httprunner.compat This module handles import compatibility issues between Python 2 and Python 3. """ -from collections import OrderedDict try: import simplejson as json diff --git a/httprunner/plugins/locusts/README.md b/httprunner/plugins/locusts/README.md index 514ea9bb..831e84d7 100644 --- a/httprunner/plugins/locusts/README.md +++ b/httprunner/plugins/locusts/README.md @@ -1,5 +1,11 @@ # locusts +## Installation + +```shell script +$ pip install locustio +``` + ## Usage ```shell script @@ -7,7 +13,11 @@ $ locusts -f xxx.yml ``` ```shell script -$ python3 -m plugins.locusts +$ locusts -f xxx.yml --processes +``` + +```shell script +$ python3 -m httprunner.plugins.locusts -h Usage: locust [options] [LocustClass [LocustClass2 ... ]] @@ -92,9 +102,3 @@ Options: --exit-code-on-error=EXIT_CODE_ON_ERROR sets the exit code to post on error ``` - -## tests - -```shell script -$ python -m plugins.locusts.test_main -``` diff --git a/httprunner/plugins/locusts/__init__.py b/httprunner/plugins/locusts/__init__.py index d16c3673..e69de29b 100644 --- a/httprunner/plugins/locusts/__init__.py +++ b/httprunner/plugins/locusts/__init__.py @@ -1,195 +0,0 @@ -# encoding: utf-8 -try: - # monkey patch ssl at beginning to avoid RecursionError when running locust. - from gevent import monkey - monkey.patch_ssl() -except ImportError: - msg = "Locust is not installed, install first and try again.\n" - msg += "install command: pip install locustio" - print(msg) - import sys - sys.exit(1) - -import io -import multiprocessing -import os -import sys - -from httprunner import logger, loader, parser - - -def parse_locustfile(file_path): - """ parse testcase file and return locustfile path. - if file_path is a Python file, assume it is a locustfile - if file_path is a YAML/JSON file, convert it to locustfile - """ - if not os.path.isfile(file_path): - logger.color_print("file path invalid, exit.", "RED") - sys.exit(1) - - file_suffix = os.path.splitext(file_path)[1] - if file_suffix == ".py": - locustfile_path = file_path - elif file_suffix in ['.yaml', '.yml', '.json']: - locustfile_path = gen_locustfile(file_path) - else: - # '' or other suffix - logger.color_print("file type should be YAML/JSON/Python, exit.", "RED") - sys.exit(1) - - return locustfile_path - - -def gen_locustfile(testcase_file_path): - """ generate locustfile from template. - """ - locustfile_path = 'locustfile.py' - template_path = os.path.join( - os.path.dirname(os.path.realpath(__file__)), - "locustfile_template" - ) - - with io.open(template_path, encoding='utf-8') as template: - with io.open(locustfile_path, 'w', encoding='utf-8') as locustfile: - template_content = template.read() - template_content = template_content.replace("$TESTCASE_FILE", testcase_file_path) - locustfile.write(template_content) - - return locustfile_path - - -def start_locust_main(): - from locust.main import main - main() - - -def start_master(sys_argv): - sys_argv.append("--master") - sys.argv = sys_argv - start_locust_main() - - -def start_slave(sys_argv): - if "--slave" not in sys_argv: - sys_argv.extend(["--slave"]) - - sys.argv = sys_argv - start_locust_main() - - -def run_locusts_with_processes(sys_argv, processes_count): - processes = [] - manager = multiprocessing.Manager() - - for _ in range(processes_count): - p_slave = multiprocessing.Process(target=start_slave, args=(sys_argv,)) - p_slave.daemon = True - p_slave.start() - processes.append(p_slave) - - try: - if "--slave" in sys_argv: - [process.join() for process in processes] - else: - start_master(sys_argv) - except KeyboardInterrupt: - manager.shutdown() - - -def main(): - """ Performance test with locust: parse command line options and run commands. - """ - sys.argv[0] = 'locust' - if len(sys.argv) == 1: - sys.argv.extend(["-h"]) - - if sys.argv[1] in ["-h", "--help", "-V", "--version"]: - start_locust_main() - - def get_arg_index(*target_args): - for arg in target_args: - if arg not in sys.argv: - continue - - return sys.argv.index(arg) + 1 - - return None - - # set logging level - loglevel_index = get_arg_index("-L", "--loglevel") - if loglevel_index and loglevel_index < len(sys.argv): - loglevel = sys.argv[loglevel_index] - else: - # default - loglevel = "WARNING" - - logger.setup_logger(loglevel) - - # get testcase file path - try: - testcase_index = get_arg_index("-f", "--locustfile") - assert testcase_index and testcase_index < len(sys.argv) - except AssertionError: - print("Testcase file is not specified, exit.") - sys.exit(1) - - testcase_file_path = sys.argv[testcase_index] - sys.argv[testcase_index] = parse_locustfile(testcase_file_path) - - if "--processes" in sys.argv: - """ locusts -f locustfile.py --processes 4 - """ - if "--no-web" in sys.argv: - logger.log_error("conflict parameter args: --processes & --no-web. \nexit.") - sys.exit(1) - - processes_index = sys.argv.index('--processes') - processes_count_index = processes_index + 1 - if processes_count_index >= len(sys.argv): - """ do not specify processes count explicitly - locusts -f locustfile.py --processes - """ - processes_count = multiprocessing.cpu_count() - logger.log_warning("processes count not specified, use {} by default.".format(processes_count)) - else: - try: - """ locusts -f locustfile.py --processes 4 """ - processes_count = int(sys.argv[processes_count_index]) - sys.argv.pop(processes_count_index) - except ValueError: - """ locusts -f locustfile.py --processes -P 8888 """ - processes_count = multiprocessing.cpu_count() - logger.log_warning("processes count not specified, use {} by default.".format(processes_count)) - - sys.argv.pop(processes_index) - run_locusts_with_processes(sys.argv, processes_count) - else: - start_locust_main() - - -def prepare_locust_tests(path): - """ prepare locust testcases - - Args: - path (str): testcase file path. - - Returns: - list: locust tests data - - [ - testcase1_dict, - testcase2_dict - ] - - """ - tests_mapping = loader.load_tests(path) - testcases = parser.parse_tests(tests_mapping) - - locust_tests = [] - - for testcase in testcases: - testcase_weight = testcase.get("config", {}).pop("weight", 1) - for _ in range(testcase_weight): - locust_tests.append(testcase) - - return locust_tests diff --git a/httprunner/plugins/locusts/__main__.py b/httprunner/plugins/locusts/__main__.py index 488e253d..dbf8961f 100644 --- a/httprunner/plugins/locusts/__main__.py +++ b/httprunner/plugins/locusts/__main__.py @@ -1,6 +1,4 @@ -import sys - -from httprunner.plugins.locusts import main +from httprunner.plugins.locusts.cli import main if __name__ == "__main__": main() diff --git a/httprunner/plugins/locusts/cli.py b/httprunner/plugins/locusts/cli.py new file mode 100644 index 00000000..882719e0 --- /dev/null +++ b/httprunner/plugins/locusts/cli.py @@ -0,0 +1,169 @@ +try: + # monkey patch ssl at beginning to avoid RecursionError when running locust. + from gevent import monkey + monkey.patch_ssl() +except ImportError: + msg = """ +Locust is not installed, install first and try again. +install with pip: +$ pip install locustio +""" + print(msg) + import sys + sys.exit(0) + +import io +import multiprocessing +import os +import sys + +from httprunner import logger + + +def parse_locustfile(file_path): + """ parse testcase file and return locustfile path. + if file_path is a Python file, assume it is a locustfile + if file_path is a YAML/JSON file, convert it to locustfile + """ + if not os.path.isfile(file_path): + logger.color_print("file path invalid, exit.", "RED") + sys.exit(1) + + file_suffix = os.path.splitext(file_path)[1] + if file_suffix == ".py": + locustfile_path = file_path + elif file_suffix in ['.yaml', '.yml', '.json']: + locustfile_path = gen_locustfile(file_path) + else: + # '' or other suffix + logger.color_print("file type should be YAML/JSON/Python, exit.", "RED") + sys.exit(1) + + return locustfile_path + + +def gen_locustfile(testcase_file_path): + """ generate locustfile from template. + """ + locustfile_path = 'locustfile.py' + template_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "locustfile_template.py" + ) + + with io.open(template_path, encoding='utf-8') as template: + with io.open(locustfile_path, 'w', encoding='utf-8') as locustfile: + template_content = template.read() + template_content = template_content.replace("$TESTCASE_FILE", testcase_file_path) + locustfile.write(template_content) + + return locustfile_path + + +def start_locust_main(): + from locust.main import main + main() + + +def start_master(sys_argv): + sys_argv.append("--master") + sys.argv = sys_argv + start_locust_main() + + +def start_slave(sys_argv): + if "--slave" not in sys_argv: + sys_argv.extend(["--slave"]) + + sys.argv = sys_argv + start_locust_main() + + +def run_locusts_with_processes(sys_argv, processes_count): + processes = [] + manager = multiprocessing.Manager() + + for _ in range(processes_count): + p_slave = multiprocessing.Process(target=start_slave, args=(sys_argv,)) + p_slave.daemon = True + p_slave.start() + processes.append(p_slave) + + try: + if "--slave" in sys_argv: + [process.join() for process in processes] + else: + start_master(sys_argv) + except KeyboardInterrupt: + manager.shutdown() + + +def main(): + """ Performance test with locust: parse command line options and run commands. + """ + sys.argv[0] = 'locust' + if len(sys.argv) == 1: + sys.argv.extend(["-h"]) + + if sys.argv[1] in ["-h", "--help", "-V", "--version"]: + start_locust_main() + + def get_arg_index(*target_args): + for arg in target_args: + if arg not in sys.argv: + continue + + return sys.argv.index(arg) + 1 + + return None + + # set logging level + loglevel_index = get_arg_index("-L", "--loglevel") + if loglevel_index and loglevel_index < len(sys.argv): + loglevel = sys.argv[loglevel_index] + else: + # default + loglevel = "WARNING" + + logger.setup_logger(loglevel) + + # get testcase file path + try: + testcase_index = get_arg_index("-f", "--locustfile") + assert testcase_index and testcase_index < len(sys.argv) + except AssertionError: + print("Testcase file is not specified, exit.") + sys.exit(1) + + testcase_file_path = sys.argv[testcase_index] + sys.argv[testcase_index] = parse_locustfile(testcase_file_path) + + if "--processes" in sys.argv: + """ locusts -f locustfile.py --processes 4 + """ + if "--no-web" in sys.argv: + logger.log_error("conflict parameter args: --processes & --no-web. \nexit.") + sys.exit(1) + + processes_index = sys.argv.index('--processes') + processes_count_index = processes_index + 1 + if processes_count_index >= len(sys.argv): + """ do not specify processes count explicitly + locusts -f locustfile.py --processes + """ + processes_count = multiprocessing.cpu_count() + logger.log_warning("processes count not specified, use {} by default.".format(processes_count)) + else: + try: + """ locusts -f locustfile.py --processes 4 """ + processes_count = int(sys.argv[processes_count_index]) + sys.argv.pop(processes_count_index) + except ValueError: + """ locusts -f locustfile.py --processes -P 8888 """ + processes_count = multiprocessing.cpu_count() + logger.log_warning("processes count not specified, use {} by default.".format(processes_count)) + + sys.argv.pop(processes_index) + run_locusts_with_processes(sys.argv, processes_count) + else: + start_locust_main() diff --git a/httprunner/plugins/locusts/locustfile_template b/httprunner/plugins/locusts/locustfile_template.py similarity index 90% rename from httprunner/plugins/locusts/locustfile_template rename to httprunner/plugins/locusts/locustfile_template.py index b3389b62..72697cfa 100644 --- a/httprunner/plugins/locusts/locustfile_template +++ b/httprunner/plugins/locusts/locustfile_template.py @@ -5,8 +5,8 @@ from locust import HttpLocust, TaskSet, task from locust.events import request_failure from httprunner.exceptions import MyBaseError, MyBaseFailure +from httprunner.plugins.locusts.utils import prepare_locust_tests from httprunner.runner import Runner -from httprunner.plugins.locusts import prepare_locust_tests logging.getLogger().setLevel(logging.CRITICAL) logging.getLogger('locust.main').setLevel(logging.INFO) @@ -38,5 +38,6 @@ class WebPageUser(HttpLocust): min_wait = 10 max_wait = 30 + # file_path is generated on locusts startup file_path = "$TESTCASE_FILE" tests = prepare_locust_tests(file_path) diff --git a/httprunner/plugins/locusts/utils.py b/httprunner/plugins/locusts/utils.py new file mode 100644 index 00000000..ab7cef91 --- /dev/null +++ b/httprunner/plugins/locusts/utils.py @@ -0,0 +1,29 @@ +from httprunner import loader, parser + + +def prepare_locust_tests(path): + """ prepare locust testcases + + Args: + path (str): testcase file path. + + Returns: + list: locust tests data + + [ + testcase1_dict, + testcase2_dict + ] + + """ + tests_mapping = loader.load_tests(path) + testcases = parser.parse_tests(tests_mapping) + + locust_tests = [] + + for testcase in testcases: + testcase_weight = testcase.get("config", {}).pop("weight", 1) + for _ in range(testcase_weight): + locust_tests.append(testcase) + + return locust_tests diff --git a/poetry.lock b/poetry.lock index bfdf0c65..e6dcd985 100644 --- a/poetry.lock +++ b/poetry.lock @@ -9,7 +9,7 @@ version = "2019.9.11" [[package]] category = "dev" description = "Foreign Function Interface for Python calling C code." -marker = "python_version < \"3\" and extra == \"secure\" or sys_platform == \"win32\" and platform_python_implementation == \"CPython\"" +marker = "python_version < \"3\" and extra == \"secure\"" name = "cffi" optional = false python-versions = "*" @@ -53,14 +53,6 @@ version = "4.0.2" [package.dependencies] colorama = "*" -[[package]] -category = "dev" -description = "Backports and enhancements for the contextlib module" -name = "contextlib2" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.6.0.post1" - [[package]] category = "dev" description = "Code coverage measurement for Python" @@ -157,42 +149,6 @@ Werkzeug = ">=0.7" click = ">=2.0" itsdangerous = ">=0.21" -[[package]] -category = "main" -description = "Clean single-source support for Python 3 and 2" -marker = "python_version >= \"2.7\" and python_version < \"2.8\"" -name = "future" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -version = "0.17.1" - -[[package]] -category = "dev" -description = "Coroutine-based network library" -name = "gevent" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "1.4.0" - -[package.dependencies] -cffi = ">=1.11.5" -greenlet = ">=0.4.14" - -[package.extras] -dnspython = ["dnspython", "idna"] -doc = ["repoze.sphinx.autointerface"] -events = ["zope.event", "zope.interface"] -test = ["zope.interface", "zope.event", "requests", "objgraph", "psutil", "futures", "mock", "coverage (>=5.0a3)", "coveralls (>=1.0)"] - -[[package]] -category = "dev" -description = "Lightweight in-process concurrent programming" -marker = "platform_python_implementation == \"CPython\"" -name = "greenlet" -optional = false -python-versions = "*" -version = "0.4.15" - [[package]] category = "main" description = "Convert HAR(HTTP Archive) to YAML/JSON testcases for HttpRunner." @@ -251,22 +207,6 @@ optional = false python-versions = "*" version = "0.82" -[[package]] -category = "dev" -description = "Website load testing framework" -name = "locustio" -optional = false -python-versions = "*" -version = "0.11.0" - -[package.dependencies] -flask = ">=0.10.1" -gevent = ">=1.2.2" -msgpack = ">=0.4.2" -pyzmq = ">=16.0.2" -requests = ">=2.9.1" -six = ">=1.10.0" - [[package]] category = "main" description = "Safely add untrusted strings to HTML/XML markup." @@ -275,18 +215,10 @@ optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" version = "1.1.1" -[[package]] -category = "dev" -description = "MessagePack (de)serializer." -name = "msgpack" -optional = false -python-versions = "*" -version = "0.6.2" - [[package]] category = "dev" description = "C parser in Python" -marker = "python_version < \"3\" and extra == \"secure\" or sys_platform == \"win32\" and platform_python_implementation == \"CPython\"" +marker = "python_version < \"3\" and extra == \"secure\"" name = "pycparser" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" @@ -317,14 +249,6 @@ optional = false python-versions = "*" version = "5.1.2" -[[package]] -category = "dev" -description = "Python bindings for 0MQ" -name = "pyzmq" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" -version = "18.1.0" - [[package]] category = "main" description = "Python HTTP for Humans." @@ -357,6 +281,7 @@ requests = ">=2.0.1,<3.0.0" [[package]] category = "dev" description = "Python 2 and 3 compatibility utilities" +marker = "python_version < \"3\" and extra == \"secure\"" name = "six" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" @@ -411,7 +336,7 @@ termcolor = ["termcolor"] watchdog = ["watchdog"] [metadata] -content-hash = "7b4557bc1f6b6d77027535d94b5cf225abe4679b57ddd8e0831cd52c4087900a" +content-hash = "599867dc93675d61c5af2f52dbd8f738c831ec87fa56fd242057aa3637a8eae1" python-versions = "~2.7 || ^3.5" [metadata.files] @@ -467,10 +392,6 @@ colorlog = [ {file = "colorlog-4.0.2-py2.py3-none-any.whl", hash = "sha256:450f52ea2a2b6ebb308f034ea9a9b15cea51e65650593dca1da3eb792e4e4981"}, {file = "colorlog-4.0.2.tar.gz", hash = "sha256:3cf31b25cbc8f86ec01fef582ef3b840950dea414084ed19ab922c8b493f9b42"}, ] -contextlib2 = [ - {file = "contextlib2-0.6.0.post1-py2.py3-none-any.whl", hash = "sha256:3355078a159fbb44ee60ea80abd0d87b80b78c248643b49aa6d94673b413609b"}, - {file = "contextlib2-0.6.0.post1.tar.gz", hash = "sha256:01f490098c18b19d2bd5bb5dc445b2054d2fa97f09a4280ba2c5f3c394c8162e"}, -] coverage = [ {file = "coverage-4.5.4-cp26-cp26m-macosx_10_12_x86_64.whl", hash = "sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28"}, {file = "coverage-4.5.4-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c"}, @@ -549,55 +470,6 @@ flask = [ {file = "Flask-0.12.4-py2.py3-none-any.whl", hash = "sha256:6c02dbaa5a9ef790d8219bdced392e2d549c10cd5a5ba4b6aa65126b2271af29"}, {file = "Flask-0.12.4.tar.gz", hash = "sha256:2ea22336f6d388b4b242bc3abf8a01244a8aa3e236e7407469ef78c16ba355dd"}, ] -future = [ - {file = "future-0.17.1.tar.gz", hash = "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8"}, -] -gevent = [ - {file = "gevent-1.4.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b7d3a285978b27b469c0ff5fb5a72bcd69f4306dbbf22d7997d83209a8ba917"}, - {file = "gevent-1.4.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:44089ed06a962a3a70e96353c981d628b2d4a2f2a75ea5d90f916a62d22af2e8"}, - {file = "gevent-1.4.0-cp27-cp27m-win32.whl", hash = "sha256:0e1e5b73a445fe82d40907322e1e0eec6a6745ca3cea19291c6f9f50117bb7ea"}, - {file = "gevent-1.4.0-cp27-cp27m-win_amd64.whl", hash = "sha256:74b7528f901f39c39cdbb50cdf08f1a2351725d9aebaef212a29abfbb06895ee"}, - {file = "gevent-1.4.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0ff2b70e8e338cf13bedf146b8c29d475e2a544b5d1fe14045aee827c073842c"}, - {file = "gevent-1.4.0-cp34-cp34m-macosx_10_14_x86_64.whl", hash = "sha256:0774babec518a24d9a7231d4e689931f31b332c4517a771e532002614e270a64"}, - {file = "gevent-1.4.0-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:d752bcf1b98174780e2317ada12013d612f05116456133a6acf3e17d43b71f05"}, - {file = "gevent-1.4.0-cp34-cp34m-win32.whl", hash = "sha256:3249011d13d0c63bea72d91cec23a9cf18c25f91d1f115121e5c9113d753fa12"}, - {file = "gevent-1.4.0-cp34-cp34m-win_amd64.whl", hash = "sha256:d1e6d1f156e999edab069d79d890859806b555ce4e4da5b6418616322f0a3df1"}, - {file = "gevent-1.4.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7d0809e2991c9784eceeadef01c27ee6a33ca09ebba6154317a257353e3af922"}, - {file = "gevent-1.4.0-cp35-cp35m-win32.whl", hash = "sha256:14b4d06d19d39a440e72253f77067d27209c67e7611e352f79fe69e0f618f76e"}, - {file = "gevent-1.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:53b72385857e04e7faca13c613c07cab411480822ac658d97fd8a4ddbaf715c8"}, - {file = "gevent-1.4.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:8d9ec51cc06580f8c21b41fd3f2b3465197ba5b23c00eb7d422b7ae0380510b0"}, - {file = "gevent-1.4.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2711e69788ddb34c059a30186e05c55a6b611cb9e34ac343e69cf3264d42fe1c"}, - {file = "gevent-1.4.0-cp36-cp36m-win32.whl", hash = "sha256:e5bcc4270671936349249d26140c267397b7b4b1381f5ec8b13c53c5b53ab6e1"}, - {file = "gevent-1.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9f7a1e96fec45f70ad364e46de32ccacab4d80de238bd3c2edd036867ccd48ad"}, - {file = "gevent-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:50024a1ee2cf04645535c5ebaeaa0a60c5ef32e262da981f4be0546b26791950"}, - {file = "gevent-1.4.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4bfa291e3c931ff3c99a349d8857605dca029de61d74c6bb82bd46373959c942"}, - {file = "gevent-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:ab4dc33ef0e26dc627559786a4fba0c2227f125db85d970abbf85b77506b3f51"}, - {file = "gevent-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:896b2b80931d6b13b5d9feba3d4eebc67d5e6ec54f0cf3339d08487d55d93b0e"}, - {file = "gevent-1.4.0-pp260-pypy_41-macosx_10_14_x86_64.whl", hash = "sha256:107f4232db2172f7e8429ed7779c10f2ed16616d75ffbe77e0e0c3fcdeb51a51"}, - {file = "gevent-1.4.0-pp260-pypy_41-win32.whl", hash = "sha256:28a0c5417b464562ab9842dd1fb0cc1524e60494641d973206ec24d6ec5f6909"}, - {file = "gevent-1.4.0.tar.gz", hash = "sha256:1eb7fa3b9bd9174dfe9c3b59b7a09b768ecd496debfc4976a9530a3e15c990d1"}, -] -greenlet = [ - {file = "greenlet-0.4.15-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99a26afdb82ea83a265137a398f570402aa1f2b5dfb4ac3300c026931817b163"}, - {file = "greenlet-0.4.15-cp27-cp27m-win32.whl", hash = "sha256:beeabe25c3b704f7d56b573f7d2ff88fc99f0138e43480cecdfcaa3b87fe4f87"}, - {file = "greenlet-0.4.15-cp27-cp27m-win_amd64.whl", hash = "sha256:9854f612e1b59ec66804931df5add3b2d5ef0067748ea29dc60f0efdcda9a638"}, - {file = "greenlet-0.4.15-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ac57fcdcfb0b73bb3203b58a14501abb7e5ff9ea5e2edfa06bb03035f0cff248"}, - {file = "greenlet-0.4.15-cp33-cp33m-win32.whl", hash = "sha256:d634a7ea1fc3380ff96f9e44d8d22f38418c1c381d5fac680b272d7d90883720"}, - {file = "greenlet-0.4.15-cp33-cp33m-win_amd64.whl", hash = "sha256:0d48200bc50cbf498716712129eef819b1729339e34c3ae71656964dac907c28"}, - {file = "greenlet-0.4.15-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:bcb530089ff24f6458a81ac3fa699e8c00194208a724b644ecc68422e1111939"}, - {file = "greenlet-0.4.15-cp34-cp34m-win32.whl", hash = "sha256:8b4572c334593d449113f9dc8d19b93b7b271bdbe90ba7509eb178923327b625"}, - {file = "greenlet-0.4.15-cp34-cp34m-win_amd64.whl", hash = "sha256:a9f145660588187ff835c55a7d2ddf6abfc570c2651c276d3d4be8a2766db490"}, - {file = "greenlet-0.4.15-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:51503524dd6f152ab4ad1fbd168fc6c30b5795e8c70be4410a64940b3abb55c0"}, - {file = "greenlet-0.4.15-cp35-cp35m-win32.whl", hash = "sha256:a19bf883b3384957e4a4a13e6bd1ae3d85ae87f4beb5957e35b0be287f12f4e4"}, - {file = "greenlet-0.4.15-cp35-cp35m-win_amd64.whl", hash = "sha256:853da4f9563d982e4121fed8c92eea1a4594a2299037b3034c3c898cb8e933d6"}, - {file = "greenlet-0.4.15-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:23d12eacffa9d0f290c0fe0c4e81ba6d5f3a5b7ac3c30a5eaf0126bf4deda5c8"}, - {file = "greenlet-0.4.15-cp36-cp36m-win32.whl", hash = "sha256:000546ad01e6389e98626c1367be58efa613fa82a1be98b0c6fc24b563acc6d0"}, - {file = "greenlet-0.4.15-cp36-cp36m-win_amd64.whl", hash = "sha256:d97b0661e1aead761f0ded3b769044bb00ed5d33e1ec865e891a8b128bf7c656"}, - {file = "greenlet-0.4.15-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:8041e2de00e745c0e05a502d6e6db310db7faa7c979b3a5877123548a4c0b214"}, - {file = "greenlet-0.4.15-cp37-cp37m-win32.whl", hash = "sha256:81fcd96a275209ef117e9ec91f75c731fa18dcfd9ffaa1c0adbdaa3616a86043"}, - {file = "greenlet-0.4.15-cp37-cp37m-win_amd64.whl", hash = "sha256:37c9ba82bd82eb6a23c2e5acc03055c0e45697253b2393c9a50cef76a3985304"}, - {file = "greenlet-0.4.15.tar.gz", hash = "sha256:9416443e219356e3c31f1f918a91badf2e37acf297e2fa13d24d1cc2380f8fbc"}, -] har2case = [ {file = "har2case-0.3.1-py2.py3-none-any.whl", hash = "sha256:84d3a5cc9fbb16e45372e7e880a936c59bbe8e9b66bad81927769e64f608e2af"}, {file = "har2case-0.3.1.tar.gz", hash = "sha256:8f159ec7cba82ec4282f46af4a9dac89f65e62796521b2426d3c89c3c9fd8579"}, @@ -621,10 +493,6 @@ jinja2 = [ jsonpath = [ {file = "jsonpath-0.82.tar.gz", hash = "sha256:46d3fd2016cd5b842283d547877a02c418a0fe9aa7a6b0ae344115a2c990fef4"}, ] -locustio = [ - {file = "locustio-0.11.0-py2.py3-none-any.whl", hash = "sha256:514562bb0040f18f7b3b74ed9beb943800030801058501c630c8b3fc02bafa27"}, - {file = "locustio-0.11.0.tar.gz", hash = "sha256:93404f831114791b0756325c53b08bff73f048eeb69688be657629feaa62b507"}, -] markupsafe = [ {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, @@ -655,29 +523,6 @@ markupsafe = [ {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] -msgpack = [ - {file = "msgpack-0.6.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:774f5edc3475917cd95fe593e625d23d8580f9b48b570d8853d06cac171cd170"}, - {file = "msgpack-0.6.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:a06efd0482a1942aad209a6c18321b5e22d64eb531ea20af138b28172d8f35ba"}, - {file = "msgpack-0.6.2-cp27-cp27m-win32.whl", hash = "sha256:8a3ada8401736df2bf497f65589293a86c56e197a80ae7634ec2c3150a2f5082"}, - {file = "msgpack-0.6.2-cp27-cp27m-win_amd64.whl", hash = "sha256:b8b4bd3dafc7b92608ae5462add1c8cc881851c2d4f5d8977fdea5b081d17f21"}, - {file = "msgpack-0.6.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:24149a75643aeaa81ece4259084d11b792308a6cf74e796cbb35def94c89a25a"}, - {file = "msgpack-0.6.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:757bd71a9b89e4f1db0622af4436d403e742506dbea978eba566815dc65ec895"}, - {file = "msgpack-0.6.2-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:32fea0ea3cd1ef820286863a6202dcfd62a539b8ec3edcbdff76068a8c2cc6ce"}, - {file = "msgpack-0.6.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:db7ff14abc73577b0bcbcf73ecff97d3580ecaa0fc8724babce21fdf3fe08ef6"}, - {file = "msgpack-0.6.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:187794cd1eb73acccd528247e3565f6760bd842d7dc299241f830024a7dd5610"}, - {file = "msgpack-0.6.2-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:b24afc52e18dccc8c175de07c1d680bdf315844566f4952b5bedb908894bec79"}, - {file = "msgpack-0.6.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:355f7fd0f90134229eaeefaee3cf42e0afc8518e8f3cd4b25f541a7104dcb8f9"}, - {file = "msgpack-0.6.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:76df51492bc6fa6cc8b65d09efdb67cbba3cbfe55004c3afc81352af92b4a43c"}, - {file = "msgpack-0.6.2-cp36-cp36m-win32.whl", hash = "sha256:f0f47bafe9c9b8ed03e19a100a743662dd8c6d0135e684feea720a0d0046d116"}, - {file = "msgpack-0.6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:c6e5024fc0cdf7f83b6624850309ddd7e06c48a75fa0d1c5173de4d93300eb19"}, - {file = "msgpack-0.6.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:30b88c47e0cdb6062daed88ca283b0d84fa0d2ad6c273aa0788152a1c643e408"}, - {file = "msgpack-0.6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:229a0ccdc39e9b6c6d1033cd8aecd9c296823b6c87f0de3943c59b8bc7c64bee"}, - {file = "msgpack-0.6.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4abdb88a9b67e64810fb54b0c24a1fd76b12297b4f7a1467d85a14dd8367191a"}, - {file = "msgpack-0.6.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dedf54d72d9e7b6d043c244c8213fe2b8bbfe66874b9a65b39c4cc892dd99dd4"}, - {file = "msgpack-0.6.2-cp37-cp37m-win32.whl", hash = "sha256:0cc7ca04e575ba34fea7cfcd76039f55def570e6950e4155a4174368142c8e1b"}, - {file = "msgpack-0.6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:1904b7cb65342d0998b75908304a03cb004c63ef31e16c8c43fee6b989d7f0d7"}, - {file = "msgpack-0.6.2.tar.gz", hash = "sha256:ea3c2f859346fcd55fc46e96885301d9c2f7a36d453f5d8f2967840efa1e1830"}, -] pycparser = [ {file = "pycparser-2.19.tar.gz", hash = "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"}, ] @@ -700,33 +545,6 @@ pyyaml = [ {file = "PyYAML-5.1.2-cp38-cp38m-win_amd64.whl", hash = "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681"}, {file = "PyYAML-5.1.2.tar.gz", hash = "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4"}, ] -pyzmq = [ - {file = "pyzmq-18.1.0-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:856b2cdf7a1e2cbb84928e1e8db0ea4018709b39804103d3a409e5584f553f57"}, - {file = "pyzmq-18.1.0-cp27-cp27m-win32.whl", hash = "sha256:2762c45e289732d4450406cedca35a9d4d71e449131ba2f491e0bf473e3d2ff2"}, - {file = "pyzmq-18.1.0-cp27-cp27m-win_amd64.whl", hash = "sha256:fa4bad0d1d173dee3e8ef3c3eb6b2bb6c723fc7a661eeecc1ecb2fa99860dd45"}, - {file = "pyzmq-18.1.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:98fa3e75ccb22c0dc99654e3dd9ff693b956861459e8c8e8734dd6247b89eb29"}, - {file = "pyzmq-18.1.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:dd5995ae2e80044e33b5077fb4bc2b0c1788ac6feaf15a6b87a00c14b4bdd682"}, - {file = "pyzmq-18.1.0-cp34-cp34m-win32.whl", hash = "sha256:260c70b7c018905ec3659d0f04db735ac830fe27236e43b9dc0532cf7c9873ef"}, - {file = "pyzmq-18.1.0-cp34-cp34m-win_amd64.whl", hash = "sha256:021dba0d1436516092c624359e5da51472b11ba8edffa334218912f7e8b65467"}, - {file = "pyzmq-18.1.0-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cf0765822e78cf9e45451647a346d443f66792aba906bc340f4e0ac7870c169c"}, - {file = "pyzmq-18.1.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:e03fe5e07e70f245dc9013a9d48ae8cc4b10c33a1968039c5a3b64b5d01d083d"}, - {file = "pyzmq-18.1.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:05fd51edd81eed798fccafdd49c936b6c166ffae7b32482e4d6d6a2e196af4e6"}, - {file = "pyzmq-18.1.0-cp35-cp35m-win32.whl", hash = "sha256:22efa0596cf245a78a99060fe5682c4cd00c58bb7614271129215c889062db80"}, - {file = "pyzmq-18.1.0-cp35-cp35m-win_amd64.whl", hash = "sha256:85b869abc894672de9aecdf032158ea8ad01e2f0c3b09ef60e3687fb79418096"}, - {file = "pyzmq-18.1.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:dc398e1e047efb18bfab7a8989346c6921a847feae2cad69fedf6ca12fb99e2c"}, - {file = "pyzmq-18.1.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:9a22c94d2e93af8bebd4fcf5fa38830f5e3b1ff0d4424e2912b07651eb1bafb4"}, - {file = "pyzmq-18.1.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:b645a49376547b3816433a7e2d2a99135c8e651e50497e7ecac3bd126e4bea16"}, - {file = "pyzmq-18.1.0-cp36-cp36m-win32.whl", hash = "sha256:a7d3f4b4bbb5d7866ae727763268b5c15797cbd7b63ea17f3b0ec1067da8994b"}, - {file = "pyzmq-18.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:01636e95a88d60118479041c6aaaaf5419c6485b7b1d37c9c4dd424b7b9f1121"}, - {file = "pyzmq-18.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f4e37f33da282c3c319849877e34f97f0a3acec09622ec61b7333205bdd13b52"}, - {file = "pyzmq-18.1.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ea09a306144dff2795e48439883349819bef2c53c0ee62a3c2fae429451843bb"}, - {file = "pyzmq-18.1.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:343b9710a61f2b167673bea1974e70b5dccfe64b5ed10626798f08c1f7227e72"}, - {file = "pyzmq-18.1.0-cp37-cp37m-win32.whl", hash = "sha256:41bf96d5f554598a0632c3ec28e3026f1d6591a50f580df38eff0b8067efb9e7"}, - {file = "pyzmq-18.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:0463bd941b6aead494d4035f7eebd70035293dd6caf8425993e85ad41de13fa3"}, - {file = "pyzmq-18.1.0-pp271-pypy_41-macosx_10_14_x86_64.whl", hash = "sha256:2fc6cada8dc53521c1189596f1898d45c5f68603194d3a6453d6db4b27f4e12e"}, - {file = "pyzmq-18.1.0-pp371-pypy3_71-macosx_10_14_x86_64.whl", hash = "sha256:1fadc8fbdf3d22753c36d4172169d184ee6654f8d6539e7af25029643363c490"}, - {file = "pyzmq-18.1.0.tar.gz", hash = "sha256:93f44739db69234c013a16990e43db1aa0af3cf5a4b8b377d028ff24515fbeb3"}, -] requests = [ {file = "requests-2.22.0-py2.py3-none-any.whl", hash = "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"}, {file = "requests-2.22.0.tar.gz", hash = "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4"}, diff --git a/pyproject.toml b/pyproject.toml index 0a9ba469..2802d27e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,23 +21,20 @@ include = ["CHANGELOG.md", "httprunner/static/*"] [tool.poetry.dependencies] python = "~2.7 || ^3.5" -requests = "*" -requests-toolbelt = "*" -pyyaml = "^5.1" -jinja2 = "*" -har2case = "*" -colorama = "*" -colorlog = "*" -filetype = "*" -future = { version = "^0.17.1", python = "~2.7" } -jsonpath = "*" +requests = "^2.22.0" +requests-toolbelt = "^0.9.1" +pyyaml = "^5.1.2" +jinja2 = "^2.10.3" +har2case = "^0.3.1" +colorama = "^0.4.1" +colorlog = "^4.0.2" +filetype = "^1.0.5" +jsonpath = "^0.82" [tool.poetry.dev-dependencies] flask = "<1.0.0" -coverage = "*" -coveralls = "*" -contextlib2 = "*" -locustio = "*" +coverage = "^4.5.4" +coveralls = "^1.8.2" [tool.poetry.scripts] hrun = "httprunner.cli:main" diff --git a/tests/test_plugins/test_locusts.py b/tests/test_plugins/test_locusts.py index 10bc736a..f838d05e 100644 --- a/tests/test_plugins/test_locusts.py +++ b/tests/test_plugins/test_locusts.py @@ -1,7 +1,7 @@ import os import unittest -from httprunner.plugins.locusts import prepare_locust_tests +from httprunner.plugins.locusts.utils import prepare_locust_tests class TestLocust(unittest.TestCase): From 533978624592c31b84040b49731126e9f98261cc Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 00:09:34 +0800 Subject: [PATCH 17/28] fix: poetry with 0.12.17 --- poetry.lock | 309 ++++++---------------------------------------------- 1 file changed, 34 insertions(+), 275 deletions(-) diff --git a/poetry.lock b/poetry.lock index e6dcd985..2dbf722e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -75,13 +75,9 @@ docopt = ">=0.6.1" requests = ">=1.0.0" [package.dependencies.urllib3] -extras = ["secure"] python = "<3" version = "*" -[package.extras] -yaml = ["PyYAML (>=3.10)"] - [[package]] category = "dev" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." @@ -103,13 +99,6 @@ version = "*" python = "<3" version = "*" -[package.extras] -docs = ["sphinx (>=1.6.5,<1.8.0 || >1.8.0)", "sphinx-rtd-theme"] -docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] -idna = ["idna (>=2.1)"] -pep8test = ["flake8", "flake8-import-order", "pep8-naming"] -test = ["pytest (>=3.6.0,<3.9.0 || >3.9.0,<3.9.1 || >3.9.1,<3.9.2 || >3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,<3.79.2 || >3.79.2)"] - [[package]] category = "dev" description = "Pythonic argument parser, that will make you smile" @@ -196,9 +185,6 @@ version = "2.10.3" [package.dependencies] MarkupSafe = ">=0.23" -[package.extras] -i18n = ["Babel (>=0.8)"] - [[package]] category = "main" description = "An XPath for JSON" @@ -237,16 +223,12 @@ version = "19.0.0" cryptography = ">=2.3" six = ">=1.5.2" -[package.extras] -docs = ["sphinx", "sphinx-rtd-theme"] -test = ["flaky", "pretend", "pytest (>=3.0.1)"] - [[package]] category = "main" description = "YAML parser and emitter for Python" name = "pyyaml" optional = false -python-versions = "*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "5.1.2" [[package]] @@ -263,10 +245,6 @@ chardet = ">=3.0.2,<3.1.0" idna = ">=2.5,<2.9" urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" -[package.extras] -security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)"] -socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] - [[package]] category = "main" description = "A utility belt for advanced users of python-requests" @@ -296,32 +274,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" version = "1.25.6" [package.dependencies] -[package.dependencies.certifi] -optional = true -version = "*" - -[package.dependencies.cryptography] -optional = true -version = ">=1.3.4" - -[package.dependencies.idna] -optional = true -version = ">=2.0.0" +certifi = "*" +cryptography = ">=1.3.4" +idna = ">=2.0.0" +pyOpenSSL = ">=0.14" [package.dependencies.ipaddress] -optional = true python = ">=2.7,<2.8" version = "*" -[package.dependencies.pyOpenSSL] -optional = true -version = ">=0.14" - -[package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] - [[package]] category = "dev" description = "The comprehensive WSGI web application library." @@ -330,238 +291,36 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "0.16.0" -[package.extras] -dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"] -termcolor = ["termcolor"] -watchdog = ["watchdog"] - [metadata] content-hash = "599867dc93675d61c5af2f52dbd8f738c831ec87fa56fd242057aa3637a8eae1" python-versions = "~2.7 || ^3.5" -[metadata.files] -certifi = [ - {file = "certifi-2019.9.11-py2.py3-none-any.whl", hash = "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"}, - {file = "certifi-2019.9.11.tar.gz", hash = "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50"}, -] -cffi = [ - {file = "cffi-1.13.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:9009e917d8f5ef780c2626e29b6bc126f4cb2a4d43ca67aa2b40f2a5d6385e78"}, - {file = "cffi-1.13.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:825ecffd9574557590e3225560a8a9d751f6ffe4a49e3c40918c9969b93395fa"}, - {file = "cffi-1.13.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:193697c2918ecdb3865acf6557cddf5076bb39f1f654975e087b67efdff83365"}, - {file = "cffi-1.13.1-cp27-cp27m-win32.whl", hash = "sha256:1ae14b542bf3b35e5229439c35653d2ef7d8316c1fffb980f9b7647e544baa98"}, - {file = "cffi-1.13.1-cp27-cp27m-win_amd64.whl", hash = "sha256:0ea23c9c0cdd6778146a50d867d6405693ac3b80a68829966c98dd5e1bbae400"}, - {file = "cffi-1.13.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec2fa3ee81707a5232bf2dfbd6623fdb278e070d596effc7e2d788f2ada71a05"}, - {file = "cffi-1.13.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:7cfcfda59ef1f95b9f729c56fe8a4041899f96b72685d36ef16a3440a0f85da8"}, - {file = "cffi-1.13.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:6fd58366747debfa5e6163ada468a90788411f10c92597d3b0a912d07e580c36"}, - {file = "cffi-1.13.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:9c77564a51d4d914ed5af096cd9843d90c45b784b511723bd46a8a9d09cf16fc"}, - {file = "cffi-1.13.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:728ec653964655d65408949b07f9b2219df78badd601d6c49e28d604efe40599"}, - {file = "cffi-1.13.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:a19089fa74ed19c4fe96502a291cfdb89223a9705b1d73b3005df4256976142e"}, - {file = "cffi-1.13.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:e22a00c0c81ffcecaf07c2bfb3672fa372c50e2bd1024ffee0da191c1b27fc71"}, - {file = "cffi-1.13.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:bb75ba21d5716abc41af16eac1145ab2e471deedde1f22c6f99bd9f995504df0"}, - {file = "cffi-1.13.1-cp35-cp35m-win32.whl", hash = "sha256:364f8404034ae1b232335d8c7f7b57deac566f148f7222cef78cf8ae28ef764e"}, - {file = "cffi-1.13.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fd82eb4694be712fcae03c717ca2e0fc720657ac226b80bbb597e971fc6928c2"}, - {file = "cffi-1.13.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:5ba86e1d80d458b338bda676fd9f9d68cb4e7a03819632969cf6d46b01a26730"}, - {file = "cffi-1.13.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:63424daa6955e6b4c70dc2755897f5be1d719eabe71b2625948b222775ed5c43"}, - {file = "cffi-1.13.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:33142ae9807665fa6511cfa9857132b2c3ee6ddffb012b3f0933fc11e1e830d5"}, - {file = "cffi-1.13.1-cp36-cp36m-win32.whl", hash = "sha256:e55b5a746fb77f10c83e8af081979351722f6ea48facea79d470b3731c7b2891"}, - {file = "cffi-1.13.1-cp36-cp36m-win_amd64.whl", hash = "sha256:47368f69fe6529f8f49a5d146ddee713fc9057e31d61e8b6dc86a6a5e38cecc1"}, - {file = "cffi-1.13.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:4895640844f17bec32943995dc8c96989226974dfeb9dd121cc45d36e0d0c434"}, - {file = "cffi-1.13.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:00d890313797d9fe4420506613384b43099ad7d2b905c0752dbcc3a6f14d80fa"}, - {file = "cffi-1.13.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a40ed527bffa2b7ebe07acc5a3f782da072e262ca994b4f2085100b5a444bbb2"}, - {file = "cffi-1.13.1-cp37-cp37m-win32.whl", hash = "sha256:6381a7d8b1ebd0bc27c3bc85bc1bfadbb6e6f756b4d4db0aa1425c3719ba26b4"}, - {file = "cffi-1.13.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1e389e069450609c6ffa37f21f40cce36f9be7643bbe5051ab1de99d5a779526"}, - {file = "cffi-1.13.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6381ab708158c4e1639da1f2a7679a9bbe3e5a776fc6d1fd808076f0e3145331"}, - {file = "cffi-1.13.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0cf9e550ac6c5e57b713437e2f4ac2d7fd0cd10336525a27224f5fc1ec2ee59a"}, - {file = "cffi-1.13.1-cp38-cp38-win32.whl", hash = "sha256:819f8d5197c2684524637f940445c06e003c4a541f9983fd30d6deaa2a5487d8"}, - {file = "cffi-1.13.1-cp38-cp38-win_amd64.whl", hash = "sha256:263242b6ace7f9cd4ea401428d2d45066b49a700852334fd55311bde36dcda14"}, - {file = "cffi-1.13.1.tar.gz", hash = "sha256:558b3afef987cf4b17abd849e7bedf64ee12b28175d564d05b628a0f9355599b"}, -] -chardet = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, -] -click = [ - {file = "Click-7.0-py2.py3-none-any.whl", hash = "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13"}, - {file = "Click-7.0.tar.gz", hash = "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"}, -] -colorama = [ - {file = "colorama-0.4.1-py2.py3-none-any.whl", hash = "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"}, - {file = "colorama-0.4.1.tar.gz", hash = "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d"}, -] -colorlog = [ - {file = "colorlog-4.0.2-py2.py3-none-any.whl", hash = "sha256:450f52ea2a2b6ebb308f034ea9a9b15cea51e65650593dca1da3eb792e4e4981"}, - {file = "colorlog-4.0.2.tar.gz", hash = "sha256:3cf31b25cbc8f86ec01fef582ef3b840950dea414084ed19ab922c8b493f9b42"}, -] -coverage = [ - {file = "coverage-4.5.4-cp26-cp26m-macosx_10_12_x86_64.whl", hash = "sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28"}, - {file = "coverage-4.5.4-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c"}, - {file = "coverage-4.5.4-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce"}, - {file = "coverage-4.5.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe"}, - {file = "coverage-4.5.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888"}, - {file = "coverage-4.5.4-cp27-cp27m-win32.whl", hash = "sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc"}, - {file = "coverage-4.5.4-cp27-cp27m-win_amd64.whl", hash = "sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24"}, - {file = "coverage-4.5.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437"}, - {file = "coverage-4.5.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6"}, - {file = "coverage-4.5.4-cp33-cp33m-macosx_10_10_x86_64.whl", hash = "sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5"}, - {file = "coverage-4.5.4-cp34-cp34m-macosx_10_12_x86_64.whl", hash = "sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef"}, - {file = "coverage-4.5.4-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e"}, - {file = "coverage-4.5.4-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca"}, - {file = "coverage-4.5.4-cp34-cp34m-win32.whl", hash = "sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0"}, - {file = "coverage-4.5.4-cp34-cp34m-win_amd64.whl", hash = "sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1"}, - {file = "coverage-4.5.4-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7"}, - {file = "coverage-4.5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47"}, - {file = "coverage-4.5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025"}, - {file = "coverage-4.5.4-cp35-cp35m-win32.whl", hash = "sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e"}, - {file = "coverage-4.5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d"}, - {file = "coverage-4.5.4-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9"}, - {file = "coverage-4.5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755"}, - {file = "coverage-4.5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9"}, - {file = "coverage-4.5.4-cp36-cp36m-win32.whl", hash = "sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f"}, - {file = "coverage-4.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5"}, - {file = "coverage-4.5.4-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca"}, - {file = "coverage-4.5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650"}, - {file = "coverage-4.5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2"}, - {file = "coverage-4.5.4-cp37-cp37m-win32.whl", hash = "sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5"}, - {file = "coverage-4.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351"}, - {file = "coverage-4.5.4-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5"}, - {file = "coverage-4.5.4.tar.gz", hash = "sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c"}, -] -coveralls = [ - {file = "coveralls-1.8.2-py2.py3-none-any.whl", hash = "sha256:9bc5a1f92682eef59f688a8f280207190d9a6afb84cef8f567fa47631a784060"}, - {file = "coveralls-1.8.2.tar.gz", hash = "sha256:fb51cddef4bc458de347274116df15d641a735d3f0a580a9472174e2e62f408c"}, -] -cryptography = [ - {file = "cryptography-2.8-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8"}, - {file = "cryptography-2.8-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2"}, - {file = "cryptography-2.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad"}, - {file = "cryptography-2.8-cp27-cp27m-win32.whl", hash = "sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2"}, - {file = "cryptography-2.8-cp27-cp27m-win_amd64.whl", hash = "sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912"}, - {file = "cryptography-2.8-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d"}, - {file = "cryptography-2.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42"}, - {file = "cryptography-2.8-cp34-abi3-macosx_10_6_intel.whl", hash = "sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879"}, - {file = "cryptography-2.8-cp34-abi3-manylinux1_x86_64.whl", hash = "sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d"}, - {file = "cryptography-2.8-cp34-abi3-manylinux2010_x86_64.whl", hash = "sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9"}, - {file = "cryptography-2.8-cp34-cp34m-win32.whl", hash = "sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c"}, - {file = "cryptography-2.8-cp34-cp34m-win_amd64.whl", hash = "sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0"}, - {file = "cryptography-2.8-cp35-cp35m-win32.whl", hash = "sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf"}, - {file = "cryptography-2.8-cp35-cp35m-win_amd64.whl", hash = "sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793"}, - {file = "cryptography-2.8-cp36-cp36m-win32.whl", hash = "sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595"}, - {file = "cryptography-2.8-cp36-cp36m-win_amd64.whl", hash = "sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7"}, - {file = "cryptography-2.8-cp37-cp37m-win32.whl", hash = "sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff"}, - {file = "cryptography-2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f"}, - {file = "cryptography-2.8-cp38-cp38-win32.whl", hash = "sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e"}, - {file = "cryptography-2.8-cp38-cp38-win_amd64.whl", hash = "sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13"}, - {file = "cryptography-2.8.tar.gz", hash = "sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651"}, -] -docopt = [ - {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, -] -enum34 = [ - {file = "enum34-1.1.6-py2-none-any.whl", hash = "sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79"}, - {file = "enum34-1.1.6-py3-none-any.whl", hash = "sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a"}, - {file = "enum34-1.1.6.tar.gz", hash = "sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"}, - {file = "enum34-1.1.6.zip", hash = "sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850"}, -] -filetype = [ - {file = "filetype-1.0.5-py2.py3-none-any.whl", hash = "sha256:4967124d982a71700d94a08c49c4926423500e79382a92070f5ab248d44fe461"}, - {file = "filetype-1.0.5.tar.gz", hash = "sha256:17a3b885f19034da29640b083d767e0f13c2dcb5dcc267945c8b6e5a5a9013c7"}, -] -flask = [ - {file = "Flask-0.12.4-py2.py3-none-any.whl", hash = "sha256:6c02dbaa5a9ef790d8219bdced392e2d549c10cd5a5ba4b6aa65126b2271af29"}, - {file = "Flask-0.12.4.tar.gz", hash = "sha256:2ea22336f6d388b4b242bc3abf8a01244a8aa3e236e7407469ef78c16ba355dd"}, -] -har2case = [ - {file = "har2case-0.3.1-py2.py3-none-any.whl", hash = "sha256:84d3a5cc9fbb16e45372e7e880a936c59bbe8e9b66bad81927769e64f608e2af"}, - {file = "har2case-0.3.1.tar.gz", hash = "sha256:8f159ec7cba82ec4282f46af4a9dac89f65e62796521b2426d3c89c3c9fd8579"}, -] -idna = [ - {file = "idna-2.8-py2.py3-none-any.whl", hash = "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"}, - {file = "idna-2.8.tar.gz", hash = "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407"}, -] -ipaddress = [ - {file = "ipaddress-1.0.23-py2.py3-none-any.whl", hash = "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc"}, - {file = "ipaddress-1.0.23.tar.gz", hash = "sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2"}, -] -itsdangerous = [ - {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, - {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, -] -jinja2 = [ - {file = "Jinja2-2.10.3-py2.py3-none-any.whl", hash = "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f"}, - {file = "Jinja2-2.10.3.tar.gz", hash = "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"}, -] -jsonpath = [ - {file = "jsonpath-0.82.tar.gz", hash = "sha256:46d3fd2016cd5b842283d547877a02c418a0fe9aa7a6b0ae344115a2c990fef4"}, -] -markupsafe = [ - {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, - {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, - {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, - {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, -] -pycparser = [ - {file = "pycparser-2.19.tar.gz", hash = "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"}, -] -pyopenssl = [ - {file = "pyOpenSSL-19.0.0-py2.py3-none-any.whl", hash = "sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6"}, - {file = "pyOpenSSL-19.0.0.tar.gz", hash = "sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200"}, -] -pyyaml = [ - {file = "PyYAML-5.1.2-cp27-cp27m-win32.whl", hash = "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8"}, - {file = "PyYAML-5.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"}, - {file = "PyYAML-5.1.2-cp34-cp34m-win32.whl", hash = "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9"}, - {file = "PyYAML-5.1.2-cp34-cp34m-win_amd64.whl", hash = "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696"}, - {file = "PyYAML-5.1.2-cp35-cp35m-win32.whl", hash = "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41"}, - {file = "PyYAML-5.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73"}, - {file = "PyYAML-5.1.2-cp36-cp36m-win32.whl", hash = "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299"}, - {file = "PyYAML-5.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b"}, - {file = "PyYAML-5.1.2-cp37-cp37m-win32.whl", hash = "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae"}, - {file = "PyYAML-5.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34"}, - {file = "PyYAML-5.1.2-cp38-cp38m-win32.whl", hash = "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9"}, - {file = "PyYAML-5.1.2-cp38-cp38m-win_amd64.whl", hash = "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681"}, - {file = "PyYAML-5.1.2.tar.gz", hash = "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4"}, -] -requests = [ - {file = "requests-2.22.0-py2.py3-none-any.whl", hash = "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"}, - {file = "requests-2.22.0.tar.gz", hash = "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4"}, -] -requests-toolbelt = [ - {file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"}, - {file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"}, -] -six = [ - {file = "six-1.12.0-py2.py3-none-any.whl", hash = "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c"}, - {file = "six-1.12.0.tar.gz", hash = "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"}, -] -urllib3 = [ - {file = "urllib3-1.25.6-py2.py3-none-any.whl", hash = "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398"}, - {file = "urllib3-1.25.6.tar.gz", hash = "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86"}, -] -werkzeug = [ - {file = "Werkzeug-0.16.0-py2.py3-none-any.whl", hash = "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4"}, - {file = "Werkzeug-0.16.0.tar.gz", hash = "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7"}, -] +[metadata.hashes] +certifi = ["e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", "fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"] +cffi = ["00d890313797d9fe4420506613384b43099ad7d2b905c0752dbcc3a6f14d80fa", "0cf9e550ac6c5e57b713437e2f4ac2d7fd0cd10336525a27224f5fc1ec2ee59a", "0ea23c9c0cdd6778146a50d867d6405693ac3b80a68829966c98dd5e1bbae400", "193697c2918ecdb3865acf6557cddf5076bb39f1f654975e087b67efdff83365", "1ae14b542bf3b35e5229439c35653d2ef7d8316c1fffb980f9b7647e544baa98", "1e389e069450609c6ffa37f21f40cce36f9be7643bbe5051ab1de99d5a779526", "263242b6ace7f9cd4ea401428d2d45066b49a700852334fd55311bde36dcda14", "33142ae9807665fa6511cfa9857132b2c3ee6ddffb012b3f0933fc11e1e830d5", "364f8404034ae1b232335d8c7f7b57deac566f148f7222cef78cf8ae28ef764e", "47368f69fe6529f8f49a5d146ddee713fc9057e31d61e8b6dc86a6a5e38cecc1", "4895640844f17bec32943995dc8c96989226974dfeb9dd121cc45d36e0d0c434", "558b3afef987cf4b17abd849e7bedf64ee12b28175d564d05b628a0f9355599b", "5ba86e1d80d458b338bda676fd9f9d68cb4e7a03819632969cf6d46b01a26730", "63424daa6955e6b4c70dc2755897f5be1d719eabe71b2625948b222775ed5c43", "6381a7d8b1ebd0bc27c3bc85bc1bfadbb6e6f756b4d4db0aa1425c3719ba26b4", "6381ab708158c4e1639da1f2a7679a9bbe3e5a776fc6d1fd808076f0e3145331", "6fd58366747debfa5e6163ada468a90788411f10c92597d3b0a912d07e580c36", "728ec653964655d65408949b07f9b2219df78badd601d6c49e28d604efe40599", "7cfcfda59ef1f95b9f729c56fe8a4041899f96b72685d36ef16a3440a0f85da8", "819f8d5197c2684524637f940445c06e003c4a541f9983fd30d6deaa2a5487d8", "825ecffd9574557590e3225560a8a9d751f6ffe4a49e3c40918c9969b93395fa", "9009e917d8f5ef780c2626e29b6bc126f4cb2a4d43ca67aa2b40f2a5d6385e78", "9c77564a51d4d914ed5af096cd9843d90c45b784b511723bd46a8a9d09cf16fc", "a19089fa74ed19c4fe96502a291cfdb89223a9705b1d73b3005df4256976142e", "a40ed527bffa2b7ebe07acc5a3f782da072e262ca994b4f2085100b5a444bbb2", "bb75ba21d5716abc41af16eac1145ab2e471deedde1f22c6f99bd9f995504df0", "e22a00c0c81ffcecaf07c2bfb3672fa372c50e2bd1024ffee0da191c1b27fc71", "e55b5a746fb77f10c83e8af081979351722f6ea48facea79d470b3731c7b2891", "ec2fa3ee81707a5232bf2dfbd6623fdb278e070d596effc7e2d788f2ada71a05", "fd82eb4694be712fcae03c717ca2e0fc720657ac226b80bbb597e971fc6928c2"] +chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] +click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"] +colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"] +colorlog = ["3cf31b25cbc8f86ec01fef582ef3b840950dea414084ed19ab922c8b493f9b42", "450f52ea2a2b6ebb308f034ea9a9b15cea51e65650593dca1da3eb792e4e4981"] +coverage = ["08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6", "0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650", "141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5", "19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d", "23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351", "245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755", "331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef", "386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca", "3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca", "60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9", "63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc", "6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5", "6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f", "7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe", "826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888", "93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5", "9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce", "af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5", "bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e", "bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e", "c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9", "dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437", "df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1", "e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c", "e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24", "e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47", "eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2", "eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28", "ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c", "efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7", "fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0", "ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025"] +coveralls = ["9bc5a1f92682eef59f688a8f280207190d9a6afb84cef8f567fa47631a784060", "fb51cddef4bc458de347274116df15d641a735d3f0a580a9472174e2e62f408c"] +cryptography = ["02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c", "1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595", "369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad", "3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651", "44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2", "4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff", "58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d", "6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42", "7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d", "73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e", "7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912", "90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793", "971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13", "a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7", "b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0", "b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879", "d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f", "de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9", "df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2", "ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf", "fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8"] +docopt = ["49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"] +enum34 = ["2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850", "644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a", "6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79", "8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"] +filetype = ["17a3b885f19034da29640b083d767e0f13c2dcb5dcc267945c8b6e5a5a9013c7", "4967124d982a71700d94a08c49c4926423500e79382a92070f5ab248d44fe461"] +flask = ["2ea22336f6d388b4b242bc3abf8a01244a8aa3e236e7407469ef78c16ba355dd", "6c02dbaa5a9ef790d8219bdced392e2d549c10cd5a5ba4b6aa65126b2271af29"] +har2case = ["84d3a5cc9fbb16e45372e7e880a936c59bbe8e9b66bad81927769e64f608e2af", "8f159ec7cba82ec4282f46af4a9dac89f65e62796521b2426d3c89c3c9fd8579"] +idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"] +ipaddress = ["6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc", "b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2"] +itsdangerous = ["321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", "b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"] +jinja2 = ["74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", "9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"] +jsonpath = ["46d3fd2016cd5b842283d547877a02c418a0fe9aa7a6b0ae344115a2c990fef4"] +markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"] +pycparser = ["a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"] +pyopenssl = ["aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200", "c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6"] +pyyaml = ["0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", "01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", "5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", "5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", "7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", "7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", "87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", "9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", "a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", "b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", "b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", "bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", "f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"] +requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"] +requests-toolbelt = ["380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f", "968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"] +six = ["3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"] +urllib3 = ["3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", "9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86"] +werkzeug = ["7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7", "e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4"] From 1e33ae54e43b781d22b613a92a3a0a169454b1f6 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 00:14:02 +0800 Subject: [PATCH 18/28] fix: missed import OrderedDict --- httprunner/response.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/httprunner/response.py b/httprunner/response.py index 9cbadc1d..8be64ca1 100644 --- a/httprunner/response.py +++ b/httprunner/response.py @@ -1,11 +1,10 @@ -# encoding: utf-8 - import re +from collections import OrderedDict import jsonpath from httprunner import exceptions, logger, utils -from httprunner.compat import OrderedDict, basestring, is_py2 +from httprunner.compat import basestring, is_py2 text_extractor_regexp_compile = re.compile(r".*\(.*\).*") From 4155723c9e9c45a2e40120194da7c88aff938ea8 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 00:44:56 +0800 Subject: [PATCH 19/28] fix: makedirs if log file dir not exists --- httprunner/logger.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/httprunner/logger.py b/httprunner/logger.py index ce2e4c97..2c0925fd 100644 --- a/httprunner/logger.py +++ b/httprunner/logger.py @@ -1,4 +1,5 @@ import logging +import os import sys from colorama import Fore, init @@ -49,6 +50,9 @@ def get_logger(name=None): _logger.setLevel(level) if LOG_FILE_PATH: + log_dir = os.path.dirname(LOG_FILE_PATH) + if not os.path.isdir(log_dir): + os.makedirs(log_dir) handler = logging.FileHandler(LOG_FILE_PATH, encoding="utf-8") else: handler = logging.StreamHandler(sys.stdout) From 070b4674279ea4f4a025c00e19d07e04844aabf5 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 09:52:29 +0800 Subject: [PATCH 20/28] fix: file handler --- httprunner/logger.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/httprunner/logger.py b/httprunner/logger.py index 2c0925fd..f025718c 100644 --- a/httprunner/logger.py +++ b/httprunner/logger.py @@ -47,8 +47,6 @@ def get_logger(name=None): if level >= logging.INFO: sys.tracebacklimit = 0 - _logger.setLevel(level) - if LOG_FILE_PATH: log_dir = os.path.dirname(LOG_FILE_PATH) if not os.path.isdir(log_dir): @@ -65,6 +63,7 @@ def get_logger(name=None): ) handler.setFormatter(formatter) _logger.addHandler(handler) + _logger.setLevel(level) loggers[name] = _logger return _logger From 9badc2534087e90640483c9f4244727223555319 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 09:57:17 +0800 Subject: [PATCH 21/28] fix: sleep 1 sec to wait log handler --- tests/test_api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_api.py b/tests/test_api.py index 1f84a8b8..011d32f2 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -206,6 +206,7 @@ class TestHttpRunner(ApiServerUnittest): log_file_path = os.path.join(os.getcwd(), 'reports', "test_log_file.log") runner = HttpRunner(failfast=True, log_file=log_file_path) runner.run(self.testcase_cli_path) + time.sleep(1) self.assertTrue(os.path.isfile(log_file_path)) os.remove(log_file_path) From 195e85ebe04f4e625505f50f5a262fd021f3ae8a Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 20:59:03 +0800 Subject: [PATCH 22/28] fix: logger initialized mupltiple times --- httprunner/logger.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/httprunner/logger.py b/httprunner/logger.py index f025718c..d16f9a09 100644 --- a/httprunner/logger.py +++ b/httprunner/logger.py @@ -8,7 +8,7 @@ from colorlog import ColoredFormatter init(autoreset=True) LOG_LEVEL = "INFO" -LOG_FILE_PATH = None +LOG_FILE_PATH = "" log_colors_config = { 'DEBUG': 'cyan', @@ -32,8 +32,9 @@ def setup_logger(log_level, log_file=None): def get_logger(name=None): """setup logger with ColoredFormatter.""" name = name or "httprunner" - if name in loggers: - return loggers[name] + logger_key = "".join([name, LOG_LEVEL, LOG_FILE_PATH]) + if logger_key in loggers: + return loggers[logger_key] _logger = logging.getLogger(name) @@ -47,6 +48,7 @@ def get_logger(name=None): if level >= logging.INFO: sys.tracebacklimit = 0 + _logger.setLevel(level) if LOG_FILE_PATH: log_dir = os.path.dirname(LOG_FILE_PATH) if not os.path.isdir(log_dir): @@ -63,9 +65,8 @@ def get_logger(name=None): ) handler.setFormatter(formatter) _logger.addHandler(handler) - _logger.setLevel(level) - loggers[name] = _logger + loggers[logger_key] = _logger return _logger From 3748df7b87b0b9781b83e8d467217bf39b243560 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 21:14:51 +0800 Subject: [PATCH 23/28] fix: compatibility in Python 2.7 ImportError(No module named builtins) will be raised if future is not installed in Python 2.7 --- poetry.lock | 111 +++++-------------------------------------------- pyproject.toml | 1 + 2 files changed, 12 insertions(+), 100 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2dbf722e..e121326e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -6,18 +6,6 @@ optional = false python-versions = "*" version = "2019.9.11" -[[package]] -category = "dev" -description = "Foreign Function Interface for Python calling C code." -marker = "python_version < \"3\" and extra == \"secure\"" -name = "cffi" -optional = false -python-versions = "*" -version = "1.13.1" - -[package.dependencies] -pycparser = "*" - [[package]] category = "main" description = "Universal encoding detector for Python 2 and 3" @@ -78,27 +66,6 @@ requests = ">=1.0.0" python = "<3" version = "*" -[[package]] -category = "dev" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -marker = "python_version < \"3\" and extra == \"secure\"" -name = "cryptography" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "2.8" - -[package.dependencies] -cffi = ">=1.8,<1.11.3 || >1.11.3" -six = ">=1.4.1" - -[package.dependencies.enum34] -python = "<3" -version = "*" - -[package.dependencies.ipaddress] -python = "<3" -version = "*" - [[package]] category = "dev" description = "Pythonic argument parser, that will make you smile" @@ -107,15 +74,6 @@ optional = false python-versions = "*" version = "0.6.2" -[[package]] -category = "dev" -description = "Python 3.4 Enum backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4" -marker = "python_version < \"3\" and extra == \"secure\"" -name = "enum34" -optional = false -python-versions = "*" -version = "1.1.6" - [[package]] category = "main" description = "Infer file type and MIME type of any file/buffer. No external dependencies." @@ -138,6 +96,15 @@ Werkzeug = ">=0.7" click = ">=2.0" itsdangerous = ">=0.21" +[[package]] +category = "main" +description = "Clean single-source support for Python 3 and 2" +marker = "python_version >= \"2.7\" and python_version < \"2.8\"" +name = "future" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "0.18.1" + [[package]] category = "main" description = "Convert HAR(HTTP Archive) to YAML/JSON testcases for HttpRunner." @@ -157,15 +124,6 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "2.8" -[[package]] -category = "dev" -description = "IPv4/IPv6 manipulation library" -marker = "python_version < \"3\" and extra == \"secure\" or python_version == \"2.7\" and extra == \"secure\"" -name = "ipaddress" -optional = false -python-versions = "*" -version = "1.0.23" - [[package]] category = "dev" description = "Various helpers to pass data to untrusted environments and back." @@ -201,28 +159,6 @@ optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" version = "1.1.1" -[[package]] -category = "dev" -description = "C parser in Python" -marker = "python_version < \"3\" and extra == \"secure\"" -name = "pycparser" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.19" - -[[package]] -category = "dev" -description = "Python wrapper module around the OpenSSL library" -marker = "python_version < \"3\" and extra == \"secure\"" -name = "pyopenssl" -optional = false -python-versions = "*" -version = "19.0.0" - -[package.dependencies] -cryptography = ">=2.3" -six = ">=1.5.2" - [[package]] category = "main" description = "YAML parser and emitter for Python" @@ -256,15 +192,6 @@ version = "0.9.1" [package.dependencies] requests = ">=2.0.1,<3.0.0" -[[package]] -category = "dev" -description = "Python 2 and 3 compatibility utilities" -marker = "python_version < \"3\" and extra == \"secure\"" -name = "six" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "1.12.0" - [[package]] category = "main" description = "HTTP library with thread-safe connection pooling, file post, and more." @@ -273,16 +200,6 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" version = "1.25.6" -[package.dependencies] -certifi = "*" -cryptography = ">=1.3.4" -idna = ">=2.0.0" -pyOpenSSL = ">=0.14" - -[package.dependencies.ipaddress] -python = ">=2.7,<2.8" -version = "*" - [[package]] category = "dev" description = "The comprehensive WSGI web application library." @@ -292,35 +209,29 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "0.16.0" [metadata] -content-hash = "599867dc93675d61c5af2f52dbd8f738c831ec87fa56fd242057aa3637a8eae1" +content-hash = "836d6dec466dfbf8a14481ed801c053a902b3fa6d8b75cf4f5aba4539c0899af" python-versions = "~2.7 || ^3.5" [metadata.hashes] certifi = ["e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", "fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"] -cffi = ["00d890313797d9fe4420506613384b43099ad7d2b905c0752dbcc3a6f14d80fa", "0cf9e550ac6c5e57b713437e2f4ac2d7fd0cd10336525a27224f5fc1ec2ee59a", "0ea23c9c0cdd6778146a50d867d6405693ac3b80a68829966c98dd5e1bbae400", "193697c2918ecdb3865acf6557cddf5076bb39f1f654975e087b67efdff83365", "1ae14b542bf3b35e5229439c35653d2ef7d8316c1fffb980f9b7647e544baa98", "1e389e069450609c6ffa37f21f40cce36f9be7643bbe5051ab1de99d5a779526", "263242b6ace7f9cd4ea401428d2d45066b49a700852334fd55311bde36dcda14", "33142ae9807665fa6511cfa9857132b2c3ee6ddffb012b3f0933fc11e1e830d5", "364f8404034ae1b232335d8c7f7b57deac566f148f7222cef78cf8ae28ef764e", "47368f69fe6529f8f49a5d146ddee713fc9057e31d61e8b6dc86a6a5e38cecc1", "4895640844f17bec32943995dc8c96989226974dfeb9dd121cc45d36e0d0c434", "558b3afef987cf4b17abd849e7bedf64ee12b28175d564d05b628a0f9355599b", "5ba86e1d80d458b338bda676fd9f9d68cb4e7a03819632969cf6d46b01a26730", "63424daa6955e6b4c70dc2755897f5be1d719eabe71b2625948b222775ed5c43", "6381a7d8b1ebd0bc27c3bc85bc1bfadbb6e6f756b4d4db0aa1425c3719ba26b4", "6381ab708158c4e1639da1f2a7679a9bbe3e5a776fc6d1fd808076f0e3145331", "6fd58366747debfa5e6163ada468a90788411f10c92597d3b0a912d07e580c36", "728ec653964655d65408949b07f9b2219df78badd601d6c49e28d604efe40599", "7cfcfda59ef1f95b9f729c56fe8a4041899f96b72685d36ef16a3440a0f85da8", "819f8d5197c2684524637f940445c06e003c4a541f9983fd30d6deaa2a5487d8", "825ecffd9574557590e3225560a8a9d751f6ffe4a49e3c40918c9969b93395fa", "9009e917d8f5ef780c2626e29b6bc126f4cb2a4d43ca67aa2b40f2a5d6385e78", "9c77564a51d4d914ed5af096cd9843d90c45b784b511723bd46a8a9d09cf16fc", "a19089fa74ed19c4fe96502a291cfdb89223a9705b1d73b3005df4256976142e", "a40ed527bffa2b7ebe07acc5a3f782da072e262ca994b4f2085100b5a444bbb2", "bb75ba21d5716abc41af16eac1145ab2e471deedde1f22c6f99bd9f995504df0", "e22a00c0c81ffcecaf07c2bfb3672fa372c50e2bd1024ffee0da191c1b27fc71", "e55b5a746fb77f10c83e8af081979351722f6ea48facea79d470b3731c7b2891", "ec2fa3ee81707a5232bf2dfbd6623fdb278e070d596effc7e2d788f2ada71a05", "fd82eb4694be712fcae03c717ca2e0fc720657ac226b80bbb597e971fc6928c2"] chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"] colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"] colorlog = ["3cf31b25cbc8f86ec01fef582ef3b840950dea414084ed19ab922c8b493f9b42", "450f52ea2a2b6ebb308f034ea9a9b15cea51e65650593dca1da3eb792e4e4981"] coverage = ["08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6", "0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650", "141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5", "19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d", "23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351", "245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755", "331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef", "386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca", "3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca", "60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9", "63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc", "6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5", "6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f", "7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe", "826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888", "93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5", "9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce", "af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5", "bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e", "bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e", "c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9", "dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437", "df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1", "e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c", "e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24", "e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47", "eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2", "eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28", "ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c", "efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7", "fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0", "ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025"] coveralls = ["9bc5a1f92682eef59f688a8f280207190d9a6afb84cef8f567fa47631a784060", "fb51cddef4bc458de347274116df15d641a735d3f0a580a9472174e2e62f408c"] -cryptography = ["02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c", "1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595", "369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad", "3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651", "44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2", "4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff", "58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d", "6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42", "7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d", "73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e", "7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912", "90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793", "971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13", "a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7", "b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0", "b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879", "d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f", "de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9", "df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2", "ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf", "fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8"] docopt = ["49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"] -enum34 = ["2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850", "644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a", "6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79", "8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"] filetype = ["17a3b885f19034da29640b083d767e0f13c2dcb5dcc267945c8b6e5a5a9013c7", "4967124d982a71700d94a08c49c4926423500e79382a92070f5ab248d44fe461"] flask = ["2ea22336f6d388b4b242bc3abf8a01244a8aa3e236e7407469ef78c16ba355dd", "6c02dbaa5a9ef790d8219bdced392e2d549c10cd5a5ba4b6aa65126b2271af29"] +future = ["858e38522e8fd0d3ce8f0c1feaf0603358e366d5403209674c7b617fa0c24093"] har2case = ["84d3a5cc9fbb16e45372e7e880a936c59bbe8e9b66bad81927769e64f608e2af", "8f159ec7cba82ec4282f46af4a9dac89f65e62796521b2426d3c89c3c9fd8579"] idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"] -ipaddress = ["6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc", "b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2"] itsdangerous = ["321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", "b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"] jinja2 = ["74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", "9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"] jsonpath = ["46d3fd2016cd5b842283d547877a02c418a0fe9aa7a6b0ae344115a2c990fef4"] markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"] -pycparser = ["a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"] -pyopenssl = ["aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200", "c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6"] pyyaml = ["0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", "01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", "5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", "5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", "7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", "7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", "87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", "9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", "a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", "b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", "b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", "bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", "f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"] requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"] requests-toolbelt = ["380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f", "968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"] -six = ["3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"] urllib3 = ["3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", "9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86"] werkzeug = ["7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7", "e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4"] diff --git a/pyproject.toml b/pyproject.toml index 2802d27e..351dd42d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ colorama = "^0.4.1" colorlog = "^4.0.2" filetype = "^1.0.5" jsonpath = "^0.82" +future = { version = "^0.18.1", python = "~2.7" } [tool.poetry.dev-dependencies] flask = "<1.0.0" From 6ea6a084c1d19b0937782cfc48b3f97d6c1a9241 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 21:19:12 +0800 Subject: [PATCH 24/28] fix: Non-ASCII character when no encoding declared --- httprunner/response.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/httprunner/response.py b/httprunner/response.py index 8be64ca1..b6062e63 100644 --- a/httprunner/response.py +++ b/httprunner/response.py @@ -25,9 +25,9 @@ class ResponseObject(object): if key == "json": value = self.resp_obj.json() elif key == "cookies": - value = self.resp_obj.cookies.get_dict() + value = self.resp_obj.cookies.get_dict() else: - value = getattr(self.resp_obj, key) + value = getattr(self.resp_obj, key) self.__dict__[key] = value return value @@ -53,7 +53,7 @@ class ResponseObject(object): } ] }, - "message": "操作成功" + "message": "success" } :param field: Jsonpath expression, e.g. 1)$.code 2) $..items.*.id From ce3e9327455a988361715391ad9a9c8cad5c939d Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 21:32:58 +0800 Subject: [PATCH 25/28] fix: compatibility in Python 2.7 ImportError will be raised in `from httprunner.plugins.locusts.utils import prepare_locust_tests` if httprunner/plugins/__init__.py is missed --- httprunner/plugins/__init__.py | 2 ++ tests/test_api.py | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 httprunner/plugins/__init__.py diff --git a/httprunner/plugins/__init__.py b/httprunner/plugins/__init__.py new file mode 100644 index 00000000..1802047f --- /dev/null +++ b/httprunner/plugins/__init__.py @@ -0,0 +1,2 @@ +# NOTICE: +# This file should not be deleted, or ImportError will be raised in Python 2.7 when importing plugin diff --git a/tests/test_api.py b/tests/test_api.py index 011d32f2..1f84a8b8 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -206,7 +206,6 @@ class TestHttpRunner(ApiServerUnittest): log_file_path = os.path.join(os.getcwd(), 'reports', "test_log_file.log") runner = HttpRunner(failfast=True, log_file=log_file_path) runner.run(self.testcase_cli_path) - time.sleep(1) self.assertTrue(os.path.isfile(log_file_path)) os.remove(log_file_path) From ea3438212bcfe55576e9abedac020e60a8c79a1d Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 21:45:37 +0800 Subject: [PATCH 26/28] bump version to 2.3.0 --- CHANGELOG.md | 15 +++++++++++++++ httprunner/__init__.py | 2 +- pyproject.toml | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cb08cae..7f9cd7f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Release History +## 2.3.0 (2019-10-27) + +**Added** + +- feat: implement plugin system prototype, make locusts as plugin +- test: add Python 3.8 to Travis-CI +- feat: add `__main__.py`, `python -m httprunner` can be used to hrun tests + +**Changed** + +- update dependency versions in pyproject.toml +- rename folder, httprunner/templates => httprunner/static +- log httprunner version before running tests +- remove unused import & code + ## 2.2.6 (2019-09-18) **Added** diff --git a/httprunner/__init__.py b/httprunner/__init__.py index ef770dc2..8b0fe4c5 100644 --- a/httprunner/__init__.py +++ b/httprunner/__init__.py @@ -1,4 +1,4 @@ -__version__ = "2.2.7" +__version__ = "2.3.0" __description__ = "One-stop solution for HTTP(S) testing." __all__ = ["__version__", "__description__"] diff --git a/pyproject.toml b/pyproject.toml index 351dd42d..5d9c8153 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "httprunner" -version = "2.2.7" +version = "2.3.0" description = "One-stop solution for HTTP(S) testing." license = "Apache-2.0" readme = "README.md" From 3ac6e47bda1125dfa6bcf5a92693ed90cd248b24 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 22:27:04 +0800 Subject: [PATCH 27/28] fix #707: duration stat error in multiple testsuites Thanks @lijuelijue and @plmmilove --- CHANGELOG.md | 4 ++++ httprunner/report.py | 22 ++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f9cd7f3..a6112afb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ - log httprunner version before running tests - remove unused import & code +**Fixed** + +- fix #707: duration stat error in multiple testsuites + ## 2.2.6 (2019-09-18) **Added** diff --git a/httprunner/report.py b/httprunner/report.py index d337de76..a3d775d4 100644 --- a/httprunner/report.py +++ b/httprunner/report.py @@ -54,11 +54,11 @@ def get_summary(result): } } summary["stat"]["successes"] = summary["stat"]["total"] \ - - summary["stat"]["failures"] \ - - summary["stat"]["errors"] \ - - summary["stat"]["skipped"] \ - - summary["stat"]["expectedFailures"] \ - - summary["stat"]["unexpectedSuccesses"] + - summary["stat"]["failures"] \ + - summary["stat"]["errors"] \ + - summary["stat"]["skipped"] \ + - summary["stat"]["expectedFailures"] \ + - summary["stat"]["unexpectedSuccesses"] summary["time"] = { 'start_at': result.start_at, @@ -80,10 +80,16 @@ def aggregate_stat(origin_stat, new_stat): for key in new_stat: if key not in origin_stat: origin_stat[key] = new_stat[key] + + elif key == "duration": + # duration = max_end_time - min_start_time + max_end_time = max(origin_stat["start_at"] + origin_stat["duration"], + new_stat["start_at"] + new_stat["duration"]) + min_start_time = min(origin_stat["start_at"], new_stat["start_at"]) + origin_stat["duration"] = max_end_time - min_start_time elif key == "start_at": - # start datetime , duration=current_time - min(stat_at) - origin_stat[key] = min(origin_stat[key], new_stat[key]) - origin_stat["duration"] = time.time() - origin_stat[key] + # start datetime + origin_stat["start_at"] = min(origin_stat["start_at"], new_stat["start_at"]) else: origin_stat[key] += new_stat[key] From 670bfd88e4cdc3cd080ffb247d8dfdd1bc597e1e Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 26 Oct 2019 22:29:30 +0800 Subject: [PATCH 28/28] change: code format --- httprunner/report.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/httprunner/report.py b/httprunner/report.py index a3d775d4..19e45718 100644 --- a/httprunner/report.py +++ b/httprunner/report.py @@ -80,16 +80,15 @@ def aggregate_stat(origin_stat, new_stat): for key in new_stat: if key not in origin_stat: origin_stat[key] = new_stat[key] - + elif key == "start_at": + # start datetime + origin_stat["start_at"] = min(origin_stat["start_at"], new_stat["start_at"]) elif key == "duration": # duration = max_end_time - min_start_time max_end_time = max(origin_stat["start_at"] + origin_stat["duration"], new_stat["start_at"] + new_stat["duration"]) min_start_time = min(origin_stat["start_at"], new_stat["start_at"]) origin_stat["duration"] = max_end_time - min_start_time - elif key == "start_at": - # start datetime - origin_stat["start_at"] = min(origin_stat["start_at"], new_stat["start_at"]) else: origin_stat[key] += new_stat[key]