from twisted.logger import Logger from twisted.internet import reactor from twisted.internet.task import LoopingCall, deferLater from klein import Klein from json import dumps, loads from json.decoder import JSONDecodeError import pprint import requests from settings import refresh_token, client_id, jwt token_refresh_sec = 30 api_base = "https://sandbox-b2b.revolut.com/api/1.0" webhook_url = "https://callback-sandbox.pathogen.is/callback" # SYSTEM VARIABLES BELOW # app = Klein() access_token = "" log = Logger() pp = pprint.PrettyPrinter(indent=2) def get_new_token(): headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { "grant_type": "refresh_token", "refresh_token": refresh_token, "client_id": client_id, "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", "client_assertion": jwt, } r = requests.post(f"{api_base}/auth/token", data=data, headers=headers) parsed = r.json() if r.status_code == 200: if "access_token" in parsed.keys(): access_token = parsed["access_token"] if len(access_token) == len(refresh_token): log.info("Refreshed access token") return True else: log.error(f"Token refresh didn't contain access token: {parsed}", parsed=parsed) return False else: log.error(f"Cannot refresh token: {parsed}", parsed=parsed) return False def transaction(sender, source_currency, dest_currency, source_amount, dest_amount): pass def setup_webhook(): log.info("Setting up webhook") headers = {"Authorization": f"Bearer {access_token}"} data = { "url": webhook_url } r = requests.post (f"{api_base}/webhook", data=data, headers=headers) parsed = r.json() if r.status_code == 200: log.info("Set up webhook") return dumps({"success": True}) else: log.info("Failed setting up webhook") @app.route("/refresh", methods=["GET"]) def refresh(request): rtrn = get_new_token() return dumps({"success": rtrn}) @app.route("/callback", methods=["POST"]) def callback(request): content = request.content.read() try: parsed = loads(content) except JSONDecodeError: log.error("Failed to parse JSON callback: {content}", content=content) return dumps({"success": False}) log.info("Callback received: {parsed}", parsed=parsed) return dumps({"success": True}) # Set up loop to refresh token, but get one first deferLater(reactor, 1, get_new_token) deferLater(reactor, 2, setup_webhook) lc = LoopingCall(get_new_token) lc.start(token_refresh_sec) resource = app.resource app.run("127.0.0.1", 8080)