Coverage for mindsdb / integrations / handlers / oilpriceapi_handler / oilpriceapi_tables.py: 0%

75 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-21 00:36 +0000

1import pandas as pd 

2from typing import List 

3from mindsdb.integrations.libs.api_handler import APITable 

4from mindsdb.integrations.utilities.handlers.query_utilities import SELECTQueryParser, SELECTQueryExecutor 

5from mindsdb.utilities import log 

6from mindsdb_sql_parser import ast 

7 

8logger = log.getLogger(__name__) 

9 

10 

11class OilPriceLatestTable(APITable): 

12 """The Latest Oil Price Table implementation""" 

13 

14 def select(self, query: ast.Select) -> pd.DataFrame: 

15 """Pulls data from the https://docs.oilpriceapi.com/guide/#prices-latest" API 

16 

17 Parameters 

18 ---------- 

19 query : ast.Select 

20 Given SQL SELECT query 

21 

22 Returns 

23 ------- 

24 pd.DataFrame 

25 latest oil price matching the query 

26 

27 Raises 

28 ------ 

29 ValueError 

30 If the query contains an unsupported condition 

31 """ 

32 

33 select_statement_parser = SELECTQueryParser( 

34 query, 

35 'latest_price', 

36 self.get_columns() 

37 ) 

38 

39 selected_columns, where_conditions, order_by_conditions, result_limit = select_statement_parser.parse_query() 

40 

41 search_params = {} 

42 subset_where_conditions = [] 

43 

44 for op, arg1, arg2 in where_conditions: 

45 if arg1 == 'by_type': 

46 if op == '=': 

47 search_params["by_type"] = arg2 

48 else: 

49 raise NotImplementedError("Only '=' operator is supported for by_type column.") 

50 

51 if not self.handler.client._is_valid_by_type(arg2): 

52 raise ValueError("Unknown value for `by_type` parameter. The allowed values are - " + self.handler.client.valid_values_by_type) 

53 

54 elif arg1 == 'by_code': 

55 if op == '=': 

56 search_params["by_code"] = arg2 

57 else: 

58 raise NotImplementedError("Only '=' operator is supported for by_code column.") 

59 

60 if not self.handler.client._is_valid_by_code(arg2): 

61 raise ValueError("Unknown value for `by_code` parameter. The allowed values are - " + self.handler.client.valid_values_by_code) 

62 

63 elif arg1 in self.get_columns(): 

64 subset_where_conditions.append([op, arg1, arg2]) 

65 

66 latest_price_df = pd.DataFrame(columns=self.get_columns()) 

67 

68 response = self.handler.client.get_latest_price(search_params.get("by_type"), search_params.get("by_code")) 

69 

70 self.check_res(res=response) 

71 

72 content = response["content"] 

73 

74 latest_price_df = pd.json_normalize(content["data"]) 

75 

76 select_statement_executor = SELECTQueryExecutor( 

77 latest_price_df, 

78 selected_columns, 

79 subset_where_conditions, 

80 order_by_conditions, 

81 result_limit 

82 ) 

83 

84 latest_price_df = select_statement_executor.execute_query() 

85 

86 return latest_price_df 

87 

88 def check_res(self, res): 

89 if res["code"] != 200: 

90 raise Exception("Error fetching results - " + res["error"]) 

91 

92 def get_columns(self) -> List[str]: 

93 """Gets all columns to be returned in pandas DataFrame responses 

94 

95 Returns 

96 ------- 

97 List[str] 

98 List of columns 

99 """ 

100 

101 return [ 

102 "price", 

103 "formatted", 

104 "currency", 

105 "code", 

106 "created_at", 

107 "type" 

108 ] 

109 

110 

111class OilPricePastDayPriceTable(APITable): 

112 """The Past Day Oil Price Table implementation""" 

113 

114 def select(self, query: ast.Select) -> pd.DataFrame: 

115 """Pulls data from the https://docs.oilpriceapi.com/guide/#prices-past-day" API 

116 

117 Parameters 

118 ---------- 

119 query : ast.Select 

120 Given SQL SELECT query 

121 

122 Returns 

123 ------- 

124 pd.DataFrame 

125 past day oil price matching the query 

126 

127 Raises 

128 ------ 

129 ValueError 

130 If the query contains an unsupported condition 

131 """ 

132 

133 select_statement_parser = SELECTQueryParser( 

134 query, 

135 'past_day_price', 

136 self.get_columns() 

137 ) 

138 

139 selected_columns, where_conditions, order_by_conditions, result_limit = select_statement_parser.parse_query() 

140 

141 search_params = {} 

142 subset_where_conditions = [] 

143 

144 for op, arg1, arg2 in where_conditions: 

145 if arg1 == 'by_type': 

146 if op == '=': 

147 search_params["by_type"] = arg2 

148 else: 

149 raise NotImplementedError("Only '=' operator is supported for by_type column.") 

150 

151 if not self.handler.client._is_valid_by_type(arg2): 

152 raise ValueError("Unknown value for `by_type` parameter. The allowed values are - " + self.handler.client.valid_values_by_type) 

153 

154 elif arg1 == 'by_code': 

155 if op == '=': 

156 search_params["by_code"] = arg2 

157 else: 

158 raise NotImplementedError("Only '=' operator is supported for by_code column.") 

159 

160 if not self.handler.client._is_valid_by_code(arg2): 

161 raise ValueError("Unknown value for `by_code` parameter. The allowed values are - " + self.handler.client.valid_values_by_code) 

162 

163 elif arg1 in self.get_columns(): 

164 subset_where_conditions.append([op, arg1, arg2]) 

165 

166 price_df = pd.DataFrame(columns=self.get_columns()) 

167 

168 response = self.handler.client.get_price_past_day(search_params.get("by_type"), search_params.get("by_code")) 

169 

170 self.check_res(res=response) 

171 

172 content = response["content"] 

173 

174 price_df = pd.json_normalize(content["data"]["prices"]) 

175 

176 select_statement_executor = SELECTQueryExecutor( 

177 price_df, 

178 selected_columns, 

179 subset_where_conditions, 

180 order_by_conditions, 

181 result_limit 

182 ) 

183 

184 price_df = select_statement_executor.execute_query() 

185 

186 return price_df 

187 

188 def check_res(self, res): 

189 if res["code"] != 200: 

190 raise Exception("Error fetching results - " + res["error"]) 

191 

192 def get_columns(self) -> List[str]: 

193 """Gets all columns to be returned in pandas DataFrame responses 

194 

195 Returns 

196 ------- 

197 List[str] 

198 List of columns 

199 """ 

200 

201 return [ 

202 "price", 

203 "formatted", 

204 "currency", 

205 "code", 

206 "created_at", 

207 "type" 

208 ]