Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- import datetime
- import time
- import yaml
- import os
- import urllib
- import requests
- import json
- import pandas as pd
- import boto3
- S3_CONFIG_FILE = "s3cfg.yml"
- CONFIG_FILE = "config.cfg"
- client = boto3.client('s3')
- class Breed:
- ### Private Variables ###
- __environment = None
- __api_url = None
- __onboarding_api_url = None
- __species_id = None
- __species_name = None
- __partner_id = None
- __partner_name = None
- __trait_id = None
- __dataset_id = None
- __trait_name = None
- __speciesDF = None
- __partnersDF = None
- __UOMlistDF = None
- __genotype_dataDF = None
- __phenotypesDF = None
- __onboarding_eventsDF = None
- __onboarding_event_raw_dataDF = None
- __onboarding_event_trait_raw_dataDF = None
- __onboarding_projectsDF = None
- __end_point_paths = None
- __api_urls = None
- __onboarding_api_urls = None
- __onboarding_comp_bio_microservice_api_url = None
- __onboarding_comp_bio_microservice_api_urls = None
- __s3buckets = None
- __current_time = datetime.datetime.now(),
- __species_germplasmsDF = None
- __user_name = None
- __germplasm_groupsDF = None
- def __init__(self, user_name=None, env=None, specie_id=None, partner_id=None, trait_id=None, dataset_id=None):
- # below loads end point paths to url to various environments
- self.__load_configurations()
- # self.__load_s3_configurations()
- if user_name:
- self.set_user(user_name)
- if env:
- self.set_environment(env)
- if specie_id:
- self.set_specie(specie_id)
- if partner_id:
- print('partner_id___________________',partner_id)
- self.set_partner(partner_id)
- if dataset_id:
- # this is required
- self.set_dataset_id(dataset_id)
- if trait_id:
- # this is required
- self.set_trait(trait_id)
- # def private(self):
- def __get_configurations(self):
- # config below used to be stored in separate yaml file but with this package
- # needed to deployed it's best to just store these locally
- with open(CONFIG_FILE) as f:
- config = yaml.load(f, Loader=yaml.FullLoader)
- return config
- def __load_configurations(self):
- print('----------------')
- config = self.__get_configurations()
- if not config:
- print("Error: attempt to get configuation from .loadLocalConfigurations failed")
- return
- print(config)
- self.__end_point_paths = config.get('endPointPaths')
- self.__api_urls = config.get('apiUrls')
- self.__s3buckets = config.get('s3buckets')
- self.__onboarding_api_urls = config.get('onboardingApiUrls')
- self.__onboarding_comp_bio_microservice_api_urls = config.get('onboardingCompBioMicroserviceApiUrls')
- def __load_s3_configurations(self):
- with open(S3_CONFIG_FILE) as f:
- config = yaml.load(f, Loader=yaml.FullLoader)
- if config:
- required_keys = ["access_key", "secret_key"]
- for key in required_keys:
- if not hasattr(config, key):
- print(f"Error: expected to find {key} in {S3_CONFIG_FILE} but did not find it")
- return
- os.environ["AWS_ACCESS_KEY_ID"] = config["access_key"]
- os.environ["AWS_SECRET_ACCESS_KEY"] = config["secret_key"]
- os.environ["AWS_DEFAULT_REGION"] = "us-east-1"
- print('\nS3config file found and successfully loaded')
- def __validate_internal_settings(self):
- # private variables below should be set by functions initialized by .initialize function
- variables = ["speciesId", "speciesName", "partnerId", "partnerName", "userName",
- "environment", "apiUrl", "datasetId", "onboardingApiUrl"]
- # TODO: continue this implementation
- def __update_url_path(self, url, path):
- parsed_url = urllib.parse.urlparse(url)
- print('-----------------',parsed_url)
- updated_url = parsed_url._replace(path=path,scheme='http',netloc='cropos-breed-api.us-east-1.elasticbeanstalk.com',params='',query='',fragment='',)
- print("-----------------------------------------",updated_url.geturl())
- return updated_url.geturl()
- def __validated_api_end_point_response(self, api_end_point):
- resp = requests.get(api_end_point)
- if resp.status_code != 200:
- print(f"Error: attempt to connect to apiEndPoint {api_end_point} failed with status: {resp.status_code}")
- return
- try:
- return resp.json()
- except:
- print(f"Error: {api_end_point} did not return json data")
- def __validate_url(self, url):
- try:
- resp = requests.get(url)
- except Exception as e:
- print(f"URL does not seem to exist: {url}",e)
- finally:
- print(f"\nValidating URL: {url}")
- return resp
- def __validate_dataframe_has_content(self, df):
- if df.empty:
- print("Error: attempt to validate data frame returned null")
- return False
- if not df.shape[1]:
- print("Error: data frame does not contain any columns")
- return False
- if not df.shape[0]:
- print("Error: data frame does not contain any rows")
- return False
- return True
- def set_user(self, user_name):
- if user_name:
- self.__user_name = user_name
- else:
- user_name = input("Please enter user Name: ")
- if not self.__user_name:
- print(f"User set to: {user_name}")
- else:
- print(f"User updated to: {self.__user_name} to {user_name}")
- self.__user_name = user_name
- def set_specie(self, specie_id):
- path = self.__end_point_paths['SpeciesPath']
- if not path:
- print("Error: failed to get 'SpeciesPath' end point path from config file")
- # make user environment is set bec specie can vary from env to env
- if not self.__api_url:
- print("Environment has not been set internally. Please run $setEnvironment() function to set it")
- # hit the end point .. get all available specie info
- # breed endpoint http://breed-api-dev.us-east-1.elasticbeanstalk.com/api/CompBio/Species
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- print('-----------------Species I-----------------------')
- self.__speciesDF = pd.DataFrame(resp)
- print('-------------',self.__speciesDF)
- if not self.__validate_dataframe_has_content(self.__speciesDF):
- print(f"Error: failed to get species from Breed end point: {path}")
- return
- if not specie_id:
- # no user specified input ..
- # give users 5 attempts to set the specie correctly
- for i in range(5):
- print("\nAvailable species:")
- print(self.__speciesDF[["Name", "Id"]])
- specie_id = input("Please select specie Id from above: ")
- row = self.__speciesDF[self.__speciesDF["Id"]==specie_id]
- if row.shape[0] == 0:
- print(f"Error: specie id {specie_id} is invalid, please try again")
- elif row.shape[0] > 1:
- print(f"Error: id {specie_id} returned multiple species")
- return
- elif row.shape[0] == 1:
- self.__species_id = row['Id'].iloc[0]
- self.__species_name = row['Name'].iloc[0]
- break
- if i==4:
- print("You have exhausted 5 attempts to set specie correctly")
- return
- else:
- row = self.__speciesDF[self.__speciesDF["Id"]== specie_id]
- if row.shape[0] == 0:
- print(f"Error: specie id {specie_id} is invalid, please try again")
- return
- elif row.shape[0] > 1:
- print(f"Error: id {specie_id} returned multiple species")
- return
- elif row.shape[0] == 1:
- self.__species_id = str(specie_id)
- self.__species_name = row['Name'].iloc[0]
- print(f"Specie set to: {self.__species_id}")
- def list_species(self):
- if not self.__speciesDF:
- print("ERROR: list of available species have not been loaded")
- return
- return self.__speciesDF
- def list_current_specie(self):
- if not (self.__species_name and self.__species_id):
- print("Error: failed to validate Breed internal settings.")
- return
- print(f"Name: {self.__species_name} Id: {self.__species_id}")
- def list_current_specie_name(self):
- return self.__species_name
- def set_environment(self, environment):
- valid_environments = ['uat', 'uat_v2', 'dev', 'dev_v2', 'prod', 'demo', 'dev2']
- if environment:
- if environment not in valid_environments:
- print(f"Error: invalid environment: {environment} valid environments are: {valid_environments}")
- return
- else:
- for i in range(5):
- environment = input("Please select environment['dev','uat','prod','demo','dev2']:")
- if environment in valid_environments:
- break
- else:
- print(f"Error: invalid environment: {environment} valid ones are: dev, uat and prod")
- if i == 4:
- print("You have exhausted 5 attempts to set environment correctly")
- return
- self.__environment = environment
- api_url = self.__api_urls[self.__environment]
- onboarding_api_url = self.__onboarding_api_urls[self.__environment]
- onboarding_comp_bio_microservice_api_url = self.__onboarding_comp_bio_microservice_api_urls[self.__environment]
- # try up to 5 times to validate URL.
- # URL validation can fail if the ec2 housing the api is stopped or other traffic related issues
- sleep_time_secs = 600
- max_validation_attempts = 5
- for j in range(max_validation_attempts):
- result = self.__validate_url(api_url)
- if not result:
- print(f"Error: validation attempt {i+1} of max_validation_attempts failed for url: {api_url}")
- time.sleep(sleep_time_secs)
- else:
- break
- if j == 4:
- print(f"Error: exiting after {max_validation_attempts} attempts to validate url: {api_url}")
- return
- self.__onboarding_api_url = onboarding_api_url
- self.__onboarding_comp_bio_microservice_api_url = onboarding_comp_bio_microservice_api_url
- print(f"STATUS: environment set to {self.__environment}")
- def list_current_environment(self):
- return self.__environment
- def set_dataset_id(self, dataset_id):
- self.__dataset_id = dataset_id
- if not dataset_id:
- self.__dataset_id = input("Please enter a datasetId: ")
- print(f"DatasetId is set to {self.__dataset_id}")
- def set_trait(self, trait_id):
- # make sure trait id is passed in
- if not trait_id:
- print("Error: you must pass in a valid trait id")
- return
- # make sure phenotypes are loaded
- if not self.__phenotypesDF:
- # load them if not
- self.__phenotypesDF = pd.DataFrame(self.load_phenotypes())
- # make sure trait id is valid
- trait_name = self.__phenotypesDF[self.__phenotypesDF["Id"]==int(trait_id)]["Name"]
- if trait_name.empty:
- print(f"Error: trait id {trait_id} is not valid for specie {self.__species_name}")
- return
- print(f"Successfully set trait to {trait_name}")
- self.__trait_id = trait_id
- self.__trait_name = trait_name
- def set_partner(self, partner_id):
- path = self.__end_point_paths['GetPartnersPath']
- if not path:
- print("Error: failed to get 'GetPartnersPath' from config file")
- return
- if not self.__api_url:
- print("Environment has not been set internally in Partner. Please run $setEnvironment() function to set it")
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- # print('____________Partner Response_______________________',resp)
- self.__partnersDF = pd.DataFrame(resp)
- # print('000000000000000',self.__partnersDF)
- if not self.__validate_dataframe_has_content(self.__partnersDF):
- print(f"Error: failed to get partners from breed end point: {path}")
- return
- if not partner_id:
- # no user specified input ..
- # give users 5 attempts to set the specie correctly
- for i in range(5):
- print("\nAvailable partners:")
- print(self.__speciesDF[["Name", "Id", "Active"]])
- partner_id = input("Please select partner Id from above: ")
- row = self.__partnersDF[self.__partnersDF["Id"]==int(partner_id)]
- print('88888888888888888888',row)
- if row.shape[0] == 0:
- print(f"Error: partner id {partner_id} is invalid, please try again")
- elif row.shape[0] > 1:
- print(f"Error: id {partner_id} returned multiple partners")
- return
- elif row.shape[0] == 1:
- self.__partner_id = partner_id
- self.__partner_name = row['Name'][0]
- break
- if i==4:
- print("You have exhausted 5 attempts to set partner correctly")
- return
- else:
- print('entering else of partner 341')
- row = self.__partnersDF[self.__partnersDF["Id"] == int(partner_id)]
- print('-------------Row-------------------',row['Name'])
- if row.shape[0] == 0:
- print(f"Error: partner id {partner_id} is invalid, please try again")
- return
- elif row.shape[0] > 1:
- print(f"Error: id {partner_id} returned multiple partners")
- return
- elif row.shape[0] == 1:
- self.__partner_id = row["Id"].iloc[0]
- self.__partner_name = row['Name'].iloc[0]
- print(f"Partener set to: {self.__partner_id}")
- def list_partenrs(self):
- if not self.__partnersDF:
- print("Error: partners have not been loaded. Please run setPartner() to load them")
- return
- print(self.__partnersDF)
- def list_current_partner(self):
- if not self.__partner_id:
- print("Error: partnerId is not internally set")
- return
- if not self.__partner_name:
- print("Error: partnerName is not internally set")
- return
- print(f"Name: {self.__partner_name}, Id: {self.__partner_id}")
- def list_current_partner_name(self):
- return self.__partner_name
- def load_phenotypes(self):
- path = self.__end_point_paths['ListPhenotypesPath']
- if not path:
- print("Error: failed to get 'GetPhenotypesBySpeciesPath' end point path from config file")
- return
- if not self.__species_id:
- print("Error: species has not been set. Please run setSpecie() function to set it")
- return
- if not self.__partner_id:
- print("Error: partner has not been set. Please run setPartner() to set it")
- return
- if not self.__dataset_id:
- print("Error: DatasetId has not been set. Please run setDatasetId() to set it")
- return
- path = f"{path}/{self.__partner_id}/{self.__dataset_id}"
- url = self.__update_url_path(self.__api_url, path)
- print(f"Phenotype access url is {url}")
- resp = self.__validated_api_end_point_response(url)
- print('---------------Phenotype Response----------------------',resp)
- # if not self.__phenotypesDF or not self.__phenotypesDF.size:
- # print(f"No phenotypes were found for specie {self.__specie_name} partner {self.__partner_name}")
- # return
- print(f"\nSuccessfully loaded phenotypes for specie {self.__species_name}")
- return resp
- def list_api_url(self):
- if not self.__api_url:
- print("ERROR: api-url has not been set")
- return self.__api_url
- def load_genotype_data(self, s3dir=None):
- # FIXME: ideally we'd want to use internally set specie/partner/event ids to
- # derive at the s3path but currently what's in s3buckets do not necessarily
- # match what's in breed DB so we'll ask the user to supply the s3path
- # 4/3/1 works in dev
- if not s3dir:
- print("Error: you must supply an s3 dir path like \"4/6/10\" to this function")
- return
- s3_bucket = self.__s3buckets[self.__environment]
- # NOTE: below set to return max of 100_000 objects this means max of 100_000 germplasms
- s3objs = client.list_objects(Bucket=s3_bucket ,Prefix=s3dir, MaxKeys=500000)
- # TODO: continue this implementation
- def list_genotype_data(self):
- if not self.__genotype_dataDF:
- print("Error: genotype data has not been loaded. Please run loadGenotypeData() function to load it first")
- return
- return self.__genotype_dataDF
- def load_germplasms(self):
- germplasm_path = self.__end_point_paths['GermplasmsPath']
- if not germplasm_path:
- print("Error: failed to validate Breed internal settings.")
- return
- print(f"Loading germplasms for datasetId {self.__dataset_id}")
- path = f"{germplasm_path}/{self.__dataset_id}"
- url = self.__update_url_path(self.__api_url, path=path)
- resp = self.__validated_api_end_point_response(url)
- df = pd.DataFrame(resp)
- if not self.__validate_dataframe_has_content(df):
- print(f"No germplasms found for datasetId: {self.__dataset_id}")
- return
- print(f"Loaded {df.shape[0]} germplasms for datasetId {self.__dataset_id}")
- self.__species_germplasmsDF = df
- if self.__species_germplasmsDF.shape[0] > 0:
- print(f"Successfully loaded {df.shape[0]} germplasms for partner: {self.__partner_name} datasetId: {self.__dataset_id}")
- else:
- print(f"After filtering for partner {self.__partner_name} no germplasms are left")
- return self.__species_germplasmsDF
- def list_germplasms(self):
- if self.__species_germplasmsDF.empty:
- print("Error: germplasms for species have not been loaded. Please run loadGermplasms() function")
- return
- if not self.__species_germplasmsDF.shape[0] > 0:
- print(f"No germplasms found for datasetId: {self.__dataset_id}")
- return
- return self.__species_germplasmsDF
- def remove_stored_germplasms(self):
- if self.__species_germplasmsDF:
- self.__species_germplasmsDF = None
- def list_access_groups(self):
- path = self.__end_point_paths['AccessGroupListPath']
- if not path:
- print("Error: failed to get AccessGroupListPath end point path from config file")
- return
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- groups = pd.DataFrame(resp)
- print(groups[["Name", "Id", "Active"]])
- def list_onboarding_event_raw_data(self, event_id):
- if not event_id:
- print("Error: onboardingEventId must be passed in. Please run listOnboardingEvents() to see a list of valid events")
- return
- if not self.__onboarding_eventsDF:
- print("Error: onboarding events have not been set. Please run listOnboardingEvents() function")
- return
- targetDF = self.__onboarding_eventsDF[self.__onboarding_eventsDF["Id"] == event_id and self.__onboarding_eventsDF["UploadType"] == "Phenotype"]
- if not targetDF.size:
- print(f"Error: failed to find 'Phenotype' upload event for id {event_id}")
- path = self.__end_point_paths['GetRawDataByEventIdPath']
- if not path:
- print("Error: failed to get 'GetRawDataByEventIdPath' from config file")
- print("Loading data .. please be patient .. this may be slow ..")
- path = path + event_id
- url = self.__update_url_path(self.__api_url, path)
- resp = requests.get(url, timeout=3)
- if resp.status_code != 200:
- print(f"Error: attempt to connnect to url failed with status {resp.status_code}")
- if self.__onboarding_event_raw_dataDF.shape[0] <= 1:
- print("Error: onboardingEvent did not return any raw data")
- # only message is set, should this be returned?
- print(f"Loaded {self.__onboarding_event_raw_dataDF.shape[0]} phenotypes raw data")
- def load_partner_raw_data(self):
- path = self.__end_point_paths["GetRawDataByEventIdPath"]
- if not path:
- print("Error: failed to get 'GetRawDataByEventIdPath' from config file")
- return
- if not self.__partner_name:
- print("Error: partner is not set. Please run setPartner() function to set it")
- if not self.__species_id:
- print("Error: specie is not set. Please run setSpecie() to set it")
- if not self.__onboarding_eventsDF:
- self.list_onboarding_events()
- if not self.__onboarding_eventsDF:
- print(f"No onboarding events found for specie: {self.__species_name} and partner: {self.__partner_name}")
- phenotypesDF = self.__onboarding_eventsDF[self.__onboarding_eventsDF["UploadType"] == "Phenotype"]
- if not phenotypesDF.shape[0]:
- print(f"No 'phenotype' UploadType found for specie: {self.__species_name} and partner: {self.__partner_name}")
- return
- onboarding_event_ids = set(list(phenotypesDF["Id"]))
- print(f"Found {len(onboarding_event_ids)} phenotype event(s) to download data from")
- print("Downloading data. Please be patient, this could take a few minutes.")
- if self.__onboarding_event_raw_dataDF:
- reply = input("There is already raw data stored internally. Would you like to delete this data and continue?")
- if reply.lower() == 'yes':
- self.__onboarding_event_raw_dataDF = None
- else:
- return
- for event_id in onboarding_event_ids:
- url_path = path + event_id
- print(url_path)
- url = self.__update_url_path(self.__api_url, url_path)
- print(url)
- # FIXME: not sure if the 5min time out below is appropriate
- resp = requests.get(url, timeout=6)
- if resp.status_code != 200:
- print(f"Error: attempt to connnect to url failed with status {resp.status_code}")
- return
- df = pd.DataFrame(resp)
- if not self.__validate_dataframe_has_content(self.__speciesDF):
- print(f"Error: end point {path} did not return any data")
- return
- print(f"Downloaded {df.shape[0]} phenotype data")
- self.__onboarding_event_raw_dataDF = pd.concat([self.__onboarding_event_raw_dataDF, df])
- def load_partner_trait_raw_data(self):
- path = self.__end_point_paths["getRawDataByEventIdAndTraitPath"]
- if not path:
- print("Error: failed to get 'getRawDataByEventIdAndTraitPath' end point path")
- if not self.__species_id:
- print("Error: species has not been set. Please run setSpecie() function to set it")
- return
- if not self.__partner_id:
- print("Error: partner has not been set. Please run setPartner() to set it")
- return
- if not self.__dataset_id:
- print("Error: DatasetId has not been set. Please run setDatasetId() to set it")
- return
- if not self.__trait_id:
- print("Error: traitId has not been set. Please run setTrait(<traitId>) to set it")
- return
- if not self.__onboarding_eventsDF:
- self.list_onboarding_events()
- if not self.__onboarding_eventsDF:
- print(f"No onboarding events found for specie: {self.__species_name} and partner: {self.__partner_name}")
- phenotypesDF = self.__onboarding_eventsDF[self.__onboarding_eventsDF["UploadType"]=="Phenotype"]
- if not phenotypesDF.shape[0]:
- print(f"No 'phenotype' UploadType found for specie: {self.__species_name} and partner {self.__partner_name}")
- onboarding_event_ids = set(list(phenotypesDF["Id"]))
- print(f"Found {len(onboarding_event_ids)} phenotype event(s) to download data from")
- print("Downloading data. Please be patient, this could take a few minutes.")
- if self.__onboarding_event_trait_raw_dataDF:
- reply = input("There is already raw data stored internally. Would you like to delete this data and continue?")
- if reply.lower() == 'yes':
- self.__onboarding_event_trait_raw_dataDF = None
- else:
- return
- for event_id in onboarding_event_ids:
- page_num = 1
- size = 50000
- while True:
- url_path = f"{path}{event_id}/{self.__trait_id}/{page_num}/{size}"
- page_num += 1
- url = self.__update_url_path(self.__api_url, url_path)
- print(url)
- resp = requests.get(url, timeout=3)
- if resp.status_code != 200:
- print(f"Error: attempt to connnect to url {url} failed with status {resp.status_code}")
- print(f"Warning: skipping onboarding id {event_id}")
- break
- df = pd.DataFrame(resp)
- if df.shape[0] == 0:
- print(f"Warning: no trait phenotype data found in onboarding event {event_id}")
- break
- if not self.__validate_dataframe_has_content(self.__speciesDF):
- print(f"Error: end point {path} did not return any data")
- return
- print(f"Downloaded {df.shape[0]} phenotype data for trait {self.__trait_name}")
- self.__onboarding_event_trait_raw_dataDF = pd.concat([self.__onboarding_event_trait_raw_dataDF, df])
- if df.shape[0] < size:
- print(f"Successfully completed {page_num} pages of download")
- break
- print(f"Successfully downloaded {self.__onboarding_event_trait_raw_dataDF.shape[0]} rows of data trait")
- def list_trait_raw_data(self):
- if self.__validate_dataframe_has_content(self.__onboarding_event_trait_raw_dataDF):
- print("Error: no trait raw data has been loaded")
- return
- return self.__onboarding_event_trait_raw_dataDF
- def remove_stored_trait_raw_data(self):
- if self.__onboarding_event_trait_raw_dataDF:
- self.__onboarding_event_trait_raw_dataDF = None
- def list_raw_data_phenotypes(self):
- if not self.__onboarding_event_raw_dataDF:
- print("Error: no phenotype raw data have been loaded")
- return
- print("Following phenotypes were found")
- phenotypes = " ".join(list(self.__onboarding_event_raw_dataDF["Phenotype"]))
- print(phenotypes)
- def filter_raw_data_for_phonotypes(self, trait):
- if not self.__onboarding_event_raw_dataDF:
- print("Error: no phenotype raw data have been loaded")
- return
- validPhenotypes = list(set(list(self.__onboarding_event_raw_dataDF["Phenotype"])))
- newDF = pd.DataFrame()
- if not trait in validPhenotypes:
- print(f"Invalid phenotype: {trait}")
- return
- ptDF = self.__onboarding_event_raw_dataDF[self.__onboarding_event_raw_dataDF["Phenotype"]==trait]
- print(f"Parsed {ptDF.shape[0]} {trait} phenotypes")
- newDF = pd.concat([newDF, ptDF])
- self.__onboarding_event_raw_dataDF = newDF
- print(f"Data set trimmed down to {self.__onboarding_event_raw_dataDF.shape[0]} rows")
- def list_raw_data(self):
- if not self.__validate_dataframe_has_content(self.__onboarding_event_raw_dataDF):
- print("Error: no phenotype data have been loaded.")
- return
- return self.__onboarding_event_raw_dataDF
- def remove_stored_raw_data(self):
- if self.__onboarding_event_raw_dataDF:
- self.__onboarding_event_raw_dataDF == None
- def upload_summarized_data(self):
- #sri
- pass
- def upload_analysis_type_status(self, dataDF, **kwargs):
- path = self.__end_point_paths["PhenotypeAnalysisTypeStatus"]
- if not path:
- print("Error: failed to get 'PhenotypeAnalysisTypeStatus' path from config file")
- return
- url = self.__update_url_path(self.__onboarding_comp_bio_microservice_api_url, path)
- # try up to 5 times to upload data, waiting 10 min in between
- validation_attempt = 0
- max_validation_attempts = 2
- sleep_time_secs = 30
- for i in range(max_validation_attempts):
- resp = requests.post(url, data = dataDF, encode = "json")
- print(resp)
- if resp.status_code != 200:
- result = resp.json()
- print(f"Error: upload Analysis Type Status {validation_attempt} of {max_validation_attempts} failed")
- time.sleep(sleep_time_secs)
- continue
- else:
- print("Successfully uploaded upload Analysis Type Status")
- break
- def get_data_by_analysis_id(self, analysis_id):
- path = self.__end_point_paths["GetPhenotypeAnalysisByIdPath"]
- if not path:
- print("Error: failed to get 'GetPhenotypeAnalysisByIdPath' end point path from config file")
- return
- if not self.__validate_internal_settings():
- print("Error: attempt to validate Breed internal setttings failed")
- return
- path = path + analysis_id
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- df = pd.DataFrame(resp)
- # FIXME: lots of columns with NAs .. maybe just print/display certain columns only
- return df
- def load_germplasm_groups(self):
- germ_plasm_groups_path = self.__end_point_paths["GermplasmGroupsPath"]
- if not germ_plasm_groups_path:
- print("Error: failed to get 'GermplasmGroupsPath' end point from config file")
- return
- if not self.__species_id:
- print("Error: specieId has not been internally set")
- return
- path = germ_plasm_groups_path + '/'+self.__species_id
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- self.__germplasm_groupsDF = pd.DataFrame(resp)
- if not self.__germplasm_groupsDF.shape[0]:
- print(f"No germplams groups were found for specie {self.__species_name}")
- return
- print(self.__germplasm_groupsDF[["Id", "Name", "Type", "SpeciesId", "Traits", "HasModel"]])
- def list_germplasm_groups(self):
- if self.__germplasm_groupsDF.empty:
- print("Error: germplasm groups have not been loaded. Please run loadGermplasmGroups() function first")
- return
- if not self.__germplasm_groupsDF.shape[0]:
- print(f"No germplasm groups found for specie: {self.__species_name}")
- return
- return self.__germplasm_groupsDF
- def list_germplasms_by_group(self, group_id):
- germ_plasm_group_path = self.__api_url["GermplasmGroupPath"]
- if not germ_plasm_group_path:
- print()
- return
- if not self.__germplasm_groupsDF:
- print("Error: germplasm groups have not been loaded. Please run loadGermplasmGroups() function first")
- return
- if not self.__germplasm_groupsDF.shape[0]:
- print(f"No germplasm groups found for specie: {self.__species_name}")
- return
- if group_id not in self.__germplasm_groupsDF["Id"]:
- print()
- return
- path = germ_plasm_group_path + group_id + "/Phenotypes/FALSE"
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- df = pd.DataFrame(resp)
- if not df.shape[0]:
- print(f"No germplasms found for germplasm group {group_id}")
- return df
- def validate_germplasm_id(self, germ_plasm_id):
- # FIXME: I think an end point was expected to exist for this but
- # there isn't one so we'll check Ids against list of ids for species
- if not self.__species_germplasmsDF:
- print("Warning: germplasms for species have not been loaded. Please run loadGermplasms function to load them")
- return
- if germ_plasm_id not in self.__species_germplasmsDF["Id"]:
- print(f"Warning: germplasmId: {germ_plasm_id} is not valid for specie {self.__species_name}")
- return
- print(f"GermplasmId {germ_plasm_id} is valid for specie {self.__species_name}")
- def list_phenotypes(self):
- if self.__phenotypesDF.empty:
- print(
- "Error: phenotypes have not been loaded. Please run loadPhenotypes() to load them")
- return
- return self.__phenotypesDF
- def check_phenotype(self, **kwargs):
- if not self.__phenotypesDF:
- print(
- "Error: phenotypes have not been loaded. Please run loadPhenotypes() to load them")
- return
- valid_params = ('id', 'name')
- if not kwargs:
- print("expected either Id or Name input for checking phenotype")
- return
- for i in kwargs:
- if i not in valid_params:
- print(
- f"Error: invalid checkPhenotpye param name: {i}"
- f" valid search params are id and name"
- )
- return
- rows = []
- if 'id' in kwargs:
- rows = self.__phenotypesDF[self.__phenotypesDF['id'] == kwargs['id']]
- elif 'name' in kwargs:
- rows = self.__phenotypesDF[self.__phenotypesDF['name'] == kwargs['name']]
- if len(rows) == 0:
- print(f"No matching phenotype were found for search params: {kwargs}")
- print(rows)
- def add_phenotype(self):
- # FIXME: no end point for this currently
- print("sorry this is not yet functional")
- def add_phenotype_value(self, **kwargs):
- # check input params
- valid_params = ('phenotypeId', 'germplasmId', 'numvalue', 'uomid')
- if len(kwargs) != 4:
- print(f"Error: expecter 5 input params for addPhenotype but got {len(kwargs)}")
- for i in kwargs:
- if i not in valid_params:
- print(f"Error: invalid addUOM param: {i}")
- return
- # dict to store phenotype params
- data = {
- 'PhenotypeId': kwargs['phenotypeId'],
- 'GermplasmId': kwargs['germplasmId'],
- 'NumValue': kwargs['numvalue'],
- 'UOMId': kwargs['uomid']
- }
- path = self.__end_point_paths.get('AddPhenotypeValuePath')
- if not path:
- print("Error: failed to get 'AddPhenotypeValuesPath' from config file")
- return
- url = self.__update_url_path(self.__api_url, path)
- response = requests.post(url, data=data)
- reply = response.text()
- if reply != 'true':
- print(f"Error: expected 'true' reply but got: {reply}")
- return
- print(reply)
- def list_UOMs(self):
- path = self.__end_point_paths.get('UOMListPath')
- if not path:
- print("Error: failed to get 'UOMListPath' from config file")
- return
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- self.__UOMlistDF = pd.DataFrame(resp)
- if self.__UOMlistDF.shape[0] == 0:
- print("Error: attempt to listUOM failed")
- return
- print(self.__UOMlistDF[["Name", "Description", "Id", "PartnerId", "Active", "CreatedBy"]])
- def check_UOM(self, uomId=None):
- if not self.__UOMlistDF:
- print("Error: uom list has not been loaded locally. Please run listUOMs()")
- return
- if uomId not in self.__UOMlistDF['id']:
- print(f"UOM with Id {uomId} does not currently exist")
- return
- else:
- rows = self.__UOMlistDF[self.__UOMlistDF['id'] == uomId]
- print(rows[["Name", "Description", "Id", "Active"]])
- # FIXME: users should also be able to filter by name
- def add_UOM(self, **kwargs):
- path = self.__end_point_paths.get('addUOMPath')
- if not path:
- print("Error: failed to get 'addUOMPath' from config file")
- return
- valid_params = ['name', 'description', 'active']
- if len(kwargs) != 3:
- print("Error: not all required inputs have been passed in, Name??, Description?? Active")
- return
- for i in kwargs:
- if i not in valid_params:
- print(f"Error: Invalid addUOM param: {i}")
- return
- if self.__UOMlistDF is None:
- print("Error: existing UOMs have not been loaded. Please run listUOMs() to load them")
- return
- rows = self.__UOMlistDF[self.__UOMlistDF['name'] == kwargs['name'].lower()]
- if len(rows) > 0:
- print(f"Error: UOM with name {kwargs['name']} already exists")
- return
- # user is not prompted to set userName so check to make sure this is set
- if not self.__user_name:
- print("Error: user name has not been set. Please run setUser() to set it")
- return
- url = self.__update_url_path(self.__api_url, path)
- data = {
- 'Name': kwargs['name'],
- 'Description': kwargs['description'],
- 'Active': kwargs['active'],
- 'CreatedTime': self.__current_time,
- 'CreatedBy': self.__user_name,
- 'PartnerId': self.__partner_id
- }
- resp = requests.post(url, data)
- reply = resp.text()
- if reply != "true":
- print(f"Error: expected 'true' reply but got: {reply}")
- return
- print("Successfully added UOM")
- def list_summary_analysis(self):
- path = self.__end_point_paths.get('PhenotypesAnalysisPath')
- if not path:
- print("Error: failed to get 'PhenotypesAnalysisPath' end point path from config file")
- return
- # make sure species and partners are internally set
- if self.__validate_internal_settings() is None:
- print("Error: failed to validate internaly settting")
- return
- path = '/'.join([path, self.__partner_id, self.__dataset_id])
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- DF = pd.DataFrame(resp)
- def validate_analysis_id(self, analysisId=None):
- if not analysisId:
- print("Expected an analysisId input but did not get it, validateAnalysisId(ID?)")
- return
- path = self.__end_point_paths.get('IsAnalysisIdValidPath')
- if not path:
- print("Error: failed to get 'IsAnalysisIdValidPath' end point from config file")
- return
- path = '/'.join(path, analysisId)
- url = self.__update_url_path(self.__api_url, path)
- resp = requests.get(url)
- reply = resp.json()
- if reply:
- print(f"analysisId {analysisId} is valid")
- else:
- print(f"analysisId {analysisId} is NOT VALID")
- def clean_analysis_id(self, analysisId):
- path = self.__end_point_paths.get('CleanAnalysisIdPath')
- if not path:
- print("Error: failed to get 'CleanAnalysisIdPath' end point from config file")
- return
- path = '/'.join([path, analysisId])
- print(f"Setting clean analysis Id: {analysisId}")
- url = self.__update_url_path(self.__api_url, path)
- resp = requests.post(url)
- result = resp.json()
- if result:
- print(f"Successfully cleaned analysisId {analysisId}")
- else:
- print(f"Error: attempt to clean analysisID return result: {result}")
- def set_live_analysis_id(self):
- print("Sorry, this function is not ready for use")
- def list_onboarding_projects(self):
- path = self.__end_point_paths.get('GetOnboardingProjectsPath')
- if not path:
- print("Failed to get 'GetOnboardingProjectsPath' end point path from config file")
- return
- # make sure internal variables such as specieId, name, etc are set
- if self.__validate_internal_settings() is None:
- print("Error: failed to validate Breed internal settings.")
- return
- url = self.__update_url_path(self.__api_url, path)
- # FIXME: species = private$speciesId to headers below doesn't actually work. End point will
- # return objects for all species so will manually filter few lines below
- # resp = GET(url, add_headers( partner_id = private$partnerId, species = private$speciesId))
- resp = requests.get(url, headers={'partner_id': self.__partner_id})
- if resp.status_code != 200:
- print(f"Attempt to connnect to url failed with status {resp.status_code}")
- DF = pd.DataFrame(resp.json())
- if DF.shape[0] == 0:
- print(f"No onboarding projects found for partnerId {self.__partner_id}")
- return
- # parse just projects for currently set specie
- DF = DF[DF['SpeciesId'] == self.__species_id]
- if DF.shape[0] == 0:
- print(f"No onboarding projects found for specieId {self.__species_id}")
- return
- print(DF[["Id", "PartnerId", "SpeciesId", "AccessGroupId", "Active", "IsComplete", "CreatedBy"]])
- def list_onboarding_events(self):
- # FIXME: this may not get refreshed when specie is changed
- path = self.__end_point_paths.get("GetCompletedOnboardingEventsPath")
- if not path:
- print("Failed to get 'GetCompletedOnboardingEventsPath' end point from config file")
- return
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- DF = pd.DataFrame(resp)
- if not self.__validate_dataframe_has_content(DF):
- print(f"Error: failed to get onboarding events from Breed end point: {path}")
- return
- # make sure internal variables such as specieId, name, etc are set
- if not self.__validate_internal_settings():
- print("Error: failed to validate Breed internal settings.")
- return
- DF = DF[DF['SpeciesId'] == self.__species_id]
- if DF.shape[0] == 0:
- print(f"No onboarding events have been found for Specie: {self.__species_name}")
- return
- DF = DF[DF["PartnerId"] == self.__partner_id]
- DF = DF[DF["UploadType"] == 'Phenotype']
- DF = DF[DF["DatasetId"] == self.__dataset_id]
- if DF.shape[0] == 0:
- print(f"No onboarding events have been found for Specie {self.__species_name} "
- f"and partner {self.__partner_name}")
- return
- self.__onboarding_eventsDF = DF
- print('\nAvailable phenotype onboarding events:')
- print(self.__onboarding_eventsDF[["Name", "Id", "UploadType", "Species", "SpeciesId", "PartnerName", "PartnerId", "DatasetId"]])
- def list_all_onboarding_events(self):
- path = self.__end_point_paths["GetOnboardingEventsPath"]
- if not path:
- print("Failed to get 'GetCompletedOnboardingEventsPath' end point path from config file")
- return
- url = self.__update_url_path(self.__api_url, path)
- resp = self.__validated_api_end_point_response(url)
- DF = pd.DataFrame(resp)
- if not self.__validate_dataframe_has_content(DF):
- print(f"Error: failed to get onboarding events from Breed end point: {path}")
- return
- print(DF[["Name", "Id", "UploadType", "Species", "SpeciesId", "PartnerName", "PartnerId" "Status", "IsComplete"]])
- def get_phenotype_analysis(self):
- # gets uploaded phenotype analysis using analysisId
- pass
- b = Breed("cropos_worker","dev_v2",392,2,29404,1765)
- b.load_germplasm_groups()
- b.list_germplasm_groups()
- b.load_germplasms()
- print(b.list_germplasms())
- b.load_phenotypes()
Add Comment
Please, Sign In to add comment