From 8c03c0fa4ee645c1283166d4785f44f81dc3ed09 Mon Sep 17 00:00:00 2001 From: Shaheed Haque Date: Thu, 11 Jul 2019 12:36:25 +0100 Subject: [PATCH 1/3] Port away from requests -> urllib3 for thread-safety. Resolves #144. --- consul/std.py | 20 ++++++++++---------- requirements.txt | 2 +- tox.ini | 3 +++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/consul/std.py b/consul/std.py index 96a5b9dc..b301c6a3 100644 --- a/consul/std.py +++ b/consul/std.py @@ -1,42 +1,42 @@ -import requests +import urllib3 from consul import base __all__ = ['Consul'] +JSON_HEADER = {'Content-Type': 'application/json'} class HTTPClient(base.HTTPClient): def __init__(self, *args, **kwargs): super(HTTPClient, self).__init__(*args, **kwargs) - self.session = requests.session() + cert_file = kwargs.get('cert', None) + cert_reqs = 'CERT_REQUIRED' if kwargs.get('verify', False) else None + self.session = urllib3.PoolManager(cert_file=cert_file, cert_reqs=cert_reqs) def response(self, response): - response.encoding = 'utf-8' return base.Response( - response.status_code, response.headers, response.text) + response.status, response.headers, response.data.decode('utf-8')) def get(self, callback, path, params=None): uri = self.uri(path, params) return callback(self.response( - self.session.get(uri, verify=self.verify, cert=self.cert))) + self.session.request('GET', uri))) def put(self, callback, path, params=None, data=''): uri = self.uri(path, params) return callback(self.response( - self.session.put(uri, data=data, verify=self.verify, - cert=self.cert))) + self.session.request('PUT', uri, body=data, headers=JSON_HEADER))) def delete(self, callback, path, params=None): uri = self.uri(path, params) return callback(self.response( - self.session.delete(uri, verify=self.verify, cert=self.cert))) + self.session.request('DELETE', uri))) def post(self, callback, path, params=None, data=''): uri = self.uri(path, params) return callback(self.response( - self.session.post(uri, data=data, verify=self.verify, - cert=self.cert))) + self.session.request('POST', uri, body=data, headers=JSON_HEADER))) class Consul(base.Consul): diff --git a/requirements.txt b/requirements.txt index 2846886d..f09e6a58 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -requests>=2.0 +urllib3>=1.25 six>=1.4 diff --git a/tox.ini b/tox.ini index 4df9a5fc..1405a865 100644 --- a/tox.ini +++ b/tox.ini @@ -21,6 +21,7 @@ commands = deps = pytest pytest-rerunfailures + requests commands = py.test --reruns=3 {posargs:consul tests} @@ -35,6 +36,7 @@ deps = tornado aiohttp flake8 + requests commands = py.test --reruns=3 {posargs:consul tests} flake8 --exclude=".tox/*,xx/*,__*,docs/*" @@ -50,6 +52,7 @@ deps = tornado aiohttp flake8 + requests commands = py.test --reruns=3 {posargs:consul tests} flake8 --exclude=".tox/*,xx/*,__*,docs/*" From 5194a57cc5da266492d7380f9e7d86aec525c511 Mon Sep 17 00:00:00 2001 From: Shaheed Haque Date: Thu, 11 Jul 2019 12:51:47 +0100 Subject: [PATCH 2/3] Address linter issue. --- consul/std.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/consul/std.py b/consul/std.py index b301c6a3..3709e203 100644 --- a/consul/std.py +++ b/consul/std.py @@ -12,7 +12,8 @@ def __init__(self, *args, **kwargs): super(HTTPClient, self).__init__(*args, **kwargs) cert_file = kwargs.get('cert', None) cert_reqs = 'CERT_REQUIRED' if kwargs.get('verify', False) else None - self.session = urllib3.PoolManager(cert_file=cert_file, cert_reqs=cert_reqs) + self.session = urllib3.PoolManager(cert_file=cert_file, + cert_reqs=cert_reqs) def response(self, response): return base.Response( From 856d769716dd2d75f94d09e4807e2d0c4f13f018 Mon Sep 17 00:00:00 2001 From: Shaheed Haque Date: Fri, 12 Jul 2019 09:46:29 +0100 Subject: [PATCH 3/3] Get tests running at least for Python3.x. --- .travis.yml | 1 + setup.py | 2 +- tests/test_aio.py | 12 ++++++++---- tox.ini | 18 +++++++++++++++++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2ab11056..0e7ddb9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: - pypy-5.3.1 - 3.5 - 3.6 + - 3.7 install: - pip install tox diff --git a/setup.py b/setup.py index 0a0385cf..02840200 100644 --- a/setup.py +++ b/setup.py @@ -53,7 +53,7 @@ def run_tests(self): url='https://github.com/cablehead/python-consul', license='MIT', description=description, - long_description=open('README.rst').read() + '\n\n' + + long_description=open('README.rst').read() + '\n\n' + # noqa: W504 open('CHANGELOG.rst').read(), py_modules=py_modules, install_requires=requirements, diff --git a/tests/test_aio.py b/tests/test_aio.py index b251231f..1077c4a6 100644 --- a/tests/test_aio.py +++ b/tests/test_aio.py @@ -10,6 +10,10 @@ Check = consul.Check +if hasattr(asyncio, 'ensure_future'): + ensure_future = asyncio.ensure_future +else: # Deprecated since Python 3.4.4 + ensure_future = getattr(asyncio, "async") @pytest.fixture @@ -74,7 +78,7 @@ def test_kv_missing(self, loop, consul_port): @asyncio.coroutine def main(): - fut = asyncio.async(put(), loop=loop) + fut = ensure_future(put(), loop=loop) yield from c.kv.put('index', 'bump') index, data = yield from c.kv.get('foo') assert data is None @@ -133,7 +137,7 @@ def test_kv_subscribe(self, loop, consul_port): @asyncio.coroutine def get(): - fut = asyncio.async(put(), loop=loop) + fut = ensure_future(put(), loop=loop) index, data = yield from c.kv.get('foo') assert data is None index, data = yield from c.kv.get('foo', index=index) @@ -197,7 +201,7 @@ def test_catalog(self, loop, consul_port): @asyncio.coroutine def nodes(): - fut = asyncio.async(register(), loop=loop) + fut = ensure_future(register(), loop=loop) index, nodes = yield from c.catalog.nodes() assert len(nodes) == 1 current = nodes[0] @@ -228,7 +232,7 @@ def test_session(self, loop, consul_port): @asyncio.coroutine def monitor(): - fut = asyncio.async(register(), loop=loop) + fut = ensure_future(register(), loop=loop) index, services = yield from c.session.list() assert services == [] yield from asyncio.sleep(20/1000.0, loop=loop) diff --git a/tox.ini b/tox.ini index 1405a865..d4375f1d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = flake8, py26, py27, pypy, py35, py36 +envlist = flake8, py26, py27, pypy, py35, py36, py37 [flake8] ignore = F811,E226 @@ -57,6 +57,22 @@ commands = py.test --reruns=3 {posargs:consul tests} flake8 --exclude=".tox/*,xx/*,__*,docs/*" +[testenv:py37] +deps = + pytest + pytest-rerunfailures + pytest-twisted + twisted + treq + pyOpenSSL + tornado + aiohttp + flake8 + requests +commands = + py.test --reruns=3 {posargs:consul tests} + flake8 --exclude=".tox/*,xx/*,__*,docs/*" + [testenv:flake8] deps = flake8 commands = flake8