Merge pull request #7 from gmr/master

2.0 Release
This commit is contained in:
Andrew Rabert 2018-11-26 16:03:13 -05:00 committed by GitHub
commit eb62c18faf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 60 additions and 82 deletions

View file

@ -1,9 +1,9 @@
language: python language: python
dist: xenial
python: python:
- '2.7' - 3.5
- '3.3' - 3.6
- '3.4' - 3.7
- pypy
install: install:
- pip install -e . - pip install -e .
- pip install -r test-requirements.txt - pip install -r test-requirements.txt
@ -18,6 +18,6 @@ deploy:
secure: qzSC7nsNS1rnDKgiZe2GiojMznf35GLzUeqlf5HESYiKDIlXLIpdxS1Ii9G+afnJH1cGT9dheDUvlRzwZ3eDsZHbVYjKtj/uvy8j4x8H+N66Zvm1AMdGvF4sDCUo01DdbsSe7Xh77VY3kV0AgHb8UZuXOgXcdN0kYJjfWuUWTl0= secure: qzSC7nsNS1rnDKgiZe2GiojMznf35GLzUeqlf5HESYiKDIlXLIpdxS1Ii9G+afnJH1cGT9dheDUvlRzwZ3eDsZHbVYjKtj/uvy8j4x8H+N66Zvm1AMdGvF4sDCUo01DdbsSe7Xh77VY3kV0AgHb8UZuXOgXcdN0kYJjfWuUWTl0=
distributions: "sdist bdist_wheel" distributions: "sdist bdist_wheel"
on: on:
python: 2.7 python: 3.6
tags: true tags: true
all_branches: true all_branches: true

View file

@ -1,6 +1,12 @@
Version History Version History
--------------- ---------------
`2.0.0`_ (26-Nov-2018)
~~~~~~~~~~~~~~~~~~~~~~
- Drop support for Python 2.7, 3.3, 3.4
- Drop support for Tornado < 4.2
- Add support for Tornado 5.1 and async with ``AsyncIOHandlerMixin``
`1.0.2`_ (20-Jun-2016) `1.0.2`_ (20-Jun-2016)
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
- Add support for async prepare in superclasses of ``HandlerMixin`` - Add support for async prepare in superclasses of ``HandlerMixin``
@ -9,6 +15,6 @@ Version History
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
- Adds ``sprockets.mixins.correlation.HandlerMixin`` - Adds ``sprockets.mixins.correlation.HandlerMixin``
.. _`2.0.0`: https://github.com/sprockets/sprockets.mixins.correlation/compare/1.0.2...2.0.0
.. _`1.0.2`: https://github.com/sprockets/sprockets.mixins.correlation/compare/1.0.1...1.0.2 .. _`1.0.2`: https://github.com/sprockets/sprockets.mixins.correlation/compare/1.0.1...1.0.2
.. _`1.0.1`: https://github.com/sprockets/sprockets.mixins.correlation/compare/0.0.0...1.0.1 .. _`1.0.1`: https://github.com/sprockets/sprockets.mixins.correlation/compare/0.0.0...1.0.1

View file

@ -1,4 +1,4 @@
Copyright (c) 2015 AWeber Communications Copyright (c) 2015-2018 AWeber Communications
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,

View file

@ -1,6 +1,5 @@
-r requirements.txt -r requirements.txt
-r test-requirements.txt -r test-requirements.txt
flake8>=2.1,<3 flake8
sphinx>=1.2,<2 sphinx>=1.2,<2
sphinx-rtd-theme>=0.1,<1.0 sphinx-rtd-theme>=0.1,<1.0
tornado>=4.0,<5

View file

@ -8,6 +8,10 @@ correlation.HandlerMixin
.. autoclass:: sprockets.mixins.correlation.HandlerMixin .. autoclass:: sprockets.mixins.correlation.HandlerMixin
:members: :members:
.. autoclass:: sprockets.mixins.correlation.AsyncIOHandlerMixin
:members:
Contributing to this Library Contributing to this Library
---------------------------- ----------------------------

