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
« 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"""
5import json
6import sys
7from urllib.parse import urlencode
9import pandas as pd
10import numpy as np
11import requests
13from pycax.caxutils import (
14 build_api_url,
15 cax_baseurl,
16 cax_GET,
17 as_list,
18 stop,
19)
21from pycax import datasets
23CAX_TABLES = datasets.getdf()
25class TablesResponse:
26 """
27 A tables Response Object
28 """
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)
41 # private members
42 self.__args = args
43 self.__url = url
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
55 def to_pandas(self):
56 """
57 Convert the results into a pandas DataFrame
58 """
59 return pd.DataFrame(self.data["records"])
62def get(tablename, qargs={}, fargs={}, **kwargs):
63 """
64 Get a table using the table name from /ca/tables API
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.
70 :return: A dictionary of class TableResponse ready for execution
72 Usage::
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
80 """
81 if not isinstance(qargs, dict):
82 raise TypeError('qargs must be a dictionary; got %s' % type(qargs).__name__)
84 if not isinstance(fargs, dict):
85 raise TypeError('fargs must be a dictionary; got %s' % type(fargs).__name__)
87 if len(fargs)>0: qargs['filter'] = dict_to_json(fargs)
89 return TablesResponse(tablename, qargs)
92def getdf(tablename, qargs={}, fargs={}, **kwargs):
93 """
94 Make table query and return a pandas DataFrame
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
100 Usage::
102 from pycax import tables
103 tables.getdf('EscData')
104 """
105 query = get(tablename, qargs=qargs, fargs=fargs, **kwargs)
106 res = query.execute()
108 return query.to_pandas()
110def tableid(tablename):
111 """
112 Retrieve a table id given a tablename
114 :param tablename: [String] table name from pycax.tables.getdf()["name"]
116 :return: A table id as an array of length 1 with id as a string
118 Usage::
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?')
127 return tab.values
129def dict_to_json(fargs):
130 """
131 Convert a dictionary to JSON format for CAX API: field, value, string format
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"}]'
136 Usage::
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)
145 return json_string