Skip to content

Commit

Permalink
aiohttp: Add patch function which adds sentry handler
Browse files Browse the repository at this point in the history
This patch function automatically sends events to Sentry if
Sentry SDK client is installed and if either Sunset header,
sunset Link relation type or Deprecation-Usage header are
present in the response.

- Fix #10
  • Loading branch information
paveldedik committed Aug 5, 2019
1 parent 6cc154f commit 3e7aa6c
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 28 deletions.
17 changes: 12 additions & 5 deletions kw/platform/aiohttp/__init__.py
Expand Up @@ -10,17 +10,24 @@

required_module = "aiohttp"
if ensure_module_is_available(required_module):
from . import utils
from . import utils, monkey
from .middlewares import user_agent_middleware
from .monkey import construct_user_agent, patch, patch_with_user_agent
from .monkey import (
construct_user_agent,
patch,
patch_with_sentry,
patch_with_user_agent,
)
from .session import KiwiClientSession

__all__ = [
"user_agent_middleware",
"KiwiClientSession",
"construct_user_agent",
"patch_with_user_agent",
"patch",
"patch_with_sentry",
"patch_with_user_agent",
"monkey",
"user_agent_middleware",
"KiwiClientSession",
"utils",
]
else:
Expand Down
44 changes: 43 additions & 1 deletion kw/platform/aiohttp/monkey.py
Expand Up @@ -7,7 +7,20 @@
import wrapt

from .. import wrappers
from ..utils import construct_user_agent
from ..utils import construct_user_agent, report_to_sentry


def _add_sentry_handler(sunset_header=True, deprecated_usage_header=True):
async def _check_headers(func, instance, args, kwargs):
response = await func(*args, **kwargs)
report_to_sentry(
response,
sunset_header=sunset_header,
deprecated_usage_header=deprecated_usage_header,
)
return response

return _check_headers


def patch_with_user_agent(user_agent=None):
Expand All @@ -28,17 +41,46 @@ def patch_with_user_agent(user_agent=None):
)


def patch_with_sentry(sunset_header=True, deprecated_usage_header=True):
"""Patch :meth:`aiohttp.ClientSession._request` to create events in Sentry.
If the HTTP response contains, for example, the ``Sunset`` HTTP header,
an event is sent to Sentry containing details about the sunset.
.. info::
The patch takes effect only if
`Sentry SDK <https://github.com/getsentry/sentry-python>`_ is installed
and properly configured.
:param sunset_header: (optional) Whether to report the presence of the ``Sunset``
header, :obj:`True` by default.
:param deprecated_usage_header: (optional) Whether to report the presence of the
``Deprecated-Usage`` header, :obj:`True` by default.
"""
wrapt.wrap_function_wrapper(
"aiohttp",
"ClientSession._request",
_add_sentry_handler(
sunset_header=sunset_header, deprecated_usage_header=deprecated_usage_header
),
)


def patch():
"""Apply all patches for :mod:`aiohttp` module.
This will automatically apply:
* :func:`kw.platform.aiohttp.patch.patch_with_user_agent`
* :func:`kw.platform.aiohttp.patch.patch_with_sentry`
"""
if getattr(aiohttp, "__kiwi_platform_patch", False):
# Already patched, skip
return

patch_with_user_agent()
patch_with_sentry()

# Mark module as patched
setattr(aiohttp, "__kiwi_platform_patch", True)
7 changes: 4 additions & 3 deletions kw/platform/aiohttp/session.py
Expand Up @@ -7,7 +7,7 @@

import aiohttp

from ..utils import add_user_agent_header, construct_user_agent
from ..utils import add_user_agent_header, construct_user_agent, report_to_sentry


with warnings.catch_warnings():
Expand All @@ -22,12 +22,13 @@ class KiwiClientSession(aiohttp.ClientSession):
from kw.platform.aiohttp import KiwiClientSession
async with KiwiClientSession() as c:
await c.get('https://kiwi.com')
async with KiwiClientSession() as client:
await client.get('https://kiwi.com')
"""

async def _request(self, *args, **kwargs):
headers = kwargs.setdefault("headers", {})
add_user_agent_header(headers, construct_user_agent)
response = await super()._request(*args, **kwargs)
report_to_sentry(response, sunset_header=True, deprecated_usage_header=True)
return response
3 changes: 3 additions & 0 deletions kw/platform/utils.py
Expand Up @@ -120,6 +120,9 @@ def report_to_sentry(response, sunset_header=True, deprecated_usage_header=True)
- ``Sunset`` or ``sunset`` relation type in ``Link`` header
- ``Deprecated-Usage``
:param sunset_header: Whether to report the ``Sunset`` header.
:param deprecated_usage_header: Whether to report the ``Deprecated-Usage`` header.
"""
if sunset_header:
sunset_warning = ""
Expand Down
28 changes: 16 additions & 12 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Expand Up @@ -58,6 +58,7 @@ wrapt = "^1.11"
requests = "^2.22"
httpretty = "^0.9.6"
pytest-mock = "^1.10"
aioresponses = {version = "^0.6.0",python = "^3.5"}

[tool.poetry.extras]
docs = ["sphinx"]
Expand Down

0 comments on commit 3e7aa6c

Please sign in to comment.