1
2
3 """
4 A base class for querying webservices.
5 """
6
7
8
9
10 __docformat__ = 'restructuredtext en'
11
12
13
14
15 import socket
16 from urllib import urlopen, quote
17
18 import impl
19
20
21
22
23
24
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
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
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
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
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
147
149 import doctest
150 doctest.testmod()
151
152
153
154
155 if __name__ == '__main__':
156 _doctest()
157
158
159
160