Handle the redirect and request token

Copy-pasting the request_token out of the browser URL bar (chapter 7) works but doesn't scale. Run a tiny local web server to capture it automatically.

# auth/local_redirect_server.py
from flask import Flask, request
import threading

app = Flask(__name__)
captured_token = {}

@app.route("/")
def capture():
    captured_token["request_token"] = request.args.get("request_token")
    captured_token["status"] = request.args.get("status")
    return "Login captured. You can close this tab."

def run_server_and_wait():
    server_thread = threading.Thread(
        target=lambda: app.run(port=80, ssl_context=None), daemon=True
    )
    server_thread.start()
    import time
    while "request_token" not in captured_token:
        time.sleep(0.5)
    return captured_token["request_token"]

Set your app's redirect URL (chapter 4) to http://127.0.0.1 (or the port you bind) to match.

# usage
from auth.local_redirect_server import run_server_and_wait
import webbrowser
from kiteconnect import KiteConnect
from config import API_KEY

kite = KiteConnect(api_key=API_KEY)
webbrowser.open(kite.login_url())
request_token = run_server_and_wait()
print("Captured request_token:", request_token)

Notes

  • request_token is single-use and expires in a couple of minutes — exchange it for an access token (chapter 9) immediately, don't store it.
  • Zerodha requires HTTPS redirect URLs for anything but 127.0.0.1 / localhost — if deploying this server on a real box, put it behind TLS (chapter 13 / ipv6-only-web-service patterns apply here if relevant to your infra).
  • status=success should be checked — a failed login redirects with status set differently and no usable request_token.

Next: 009 — Exchange request token for an access token