View file

@ -1 +1 @@
tornado>=3.1,<4.4 tornado>=4.0,<5.2

View file

@ -1,5 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
import codecs import codecs
from os import path
import sys import sys
import setuptools import setuptools
@ -7,24 +8,23 @@ import setuptools
from sprockets.mixins import correlation from sprockets.mixins import correlation
def read_requirements_file(req_name): def read_requirements(name):
requirements = [] requirements = []
try: try:
with codecs.open(req_name, encoding='utf-8') as req_file: with open(path.join('requires', name)) as req_file:
for req_line in req_file: for line in req_file:
if '#' in req_line: if '#' in line:
req_line = req_line[0:req_line.find('#')].strip() line = line[:line.index('#')]
if req_line: line = line.strip()
requirements.append(req_line.strip()) if line.startswith('-r'):
requirements.extend(read_requirements(line[2:].strip()))
elif line and not line.startswith('-'):
requirements.append(line)
except IOError: except IOError:
pass pass
return requirements return requirements
install_requires = read_requirements_file('requirements.txt')
setup_requires = read_requirements_file('setup-requirements.txt')
tests_require = read_requirements_file('test-requirements.txt')
setuptools.setup( setuptools.setup(
name='sprockets.mixins.correlation', name='sprockets.mixins.correlation',
version=correlation.__version__, version=correlation.__version__,
@ -35,16 +35,15 @@ setuptools.setup(
author_email='api@aweber.com', author_email='api@aweber.com',
license=codecs.open('LICENSE', encoding='utf-8').read(), license=codecs.open('LICENSE', encoding='utf-8').read(),
classifiers=[ classifiers=[
'Development Status :: 4 - Beta', 'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License', 'License :: OSI Approved :: BSD License',
'Natural Language :: English', 'Natural Language :: English',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy', 'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries', 'Topic :: Software Development :: Libraries',
@ -52,9 +51,8 @@ setuptools.setup(
], ],
packages=setuptools.find_packages(), packages=setuptools.find_packages(),
namespace_packages=['sprockets'], namespace_packages=['sprockets'],
install_requires=install_requires, install_requires=read_requirements('requirements.txt'),
setup_requires=setup_requires, tests_require=read_requirements('test-requirements.txt'),
tests_require=tests_require,
test_suite='nose.collector', test_suite='nose.collector',
zip_safe=True, zip_safe=True,
) )

View file

@ -1,12 +1,11 @@
try: try:
from .mixins import HandlerMixin from .mixins import HandlerMixin
except ImportError:
except ImportError as error:
class HandlerMixin(object): class HandlerMixin(object):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
raise error raise ImportError
version_info = (1, 0, 2) version_info = (2, 0, 0)
__version__ = '.'.join(str(v) for v in version_info[:3]) __version__ = '.'.join(str(v) for v in version_info[:3])

View file

@ -1,15 +1,6 @@
import uuid import uuid
import tornado.gen from tornado import concurrent, log
import tornado.log
if tornado.version_info[0] >= 4:
from tornado.concurrent import is_future
else:
import tornado.concurrent
def is_future(maybe_future):
return isinstance(maybe_future, tornado.concurrent.Future)
class HandlerMixin(object): class HandlerMixin(object):
@ -50,14 +41,13 @@ class HandlerMixin(object):
self.__correlation_id = str(uuid.uuid4()) self.__correlation_id = str(uuid.uuid4())
super(HandlerMixin, self).__init__(*args, **kwargs) super(HandlerMixin, self).__init__(*args, **kwargs)
@tornado.gen.coroutine async def prepare(self):
def prepare(self):
# Here we want to copy an incoming Correlation-ID header if # Here we want to copy an incoming Correlation-ID header if
# one exists. We also want to set it in the outgoing response # one exists. We also want to set it in the outgoing response
# which the property setter does for us. # which the property setter does for us.
maybe_future = super(HandlerMixin, self).prepare() maybe_future = super(HandlerMixin, self).prepare()
if is_future(maybe_future): if concurrent.is_future(maybe_future):
yield maybe_future await maybe_future
correlation_id = self.get_request_header(self.__header_name, None) correlation_id = self.get_request_header(self.__header_name, None)
if correlation_id is not None: if correlation_id is not None:
@ -113,11 +103,11 @@ def correlation_id_logger(handler):
is processing the client request. is processing the client request.
""" """
if handler.get_status() < 400: if handler.get_status() < 400:
log_method = tornado.log.access_log.info log_method = log.access_log.info
elif handler.get_status() < 500: elif handler.get_status() < 500:
log_method = tornado.log.access_log.warning log_method = log.access_log.warning
else: else:
log_method = tornado.log.access_log.error log_method = log.access_log.error
request_time = 1000.0 * handler.request.request_time() request_time = 1000.0 * handler.request.request_time()
correlation_id = getattr(handler, "correlation_id", None) correlation_id = getattr(handler, "correlation_id", None)
if correlation_id is None: if correlation_id is None:

View file

@ -1,4 +1,4 @@
coverage>=3.7,<4 coverage>=4.5.2,<5
coveralls>=0.4,<1 coveralls>=1.5.1,<2
nose>=1.3,<2 nose>=1.3.7,<2
tox>=1.7,<2 tox>=3.5.3,<4

View file

@ -23,18 +23,15 @@ class CorrelationMixinTests(testing.AsyncHTTPTestCase):
]) ])
def test_that_correlation_id_is_returned_when_successful(self): def test_that_correlation_id_is_returned_when_successful(self):
self.http_client.fetch(self.get_url('/status/200'), self.stop) response = self.fetch('/status/200')
response = self.wait()
self.assertIsNotNone(response.headers.get('Correlation-ID')) self.assertIsNotNone(response.headers.get('Correlation-ID'))
def test_that_correlation_id_is_returned_in_error(self): def test_that_correlation_id_is_returned_in_error(self):
self.http_client.fetch(self.get_url('/status/500'), self.stop) response = self.fetch('/status/500')
response = self.wait()
self.assertIsNotNone(response.headers.get('Correlation-ID')) self.assertIsNotNone(response.headers.get('Correlation-ID'))
def test_that_correlation_id_is_copied_from_request(self): def test_that_correlation_id_is_copied_from_request(self):
correlation_id = uuid.uuid4().hex correlation_id = uuid.uuid4().hex
self.http_client.fetch(self.get_url('/status/200'), self.stop, response = self.fetch('/status/500',
headers={'Correlation-Id': correlation_id}) headers={'Correlation-Id': correlation_id})
response = self.wait()
self.assertEqual(response.headers['correlation-id'], correlation_id) self.assertEqual(response.headers['correlation-id'], correlation_id)

27
tox.ini
View file

@ -1,5 +1,5 @@
[tox] [tox]
envlist = py27,py33,py34,pypy,pypy3,tornado31,tornado32,tornado40,tornado43 envlist = py35,py36,py37,tornado43,torando51
toxworkdir = {toxinidir}/build/tox toxworkdir = {toxinidir}/build/tox
skip_missing_intepreters = true skip_missing_intepreters = true
@ -9,27 +9,12 @@ deps =
tornado tornado
commands = {envbindir}/nosetests commands = {envbindir}/nosetests
[testenv:py27]
deps =
{[testenv]deps}
mock
[testenv:tornado31]
deps =
-rtest-requirements.txt
tornado>=3.1,<3.2
[testenv:tornado32]
deps =
-rtest-requirements.txt
tornado>=3.2,<3.3
[testenv:tornado40]
deps =
-rtest-requirements.txt
tornado>=4.0,<4.1
[testenv:tornado43] [testenv:tornado43]
deps = deps =
-rtest-requirements.txt -rtest-requirements.txt
tornado>=4.3,<4.4 tornado>=4.3,<4.4
[testenv:tornado51]
deps =
-rtest-requirements.txt
tornado>=5.1,<5.2