def get_stock_codes(self, cached=True, as_json=False): """ returns a dictionary with key as stock code and value as stock name. It also implements cache functionality and hits the server only if user insists or cache is empty :return: dict """ url = self.stocks_csv_url req = Request(url, None, self.headers) res_dict = {} if cached is not True or self.__CODECACHE__ is None: # raises HTTPError and URLError res = self.opener.open(req) if res is not None: # for py3 compat covert byte file like object to # string file like object res = byte_adaptor(res) for line in res.read().split('\n'): if line != '' and re.search(',', line): (code, name) = line.split(',')[0:2] res_dict[code] = name # else just skip the evaluation, line may not be a valid csv else: raise Exception('no response received') self.__CODECACHE__ = res_dict return self.render_response(self.__CODECACHE__, as_json)
def get_index_quote(self, code, as_json=False): """ params: code : string index code as_json: True|False returns: a dict | json quote for the given index """ url = self.index_url if self.is_valid_index(code): req = Request(url, None, self.headers) # raises HTTPError and URLError resp = self.opener.open(req) resp = byte_adaptor(resp) resp_list = json.load(resp)['data'] # this is list of dictionaries resp_list = [ self.clean_server_response(item) for item in resp_list ] # search the right list element to return search_flag = False for item in resp_list: if item['name'] == code.upper(): search_flag = True break return self.render_response(item, as_json) if search_flag else None
def get_index_list(self, as_json=False): """ get list of indices and codes params: as_json: True | False returns: a list | json of index codes """ url = self.index_url req = Request(url, None, self.headers) # raises URLError or HTTPError resp = self.opener.open(req) resp = byte_adaptor(resp) resp_list = json.load(resp)['data'] index_list = [str(item['name']) for item in resp_list] return self.render_response(index_list, as_json)
def get_advances_declines(self, as_json=False): """ :return: a list of dictionaries with advance decline data :raises: URLError, HTTPError """ url = self.advances_declines_url req = Request(url, None, self.headers) # raises URLError or HTTPError resp = self.opener.open(req) # for py3 compat covert byte file like object to # string file like object resp = byte_adaptor(resp) resp_dict = json.load(resp) resp_list = [ self.clean_server_response(item) for item in resp_dict['data'] ] return self.render_response(resp_list, as_json)
def get_top_losers(self, as_json=False): """ :return: a list of dictionaries containing top losers of the day """ url = self.top_loser_url req = Request(url, None, self.headers) # this can raise HTTPError and URLError res = self.opener.open(req) # for py3 compat covert byte file like object to # string file like object res = byte_adaptor(res) res_dict = json.load(res) # clean the output and make appropriate type conversions res_list = [ self.clean_server_response(item) for item in res_dict['data'] ] return self.render_response(res_list, as_json)
def get_quote(self, code, as_json=False): """ gets the quote for a given stock code :param code: :return: dict or None :raises: HTTPError, URLError """ code = code.upper() if self.is_valid_code(code): url = self.build_url_for_quote(code) req = Request(url, None, self.headers) # this can raise HTTPError and URLError, but we are not handling it # north bound APIs should use it for exception handling res = self.opener.open(req) # for py3 compat covert byte file like object to # string file like object res = byte_adaptor(res) # Now parse the response to get the relevant data match = re.search(\ r'\{<div\s+id="responseDiv"\s+style="display:none">\s+(\{.*?\{.*?\}.*?\})', res.read(), re.S ) # ast can raise SyntaxError, let's catch only this error try: buffer = match.group(1) buffer = js_adaptor(buffer) response = self.clean_server_response( ast.literal_eval(buffer)['data'][0]) except SyntaxError as err: raise Exception('ill formatted response') else: return self.render_response(response, as_json) else: return None