import requests from json import JSONDecodeError HTTP_STATUS_OK = 200 HTTP_STATUS_AUTHENTICATE = 401 class WikiException(Exception): pass def _filter_params(params): result = {} for key, value in sorted(params.items(), key=lambda t: t[0] == "token"): if isinstance(value, bool): if value: result[key] = "" else: result[key] = value return result class WikiClient: def __init__(self, endpoint): self.endpoint = endpoint self.token = None self.cookies = requests.cookies.RequestsCookieJar() def is_logged_in(self): return self.token is not None def login(self, user, password, domain=None): # todo: Change this to the new MediaWiki tokens api token_answer = self.do_action("login", method="post", lgname=user) if "login" not in token_answer or "token" not in token_answer["login"]: raise WikiException("No token in login answer.") lgtoken = token_answer["login"]["token"] login_answer = self.do_action( "login", method="post", lgname=user, lgpassword=password, lgdomain=domain, lgtoken=lgtoken) if ("login" not in login_answer or "result" not in login_answer["login"] or login_answer["login"]["result"] != "Success"): raise WikiException("Login not successful.") def logout(self): self.do_action("logout") def do_action(self, action, method="get", data=None, **kwargs): kwargs["action"] = action kwargs["format"] = "json" params = _filter_params(kwargs) def _do_request(): if method == "get": return requests.get( self.endpoint, cookies=self.cookies, params=params) elif method == "post": return requests.post( self.endpoint, cookies=self.cookies, data=data, params=params) req = _do_request() if req.status_code != HTTP_STATUS_OK: raise WikiException( "HTTP status code {} on action {}.".format( req.status_code, action)) self.cookies.update(req.cookies) try: return req.json() except JSONDecodeError: raise WikiException("Server did not return valid JSON.")