Python Environment Setup
Build a robust FastAPI or Flask application to receive webhooks and route orders to Zerodha KiteConnect.
Dependencies
Create a `requirements.txt` file:
# requirements.txt kiteconnect==4.2.0 fastapi==0.115.0 uvicorn==0.30.0 python-dotenv==1.0.1 requests==2.31.0
Install with: `pip install -r requirements.txt`
Environment Config
Create a `.env` file to store secrets securely. Never commit this file to Git.
# .env KITE_API_KEY=your_api_key KITE_API_SECRET=your_api_secret KITE_REQUEST_TOKEN=your_daily_request_token KITE_ACCESS_TOKEN=your_daily_access_token WEBHOOK_SECRET=your_hmac_secret_for_validation
Verified Webhook Handler
This example shows how to verify the TradingView signature and place an order.
import hmac, hashlib, json, os
from fastapi import FastAPI, HTTPException, Request
from kiteconnect import KiteConnect
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
kite = KiteConnect(api_key=os.getenv("KITE_API_KEY"))
# In production, you'd load the access token from a persistent store
kite.set_access_token(os.getenv("KITE_ACCESS_TOKEN"))
async def verify_signature(request: Request, payload: dict):
secret = os.getenv("WEBHOOK_SECRET", "")
# Reconstruct the body for HMAC check (careful with ordering/whitespace)
# TradingView sends plain text body; simpler to verify raw body if possible.
# Ideally, send the signature in a header `X-TradingView-Signature` if you can,
# but since TV alerts are payload-based, we check the field.
expected_sig = payload.get("signature")
if not expected_sig:
# If you didn't set up signatures, skip or fail.
return
# Simplified check (implementation depends on how you generate sig in Pine)
if expected_sig != "expected_secret_token":
raise HTTPException(status_code=401, detail="Invalid signature")
@app.post("/webhook/tradingview")
async def receive_webhook(request: Request):
payload = await request.json()
await verify_signature(request, payload)
try:
order_id = kite.place_order(
variety=kite.VARIETY_REGULAR,
exchange=kite.EXCHANGE_NFO,
tradingsymbol=payload["symbol"], # e.g., "NIFTY24FEBFUT"
transaction_type=payload["side"].upper(),
quantity=int(payload["qty"]),
product=kite.PRODUCT_MIS,
order_type=kite.ORDER_TYPE_MARKET,
tag="tv_autotrade"
)
return {"status": "success", "order_id": order_id}
except Exception as e:
print(f"Order failed: {e}")
raise HTTPException(status_code=500, detail=str(e))
Deployment & Production Readiness
Running on your local laptop is fine for testing, but for live markets, you need a stable environment. Here is a production checklist.
1. Process Management
Use a process manager like Supervisor or Systemd on Linux, or Docker. If
your script crashes, these tools will auto-restart it.
# Simple Dockerfile example
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
2. HTTPS / SSL
TradingView requires your webhook URL to be publicly accessible. You have two main options:
- Cloud Hosting (Recommended): Deploy to Heroku, Render, or AWS Lambda. These
provide HTTPS URLs automatically (e.g.,
https://my-app.herokuapp.com). - Tunneling (Dev only): Use tools like NGrok (
ngrok http 8000) to get a temporary public URL for testing. Do not use this for live trading as the URL changes every restart.
Troubleshooting KiteConnect
TokenException
Usually means your access_token has expired. Tokens are valid for
only one day (until approx 7:30 AM next day). You must re-login every morning.
NetworkException
Connection to Kite timed out. Implementing a retry logic with exponential backoff is crucial for handling temporary API blips.