osparamatrix / ks-orderapi-python

47 stars 59 forks source link

Working code for 2FA login without OTP #39

Open algowhizz opened 3 years ago

algowhizz commented 3 years ago

Hi, I just saw that lot of people were looking for a way to login without a new OTP everyday. Kotak session_API allows us to do exactly that by using OTT (one time token) instead of OTP. I have made a script to login without OTP which you can find here : https://github.com/algowhizz/kotakapi/blob/master/2fa_ott_login.py

Before placing orders or any other operation, you have to pass the "user_session_token" to client using client.set_session_token function that I recently added to my fork of official Kotak repository. As an example :

client = ks_api.KSTradeApi(access_token = access_token, userid = user_id, 
                                        consumer_key = consumer_key, ip = kotak_ip, app_id = kotak_appId)
client.set_session_token(session_token=user_session_token)

You can check and install the fork from here : https://github.com/algowhizz/ks-orderapi-python Function that I added : https://github.com/algowhizz/ks-orderapi-python/commit/4cb939f41c3e2003daa69d72aaffab64c86fd0bd

nishu88 commented 3 years ago

What should be the kotak_ip? Currently im getting this error {"fault":{"code":99999,"description":"Session token is either expired or not correct","message":"You have been logged out. Login again"}}

algowhizz commented 3 years ago

Kotak IP could be anything , I am using 1.1.1.1 Regarding your error, make sure you are generating the session token properly https://github.com/algowhizz/kotakapi/blob/52a27c0e5986c8c3e4428198625df5921387120f/2fa_ott_login.py#L36 and then using the same to initialize the client. It is working fine for me.

nishu88 commented 3 years ago

Generating session tokens {'success': {'advancedChart': {'host': ' ', 'port': 443}, 'apiToken': {'redirect': {'host': 'https://cksapi.kotaksecurities.com', 'port': 443}, 'sessionId': 'XXXX128#0-192111'}, 'broadcast': {'host': ' ', 'port': 443}, 'clientCode': 'XXXXX', 'clientName': 'XXXXX XXXX', 'emailId': '-', 'enabledProducts': ['NORMAL', 'SUPERMULTIPLE', 'SUPERMULTIPLEOPTION', 'MTF', 'MIS'], 'enabledSegments': ['CASH', 'FO', 'CDS'], 'getLtp': {'host': ' ', 'port': 443}, 'isNRI': 'N', 'loginTime': '9/2/2021 12:11:38 PM', 'marketData': {'host': ' ', 'port': 443}, 'phoneNo': '-', 'redirect': {'host': 'https://ctradeapi.kotaksecurities.com/apim', 'port': 443}, 'search': {'host': ' ', 'port': 443}, 'service': {'host': 'https://tradeapi.kotaksecurities.com/apim', 'port': 443}, 'sessionToken': '75E3DXXXBXXXF140E98XXX8XXXXXX', 'stwtFlag': '-', 'userId': 'NAXXXXXX', 'weblink': {'host': 'https://mtrade.kotaksecurities.com/', 'port': 443}}} Sessions token generated

No luck, the json_response() looks like this. But when i use the session token.. it says {"fault":{"code":99999,"description":"Session token is either expired or not correct","message":"You have been logged out. Login again"}}

algowhizz commented 3 years ago

Have you installed my fork and are you using this exact format :

client = ks_api.KSTradeApi(access_token = access_token, userid = user_id, 
                                        consumer_key = consumer_key, ip = kotak_ip, app_id = kotak_appId)
client.set_session_token(session_token=user_session_token)

This should work as I am using it since 3 days now.

algowhizz commented 3 years ago

I would suggest you to check the output of get_kotak_session_token() or first try to provide session_token as a simple string like below : client.set_session_token(session_token='75E3DXXXBXXXF140E98XXX8XXXXXX')

nishu88 commented 3 years ago

