#!/usr/sbin/env python3 # Twisted/Klein imports from twisted.logger import Logger from twisted.internet import reactor from twisted.internet.task import LoopingCall, deferLater from klein import Klein # Other library imports from json import dumps, loads from json.decoder import JSONDecodeError # Project imports from settings import settings from revolut import Revolut class WebApp(object): """ Our Klein webapp. """ app = Klein() def __init__(self): self.revolut = Revolut() self.log = Logger("webapp") @app.route("/refresh", methods=["GET"]) def refresh(self, request): rtrn = self.revolut.get_new_token() return dumps({"success": rtrn}) @app.route("/callback", methods=["POST"]) def callback(self, request): content = request.content.read() try: parsed = loads(content) except JSONDecodeError: self.log.error("Failed to parse JSON callback: {content}", content=content) return dumps({"success": False}) self.log.info("Callback received: {parsed}", parsed=parsed) return dumps({"success": True}) def start(webapp): """ Schedule to refresh the API token once the reactor starts, and create LoopingCapp to refresh it periodically. """ deferLater(reactor, 1, webapp.revolut.get_new_token) deferLater(reactor, 4, webapp.revolut.setup_webhook) lc = LoopingCall(webapp.revolut.get_new_token) lc.start(settings.token_refresh_sec) if __name__ == "__main__": webapp = WebApp() start(webapp) webapp.app.run("127.0.0.1", 8080)