Skip to content

Commit

Permalink
Added marimo report generation to worker
Browse files Browse the repository at this point in the history
  • Loading branch information
MitchellAV committed Jun 7, 2024
1 parent 6d729ea commit ff6390d
Show file tree
Hide file tree
Showing 15 changed files with 868 additions and 176 deletions.
1 change: 1 addition & 0 deletions compressions/1/sdt-submission/submission_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
def detect_time_shifts(
time_series, latitude=None, longitude=None, data_sampling_frequency=None
):
raise NotImplementedError("This function is not implemented yet.")
dh = DataHandler(time_series.to_frame())
dh.run_pipeline(fix_shifts=True, verbose=False, round_shifts_to_hour=False)
return dh.time_shift_analysis.correction_estimate
60 changes: 36 additions & 24 deletions ec2/insert_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@
import sys
import requests

from utility import request_to_API_w_credentials


# Fetch data from the remote API
def get_data_from_api_to_df(api_url: str, endpoint: str) -> pd.DataFrame:
response = requests.get(f"{api_url}{endpoint}")
if not response.ok:
raise ValueError(
f"Error fetching data from the API. Status code: {response.status_code} {response.content}"
)
data = response.json()
# response = requests.get(f"{api_url}{endpoint}")
# if not response.ok:
# raise ValueError(
# f"Error fetching data from the API. Status code: {response.status_code} {response.content}"
# )
# data = response.json()

data = request_to_API_w_credentials("GET", endpoint=endpoint)

# Check if the data is a dictionary of scalar values
if isinstance(data, dict) and all(np.isscalar(v) for v in data.values()):
# If it is, wrap the values in lists
Expand All @@ -33,12 +38,15 @@ def get_data_from_api_to_df(api_url: str, endpoint: str) -> pd.DataFrame:
def post_data_to_api_to_df(
api_url: str, endpoint: str, data: dict
) -> pd.DataFrame:
response = requests.post(f"{api_url}{endpoint}", json=data)
if not response.ok:
raise ValueError(
f"Error posting data to the API. Status code: {response.status_code} {response.content}"
)
data = response.json()
# response = requests.post(f"{api_url}{endpoint}", json=data)
# if not response.ok:
# raise ValueError(
# f"Error posting data to the API. Status code: {response.status_code} {response.content}"
# )
# data = response.json()

data = request_to_API_w_credentials("POST", endpoint=endpoint, data=data)

# Check if the data is a dictionary of scalar values
if isinstance(data, dict) and all(np.isscalar(v) for v in data.values()):
# If it is, wrap the values in lists
Expand Down Expand Up @@ -197,10 +205,10 @@ def __init__(

# Fetching the data
db_sys_metadata_df = get_data_from_api_to_df(
api_url, "/system_metadata/systemmetadata/"
api_url, "system_metadata/systemmetadata"
)
db_file_metadata_df = get_data_from_api_to_df(
api_url, "/file_metadata/filemetadata/"
api_url, "file_metadata/filemetadata"
)

self.config = config
Expand Down Expand Up @@ -285,7 +293,7 @@ def getAllAnalyses(self, api_url: str) -> pd.DataFrame:
List: List of all analyses.
"""

df = get_data_from_api_to_df(api_url, "/analysis/home")
df = get_data_from_api_to_df(api_url, "analysis/home")

return df

Expand Down Expand Up @@ -483,7 +491,7 @@ def updateSystemMetadataIDs(self):
"""

db_sys_metadata_df = get_data_from_api_to_df(
self.api_url, "/system_metadata/systemmetadata/"
self.api_url, "system_metadata/systemmetadata"
)

self.db_sys_metadata_df = db_sys_metadata_df
Expand Down Expand Up @@ -535,7 +543,7 @@ def updateFileMetadataIDs(self):
"""

db_file_metadata_df = get_data_from_api_to_df(
self.api_url, "/file_metadata/filemetadata/"
self.api_url, "file_metadata/filemetadata"
)

self.db_file_metadata_df = db_file_metadata_df
Expand Down Expand Up @@ -731,14 +739,18 @@ def getSystemMetadataIDs(self, api_url: str):
int: New system metadata ID.
"""

full_url = api_url + "/system_metadata/systemmetadata"
# full_url = api_url + "/system_metadata/systemmetadata"

r = requests.get(full_url)
if r.status_code != 200:
raise ValueError(
f"Error getting the system metadata from the API. Status code: {r.status_code}"
)
data = r.json()
endpoint = "system_metadata/systemmetadata"

data = request_to_API_w_credentials("GET", endpoint=endpoint)

# r = requests.get(full_url)
# if r.status_code != 200:
# raise ValueError(
# f"Error getting the system metadata from the API. Status code: {r.status_code}"
# )
# data = r.json()
new_system_id = len(data) + 1

return new_system_id
Expand Down
11 changes: 9 additions & 2 deletions ec2/insert_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,23 @@ def get_input_or_default(prompt, default_value):

config_file_path = config["config_file_path"]
file_data_folder_path = config["file_data_folder_path"]
evaluation_scripts_folder_path = config["evaluation_scripts_folder_path"]
evaluation_scripts_folder_path = config[
"evaluation_scripts_folder_path"
]
sys_metadata_file_path = config["sys_metadata_file_path"]
file_metadata_file_path = config["file_metadata_file_path"]
validation_data_folder_path = config["validation_data_folder_path"]
private_report_template_file_path = config[
"private_report_template_file_path"
]

print(f"api_url: {api_url}")
print(f"s3_url: {s3_url}")
print(f"config_file_path: {config_file_path}")
print(f"file_data_folder_path: {file_data_folder_path}")
print(f"evaluation_scripts_folder_path: {evaluation_scripts_folder_path}")
print(
f"evaluation_scripts_folder_path: {evaluation_scripts_folder_path}"
)
print(f"sys_metadata_file_path: {sys_metadata_file_path}")
print(f"file_metadata_file_path: {file_metadata_file_path}")
print(f"validation_data_folder_path: {validation_data_folder_path}")
Expand Down
3 changes: 2 additions & 1 deletion ec2/routes.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
"sys_metadata_file_path": "./time-shift-validation-hub/data/system_metadata.csv",
"file_metadata_file_path": "./time-shift-validation-hub/data/file_metadata.csv",
"evaluation_scripts_folder_path": "./evaluation_scripts",
"validation_data_folder_path": "./time-shift-validation-hub/data/validation_data"
"validation_data_folder_path": "./time-shift-validation-hub/data/validation_data",
"private_report_template_path": "./time-shift-validation-hub/data/private_report_template.py"
}
174 changes: 174 additions & 0 deletions ec2/utility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import os
import requests
import logging
from logging import Logger
from typing import Any, Callable, TypeVar
import json