Tried this as well, NO luck :( I think its got to do with how to run the code... I think my session is getting expired as soon as i create it.

nishu88 commented 3 years ago

UPDATE:

{'success': [{'wtoken': '11717', 'ltp': '36761.1500', 'lv_net_chg': '-0.7015', 'lv_net_chg_perc': '-0.0019046300293500365', 'open_price': '', 'closing_price': '36831.3000', 'high_price': '', 'low_price': '', 'average_trade_price': '', 'last_trade_qty': '', 'BD_last_traded_time': '03/09/2021 15:31:23', 'OI': '', 'BD_TTQ': '', 'market_exchange': 'NSE', 'stk_name': 'NIFTY BANK', 'display_segment': 'EQ', 'display_fno_eq': ''}]}

Traceback (most recent call last):
  File "test_session.py", line 62, in <module>
    positions = (client.positions(position_type = "OPEN"))
  File "/usr/local/lib/python3.8/dist-packages/ks_api_client/ks_api.py", line 173, in positions
    positions_res = ks_api_client.PositionsApi(self.api_client).positions_open(self.consumer_key,self.session_token)
  File "/usr/local/lib/python3.8/dist-packages/ks_api_client/api/positions_api.py", line 196, in positions_open
    return self.positions_open_with_http_info(consumerKey, sessionToken, **kwargs)  # noqa: E501
  File "/usr/local/lib/python3.8/dist-packages/ks_api_client/api/positions_api.py", line 291, in positions_open_with_http_info
    return self.api_client.call_api(
  File "/usr/local/lib/python3.8/dist-packages/ks_api_client/api_client.py", line 354, in call_api
    return self.__call_api(resource_path, method,
  File "/usr/local/lib/python3.8/dist-packages/ks_api_client/api_client.py", line 173, in __call_api
    raise e
  File "/usr/local/lib/python3.8/dist-packages/ks_api_client/api_client.py", line 166, in __call_api
    response_data = self.request(
  File "/usr/local/lib/python3.8/dist-packages/ks_api_client/api_client.py", line 380, in request
    return self.rest_client.GET(url,
  File "/usr/local/lib/python3.8/dist-packages/ks_api_client/rest.py", line 220, in GET
    return self.request("GET", url,
  File "/usr/local/lib/python3.8/dist-packages/ks_api_client/rest.py", line 214, in request
    raise ApiException(status = r.status, reason = r.reason, body = r.data)
ks_api_client.exceptions.ApiException: (401)
Reason: Unauthorized
HTTP response body: {"fault":{"code":99999,"description":"Session token is either expired or not correct","message":"You have been logged out. Login again"}}

The Quotes API works but not the positions API.

nishu88 commented 3 years ago

@algowhizz Can you confirm if this works for you?

positions = (client.positions(position_type = "OPEN"))
algowhizz commented 3 years ago

Yes, positions API is working for me.

AN-18 commented 3 years ago

Hi @algowhizz, I tried your this code https://github.com/algowhizz/kotakapi/blob/master/2fa_ott_login.py got the response 'sessions token generated' but where i can see this token

algowhizz commented 2 years ago

It is stored in variable user_session_token. You can print it to see the token.

Algotrader77 commented 2 years ago

I was looking for this all over! Thanks for this. However, I have a problem. I ran your code and was able to generate a session token successfully. However, when the following code runs, I get an error.

client = ks_api.KSTradeApi(access_token = access_token, userid = user_id, consumer_key = consumer_key, ip = kotak_ip, app_id = kotak_appId)

client.set_session_token(session_token=user_session_token)

Traceback (most recent call last): File "E:\Algo\AlgoBase\Kotakautologin.py", line 46, in client.set_session_token(session_token=user_session_token) AttributeError: 'KSTradeApi' object has no attribute 'set_session_token'

Because,, my understanding is that only after the session token is set, i will be able to execute other api calls like positions, orders, etc.

Pls help

algowhizz commented 2 years ago

Hi, I am glad you found it useful. You need to either clone the repository from my fork or add a function to your own fork/clone like below :

https://github.com/osparamatrix/ks-orderapi-python/pull/40/commits/4cb939f41c3e2003daa69d72aaffab64c86fd0bd

Check the highlighted changes in the commit.

Algotrader77 commented 2 years ago

Worked like a charm. Fantastic. Thank you so much for this. I had been looking for an autologin feature for Kotak and finally found a solution, thank to you!

pv-ajay-thota commented 2 years ago

Hi I am also getting the below error.. I was able to set the session token.. but If I make any request.. like Positions..

FYI.. I have used your fork.. I am not sure why it is getting logged out..

>>> client.margin_required(transaction_type="BUY", order_info=order_info)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\Work\zzz_others\projects1\ksec-trade\.venv\lib\site-packages\ks_api_client\ks_api.py", line 349, in margin_required     
    margin_required = ks_api_client.MarginApi(self.api_client).margin_required(
  File "D:\Work\zzz_others\projects1\ksec-trade\.venv\lib\site-packages\ks_api_client\api\margin_api.py", line 56, in margin_required
    return self.margin_required_with_http_info(consumerKey, sessionToken, **kwargs)  # noqa: E501
  File "D:\Work\zzz_others\projects1\ksec-trade\.venv\lib\site-packages\ks_api_client\api\margin_api.py", line 160, in margin_required_with_http_info
    return self.api_client.call_api(
  File "D:\Work\zzz_others\projects1\ksec-trade\.venv\lib\site-packages\ks_api_client\api_client.py", line 354, in call_api        
    return self.__call_api(resource_path, method,
  File "D:\Work\zzz_others\projects1\ksec-trade\.venv\lib\site-packages\ks_api_client\api_client.py", line 173, in __call_api      
    raise e
  File "D:\Work\zzz_others\projects1\ksec-trade\.venv\lib\site-packages\ks_api_client\api_client.py", line 166, in __call_api      
    response_data = self.request(
  File "D:\Work\zzz_others\projects1\ksec-trade\.venv\lib\site-packages\ks_api_client\api_client.py", line 398, in request
    return self.rest_client.POST(url,
  File "D:\Work\zzz_others\projects1\ksec-trade\.venv\lib\site-packages\ks_api_client\rest.py", line 255, in POST
    return self.request("POST", url,
  File "D:\Work\zzz_others\projects1\ksec-trade\.venv\lib\site-packages\ks_api_client\rest.py", line 214, in request
    raise ApiException(status = r.status, reason = r.reason, body = r.data)
ks_api_client.exceptions.ApiException: (401)
Reason: Unauthorized
HTTP response body: {"fault":{"code":99999,"description":"Session token is either expired or not correct","message":"You have been 
logged out of your account due to inactivity or have logged into another device. Kindly re-login."}}