Skip to content

ajithdaniel/dhan-auto-auth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dhan Auto Auth

Automated OAuth token refresh for Dhan trading API. Single Python file, no framework dependencies.

Dhan access tokens expire every 24 hours and require browser-based login with TOTP 2FA. This tool automates the entire flow using Playwright — set it on a cron job and never manually refresh again.

Why This Exists

If you use Dhan's trading or data APIs, you know the pain:

  • Tokens expire daily at ~8:30 AM IST
  • Refreshing requires browser login → mobile number → TOTP → redirect
  • No programmatic token refresh endpoint exists
  • Miss a refresh = your algo/dashboard goes down

This solves it with a single file you can drop into any project.

Quick Start

# Install
pip install playwright pyotp requests python-dateutil
playwright install chromium

# Set credentials
export DHAN_CLIENT_ID=your_client_id
export DHAN_API_KEY=your_oauth_app_id
export DHAN_API_SECRET=your_oauth_app_secret
export DHAN_MOBILE=your_mobile_number
export DHAN_TOTP_SECRET=YOUR_BASE32_SECRET
from dhan_auth import DhanAuth

auth = DhanAuth(
    client_id="your_client_id",
    api_key="your_app_id",
    api_secret="your_app_secret",
    mobile="your_mobile_number",
    totp_secret="YOUR_BASE32_SECRET",
)

# Get token (auto-refreshes if expired)
token = auth.token()

# Use with dhanhq
from dhanhq import dhanhq
dhan = dhanhq("your_client_id", token)

How It Works

                    ┌─────────────────────────────┐
                    │  auth.token() / auth.refresh()│
                    └──────────────┬──────────────┘
                                   │
                    ┌──────────────▼──────────────┐
                    │  1. Generate Consent ID      │
                    │  POST auth.dhan.co/app/      │
                    │  generate-consent             │
                    └──────────────┬──────────────┘
                                   │
                    ┌──────────────▼──────────────┐
                    │  2. Playwright Browser Login  │
                    │  • Enter mobile number        │
                    │  • Generate & enter TOTP      │
                    │  • Enter PIN (if required)    │
                    │  • Capture redirect tokenId   │
                    └──────────────┬──────────────┘
                                   │
                    ┌──────────────▼──────────────┐
                    │  3. Consume Consent           │
                    │  POST auth.dhan.co/app/       │
                    │  consumeApp-consent           │
                    │  → Returns accessToken        │
                    └──────────────┬──────────────┘
                                   │
                    ┌──────────────▼──────────────┐
                    │  4. Save to token.json        │
                    │  Valid for ~24 hours           │
                    └─────────────────────────────┘

Features

  • Single file — just copy dhan_auth.py into your project
  • Auto-refresh — call auth.token() and it handles expiry automatically
  • TOTP automation — generates TOTP codes using pyotp, handles timing edge cases
  • Multiple input strategies — handles Dhan's various OTP input formats (individual boxes, single field, tel inputs)
  • 30-min cooldown — prevents burning Dhan's daily consent limit
  • Token persistence — saves to JSON file, survives restarts
  • Manual flow support — generate consent URL for browser-based auth when headless isn't possible
  • Headless & headed — works on servers (EC2, Docker) and desktops

API

DhanAuth(client_id, api_key, api_secret, mobile, totp_secret, pin="", token_file="data/token.json")

Initialize the authenticator.

Param Description
client_id Your Dhan client ID (from profile)
api_key OAuth app ID (from Dhan API portal)
api_secret OAuth app secret
mobile Registered mobile number
totp_secret Base32 TOTP secret (from authenticator app setup)
pin 6-digit PIN, optional (only if Dhan asks for it)
token_file Path to save token JSON (default: data/token.json)

Methods

Method Returns Description
auth.token() str Get valid access token. Auto-refreshes if expired.
auth.refresh() dict Force full OAuth refresh via Playwright. Returns token data.
auth.status() dict Token status: is_valid, hours_remaining, expires_at
auth.get_consent_url() str Generate consent URL for manual browser login
auth.consume(token_id) dict Exchange tokenId from redirect for access token