T = TypeVar("T")


def is_local():
"""
Checks if the application is running locally or in an Amazon ECS environment.
Returns:
bool: True if the application is running locally, False otherwise.
"""
return "PROD" not in os.environ


IS_LOCAL = is_local()

API_BASE_URL = (
"http://api:8005" if IS_LOCAL else "http://api.pv-validation-hub.org"
)

S3_BASE_URL = "http://s3:5000/get_object/" if IS_LOCAL else "s3://"


def logger_if_able(
message: str, logger: Logger | None = None, level: str = "INFO"
):
if logger is not None:
levels_dict = {
"DEBUG": logging.DEBUG,
"INFO": logging.INFO,
"WARNING": logging.WARNING,
"ERROR": logging.ERROR,
"CRITICAL": logging.CRITICAL,
}

level = level.upper()

if level not in levels_dict:
raise Exception(f"Invalid log level: {level}")

log_level = levels_dict[level]

logger.log(log_level, message)
else:
print(message)


def request_handler(
method: str,
endpoint: str,
data: dict[str, Any] | None = None,
headers: dict[str, Any] | None = None,
logger: Logger | None = None,
):

r = method_request(method, endpoint, headers=headers, data=data)
if not r.ok:
logger_if_able(f"Error: {r.text}", logger, "ERROR")
raise Exception("Failed to get data")
json_body: dict[str, Any] = json.loads(r.text)
return json_body


def method_request(
method: str,
url: str,
data: dict[str, Any] | None = None,
headers: dict[str, Any] | None = None,
logger: Logger | None = None,
):

logger_if_able(f"{method} request to {url}", logger)

base_headers = {
"Content-Type": "application/json",
}

all_headers = {**base_headers, **headers} if headers else base_headers

body = json.dumps(data) if data else None

response = requests.request(method, url, headers=all_headers, data=body)

return response


def login_to_API(username: str, password: str, logger: Logger | None = None):

login_url = f"{API_BASE_URL}/login"

json_body = request_handler(
"POST", login_url, {"username": username, "password": password}
)

if "token" not in json_body:
logger_if_able("Token not in response", logger, "ERROR")
raise Exception("Token not in response")
token: str = json_body["token"]
return token


def with_credentials(logger: Logger | None = None):

username = os.environ.get("admin_username")
password = os.environ.get("admin_password")

if not username or not password:
raise Exception("Missing admin credentials")

api_auth_token = None
headers = {}

def decorator(func: Callable[..., T]):
# @wraps(func)
def wrapper(*args, **kwargs):
nonlocal api_auth_token
if not api_auth_token:
logger_if_able("Logging in", logger)
api_auth_token = login_to_API(username, password, logger)
headers["Authorization"] = f"Token {api_auth_token}"
kwargs["auth"] = headers
return func(*args, **kwargs)

return wrapper

return decorator


@with_credentials()
def request_to_API_w_credentials(
method: str,
endpoint: str,
data: dict[str, Any] | None = None,
headers: dict[str, Any] | None = None,
logger: Logger | None = None,
**kwargs: Any,
):

url = f"{API_BASE_URL}/{endpoint}"

auth_header: dict[str, str] | None = (
kwargs["auth"] if "auth" in kwargs else None
)

if auth_header is None:
raise Exception("No auth header found")

if headers is None:
headers = {}

headers = {**headers, **auth_header}

data = request_handler(method, url, data, headers, logger)
return data


def request_to_API(
method: str,
endpoint: str,
data: dict[str, Any] | None = None,
headers: dict[str, Any] | None = None,
logger: Logger | None = None,
):

url = f"{API_BASE_URL}/{endpoint}"

data = request_handler(method, url, data, headers, logger)
return data
16 changes: 10 additions & 6 deletions marimo/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import Any
import os
import json
import pandas as pd
from utility import (
generate_private_report_for_submission,
)
Expand All @@ -12,16 +11,21 @@
def main(action: str = "export"):
action = action.lower()

data_file_path = os.path.join(os.path.dirname(__file__), "data.json")
data_file_path = os.path.join(
os.path.dirname(__file__), "time_shifts_full_results.csv"
)

html_file_path = os.path.join(os.path.dirname(__file__), "template.html")
template_file_path = os.path.join(os.path.dirname(__file__), "template.py")

json_data: dict[str, Any] = {}
df = pd.DataFrame()

with open(data_file_path, "r") as data_file:
json_data = json.load(data_file)
df = pd.read_csv(data_file)

generate_private_report_for_submission(json_data, action, html_file_path)
generate_private_report_for_submission(
df, action, template_file_path, html_file_path
)


if __name__ == "__main__":
Expand Down
Loading

0 comments on commit ff6390d

Please sign in to comment.