Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Default usage of raven.Client does not import twisted or requests #1260

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion raven/breadcrumbs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
from __future__ import absolute_import

try:
import __builtin__ as builtins
except ImportError:
import builtins

import os
import logging
import sys

from time import time
from types import FunctionType
Expand Down Expand Up @@ -295,6 +301,20 @@ def register_logging_handler(callback):


hooked_libraries = {}
delayed_hooks = {}
_orig_import = __import__


def delayed_hook_libraries(name, globals={}, locals={}, fromlist=[], level=-1):
if level == -1:
result = _orig_import(name, globals, locals, fromlist) # python 3.x workaround
else:
result = _orig_import(name, globals, locals, fromlist, level)

if name in delayed_hooks:
func = delayed_hooks[name]
func()
return result


def libraryhook(name):
Expand Down Expand Up @@ -390,7 +410,12 @@ def hook_libraries(libraries):
func = hooked_libraries.get(lib)
if func is None:
raise RuntimeError('Unknown library %r for hooking' % lib)
func()
if lib in sys.modules:
func() # lib is already loaded
else:
delayed_hooks[lib] = func
if delayed_hooks:
builtins.__import__ = delayed_hook_libraries


import raven.context
5 changes: 1 addition & 4 deletions raven/conf/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ def discover_default_transport():
return ThreadedHTTPTransport


DEFAULT_TRANSPORT = discover_default_transport()


class RemoteConfig(object):
def __init__(self, base_url=None, project=None, public_key=None,
secret_key=None, transport=None, options=None):
Expand All @@ -52,7 +49,7 @@ def __init__(self, base_url=None, project=None, public_key=None,
self.options = options or {}
self.store_endpoint = store_endpoint

self._transport_cls = transport or DEFAULT_TRANSPORT
self._transport_cls = transport or discover_default_transport()

def __unicode__(self):
return text_type(self.base_url)
Expand Down
15 changes: 8 additions & 7 deletions raven/transport/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,28 @@

from raven.transport.http import HTTPTransport

try:
import requests
has_requests = True
except ImportError:
has_requests = False


class RequestsHTTPTransport(HTTPTransport):

scheme = ['requests+http', 'requests+https']

def __init__(self, *args, **kwargs):
try:
import requests # NOQA
has_requests = True
except ImportError:
has_requests = False

if not has_requests:
raise ImportError('RequestsHTTPTransport requires requests.')

super(RequestsHTTPTransport, self).__init__(*args, **kwargs)

def send(self, url, data, headers):
import requests
if self.verify_ssl:
# If SSL verification is enabled use the provided CA bundle to
# perform the verification.
self.verify_ssl = self.ca_certs
requests.post(url, data=data, headers=headers,
verify=self.verify_ssl, timeout=self.timeout)
verify=self.verify_ssl, timeout=self.timeout)
23 changes: 12 additions & 11 deletions raven/transport/twisted.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,22 @@
"""
from __future__ import absolute_import


from raven.utils.compat import BytesIO
from raven.transport.base import AsyncTransport
from raven.transport.http import HTTPTransport

try:
from twisted.web.client import (
Agent, FileBodyProducer, HTTPConnectionPool, ResponseNeverReceived,
readBody,
)
from twisted.web.http_headers import Headers
has_twisted = True
except ImportError:
has_twisted = False


class TwistedHTTPTransport(AsyncTransport, HTTPTransport):
scheme = ['twisted+http', 'twisted+https']

def __init__(self, *args, **kwargs):
try:
from twisted.web.client import Agent, HTTPConnectionPool
import twisted.web.http_headers # NOQA
has_twisted = True
except ImportError:
has_twisted = False

if not has_twisted:
raise ImportError('TwistedHTTPTransport requires twisted.web.')

Expand All @@ -39,6 +35,9 @@ def __init__(self, *args, **kwargs):
self._agent = Agent(reactor, pool=HTTPConnectionPool(reactor))

def async_send(self, url, data, headers, success_cb, failure_cb):
from twisted.web.client import FileBodyProducer, ResponseNeverReceived
from twisted.web.http_headers import Headers

d = self._agent.request(
b"POST", url,
bodyProducer=FileBodyProducer(BytesIO(data)),
Expand All @@ -58,6 +57,8 @@ def on_success(response):
Success only means that the request succeeded, *not* that the
actual submission was successful.
"""
from twisted.web.client import readBody

if response.code == 200:
success_cb()
else:
Expand Down
2 changes: 2 additions & 0 deletions tests/breadcrumbs/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ def new_func(self):
crumbs = client.context.breadcrumbs.get_buffer()
assert 'dummy' not in set([i['type'] for i in crumbs])

# pretend 'dummy' is a module, and is already loaded
sys.modules['dummy'] = None
client = Client('http://foo:[email protected]/0', hook_libraries=['requests', 'dummy'])
with client.context:
DummyClass().dummy_method()
Expand Down
5 changes: 4 additions & 1 deletion tests/transport/requests/test_threaded_requests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import mock
import time

import requests

from raven.utils.testutils import TestCase

from raven.base import Client
Expand All @@ -26,7 +29,7 @@ def setUp(self):
self.url = "threaded+requests+http://some_username:some_password@localhost:8143/1"
self.client = Client(dsn=self.url)

@mock.patch('raven.transport.requests.post')
@mock.patch('requests.post')
def test_does_send(self, send):
self.client.captureMessage(message='foo')

Expand Down
3 changes: 2 additions & 1 deletion tests/transport/requests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from raven.utils.testutils import TestCase
from raven.base import Client
import requests


class RequestsTransportTest(TestCase):
Expand All @@ -12,7 +13,7 @@ def setUp(self):
dsn="requests+http://some_username:some_password@localhost:8143/1",
)

@mock.patch('raven.transport.requests.post')
@mock.patch('requests.post')
def test_does_send(self, post):
self.client.captureMessage(message='foo')
self.assertEqual(post.call_count, 1)
Expand Down