Exchange request token for an access token

The request_token (chapter 8) is exchanged, together with your api_secret, for an access_token — the credential you'll attach to every subsequent API call today.

# auth/session.py (continued)
from kiteconnect import KiteConnect
from config import API_KEY, API_SECRET

def generate_session(request_token: str) -> str:
    kite = KiteConnect(api_key=API_KEY)
    data = kite.generate_session(request_token, api_secret=API_SECRET)
    access_token = data["access_token"]
    kite.set_access_token(access_token)
    return access_token
# usage
access_token = generate_session(request_token)
print("Access token:", access_token)

data also contains user_id, user_name, email, login_time, and public_token — useful for logging who/when a session was created, not needed for trading calls.

Why the exchange happens server-side with the secret

request_token alone isn't enough to get a session — you must also prove you hold api_secret. This is what stops someone who intercepts the redirect URL (e.g. via a shared machine or malicious redirect) from completing the login on your app's behalf; they'd need the secret too, which never appears in the browser flow.

Checkpoint script

# auth/login.py — full manual flow start to finish
import webbrowser
from kiteconnect import KiteConnect
from config import API_KEY
from auth.local_redirect_server import run_server_and_wait
from auth.session import generate_session

kite = KiteConnect(api_key=API_KEY)
webbrowser.open(kite.login_url())
request_token = run_server_and_wait()
access_token = generate_session(request_token)
kite.set_access_token(access_token)

profile = kite.profile()
print("Logged in as:", profile["user_name"])

Run this once. If it prints your name, auth works end to end.

Next: 010 — Persist and refresh the access token daily