Coverage for /home/runner/work/pycax/pycax/pycax/tables/tables.py: 98%

45 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-26 00:27 +0000

1""" 

2Get a table from the API via table_id 

3""" 

4 

5import json 

6import sys 

7from urllib.parse import urlencode 

8 

9import pandas as pd 

10import numpy as np 

11import requests 

12 

13from pycax.caxutils import ( 

14 build_api_url, 

15 cax_baseurl, 

16 cax_GET, 

17 as_list, 

18 stop, 

19) 

20 

21from pycax import datasets 

22 

23CAX_TABLES = datasets.getdf() 

24 

25class TablesResponse: 

26 """ 

27 A tables Response Object 

28 """ 

29 

30 def __init__(self, tablename, args): 

31 """ 

32 Initialise the object parameters 

33 """ 

34 self.data = None 

35 self.tablename = tablename 

36 self.tableid = tableid(tablename)[0] 

37 args['table_id'] = self.tableid 

38 url = cax_baseurl + "ca" 

39 self.api_url = build_api_url(url, args) 

40 

41 # private members 

42 self.__args = args 

43 self.__url = url 

44 

45 def execute(self, **kwargs): 

46 """ 

47 Execute or fetch the data based on the query 

48 """ 

49 out = cax_GET( 

50 self.__url, self.__args, **kwargs 

51 ) 

52 self.data = out 

53 return self.data 

54 

55 def to_pandas(self): 

56 """ 

57 Convert the results into a pandas DataFrame 

58 """ 

59 return pd.DataFrame(self.data["records"]) 

60 

61 

62def get(tablename, qargs={}, fargs={}, **kwargs): 

63 """ 

64 Get a table using the table name from /ca/tables API 

65 

66 :param tablename: [String] A table name listed in the datasets table 

67 :param qargs: [dict] a dictionary of query parameters. The default is no parameters. See usage for common query parameters 

68 :param fargs: [dict] a dictionary of filter values as {colname1: value}, {colname1: [value1, value2]} or {colname1: value, colname2: value}. The default is no filter. See usage for examples. 

69 

70 :return: A dictionary of class TableResponse ready for execution 

71 

72 Usage:: 

73 

74 from pycax import tables 

75 query = tables.get('EscData', qargs={'limit': 1}) 

76 query.execute() 

77 query.data # get the data 

78 query.api_url # get the API url 

79 

80 """ 

81 if not isinstance(qargs, dict): 

82 raise TypeError('qargs must be a dictionary; got %s' % type(qargs).__name__) 

83 

84 if not isinstance(fargs, dict): 

85 raise TypeError('fargs must be a dictionary; got %s' % type(fargs).__name__) 

86 

87 if len(fargs)>0: qargs['filter'] = dict_to_json(fargs) 

88 

89 return TablesResponse(tablename, qargs) 

90 

91 

92def getdf(tablename, qargs={}, fargs={}, **kwargs): 

93 """ 

94 Make table query and return a pandas DataFrame 

95 

96 :param qargs: [dict] a dictionary of query parameters. The default is no parameters which returns the full table. 

97 :param fargs: [dict] a dictionary of filter values as {colname1: value}, {colname1: [value1, value2]} or {colname1: value, colname2: value}. The default is no filter. See usage for examples. 

98 :return: A pandas DataFrame 

99 

100 Usage:: 

101 

102 from pycax import tables 

103 tables.getdf('EscData') 

104 """ 

105 query = get(tablename, qargs=qargs, fargs=fargs, **kwargs) 

106 res = query.execute() 

107 

108 return query.to_pandas() 

109 

110def tableid(tablename): 

111 """ 

112 Retrieve a table id given a tablename 

113 

114 :param tablename: [String] table name from pycax.tables.getdf()["name"] 

115 

116 :return: A table id as an array of length 1 with id as a string 

117 

118 Usage:: 

119 

120 from pycax import tables 

121 tables.tableid("NOSA") 

122 """ 

123 tab = CAX_TABLES[CAX_TABLES['name']==tablename]['id'] 

124 if not 1 == len(tab): 

125 stop('Something wrong; no table id returned. Did you misspell the table name?') 

126 

127 return tab.values 

128 

129def dict_to_json(fargs): 

130 """ 

131 Convert a dictionary to JSON format for CAX API: field, value, string format 

132 

133 :param fargs: [dict] a dictionary of filter values as {colname1: value}, {colname1: [value1, value2]} or {colname1: value, colname2: value}. The default is no filter. See usage for examples. 

134 :return: JSON for the filter in the format that CAX API wants: '[{"field": "popid", "value": 7, "type": "string"}]' 

135 

136 Usage:: 

137 

138 from pycax import tables 

139 tables.dict_to_json({'popid':7}) 

140 """ 

141 # The CAX API requires that the filter be in a specific format 

142 array = [ {'field' : i, 'value' : fargs[i], 'type': 'string' if len(as_list(fargs[i]))<2 else 'list'} for i in fargs] 

143 json_string = json.dumps(array, default=lambda x: x.item() if isinstance(x, np.generic) else x) 

144 

145 return json_string