%global _empty_manifest_terminate_build 0
Name:		python-opentracing-instrumentation
Version:	3.3.1
Release:	1
Summary:	Tracing Instrumentation using OpenTracing API (http://opentracing.io)
License:	MIT
URL:		https://github.com/uber-common/opentracing-python-instrumentation
Source0:	https://mirrors.nju.edu.cn/pypi/web/packages/83/91/03713e8c173d4792cb9dfac9411a739ad64f71f00de44d27b2f9a2e42fcb/opentracing_instrumentation-3.3.1.tar.gz
BuildArch:	noarch

Requires:	python3-future
Requires:	python3-wrapt
Requires:	python3-tornado
Requires:	python3-contextlib2
Requires:	python3-opentracing
Requires:	python3-six
Requires:	python3-boto3
Requires:	python3-botocore
Requires:	python3-celery
Requires:	python3-doubles
Requires:	python3-flake8
Requires:	python3-flake8-quotes
Requires:	python3-mock
Requires:	python3-moto
Requires:	python3-psycopg2-binary
Requires:	python3-sqlalchemy
Requires:	python3-pytest
Requires:	python3-pytest-cov
Requires:	python3-pytest-localserver
Requires:	python3-pytest-mock
Requires:	python3-pytest-tornado
Requires:	python3-basictracer
Requires:	python3-redis
Requires:	python3-Sphinx
Requires:	python3-sphinx-rtd-theme
Requires:	python3-testfixtures
Requires:	python3-MySQL-python

%description
[![PyPI version][pypi-img]][pypi] [![Python versions][pyver-img]][pypi] [![Pypi Downloads][pydl-img]][pypi] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] 


# opentracing-python-instrumentation

