Package biblio :: Package webquery :: Module basewebquery
[hide private]
[frames] | no frames]

Source Code for Module biblio.webquery.basewebquery

  1  #! /usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  """ 
  4  A base class for querying webservices. 
  5  """ 
  6  # TODO: list of possible apis at http://techessence.info/apis and 
  7  # http://www.programmableweb.com/apitag/books# 
  8   
  9   
 10  __docformat__ = 'restructuredtext en' 
 11   
 12   
 13  ### IMPORTS ### 
 14   
 15  import socket 
 16  from urllib import urlopen, quote 
 17   
 18  import impl 
 19   
 20   
 21  ### CONSTANTS & DEFINES ### 
 22   
 23  ### IMPLEMENTATION ### 
 24   
25 -class BaseWebquery (impl.ReprObj):
26 """ 27 A base class for querying webservices. 28 29 This serves as a foundation for other web-query classes, centralising a 30 small amount of functionality and providing a common interface. 31 32 """ 33 34 _repr_fields = [ 35 'root_url', 36 'timeout', 37 'limits', 38 ] 39
40 - def __init__ (self, root_url, timeout=5.0, limits=[]):
41 """ 42 Ctor, allowing the setting of the webservice, timeout and limits on use. 43 44 :Parameters: 45 root_url : string 46 The url to be used as the basis for all requests to this service. 47 It should be the common "stem" that does not vary for any request. 48 timeout : int or float 49 How many seconds to wait for a response. 50 limits : iterable 51 A list of QueryThrottles to impose upon the use of this webservice. 52 53 """ 54 self.root_url = root_url 55 self.timeout = timeout 56 self.limits = limits or []
57
58 - def request (self, sub_url):
59 """ 60 Send a request to the webservice and return the response. 61 62 :Parameters: 63 sub_url : string 64 This will be added to the root url set in the c'tor and used as the 65 actual url that is requested. 66 67 :Returns: 68 The data in the webservice response. 69 70 This is the low-level calls that checks any throttling, send the request 71 and actually fetches the response data. For consistency, all service 72 access should be placed through here. 73 74 """ 75 for limit in self.limits: 76 limit.check_limit (self) 77 socket.setdefaulttimeout (self.timeout) 78 full_url = self._build_request_url (sub_url) 79 return urlopen (full_url).read()
80
81 - def _build_request_url (self, sub_url):
82 """ 83 Assemble the full url for requesting data. 84 85 :Parameters: 86 sub_url : string 87 The later part of a request url that can change. 88 89 :Returns: 90 The url to be used for the webservice request. 91 92 This is an internal method, intended for over-riding or modifying the 93 request construction in subclasses, for example where an access key must 94 be included. 95 96 """ 97 return self.root_url + sub_url
98 99
100 -class BaseKeyedWebQuery (BaseWebquery):
101 """ 102 A Webquery that requires an access key. 103 """
104 - def __init__ (self, root_url, key, timeout=5.0, limits=[]):
105 """ 106 Ctor, allowing the setting of a webservice access key. 107 108 :Parameters: 109 root_url 110 See `BaseWebquery`. Either this or the sub_url passed to `request` 111 must include a keyword formatting for the access key, i.e. 112 ``%(key)s``. 113 key : string 114 The access or PAI key to be passed to the webservice for access. 115 timeout 116 See `BaseWebquery`. 117 limits 118 See `BaseWebquery`. 119 120 """ 121 BaseWebquery.__init__ (self, root_url=root_url, timeout=timeout, 122 limits=limits) 123 self.key = key
124
125 - def _build_request_url (self, sub_url):
126 """ 127 Assemble the full url for requesting data. 128 129 :Parameters: 130 sub_url : string 131 See `BaseWebquery`. 132 133 :Returns: 134 The url to be used for the webservice request, including the 135 access key. 136 137 This builds the url for any request, including the access key. Either 138 the root_url passed to the c'tor or the sub_url passed to the request 139 must include keyword formatting for the access key, i.e. ``%(key)s``. 140 141 """ 142 full_url = self.root_url + sub_url 143 return full_url % {'key': self.key}
144 145 146 ### TEST & DEBUG ### 147
148 -def _doctest ():
149 import doctest 150 doctest.testmod()
151 152 153 ### MAIN ### 154 155 if __name__ == '__main__': 156 _doctest() 157 158 159 ### END ###################################################################### 160