GET checks into CSV files
Use a Python and the Soda Cloud API to retrieve check and dataset info from a Soda Cloud account and populate CSV files.
Last updated
Was this helpful?
Was this helpful?
python api2csv.pyStarting collection of all datasets/checks...
Fetching all datasets on page: 0
The following csv file was generated successfully: all_datasets
Fetching all checks on page 0
The following csv file was generated successfully: all_checksimport requests
import time
import sys
import pandas as pd
from datetime import datetime
# Soda Cloud account
soda_cloud_url = 'https://cloud.us.soda.io' # cloud.us.soda.io (US Customers) or cloud.soda.io (EU Customers)
soda_apikey = 'XXX' # Soda Cloud API key ID
soda_apikey_secret = 'XXX' # Soda Cloud API key secret
# The file names and file type to which you want to save the output (CSV or JSON)
datasets_filename = 'all_datasets'
checks_filename = 'all_checks'
file_type = 'csv'
# ------------------------------------------------------------------------------
if file_type not in ['csv', 'json']:
print("You must input the correct file_type: csv or json. You input "+file_type)
sys.exit()
print("Starting collection of all datasets/checks...")
datasets = []
checks = []
response_datasets = requests.get(
soda_cloud_url + '/api/v1/datasets?page=0',
auth=(soda_apikey , soda_apikey_secret)
)
if response_datasets.status_code == 401 or response_datasets.status_code == 403:
print("Unauthorized or Forbidden access. Please check your API keys and/or permissions in Soda.")
sys.exit()
# Collect all datasets
if response_datasets.status_code == 200:
dataset_pages = response_datasets.json().get('totalPages')
i = 0
while i < dataset_pages:
dq_datasets = requests.get(
soda_cloud_url + '/api/v1/datasets?page='+str(i),
auth=(soda_apikey , soda_apikey_secret))
if dq_datasets.status_code == 200:
print("Fetching all datasets on page: "+str(i))
list = dq_datasets.json().get("content")
datasets.extend(list)
i += 1
elif dq_datasets.status_code == 429:
print("API Rate Limit reached when fetching datasets on page: " +str(i)+ ". Pausing for 30 seconds.")
time.sleep(30)
# Retry fetching the same page
else:
print("Error fetching datasets on page "+str(i)+". Status code:", dq_datasets.status_code)
else:
print("Error fetching initial datasets. Status code:", response_datasets.status_code)
sys(exit)
df_datasets = pd.DataFrame(datasets)
current_time = datetime.now().strftime('%Y-%m-%d %I:%M:%S %p')
df_datasets.insert(0, 'record_created', current_time)
# Create datasets file
if file_type == 'csv':
df_datasets.to_csv(datasets_filename +'.csv', index=False)
if file_type == 'json':
df_datasets.to_json(datasets_filename +'.json', orient='records', date_format='iso', lines=False)
print(f"The following {file_type} file was generated successfully: {datasets_filename}")
# Fetch all checks
response_checks = requests.get(
soda_cloud_url + '/api/v1/checks?size=100',
auth=(soda_apikey , soda_apikey_secret))
if response_checks.status_code == 200:
check_pages = response_checks.json().get('totalPages')
i = 0
while i < check_pages:
dq_checks = requests.get(
soda_cloud_url + '/api/v1/checks?size=100&page='+str(i),
auth=(soda_apikey , soda_apikey_secret))
if dq_checks.status_code == 200:
print("Fetching all checks on page "+str(i))
check_list = dq_checks.json().get("content")
checks.extend(check_list)
i += 1
elif dq_checks.status_code == 429:
print("API Rate Limit reached when fetching checks on page: " +str(i)+ ". Pausing for 30 seconds.")
time.sleep(30)
# Retry fetching the same page
else:
print("Error fetching checks on page "+str(i)+". Status code:", dq_checks.status_code)
else:
print("Error fetching initial checks. Status code:", response_checks.status_code)
sys(exit)
df_checks = pd.DataFrame(checks)
# Clean up dataframe
df_checks.insert(0, 'record_created', current_time)
df_checks['dataset_id'] = df_checks['datasets'].apply(lambda x: x[0]['id'] if x else None)
df_checks['dataset_name'] = df_checks['datasets'].apply(lambda x: x[0]['name'] if x else None)
df_checks['dataset_url'] = df_checks['datasets'].apply(lambda x: x[0]['cloudUrl'] if x else None)
df_checks['lastCheckResultValue'] = df_checks['lastCheckResultValue'].apply(lambda x: x.get('value') if isinstance(x, dict) and 'value' in x else (x.get('valueLabel') if isinstance(x, dict) and 'valueLabel' in x else x))
df_checks['attributes'] = df_checks['attributes'].fillna({})
df_checks['check_owner'] = df_checks['owner'].apply(lambda x: x.get('firstName', '') + ' ' + x.get('lastName', '') if isinstance(x, dict) else '')
df_checks['owner_email'] = df_checks['owner'].apply(lambda x: x.get('email', '') if isinstance(x, dict) else '')
# Rename columns
df_checks.rename(columns={'id': 'check_id'}, inplace=True)
df_checks.rename(columns={'name': 'check_name'}, inplace=True)
df_checks.rename(columns={'evaluationStatus': 'check_status'}, inplace=True)
df_checks.rename(columns={'definition': 'check_definition'}, inplace=True)
df_checks.rename(columns={'cloudUrl': 'check_url'}, inplace=True)
# Add attribute names as separate columns with attribute values
for index, row in df_checks.iterrows():
attributes_dict = row['attributes']
for key in attributes_dict:
column_name = key
column_value = attributes_dict[key]
df_checks.at[index, column_name] = column_value
# Drop original columns
df_checks = df_checks.drop(columns=['attributes'])
df_checks = df_checks.drop(columns=['datasets'])
df_checks = df_checks.drop(columns=['owner'])
# Create checks file
if file_type == 'json':
df_checks.to_json(checks_filename +'.json', orient='records', date_format='iso', lines=False)
if file_type == 'csv':
df_checks.to_csv(checks_filename +'.csv', index=False)
print(f"The following {file_type} file was generated successfully: {checks_filename}")