1111from tkinter .ttk import Combobox , Button
1212from typing import Union , Optional , List , Dict , Tuple , TextIO , Any
1313
14- import bs4
1514import pandas
1615import requests
1716import streamtologger
@@ -43,8 +42,7 @@ def __init__(self, window: Tk) -> None:
4342 self .url_oc : str = "https://www.nseindia.com/option-chain"
4443 self .url_index : str = "https://www.nseindia.com/api/option-chain-indices?symbol="
4544 self .url_stock : str = "https://www.nseindia.com/api/option-chain-equities?symbol="
46- self .url_symbols : str = "https://www.nseindia.com/products-services/" \
47- "equity-derivatives-list-underlyings-information"
45+ self .url_symbols : str = "https://www.nseindia.com/api/underlying-information"
4846 self .url_icon_png : str = "https://raw.githubusercontent.com/VarunS2002/" \
4947 "Python-NSE-Option-Chain-Analyzer/master/nse_logo.png"
5048 self .url_icon_ico : str = "https://raw.githubusercontent.com/VarunS2002/" \
@@ -56,6 +54,8 @@ def __init__(self, window: Tk) -> None:
5654 'like Gecko) Chrome/80.0.3987.149 Safari/537.36' ,
5755 'accept-language' : 'en,gu;q=0.9,hi;q=0.8' ,
5856 'accept-encoding' : 'gzip, deflate, br' }
57+ self .session : requests .Session = requests .Session ()
58+ self .cookies : Dict [str , str ] = {}
5959 self .get_symbols (window )
6060 self .config_parser : configparser .ConfigParser = configparser .ConfigParser ()
6161 self .create_config (new = True ) if not os .path .isfile ('NSE-OCA.ini' ) else None
@@ -70,8 +70,6 @@ def __init__(self, window: Tk) -> None:
7070 'Time' , 'Value' , f'Call Sum ({ self .units_str } )' , f'Put Sum ({ self .units_str } )' ,
7171 f'Difference ({ self .units_str } )' ,
7272 f'Call Boundary ({ self .units_str } )' , f'Put Boundary ({ self .units_str } )' , 'Call ITM' , 'Put ITM' )
73- self .session : requests .Session = requests .Session ()
74- self .cookies : Dict [str , str ] = {}
7573 self .toaster : win10toast .ToastNotifier = win10toast .ToastNotifier () if is_windows_10_or_11 else None
7674 self .get_icon ()
7775 self .login_win (window )
@@ -88,41 +86,23 @@ def create_error_window(error_window: Tk):
8886 error_window .destroy ()
8987
9088 try :
91- symbols_information : requests .Response = requests .get (self .url_symbols , headers = self .headers )
89+ request : requests .Response = self .session .get (self .url_oc , headers = self .headers , timeout = 5 )
90+ self .cookies = dict (request .cookies )
91+ response : requests .Response = self .session .get (self .url_symbols , headers = self .headers , timeout = 5 ,
92+ cookies = self .cookies )
9293 except Exception as err :
9394 print (err , sys .exc_info ()[0 ], "19" )
9495 create_error_window (window )
9596 sys .exit ()
96- symbols_information_soup : bs4 .BeautifulSoup = bs4 .BeautifulSoup (symbols_information .content , "html.parser" )
9797 try :
98- symbols_table : bs4 .element .Tag = symbols_information_soup .findChildren ('table' )[0 ]
99- except IndexError as err :
98+ json_data : Dict [str , Dict [str , List [Dict [str , Union [str , int ]]]]] = response .json ()
99+ except Exception as err :
100+ print (response )
100101 print (err , sys .exc_info ()[0 ], "20" )
101102 create_error_window (window )
102103 sys .exit ()
103- symbols_table_rows : List [bs4 .element .Tag ] = list (symbols_table .findChildren (['th' , 'tr' ]))
104- symbols_table_rows_str : List [str ] = ['' for _ in range (len (symbols_table_rows ) - 1 )]
105- for column in range (len (symbols_table_rows ) - 1 ):
106- symbols_table_rows_str [column ] = str (symbols_table_rows [column ])
107- divider_row : str = '<tr>\n ' \
108- '<td colspan="3"><strong>Derivatives on Individual Securities</strong></td>\n ' \
109- '</tr>'
110- for column in range (4 , symbols_table_rows_str .index (divider_row ) + 1 ):
111- cells : bs4 .element .ResultSet = symbols_table_rows [column ].findChildren ('td' )
112- column : int = 0
113- for cell in cells :
114- if column == 2 :
115- self .indices .append (cell .string )
116- column += 1
117- for column in reversed (range (symbols_table_rows_str .index (divider_row ) + 1 )):
118- symbols_table_rows .pop (column )
119- for row in symbols_table_rows :
120- cells : bs4 .element .ResultSet = row .findChildren ('td' )
121- column : int = 0
122- for cell in cells :
123- if column == 2 :
124- self .stocks .append (cell .string )
125- column += 1
104+ self .indices = [item ['symbol' ] for item in json_data ['data' ]['IndexList' ]]
105+ self .stocks = [item ['symbol' ] for item in json_data ['data' ]['UnderlyingList' ]]
126106
127107 def get_icon (self ) -> None :
128108 self .icon_png_path : str
@@ -331,7 +311,6 @@ def get_data(self, event: Optional[Event] = None) -> Optional[Tuple[Optional[req
331311 return self .get_data_refresh ()
332312
333313 def get_data_first_run (self ) -> Optional [Tuple [Optional [requests .Response ], Any ]]:
334- request : Optional [requests .Response ] = None
335314 response : Optional [requests .Response ] = None
336315 self .units_str = 'in K' if self .option_mode == 'Index' else 'in 10s'
337316 self .output_columns : Tuple [str , str , str , str , str , str , str , str , str ] = (
@@ -354,11 +333,8 @@ def get_data_first_run(self) -> Optional[Tuple[Optional[requests.Response], Any]
354333
355334 url : str = self .url_index + self .index if self .option_mode == 'Index' else self .url_stock + self .stock
356335 try :
357- request = self .session .get (self .url_oc , headers = self .headers , timeout = 5 )
358- self .cookies = dict (request .cookies )
359336 response = self .session .get (url , headers = self .headers , timeout = 5 , cookies = self .cookies )
360337 except Exception as err :
361- print (request )
362338 print (response )
363339 print (err , sys .exc_info ()[0 ], "1" )
364340 messagebox .showerror (title = "Error" , message = "Error in fetching dates.\n Please retry." )
@@ -367,7 +343,7 @@ def get_data_first_run(self) -> Optional[Tuple[Optional[requests.Response], Any]
367343 self .date_menu .config (values = tuple (self .dates ))
368344 self .date_menu .current (0 )
369345 return
370- json_data : Any
346+ json_data : Dict [ str , Any ]
371347 if response is not None :
372348 try :
373349 json_data = response .json ()
@@ -541,8 +517,6 @@ def change_option_mode(self) -> None:
541517 self .index_menu .config (state = 'readonly' )
542518 self .stock_menu .config (state = DISABLED )
543519
544- self .get_data ()
545-
546520 self .config_parser .set ('main' , 'option_mode' , f'{ self .option_mode } ' )
547521 with open ('NSE-OCA.ini' , 'w' ) as f :
548522 self .config_parser .write (f )
0 commit comments