Skip to content

Commit

Permalink
Offload retry logic to requests and urllib3.
Browse files Browse the repository at this point in the history
Urllib3 comes with good retry logic, which is exposed through the
requests `HTTPAdapter`. Attach retry options to the session adapters and
delete custom retry logic from robobrowser.
  • Loading branch information
jmcarp committed Jun 7, 2015
1 parent 38d646a commit a243352
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 33 deletions.
12 changes: 5 additions & 7 deletions robobrowser/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
import requests
from bs4 import BeautifulSoup
from werkzeug import cached_property
from requests.exceptions import RequestException
from requests.packages.urllib3.util.retry import Retry

from robobrowser import helpers
from robobrowser import exceptions
from robobrowser.compat import urlparse
from robobrowser.forms.form import Form
from robobrowser.cache import RoboHTTPAdapter
from robobrowser.helpers import retry


_link_ptn = re.compile(r'^(a|button)$', re.I)
Expand Down Expand Up @@ -68,7 +67,7 @@ class RoboBrowser(object):
def __init__(self, session=None, parser=None, user_agent=None,
history=True, timeout=None, allow_redirects=True, cache=False,
cache_patterns=None, max_age=None, max_count=None, tries=None,

This comment has been minimized.

Copy link
@zajalo

zajalo Oct 4, 2015

Wouldn't it be more intuitive to name the param "retries" instead of "tries"? Tries implies that if I set it to 1 there be no retries and I would have to set it to at least 2 for a retry. We shouldn't assume that the first attempt is not a try.

errors=RequestException, delay=None, multiplier=None):
multiplier=None):

self.session = session or requests.Session()

Expand Down Expand Up @@ -107,10 +106,9 @@ def __init__(self, session=None, parser=None, user_agent=None,

# Set up retries
if tries:
decorator = retry(tries, errors, delay, multiplier)
self._open, self.open = self.open, decorator(self.open)
self._submit_form, self.submit_form = \
self.submit_form, decorator(self.submit_form)
retry = Retry(tries, backoff_factor=multiplier)
for protocol in ['http://', 'https://']:
self.session.adapters[protocol].max_retries = retry

def __repr__(self):
try:
Expand Down
26 changes: 0 additions & 26 deletions robobrowser/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
"""

import re
import time
import logging
import functools

from bs4 import BeautifulSoup
from bs4.element import Tag
Expand Down Expand Up @@ -91,26 +88,3 @@ def lowercase_attr_names(tag):
(key.lower(), value)
for key, value in iteritems(tag.attrs)
])


def retry(tries, errors=None, delay=3, multiplier=2, logger=None):

errors = errors or Exception
logger = logger or logging.getLogger(__name__)

def decorator(func):

@functools.wraps(func)
def decorated(*args, **kwargs):
mdelay = delay
for _ in range(tries - 1):
try:
return func(*args, **kwargs)
except errors as error:
logger.exception(error)
time.sleep(mdelay)
mdelay *= multiplier
return func(*args, **kwargs)
return decorated

return decorator

0 comments on commit a243352

Please sign in to comment.