Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: chrome/common/extensions/docs/server2/appengine_url_fetcher.py

Issue 575613003: Docserver: Gitiles auth and cron refactoring. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import base64 5 import base64
6 import logging
6 import posixpath 7 import posixpath
8 import time
7 9
8 from appengine_wrappers import urlfetch 10 from appengine_wrappers import urlfetch
9 from environment import GetAppVersion 11 from environment import GetAppVersion
10 from future import Future 12 from future import Future
11 13
12 14
15 _MAX_RETRIES = 5
16 _RETRY_DELAY_SECONDS = 30
17
18
13 def _MakeHeaders(username, password, access_token): 19 def _MakeHeaders(username, password, access_token):
14 headers = { 20 headers = {
15 'User-Agent': 'Chromium docserver %s' % GetAppVersion(), 21 'User-Agent': 'Chromium docserver %s' % GetAppVersion(),
16 'Cache-Control': 'max-age=0', 22 'Cache-Control': 'max-age=0',
17 } 23 }
18 if username is not None and password is not None: 24 if username is not None and password is not None:
19 headers['Authorization'] = 'Basic %s' % base64.b64encode( 25 headers['Authorization'] = 'Basic %s' % base64.b64encode(
20 '%s:%s' % (username, password)) 26 '%s:%s' % (username, password))
21 if access_token is not None: 27 if access_token is not None:
22 headers['Authorization'] = 'OAuth %s' % access_token 28 headers['Authorization'] = 'OAuth %s' % access_token
23 return headers 29 return headers
24 30
25 31
26 class AppEngineUrlFetcher(object): 32 class AppEngineUrlFetcher(object):
27 """A wrapper around the App Engine urlfetch module that allows for easy 33 """A wrapper around the App Engine urlfetch module that allows for easy
28 async fetches. 34 async fetches.
29 """ 35 """
30 def __init__(self, base_path=None): 36 def __init__(self, base_path=None):
31 assert base_path is None or not base_path.endswith('/'), base_path 37 assert base_path is None or not base_path.endswith('/'), base_path
32 self._base_path = base_path 38 self._base_path = base_path
39 self._retries_left = _MAX_RETRIES
33 40
34 def Fetch(self, url, username=None, password=None, access_token=None): 41 def Fetch(self, url, username=None, password=None, access_token=None):
35 """Fetches a file synchronously. 42 """Fetches a file synchronously.
36 """ 43 """
37 return urlfetch.fetch(self._FromBasePath(url), 44 return urlfetch.fetch(self._FromBasePath(url),
38 deadline=20, 45 deadline=20,
39 headers=_MakeHeaders(username, 46 headers=_MakeHeaders(username,
40 password, 47 password,
41 access_token)) 48 access_token))
42 49
43 def FetchAsync(self, url, username=None, password=None, access_token=None): 50 def FetchAsync(self, url, username=None, password=None, access_token=None):
44 """Fetches a file asynchronously, and returns a Future with the result. 51 """Fetches a file asynchronously, and returns a Future with the result.
45 """ 52 """
53 def process_result(result):
54 if result.status_code == 429:
55 if self._retries_left == 0:
56 logging.error('Still throttled. Giving up.')
57 return result
58 self._retries_left -= 1
59 logging.info('Throttled. Trying again in %s seconds.' %
60 _RETRY_DELAY_SECONDS)
61 time.sleep(_RETRY_DELAY_SECONDS)
62 return self.FetchAsync(url, username, password, access_token).Get()
63 return result
64
46 rpc = urlfetch.create_rpc(deadline=20) 65 rpc = urlfetch.create_rpc(deadline=20)
47 urlfetch.make_fetch_call(rpc, 66 urlfetch.make_fetch_call(rpc,
48 self._FromBasePath(url), 67 self._FromBasePath(url),
49 headers=_MakeHeaders(username, 68 headers=_MakeHeaders(username,
50 password, 69 password,
51 access_token)) 70 access_token))
52 return Future(callback=lambda: rpc.get_result()) 71 return Future(callback=lambda: process_result(rpc.get_result()))
53 72
54 def _FromBasePath(self, url): 73 def _FromBasePath(self, url):
55 assert not url.startswith('/'), url 74 assert not url.startswith('/'), url
56 if self._base_path is not None: 75 if self._base_path is not None:
57 url = posixpath.join(self._base_path, url) if url else self._base_path 76 url = posixpath.join(self._base_path, url) if url else self._base_path
58 return url 77 return url
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698