Skip to content

Commit a338d7c

Browse files
authored
Merge pull request #60 from ptmcg/issue_59
Updates for compatibility with Flask 3.0 and recent Python versions
2 parents c7270ca + d78c2ab commit a338d7c

10 files changed

+91
-41
lines changed

example/client.py

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
import sys
2+
if sys.version_info[:2] >= (3, 10):
3+
# compat for Python written pre-3.10
4+
import collections
5+
import collections.abc
6+
collections.MutableMapping = collections.abc.MutableMapping
7+
18
import requests
29
import time
310
from opentracing_instrumentation.client_hooks import install_all_patches

example/server.py

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
import sys
2+
if sys.version_info[:2] >= (3, 10):
3+
# compat for Python written pre-3.10
4+
import collections
5+
import collections.abc
6+
collections.MutableMapping = collections.abc.MutableMapping
7+
18
import logging
29
from jaeger_client import Config
310
from flask_opentracing import FlaskTracing

flask_opentracing/tracing.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import opentracing
22
from opentracing.ext import tags
3-
from flask import _request_ctx_stack as stack
3+
from flask import request as flask_current_request
44

55

66
class FlaskTracing(opentracing.Tracer):
@@ -101,14 +101,14 @@ def get_span(self, request=None):
101101
102102
@param request the request to get the span from
103103
"""
104-
if request is None and stack.top:
105-
request = stack.top.request
104+
if request is None:
105+
request = flask_current_request
106106

107107
scope = self._current_scopes.get(request, None)
108108
return None if scope is None else scope.span
109109

110110
def _before_request_fn(self, attributes):
111-
request = stack.top.request
111+
request = flask_current_request
112112
operation_name = request.endpoint
113113
headers = {}
114114
for k, v in request.headers:
@@ -140,7 +140,7 @@ def _before_request_fn(self, attributes):
140140
self._call_start_span_cb(span, request)
141141

142142
def _after_request_fn(self, response=None, error=None):
143-
request = stack.top.request
143+
request = flask_current_request
144144

145145
# the pop call can fail if the request is interrupted by a
146146
# `before_request` method so we need a default

requirements-test.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# add dependencies in setup.py
22

33
-r requirements.txt
4+
tox
45

56
-e .[tests]

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
test=pytest
33

44
[metadata]
5-
description-file = README.rst
5+
description_file = README.rst
66

77
[tool:pytest]
88
addopts =

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
'mock',
3434
'pytest',
3535
'pytest-cov',
36+
'tox',
3637
],
3738
},
3839
classifiers=[

tests/README.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ Run the tests with the following command:
55

66
.. code-block::
77
8-
$ python setup.py test
8+
$ pip install -r requirements-test.txt
9+
$ tox

tests/test_flask_tracing.py

+5-33
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from opentracing.ext import tags
77
from opentracing.mocktracer import MockTracer
88
from flask_opentracing import FlaskTracing
9+
from flaky import flaky
910

1011

1112
app = Flask(__name__)
@@ -19,8 +20,8 @@
1920

2021

2122
def flush_spans(tcr):
22-
for req in tcr._current_scopes:
23-
tcr._current_scopes[req].close()
23+
for span in tcr._current_scopes.values():
24+
span.close()
2425
tcr._current_scopes = {}
2526

2627

@@ -101,9 +102,9 @@ def test_span_tags(self):
101102
tags.HTTP_METHOD: 'GET',
102103
tags.SPAN_KIND: tags.SPAN_KIND_RPC_SERVER,
103104
tags.HTTP_URL: 'http://localhost/another_test_simple',
104-
'is_xhr': 'False',
105105
}
106106

107+
@flaky(max_runs=5)
107108
def test_requests_distinct(self):
108109
with app.test_request_context('/test'):
109110
app.preprocess_request()
@@ -176,6 +177,7 @@ def _verify_error(self, span):
176177
RuntimeError
177178
)
178179

180+
@flaky(max_runs=5)
179181
def test_over_wire(self):
180182
rv = test_app.get('/wire')
181183
assert '200' in str(rv.status_code)
@@ -193,33 +195,3 @@ def test_child_span(self):
193195
assert len(spans) == 2
194196
assert spans[0].context.trace_id == spans[1].context.trace_id
195197
assert spans[0].parent_id == spans[1].context.span_id
196-
197-
198-
class TestTracingStartSpanCallback(unittest.TestCase):
199-
def test_simple(self):
200-
def start_span_cb(span, request):
201-
span.set_tag('component', 'not-flask')
202-
span.set_tag('mytag', 'myvalue')
203-
204-
tracing = FlaskTracing(MockTracer(), True, app,
205-
start_span_cb=start_span_cb)
206-
rv = test_app.get('/test')
207-
assert '200' in str(rv.status_code)
208-
209-
spans = tracing.tracer.finished_spans()
210-
assert len(spans) == 1
211-
assert spans[0].tags.get(tags.COMPONENT, None) == 'not-flask'
212-
assert spans[0].tags.get('mytag', None) == 'myvalue'
213-
214-
def test_error(self):
215-
def start_span_cb(span, request):
216-
raise RuntimeError('Should not happen')
217-
218-
tracing = FlaskTracing(MockTracer(), True, app,
219-
start_span_cb=start_span_cb)
220-
rv = test_app.get('/test')
221-
assert '200' in str(rv.status_code)
222-
223-
spans = tracing.tracer.finished_spans()
224-
assert len(spans) == 1
225-
assert spans[0].tags.get(tags.ERROR, None) is None
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import unittest
2+
from abc import abstractmethod
3+
4+
from flask import Flask
5+
from opentracing.ext import tags
6+
from opentracing.mocktracer import MockTracer
7+
from flask_opentracing import FlaskTracing
8+
9+
10+
class _StartSpanCallbackTestCase(unittest.TestCase):
11+
@staticmethod
12+
@abstractmethod
13+
def start_span_cb(span, request):
14+
pass
15+
16+
def setUp(self):
17+
self.app = Flask(__name__)
18+
self.tracing = FlaskTracing(
19+
MockTracer(), True, self.app, start_span_cb=self.start_span_cb
20+
)
21+
self.test_app = self.app.test_client()
22+
23+
@self.app.route('/test')
24+
def check_test_works():
25+
return 'Success'
26+
27+
28+
class TestFlaskTracingStartSpanCallbackSetTags(_StartSpanCallbackTestCase):
29+
@staticmethod
30+
def start_span_cb(span, request):
31+
print('setting tags')
32+
span.set_tag('component', 'not-flask')
33+
span.set_tag('mytag', 'myvalue')
34+
35+
def test_simple(self):
36+
rv = self.test_app.get('/test')
37+
assert '200' in str(rv.status_code)
38+
39+
spans = self.tracing.tracer.finished_spans()
40+
assert len(spans) == 1
41+
assert spans[0].tags.get(tags.COMPONENT, None) == 'not-flask'
42+
assert spans[0].tags.get('mytag', None) == 'myvalue'
43+
44+
45+
class TestFlaskTracingStartSpanCallbackRaisesError(
46+
_StartSpanCallbackTestCase
47+
):
48+
@staticmethod
49+
def start_span_cb(span, request):
50+
print('raising exception')
51+
raise RuntimeError('Should not happen')
52+
53+
def test_error(self):
54+
rv = self.test_app.get('/test')
55+
assert '200' in str(rv.status_code)
56+
57+
spans = self.tracing.tracer.finished_spans()
58+
assert len(spans) == 1
59+
assert spans[0].tags.get(tags.ERROR, None) is None

tox.ini

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tox]
2-
envlist = py27,py3{5,6,7,8},pypy{,3},flake8
2+
envlist = py27,py3{5,6,7,8,9,10,11,12},pypy{,3},flake8
33
skip_missing_interpreters = true
44

55
[travis]
@@ -19,6 +19,8 @@ deps =
1919
commands = flake8 flask_opentracing tests
2020

2121
[testenv]
22+
deps =
23+
flaky
2224
extras = tests
2325
commands =
2426
pytest

0 commit comments

Comments
 (0)