Cron Setup (Daily Auto-Refresh)

Option A: Shell script

# Add to crontab (8:55 AM IST = 3:25 UTC)
crontab -e
25 3 * * 1-5 /path/to/refresh.sh --force >> /var/log/dhan_refresh.log 2>&1

The included refresh.sh script:

  • Checks if backend is running
  • Skips if token is fresh (>20h remaining)
  • Calls /api/auth/refresh endpoint
  • Prevents concurrent runs with lock file

Option B: Python cron

# Use with APScheduler, Celery, or any scheduler
from dhan_auth import DhanAuth

auth = DhanAuth(...)

def daily_refresh():
    info = auth.status()
    if not info["is_valid"] or info["hours_remaining"] < 2:
        auth.refresh()
        print(f"Refreshed! Expires: {auth.status()['expires_at']}")

Option C: Systemd timer

# /etc/systemd/system/dhan-refresh.timer
[Unit]
Description=Dhan token refresh

[Timer]
OnCalendar=Mon..Fri 08:55 Asia/Kolkata
Persistent=true

[Install]
WantedBy=timers.target

FastAPI Server (Optional)

If you want HTTP endpoints for token management:

pip install fastapi uvicorn
uvicorn server:app --port 8000

Endpoints:

Route Method Description
/api/auth/status GET Token status
/api/auth/refresh POST Force refresh
/api/auth/token GET Get current token
/api/auth/consent/generate POST Manual auth URL
/api/auth/consent/consume POST Exchange tokenId
/api/health GET Health check

Deployment

EC2 / Cloud Server

# Install Playwright + Chromium
pip install playwright
playwright install chromium
playwright install-deps  # System dependencies (Ubuntu/Debian)

# For ARM (Graviton/t4g instances)
# Playwright auto-detects architecture

Docker

FROM python:3.11-slim
RUN pip install playwright pyotp requests python-dateutil
RUN playwright install chromium && playwright install-deps
COPY dhan_auth.py .
COPY your_app.py .
CMD ["python", "your_app.py"]

Getting Your Credentials

  1. Client ID: Login to web.dhan.co → Profile → Client ID
  2. API Key & Secret: Go to dhanhq.co → Create App → Get app_id and app_secret
  3. TOTP Secret: When setting up TOTP in Dhan app, copy the Base32 secret (the text code, not the QR). If already set up, you may need to reset TOTP to get the secret again.
  4. Mobile: The mobile number registered with your Dhan account

Troubleshooting

Issue Solution
Consent generation failed: 401 Check api_key and api_secret are correct
Timeout waiting for redirect TOTP might be wrong — verify totp_secret with an authenticator app
TOTP not auto-submitted Dhan changed their UI — the code handles this with explicit button click fallback
Token refresh failed after midnight Dhan resets consent limits at midnight IST — retry after 12:00 AM
No chromium on server Run playwright install chromium && playwright install-deps
Works locally, fails on EC2 Add --no-sandbox flag (already included in the code)

How Dhan Auth Actually Works (for contributors)

Dhan doesn't have a standard OAuth refresh token flow. Instead:

  1. Consent API (/app/generate-consent) creates a one-time login session
  2. Browser login is mandatory — Dhan requires actual browser interaction (no pure API login)
  3. TOTP is required — can't use OTP (would need SMS access)
  4. After successful login, Dhan redirects to your redirect_url with a tokenId query parameter
  5. Consume API (/app/consumeApp-consent) exchanges tokenId for accessToken
  6. Token is valid for ~24 hours (until next day ~8:30 AM IST)

The Playwright automation mimics a human logging in — fills mobile, enters TOTP digits one by one with keyboard events (React needs this), and captures the redirect.

License

MIT — use it however you want.

Contributing

PRs welcome! Especially for:

  • Handling new Dhan login UI changes
  • Adding support for OTP-based login (if you have SMS automation)
  • Better error recovery and retry logic

About

Automated OAuth token refresh for Dhan trading API. Single Python file, Playwright browser automation with TOTP.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors