├── README.md ├── get_fyers_access_token.py └── totp_image.png /README.md: -------------------------------------------------------------------------------- 1 | >*Fyers APIs official documentation: [https://myapi.fyers.in/docs/](https://myapi.fyers.in/docsv3)* 2 | >*You can create Fyers API APPs at [https://myapi.fyers.in/dashboard/](https://myapi.fyers.in/dashboard/)* 3 | 4 | 5 | >If not already, enable login via External 2FA TOTP at https://myaccount.fyers.in/ManageAccount. 6 | While enabling External 2FA TOTP, copy the TOTP KEY and scan the QR code using Google or Microsoft Authenticator, as shown below. 7 | >*If you don't want to use Authenticator app, you can generate TOTP using the code in the repo https://github.com/tkanhe/totp-generator with TOTP KEY.* 8 | 9 | ![alt text](https://github.com/tkanhe/fyers-api-access-token-v3/blob/main/totp_image.png) 10 | 11 | ### *Note:* 12 | If you have just created the app and using it first time, then go to the URL (generated by running the following code) manually in the browser and give permissions to access the app. It is a one-time process. After that, you can use the script. 13 | ``` 14 | from fyers_apiv3 import fyersModel 15 | 16 | client_id = "******" # App ID of the created app (ex., "L9NY305RTW-100") 17 | secret_key = "******" # Secret ID of the created app 18 | redirect_uri = "******" # Redircet URL you entered while creating the app (ex., "https://trade.fyers.in/api-login/redirect-uri/index.html") 19 | 20 | session = fyersModel.SessionModel(client_id=client_id, secret_key=secret_key, redirect_uri=redirect_uri, response_type="code", state="sample_state") 21 | 22 | url = session.generate_authcode() 23 | print(url) 24 | ``` 25 | 26 | ### Input parameters: 27 | ``` 28 | totp_key = "******" # totp_key (ex., "OMKRABCDCDVDFGECLWXK6OVB7T4DTKU5") 29 | username = "******" # Fyers Client ID (ex., "TK01248") 30 | pin = 1246 # four-digit PIN 31 | client_id = "******" # App ID of the created app (ex., "L9NY305RTW-100") 32 | secret_key = "******" # Secret ID of the created app 33 | redirect_uri = "******" # Redircet URL you entered while creating the app 34 | ``` 35 | 36 | ### Requirements: 37 | - Python 3.6+ 38 | - Requests ```pip install requests``` 39 | - Fyers API V3 ```pip install fyers-apiv3``` 40 | -------------------------------------------------------------------------------- /get_fyers_access_token.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import hmac 3 | import os 4 | import struct 5 | import time 6 | from urllib.parse import urlparse, parse_qs 7 | 8 | import requests 9 | from fyers_apiv3 import fyersModel 10 | 11 | totp_key = "******" # totp_key (ex., "OMKRABCDCDVDFGECLWXK6OVB7T4DTKU5") 12 | username = "******" # Fyers Client ID (ex., "TK01248") 13 | pin = 1246 # four-digit PIN 14 | client_id = "******" # App ID of the created app (ex., "L9NY305RTW-100") 15 | secret_key = "******" # Secret ID of the created app 16 | redirect_uri = "******" # Redircet URL you entered while creating the app (ex., "https://trade.fyers.in/api-login/redirect-uri/index.html") 17 | 18 | 19 | def read_file(): 20 | try: 21 | with open("fyers_token.txt", "r") as f: 22 | token = f.read().strip() 23 | return token 24 | except FileNotFoundError: 25 | return None 26 | 27 | 28 | def write_file(token): 29 | with open("fyers_token.txt", "w") as f: 30 | f.write(token) 31 | 32 | 33 | def totp(key, time_step=30, digits=6, digest="sha1"): 34 | key = base64.b32decode(key.upper() + "=" * ((8 - len(key)) % 8)) 35 | counter = struct.pack(">Q", int(time.time() / time_step)) 36 | mac = hmac.new(key, counter, digest).digest() 37 | offset = mac[-1] & 0x0F 38 | binary = struct.unpack(">L", mac[offset : offset + 4])[0] & 0x7FFFFFFF 39 | return str(binary)[-digits:].zfill(digits) 40 | 41 | 42 | def get_token(): 43 | headers = { 44 | "Accept": "application/json", 45 | "Accept-Language": "en-US,en;q=0.9", 46 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", 47 | } 48 | 49 | s = requests.Session() 50 | s.headers.update(headers) 51 | 52 | data1 = f'{{"fy_id":"{base64.b64encode(f"{username}".encode()).decode()}","app_id":"2"}}' 53 | r1 = s.post("https://api-t2.fyers.in/vagator/v2/send_login_otp_v2", data=data1) 54 | 55 | request_key = r1.json()["request_key"] 56 | data2 = f'{{"request_key":"{request_key}","otp":{totp(totp_key)}}}' 57 | r2 = s.post("https://api-t2.fyers.in/vagator/v2/verify_otp", data=data2) 58 | assert r2.status_code == 200, f"Error in r2:\n {r2.text}" 59 | 60 | request_key = r2.json()["request_key"] 61 | data3 = f'{{"request_key":"{request_key}","identity_type":"pin","identifier":"{base64.b64encode(f"{pin}".encode()).decode()}"}}' 62 | r3 = s.post("https://api-t2.fyers.in/vagator/v2/verify_pin_v2", data=data3) 63 | assert r3.status_code == 200, f"Error in r3:\n {r3.json()}" 64 | 65 | headers = {"authorization": f"Bearer {r3.json()['data']['access_token']}", "content-type": "application/json; charset=UTF-8"} 66 | data4 = f'{{"fyers_id":"{username}","app_id":"{client_id[:-4]}","redirect_uri":"{redirect_uri}","appType":"100","code_challenge":"","state":"abcdefg","scope":"","nonce":"","response_type":"code","create_cookie":true}}' 67 | r4 = s.post("https://api.fyers.in/api/v2/token", headers=headers, data=data4) 68 | assert r4.status_code == 308, f"Error in r4:\n {r4.json()}" 69 | 70 | parsed = urlparse(r4.json()["Url"]) 71 | auth_code = parse_qs(parsed.query)["auth_code"][0] 72 | 73 | session = fyersModel.SessionModel(client_id=client_id, secret_key=secret_key, redirect_uri=redirect_uri, response_type="code", grant_type="authorization_code") 74 | session.set_token(auth_code) 75 | response = session.generate_token() 76 | return response["access_token"] 77 | 78 | 79 | def get_profile(token): 80 | fyers = fyersModel.FyersModel(client_id=client_id, token=token, log_path=os.getcwd()) 81 | return fyers.get_profile() 82 | 83 | 84 | def main(): 85 | token = read_file() 86 | if token is None: 87 | token = get_token() 88 | 89 | resp = get_profile(token) 90 | 91 | if "error" in resp["s"] or "error" in resp["message"] or "expired" in resp["message"]: 92 | token = get_token() 93 | resp = get_profile(token) 94 | 95 | write_file(token) 96 | print("Fyers access token is saved in `fyers_token.txt` file.") 97 | print(resp) 98 | 99 | 100 | if __name__ == "__main__": 101 | main() 102 | -------------------------------------------------------------------------------- /totp_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkanhe/fyers-api-access-token-v3/05cd8cd26f4b04a9bce5ac93b21600a06d90572e/totp_image.png --------------------------------------------------------------------------------