From 32bf257a24bf26d583eadaba149789f0af59af5c Mon Sep 17 00:00:00 2001 From: Ruge Li Date: Thu, 6 Jul 2023 14:12:09 -0700 Subject: [PATCH] store results to S3 and firebase --- cellpack/autopack/AWSHandler.py | 42 +++++++++++++++++ cellpack/autopack/FirebaseHandler.py | 12 +++++ .../upy/simularium/simularium_helper.py | 45 ++++++++++++------- 3 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 cellpack/autopack/AWSHandler.py diff --git a/cellpack/autopack/AWSHandler.py b/cellpack/autopack/AWSHandler.py new file mode 100644 index 000000000..2ea313c48 --- /dev/null +++ b/cellpack/autopack/AWSHandler.py @@ -0,0 +1,42 @@ +import logging +import boto3 +from botocore.exceptions import ClientError +import os + +class AWSHandler(object): + """ + Handles all the AWS S3 operations + """ + + def __init__(self, bucket_name, aws_access_key_id=None, aws_secret_access_key=None, region_name=None): + self.bucket_name = bucket_name + self.s3_client = boto3.client( + 's3', + aws_access_key_id=aws_access_key_id, + aws_secret_access_key=aws_secret_access_key, # TODO: check how do we want to handle credentials? + region_name=region_name + ) + + + def upload_file(self, file_name, folder_name=None, object_name=None): + """Upload a file to an S3 bucket + + :param file_name: File to upload + :param bucket: Bucket to upload to + :param object_name: S3 object name. If not specified then file_name is used + :return: True if file was uploaded, else False + """ + + # If S3 object_name was not specified, use file_name + if object_name is None: + object_name = folder_name + os.path.basename(file_name) + else: + object_name = folder_name + object_name + + # Upload the file + try: + response = self.s3_client.upload_file(file_name, self.bucket_name, object_name) + except ClientError as e: + logging.error(e) + return False + return True \ No newline at end of file diff --git a/cellpack/autopack/FirebaseHandler.py b/cellpack/autopack/FirebaseHandler.py index e42955024..e7d60cfbc 100644 --- a/cellpack/autopack/FirebaseHandler.py +++ b/cellpack/autopack/FirebaseHandler.py @@ -42,6 +42,14 @@ def get_creds(): if creds is None or "firebase" not in creds: creds = FirebaseHandler.write_creds_path() return creds["firebase"] + + @staticmethod + def get_username(): + creds = read_json_file("./.creds") + try: + return creds["username"] + except KeyError: + raise ValueError("No username found in .creds file") def db_name(self): return self.name @@ -53,6 +61,10 @@ def doc_id(doc): @staticmethod def create_path(collection, doc_id): return f"firebase:{collection}/{doc_id}" + + @staticmethod + def create_timestamp(): + return firestore.SERVER_TIMESTAMP @staticmethod def get_path_from_ref(doc): diff --git a/cellpack/autopack/upy/simularium/simularium_helper.py b/cellpack/autopack/upy/simularium/simularium_helper.py index a0c6f9bf9..7c44d0fbc 100644 --- a/cellpack/autopack/upy/simularium/simularium_helper.py +++ b/cellpack/autopack/upy/simularium/simularium_helper.py @@ -17,13 +17,12 @@ ) from simulariumio.cellpack import CellpackConverter, HAND_TYPE from simulariumio.constants import DISPLAY_TYPE, VIZ_TYPE +from cellpack.autopack.FirebaseHandler import FirebaseHandler from cellpack.autopack.upy import hostHelper +from cellpack.autopack.AWSHandler import AWSHandler import collada -import boto3 -import logging - class Instance: def __init__(self, name, instance_id, unique_id, radius, viz_type, mesh=None): @@ -1334,8 +1333,11 @@ def writeToFile(self, file_name, bb, recipe_name, version): time_units=UnitData("ns"), # nanoseconds spatial_units=UnitData("nm"), # nanometers ) - print("simularium helper---", vars(converted_data)) TrajectoryConverter(converted_data).save(file_name, False) + print("file--", file_name) + simularium_file = file_name + ".simularium" + print("sim_file", simularium_file) + # simulariumHelper.store_results_to_s3(simularium_file,folder_name="simularium/") def raycast(self, **kw): intersect = False @@ -1350,15 +1352,28 @@ def raycast(self, **kw): def raycast_test(self, obj, start, end, length, **kw): return - # def store_results_in_s3(bucket_name, file_name, object_name=None): - # if object_name is None: - # object_name = file_name - - # s3_client = boto3.client("3s") - # try: - # response = s3_client.upload_file(file_name, bucket_name, object_name) - # except ClientError as e: - # logging.error(e) - # return False - # return True + @staticmethod + def store_results_to_s3(file_name, folder_name=None, object_name=None): + handler = AWSHandler( + bucket_name="cellpack-results", + aws_access_key_id=os.environ.get("AWS_ACCESS_KEY_ID"), + aws_secret_access_key=os.environ.get("AWS_SECRET_ACCESS_KEY"), + region_name="us-west-2", + ) + print(handler.upload_file(file_name,folder_name,object_name)) + + def upload_metadata_to_firebase(result_name, aws_url): + db = FirebaseHandler() + username = db.get_username() + timestamp = db.create_timestamp() + db.set_doc( + "results", + result_name, + { + "user": username, + "created": timestamp, + "aws_url": aws_url + } + ) + upload_metadata_to_firebase("testing result2", "testing_url2")