Skip to content

Commit

Permalink
Merge pull request kpn#32 from imiric/feature/async-decorator
Browse files Browse the repository at this point in the history
NEW Add async decorator
  • Loading branch information
sergray authored Jul 11, 2017
2 parents 9b567a0 + add66c4 commit 862e16f
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 0 deletions.
22 changes: 22 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,28 @@ And the following in Elasticsearch
]
It's also possible to decorate coroutines or awaitables in Python >=3.5.

For example:

.. code-block:: python
import asyncio
from time_execution import time_execution_async
# ... Setup the desired backend(s) as described above ...
# Wrap the methods where you want the metrics
@time_execution_async
async def hello():
await asyncio.sleep(1)
return 'World'
# Now when we schedule hello() we will get metrics in our backends
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
Hooks
-----

Expand Down
23 changes: 23 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,29 @@ And the following in Elasticsearch
}
]
It's also possible to decorate coroutines or awaitables in Python >=3.5.

For example:

.. code-block:: python
import asyncio
from time_execution import time_execution_async
# ... Setup the desired backend(s) as described above ...
# Wrap the methods where you want the metrics
@time_execution_async
async def hello():
await asyncio.sleep(1)
return 'World'
# Now when we schedule hello() we will get metrics in our backends
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
.. _usage-hooks:

Hooks
Expand Down
42 changes: 42 additions & 0 deletions tests/test_decorator_async.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import asyncio
from unittest.mock import Mock

import pytest
from time_execution import time_execution_async


@pytest.fixture
def patch_backend(monkeypatch):
m = Mock()
monkeypatch.setattr('time_execution.decorator.write_metric', m)
return m


@time_execution_async
async def go_async(arg=None):
await asyncio.sleep(0.01)
return arg


class TestTimeExecutionAsync:
pytestmark = pytest.mark.asyncio

async def test_plain(self, patch_backend):
count = 4

for i in range(count):
await go_async()

assert patch_backend.call_count == count
call_args = patch_backend.call_args[1]
assert call_args['name'] == 'tests.test_decorator_async.go_async'
assert call_args['value'] >= 10 # in ms

async def test_with_arguments(self, patch_backend):
res = await go_async('ok')

assert res == 'ok'
assert patch_backend.call_count == 1
call_args = patch_backend.call_args[1]
assert call_args['name'] == 'tests.test_decorator_async.go_async'
assert call_args['value'] >= 10 # in ms
3 changes: 3 additions & 0 deletions time_execution/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import sys

PY_35_GT = sys.version_info >= (3, 5)
9 changes: 9 additions & 0 deletions time_execution/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from fqn_decorators import Decorator
from pkgsettings import Settings

from .constants import PY_35_GT

SHORT_HOSTNAME = socket.gethostname()

settings = Settings()
Expand Down Expand Up @@ -74,3 +76,10 @@ def get_exception(self):
six.reraise(*self.exc_info)
except Exception as e:
return e


if PY_35_GT:
from fqn_decorators.async import AsyncDecorator # isort:skip

class time_execution_async(AsyncDecorator, time_execution):
pass
13 changes: 13 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,24 @@ deps =
-rrequirements/requirements-base.txt
-rrequirements/requirements-testing.txt

[testenv:py27]
setenv =
PYTEST_ADDOPTS = --ignore tests/test_decorator_async.py
deps =
{[testenv]deps}

[testenv:py35]
deps =
{[testenv]deps}
pytest-asyncio==0.6.0

[testenv:lint]
basepython = python3.5
commands = flake8 time_execution tests --exclude=time_execution/__init__.py
deps = flake8

[testenv:docs]
basepython = python3.5
commands =
python {toxinidir}/docs/apidoc.py -T -M -d 2 -o {toxinidir}/docs/api {toxinidir}/time_execution
sphinx-build -W -b html {toxinidir}/docs {toxinidir}/docs/_build/html
Expand Down

0 comments on commit 862e16f

Please sign in to comment.