Revision: 4507
Author: russblau
Date: 2007-11-05 15:13:10 +0000 (Mon, 05 Nov 2007)
Log Message:
-----------
Generalize query method; add some response processing and error handling.
Modified Paths:
--------------
branches/rewrite/pywikibot/data/api.py
Modified: branches/rewrite/pywikibot/data/api.py
===================================================================
--- branches/rewrite/pywikibot/data/api.py 2007-11-05 10:23:03 UTC (rev 4506)
+++ branches/rewrite/pywikibot/data/api.py 2007-11-05 15:13:10 UTC (rev 4507)
@@ -12,17 +12,78 @@
import urllib
import http
+import simplejson as json
+import warnings
+class APIError(Exception):
+ """The wiki site returned an error message."""
+ def __init__(self, errordict):
+ """Save error dict returned by MW API."""
+ self.errors = errordict
+ def __str__(self):
+ return "%(code)s: %(info)s" % self.errors
+
+
class API:
def __init__(self, site):
self.site = site
- def query(prop, **kwargs):
- params = dict(kwargs)
- params['action'] = 'query'
+ def request(self, **params):
if not params.has_key('format'): #Most probably, we want the JSON format
params['format'] = 'json'
+ return http.HTTP(None).POST('/w/api.php',params) #TODO: Use site's
HTTP object instead
- return http.HTTP(None).POST('/w/api.php',params) #TODO: Use site's
HTTP object instead
+ def query(self, **params):
+ if not params.has_key('action'):
+ params['action'] = 'query'
+ return self.request(**params)
+
+ def query_response(self, **params):
+ """Submit a query and parse the response, returning a dict or
None."""
+ if params.has_key('format') and params['format'] !=
'json':
+ raise TypeError("Query format '%s' cannot be parsed." %
params['format'])
+ while True:
+ httpcode, rawdata = self.query(**params)
+ if httpcode != 200:
+ raise APIError(
+ {'code': httpcode,
+ 'info': "HTTP error code received.",
+ 'data': rawdata})
+ if rawdata.startswith(u"unknown_action"):
+ e = {'code': data[:14], 'info': data[16:]}
+ raise APIError(e)
+ try:
+ result = json.loads(rawdata)
+ except ValueError:
+ # if the result isn't valid JSON, there must be a server
+ # problem. Wait a few seconds and try again
+ # TODO: implement a throttle
+ warnings.warn(
+"Non-JSON response received from server %s; the server may be down."
+ % self.site)
+ continue
+ if type(result) is dict:
+ if result.has_key("error"):
+ # raise error
+ raise APIError(result['error'])
+ if result.has_key("query"):
+ return result
+ raise APIError(
+ {'code': "Unknown API error",
+ 'info': "Response received with no 'query'
key.",
+ 'data': result})
+ if type(result) is list:
+ if result == []:
+ return None
+ raise APIError(
+ {'code': "Unknown API error",
+ 'info': "Query returned a list instead of a
dict.",
+ 'data': result})
+ raise APIError(
+ {'code': "Unknown API error",
+ 'info': "Unable to process query response of type
%s."
+ % type(result),
+ 'data': result})
+
Show replies by date