A collection of instrumentation tools to enable tracing with 
[OpenTracing API](http://opentracing.io).

## Module

Make sure you are running recent enough versions of `pip` and `setuptools`, e.g. before installing your project requirements execute this:

```
pip install --upgrade "setuptools>=29" "pip>=9"
```

The module name is `opentracing_instrumentation`.

## What's inside

### Supported client frameworks

The following libraries are instrumented for tracing in this module:
 * [boto3](https://github.com/boto/boto3) — AWS SDK for Python
 * [Celery](https://github.com/celery/celery) — Distributed Task Queue
 * `urllib2`
 * `requests`
 * `SQLAlchemy`
 * `MySQLdb`
 * `psycopg2`
 * Tornado HTTP client
 *  `redis`

#### Limitations

For some operations, `Boto3` uses `ThreadPoolExecutor` under the hood.
So, in order to make it thread-safe, the instrumentation is implemented using
`span_in_stack_context()` which
[forces you](https://github.com/uber-common/opentracing-python-instrumentation#in-process-context-propagation)
to use `TornadoScopeManager`.

### Server instrumentation

For inbound requests a helper function `before_request` is provided for creating middleware for frameworks like Flask and uWSGI.

### Manual instrumentation

Finally, a `@traced_function` decorator is provided for manual instrumentation.

### In-process Context Propagation

As part of the OpenTracing 2.0 API, in-process `Span` propagation happens through the newly defined
[ScopeManager](https://opentracing-python.readthedocs.io/en/latest/api.html#scope-managers)
interface. However, the existing functionality has been kept to provide backwards compatibility and
ease code migration:

`span_in_context()` implements context propagation using the current `opentracing.tracer.scope_manager`,
expected to be a thread-local based `ScopeManager`, such as `opentracing.scope_managers.ThreadLocalScopeManager`.

`span_in_stack_context()` implements context propagation for Tornado applications
using the current `opentracing.tracer.scope_manager` too, expected to be an instance of
 `opentracing.scope_managers.tornado.TornadoScopeManager`.

`get_current_span()` returns the currently active `Span`, if any.

Direct access to the `request_context` module as well as usage of `RequestContext` and `RequestContextManager`
have been **fully** deprecated, as they do not integrate with the new OpenTracing 2.0 API.
Using them along `get_current_span()` is guaranteed to work, but it is **highly** recommended
to switch to the previously mentioned functions.

## Usage

This library provides two types of instrumentation, explicit instrumentation
for server endpoints, and implicit instrumentation for client call sites.

Server endpoints are instrumented by creating a middleware class that:

 1. initializes the specific tracer implementation
 2. wraps incoming request handlers into a method that reads the incoming
    tracing info from the request and creates a new tracing Span

Client call sites are instrumented implicitly by executing a set of 
available `client_hooks` that monkey-patch some API points in several 
common libraries like `SQLAlchemy`, `urllib2`, Tornado Async HTTP Client.
The initialization of those hooks is usually also done from the middleware
class's `__init__` method.

There is a client-server example using this library with Flask instrumentation
from opentracing-contrib: https://github.com/opentracing-contrib/python-flask/tree/master/example.

Here's an example of a middleware for [Clay framework](https://github.com/uber/clay):

```python

from opentracing_instrumentation import span_in_context
from opentracing_instrumentation.http_server import before_request
from opentracing_instrumentation.http_server import WSGIRequestWrapper
from opentracing_instrumentation.client_hooks import install_all_patches


class TracerMiddleware(object):

    def __init__(self, app, wsgi_app):
        self.wsgi_app = wsgi_app
        self.service_name = app.name

        CONFIG.app_name = self.service_name
        CONFIG.caller_name_headers.append('X-Uber-Source')
        CONFIG.callee_endpoint_headers.append('X-Uber-Endpoint')

        install_all_patches()
        self.wsgi_app = create_wsgi_middleware(wsgi_app)
        self.init_tracer()

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def init_tracer(self):
        # code specific to your tracer implementation
        pass


def create_wsgi_middleware(other_wsgi, tracer=None):
    """
    Create a wrapper middleware for another WSGI response handler.
    If tracer is not passed in, 'opentracing.tracer' is used.
    """

    def wsgi_tracing_middleware(environ, start_response):
        # TODO find out if the route can be retrieved from somewhere

        request = WSGIRequestWrapper.from_wsgi_environ(environ)
        span = before_request(request=request, tracer=tracer)

        # Wrapper around the real start_response object to log
        # additional information to opentracing Span
        def start_response_wrapper(status, response_headers, exc_info=None):
            if exc_info is not None:
                span.set_tag('error', str(exc_info))
            span.finish()

            return start_response(status, response_headers)

        with span_in_context(span):
            return other_wsgi(environ, start_response_wrapper)

    return wsgi_tracing_middleware
```

And here's an example for middleware in Tornado-based app:

```python

import opentracing
from opentracing.scope_managers.tornado import TornadoScopeManager
from opentracing_instrumentation import span_in_stack_context, http_server


opentracing.tracer = MyOpenTracingTracer(scope_manager=TornadoScopeManager())


class TracerMiddleware(object):

    def __init__(self):
        # perform initialization similar to above, including installing
        # the client_hooks

    @gen.coroutine
    def __call__(self, request, handler, next_mw):
        request_wrapper = http_server.TornadoRequestWrapper(request=request)
        span = http_server.before_request(request=request_wrapper)

        @gen.coroutine
        def next_middleware_with_span():
            yield next_mw()

        yield run_coroutine_with_span(span=span,
                                      func=next_middleware_with_span)

        span.finish()


def run_coroutine_with_span(span, func, *args, **kwargs):
    """Wrap the execution of a Tornado coroutine func in a tracing span.

    This makes the span available through the get_current_span() function.

    :param span: The tracing span to expose.
    :param func: Co-routine to execute in the scope of tracing span.
    :param args: Positional args to func, if any.
    :param kwargs: Keyword args to func, if any.
    """
    with span_in_stack_context(span):
        return func(*args, **kwargs)
```

### Customization

For the `requests` library, in case you want to set custom tags
to spans depending on content or some metadata of responses,
you can set `response_handler_hook`.
The hook must be a method with a signature `(response, span)`,
where `response` and `span` are positional arguments,
so you can use different names for them if needed.

```python
from opentracing_instrumentation.client_hooks.requests import patcher


def hook(response, span):
    if not response.ok:
        span.set_tag('error', 'true')


patcher.set_response_handler_hook(hook)
```

If you have issues with getting the parent span, it is possible to override
default function that retrieves parent span. 

```python 
from opentracing_instrumentation.client_hooks import install_all_patches,
     set_current_span_func

set_current_span_func(my_custom_extractor_func)
install_all_patches()

``` 

## Development

`PostgreSQL`, `RabbitMQ`, `Redis`, and `DynamoDB` are required for certain tests.

```bash
docker-compose up -d
```

To prepare a development environment please execute the following commands.
```bash
virtualenv env
source env/bin/activate
make bootstrap
make test
```

You can use [tox](https://tox.readthedocs.io) to run tests as well.
```bash
tox
```

[ci-img]: https://travis-ci.org/uber-common/opentracing-python-instrumentation.svg?branch=master
[ci]: https://travis-ci.org/uber-common/opentracing-python-instrumentation
[pypi-img]: https://img.shields.io/pypi/v/opentracing_instrumentation.svg
[pypi]: https://pypi.python.org/pypi/opentracing_instrumentation
[cov-img]: https://coveralls.io/repos/github/uber-common/opentracing-python-instrumentation/badge.svg
[cov]: https://coveralls.io/github/uber-common/opentracing-python-instrumentation
[pyver-img]: https://img.shields.io/pypi/pyversions/opentracing-instrumentation.svg 
[pydl-img]: https://img.shields.io/pypi/dm/opentracing-instrumentation.svg 




%package -n python3-opentracing-instrumentation
Summary:	Tracing Instrumentation using OpenTracing API (http://opentracing.io)
Provides:	python-opentracing-instrumentation
BuildRequires:	python3-devel
BuildRequires:	python3-setuptools
BuildRequires:	python3-pip
%description -n python3-opentracing-instrumentation
[![PyPI version][pypi-img]][pypi] [![Python versions][pyver-img]][pypi] [![Pypi Downloads][pydl-img]][pypi] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] 


# opentracing-python-instrumentation

A collection of instrumentation tools to enable tracing with 
[OpenTracing API](http://opentracing.io).

## Module

Make sure you are running recent enough versions of `pip` and `setuptools`, e.g. before installing your project requirements execute this:

```
pip install --upgrade "setuptools>=29" "pip>=9"
```

The module name is `opentracing_instrumentation`.

## What's inside

### Supported client frameworks

The following libraries are instrumented for tracing in this module:
 * [boto3](https://github.com/boto/boto3) — AWS SDK for Python
 * [Celery](https://github.com/celery/celery) — Distributed Task Queue
 * `urllib2`
 * `requests`
 * `SQLAlchemy`
 * `MySQLdb`
 * `psycopg2`
 * Tornado HTTP client
 *  `redis`

#### Limitations

For some operations, `Boto3` uses `ThreadPoolExecutor` under the hood.
So, in order to make it thread-safe, the instrumentation is implemented using
`span_in_stack_context()` which
[forces you](https://github.com/uber-common/opentracing-python-instrumentation#in-process-context-propagation)
to use `TornadoScopeManager`.

### Server instrumentation

For inbound requests a helper function `before_request` is provided for creating middleware for frameworks like Flask and uWSGI.

### Manual instrumentation

Finally, a `@traced_function` decorator is provided for manual instrumentation.

### In-process Context Propagation

As part of the OpenTracing 2.0 API, in-process `Span` propagation happens through the newly defined
[ScopeManager](https://opentracing-python.readthedocs.io/en/latest/api.html#scope-managers)
interface. However, the existing functionality has been kept to provide backwards compatibility and
ease code migration:

`span_in_context()` implements context propagation using the current `opentracing.tracer.scope_manager`,
expected to be a thread-local based `ScopeManager`, such as `opentracing.scope_managers.ThreadLocalScopeManager`.

`span_in_stack_context()` implements context propagation for Tornado applications
using the current `opentracing.tracer.scope_manager` too, expected to be an instance of
 `opentracing.scope_managers.tornado.TornadoScopeManager`.

`get_current_span()` returns the currently active `Span`, if any.

Direct access to the `request_context` module as well as usage of `RequestContext` and `RequestContextManager`
have been **fully** deprecated, as they do not integrate with the new OpenTracing 2.0 API.
Using them along `get_current_span()` is guaranteed to work, but it is **highly** recommended
to switch to the previously mentioned functions.

## Usage

This library provides two types of instrumentation, explicit instrumentation
for server endpoints, and implicit instrumentation for client call sites.

Server endpoints are instrumented by creating a middleware class that:

 1. initializes the specific tracer implementation
 2. wraps incoming request handlers into a method that reads the incoming
    tracing info from the request and creates a new tracing Span

Client call sites are instrumented implicitly by executing a set of 
available `client_hooks` that monkey-patch some API points in several 
common libraries like `SQLAlchemy`, `urllib2`, Tornado Async HTTP Client.
The initialization of those hooks is usually also done from the middleware
class's `__init__` method.

There is a client-server example using this library with Flask instrumentation
from opentracing-contrib: https://github.com/opentracing-contrib/python-flask/tree/master/example.

Here's an example of a middleware for [Clay framework](https://github.com/uber/clay):

```python

from opentracing_instrumentation import span_in_context
from opentracing_instrumentation.http_server import before_request
from opentracing_instrumentation.http_server import WSGIRequestWrapper
from opentracing_instrumentation.client_hooks import install_all_patches


class TracerMiddleware(object):

    def __init__(self, app, wsgi_app):
        self.wsgi_app = wsgi_app
        self.service_name = app.name

        CONFIG.app_name = self.service_name
        CONFIG.caller_name_headers.append('X-Uber-Source')
        CONFIG.callee_endpoint_headers.append('X-Uber-Endpoint')

        install_all_patches()
        self.wsgi_app = create_wsgi_middleware(wsgi_app)
        self.init_tracer()

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def init_tracer(self):
        # code specific to your tracer implementation
        pass


def create_wsgi_middleware(other_wsgi, tracer=None):
    """
    Create a wrapper middleware for another WSGI response handler.
    If tracer is not passed in, 'opentracing.tracer' is used.
    """

    def wsgi_tracing_middleware(environ, start_response):
        # TODO find out if the route can be retrieved from somewhere

        request = WSGIRequestWrapper.from_wsgi_environ(environ)
        span = before_request(request=request, tracer=tracer)

        # Wrapper around the real start_response object to log
        # additional information to opentracing Span
        def start_response_wrapper(status, response_headers, exc_info=None):
            if exc_info is not None:
                span.set_tag('error', str(exc_info))
            span.finish()

            return start_response(status, response_headers)

        with span_in_context(span):
            return other_wsgi(environ, start_response_wrapper)

    return wsgi_tracing_middleware
```

And here's an example for middleware in Tornado-based app:

```python

import opentracing
from opentracing.scope_managers.tornado import TornadoScopeManager
from opentracing_instrumentation import span_in_stack_context, http_server


opentracing.tracer = MyOpenTracingTracer(scope_manager=TornadoScopeManager())


class TracerMiddleware(object):

    def __init__(self):
        # perform initialization similar to above, including installing
        # the client_hooks

    @gen.coroutine
    def __call__(self, request, handler, next_mw):
        request_wrapper = http_server.TornadoRequestWrapper(request=request)
        span = http_server.before_request(request=request_wrapper)

        @gen.coroutine
        def next_middleware_with_span():
            yield next_mw()

        yield run_coroutine_with_span(span=span,
                                      func=next_middleware_with_span)

        span.finish()


def run_coroutine_with_span(span, func, *args, **kwargs):
    """Wrap the execution of a Tornado coroutine func in a tracing span.

    This makes the span available through the get_current_span() function.

    :param span: The tracing span to expose.
    :param func: Co-routine to execute in the scope of tracing span.
    :param args: Positional args to func, if any.
    :param kwargs: Keyword args to func, if any.
    """
    with span_in_stack_context(span):
        return func(*args, **kwargs)
```

### Customization

For the `requests` library, in case you want to set custom tags
to spans depending on content or some metadata of responses,
you can set `response_handler_hook`.
The hook must be a method with a signature `(response, span)`,
where `response` and `span` are positional arguments,
so you can use different names for them if needed.

```python
from opentracing_instrumentation.client_hooks.requests import patcher


def hook(response, span):
    if not response.ok:
        span.set_tag('error', 'true')


patcher.set_response_handler_hook(hook)
```

If you have issues with getting the parent span, it is possible to override
default function that retrieves parent span. 

```python 
from opentracing_instrumentation.client_hooks import install_all_patches,
     set_current_span_func

set_current_span_func(my_custom_extractor_func)
install_all_patches()

``` 

## Development

`PostgreSQL`, `RabbitMQ`, `Redis`, and `DynamoDB` are required for certain tests.

```bash
docker-compose up -d
```

To prepare a development environment please execute the following commands.
```bash
virtualenv env
source env/bin/activate
make bootstrap
make test
```

You can use [tox](https://tox.readthedocs.io) to run tests as well.
```bash
tox
```

[ci-img]: https://travis-ci.org/uber-common/opentracing-python-instrumentation.svg?branch=master
[ci]: https://travis-ci.org/uber-common/opentracing-python-instrumentation
[pypi-img]: https://img.shields.io/pypi/v/opentracing_instrumentation.svg
[pypi]: https://pypi.python.org/pypi/opentracing_instrumentation
[cov-img]: https://coveralls.io/repos/github/uber-common/opentracing-python-instrumentation/badge.svg
[cov]: https://coveralls.io/github/uber-common/opentracing-python-instrumentation
[pyver-img]: https://img.shields.io/pypi/pyversions/opentracing-instrumentation.svg 
[pydl-img]: https://img.shields.io/pypi/dm/opentracing-instrumentation.svg 




%package help
Summary:	Development documents and examples for opentracing-instrumentation
Provides:	python3-opentracing-instrumentation-doc
%description help
[![PyPI version][pypi-img]][pypi] [![Python versions][pyver-img]][pypi] [![Pypi Downloads][pydl-img]][pypi] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] 


# opentracing-python-instrumentation

A collection of instrumentation tools to enable tracing with 
[OpenTracing API](http://opentracing.io).

## Module

Make sure you are running recent enough versions of `pip` and `setuptools`, e.g. before installing your project requirements execute this:

```
pip install --upgrade "setuptools>=29" "pip>=9"
```

The module name is `opentracing_instrumentation`.

## What's inside

### Supported client frameworks

The following libraries are instrumented for tracing in this module:
 * [boto3](https://github.com/boto/boto3) — AWS SDK for Python
 * [Celery](https://github.com/celery/celery) — Distributed Task Queue
 * `urllib2`
 * `requests`
 * `SQLAlchemy`
 * `MySQLdb`
 * `psycopg2`
 * Tornado HTTP client
 *  `redis`

#### Limitations

For some operations, `Boto3` uses `ThreadPoolExecutor` under the hood.
So, in order to make it thread-safe, the instrumentation is implemented using
`span_in_stack_context()` which
[forces you](https://github.com/uber-common/opentracing-python-instrumentation#in-process-context-propagation)
to use `TornadoScopeManager`.

### Server instrumentation

For inbound requests a helper function `before_request` is provided for creating middleware for frameworks like Flask and uWSGI.

### Manual instrumentation

Finally, a `@traced_function` decorator is provided for manual instrumentation.

### In-process Context Propagation

As part of the OpenTracing 2.0 API, in-process `Span` propagation happens through the newly defined
[ScopeManager](https://opentracing-python.readthedocs.io/en/latest/api.html#scope-managers)
interface. However, the existing functionality has been kept to provide backwards compatibility and
ease code migration:

`span_in_context()` implements context propagation using the current `opentracing.tracer.scope_manager`,
expected to be a thread-local based `ScopeManager`, such as `opentracing.scope_managers.ThreadLocalScopeManager`.

`span_in_stack_context()` implements context propagation for Tornado applications
using the current `opentracing.tracer.scope_manager` too, expected to be an instance of
 `opentracing.scope_managers.tornado.TornadoScopeManager`.

`get_current_span()` returns the currently active `Span`, if any.

Direct access to the `request_context` module as well as usage of `RequestContext` and `RequestContextManager`
have been **fully** deprecated, as they do not integrate with the new OpenTracing 2.0 API.
Using them along `get_current_span()` is guaranteed to work, but it is **highly** recommended
to switch to the previously mentioned functions.

## Usage

This library provides two types of instrumentation, explicit instrumentation
for server endpoints, and implicit instrumentation for client call sites.

Server endpoints are instrumented by creating a middleware class that:

 1. initializes the specific tracer implementation
 2. wraps incoming request handlers into a method that reads the incoming
    tracing info from the request and creates a new tracing Span

Client call sites are instrumented implicitly by executing a set of 
available `client_hooks` that monkey-patch some API points in several 
common libraries like `SQLAlchemy`, `urllib2`, Tornado Async HTTP Client.
The initialization of those hooks is usually also done from the middleware
class's `__init__` method.

There is a client-server example using this library with Flask instrumentation
from opentracing-contrib: https://github.com/opentracing-contrib/python-flask/tree/master/example.

Here's an example of a middleware for [Clay framework](https://github.com/uber/clay):

```python

from opentracing_instrumentation import span_in_context
from opentracing_instrumentation.http_server import before_request
from opentracing_instrumentation.http_server import WSGIRequestWrapper
from opentracing_instrumentation.client_hooks import install_all_patches


class TracerMiddleware(object):

    def __init__(self, app, wsgi_app):
        self.wsgi_app = wsgi_app
        self.service_name = app.name

        CONFIG.app_name = self.service_name
        CONFIG.caller_name_headers.append('X-Uber-Source')
        CONFIG.callee_endpoint_headers.append('X-Uber-Endpoint')

        install_all_patches()
        self.wsgi_app = create_wsgi_middleware(wsgi_app)
        self.init_tracer()

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def init_tracer(self):
        # code specific to your tracer implementation
        pass


def create_wsgi_middleware(other_wsgi, tracer=None):
    """
    Create a wrapper middleware for another WSGI response handler.
    If tracer is not passed in, 'opentracing.tracer' is used.
    """

    def wsgi_tracing_middleware(environ, start_response):
        # TODO find out if the route can be retrieved from somewhere

        request = WSGIRequestWrapper.from_wsgi_environ(environ)
        span = before_request(request=request, tracer=tracer)

        # Wrapper around the real start_response object to log
        # additional information to opentracing Span
        def start_response_wrapper(status, response_headers, exc_info=None):
            if exc_info is not None:
                span.set_tag('error', str(exc_info))
            span.finish()

            return start_response(status, response_headers)

        with span_in_context(span):
            return other_wsgi(environ, start_response_wrapper)

    return wsgi_tracing_middleware
```

And here's an example for middleware in Tornado-based app:

```python

import opentracing
from opentracing.scope_managers.tornado import TornadoScopeManager
from opentracing_instrumentation import span_in_stack_context, http_server


opentracing.tracer = MyOpenTracingTracer(scope_manager=TornadoScopeManager())


class TracerMiddleware(object):

    def __init__(self):
        # perform initialization similar to above, including installing
        # the client_hooks

    @gen.coroutine
    def __call__(self, request, handler, next_mw):
        request_wrapper = http_server.TornadoRequestWrapper(request=request)
        span = http_server.before_request(request=request_wrapper)

        @gen.coroutine
        def next_middleware_with_span():
            yield next_mw()

        yield run_coroutine_with_span(span=span,
                                      func=next_middleware_with_span)

        span.finish()


def run_coroutine_with_span(span, func, *args, **kwargs):
    """Wrap the execution of a Tornado coroutine func in a tracing span.

    This makes the span available through the get_current_span() function.

    :param span: The tracing span to expose.
    :param func: Co-routine to execute in the scope of tracing span.
    :param args: Positional args to func, if any.
    :param kwargs: Keyword args to func, if any.
    """
    with span_in_stack_context(span):
        return func(*args, **kwargs)
```

### Customization

For the `requests` library, in case you want to set custom tags
to spans depending on content or some metadata of responses,
you can set `response_handler_hook`.
The hook must be a method with a signature `(response, span)`,
where `response` and `span` are positional arguments,
so you can use different names for them if needed.

```python
from opentracing_instrumentation.client_hooks.requests import patcher


def hook(response, span):
    if not response.ok:
        span.set_tag('error', 'true')


patcher.set_response_handler_hook(hook)
```

If you have issues with getting the parent span, it is possible to override
default function that retrieves parent span. 

```python 
from opentracing_instrumentation.client_hooks import install_all_patches,
     set_current_span_func

set_current_span_func(my_custom_extractor_func)
install_all_patches()

``` 

## Development

`PostgreSQL`, `RabbitMQ`, `Redis`, and `DynamoDB` are required for certain tests.

```bash
docker-compose up -d
```

To prepare a development environment please execute the following commands.
```bash
virtualenv env
source env/bin/activate
make bootstrap
make test
```

You can use [tox](https://tox.readthedocs.io) to run tests as well.
```bash
tox
```

[ci-img]: https://travis-ci.org/uber-common/opentracing-python-instrumentation.svg?branch=master
[ci]: https://travis-ci.org/uber-common/opentracing-python-instrumentation
[pypi-img]: https://img.shields.io/pypi/v/opentracing_instrumentation.svg
[pypi]: https://pypi.python.org/pypi/opentracing_instrumentation
[cov-img]: https://coveralls.io/repos/github/uber-common/opentracing-python-instrumentation/badge.svg
[cov]: https://coveralls.io/github/uber-common/opentracing-python-instrumentation
[pyver-img]: https://img.shields.io/pypi/pyversions/opentracing-instrumentation.svg 
[pydl-img]: https://img.shields.io/pypi/dm/opentracing-instrumentation.svg 




%prep
%autosetup -n opentracing-instrumentation-3.3.1

%build
%py3_build

%install
%py3_install
install -d -m755 %{buildroot}/%{_pkgdocdir}
if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
pushd %{buildroot}
if [ -d usr/lib ]; then
	find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/lib64 ]; then
	find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/bin ]; then
	find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/sbin ]; then
	find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
fi
touch doclist.lst
if [ -d usr/share/man ]; then
	find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
fi
popd
mv %{buildroot}/filelist.lst .
mv %{buildroot}/doclist.lst .

%files -n python3-opentracing-instrumentation -f filelist.lst
%dir %{python3_sitelib}/*

%files help -f doclist.lst
%{_docdir}/*

%changelog
* Sun Apr 23 2023 Python_Bot <Python_Bot@openeuler.org> - 3.3.1-1
- Package Spec generated