From 85c0f2dc79a61b2b0a77bb7d42b90b3f426b21f1 Mon Sep 17 00:00:00 2001 From: alex patrie Date: Mon, 8 May 2023 13:37:55 -0400 Subject: [PATCH 1/5] implemented generalized macOS handler in Config --- biosimulators_utils/config.py | 58 +++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/biosimulators_utils/config.py b/biosimulators_utils/config.py index 3e530a9a..9cae2378 100644 --- a/biosimulators_utils/config.py +++ b/biosimulators_utils/config.py @@ -6,16 +6,25 @@ :License: MIT """ -from .omex_meta.data_model import OmexMetadataInputFormat, OmexMetadataOutputFormat, OmexMetadataSchema -from .report.data_model import ReportFormat # noqa: F401 -from .viz.data_model import VizFormat # noqa: F401 -from kisao import AlgorithmSubstitutionPolicy # noqa: F401 -import appdirs import enum import os +import platform +import appdirs +from kisao import AlgorithmSubstitutionPolicy # noqa: F401 +from biosimulators_utils.log.data_model import StandardOutputErrorCapturerLevel +from biosimulators_utils.omex_meta.data_model import OmexMetadataInputFormat, OmexMetadataOutputFormat, OmexMetadataSchema +from biosimulators_utils.report.data_model import ReportFormat # noqa: F401 +from biosimulators_utils.viz.data_model import VizFormat # noqa: F401 + __all__ = ['Config', 'get_config', 'Colors', 'get_app_dirs'] +CURRENT_PLATFORM = platform.system() +try: + assert CURRENT_PLATFORM == "Darwin" + DEFAULT_STDOUT_LEVEL = StandardOutputErrorCapturerLevel.python +except AssertionError as e: + DEFAULT_STDOUT_LEVEL = StandardOutputErrorCapturerLevel.c DEFAULT_OMEX_METADATA_INPUT_FORMAT = OmexMetadataInputFormat.rdfxml DEFAULT_OMEX_METADATA_OUTPUT_FORMAT = OmexMetadataOutputFormat.rdfxml_abbrev DEFAULT_OMEX_METADATA_SCHEMA = OmexMetadataSchema.biosimulations @@ -65,6 +74,7 @@ class Config(object): BIOSIMULATIONS_API_AUDIENCE (:obj:`str`): audience for the BioSimulations API VERBOSE (:obj:`bool`): whether to display the detailed output of the execution of each task DEBUG (:obj:`bool`): whether to raise exceptions rather than capturing them + STDOUT_LEVEL (:obj:`StandardOutputErrorCapturerLevel`): level at which to log the output """ def __init__(self, @@ -82,7 +92,7 @@ def __init__(self, COLLECT_COMBINE_ARCHIVE_RESULTS=False, COLLECT_SED_DOCUMENT_RESULTS=False, SAVE_PLOT_DATA=True, - REPORT_FORMATS=[ReportFormat.h5], + REPORT_FORMATS=[ReportFormat.csv], VIZ_FORMATS=[VizFormat.pdf], H5_REPORTS_PATH=DEFAULT_H5_REPORTS_PATH, REPORTS_PATH=DEFAULT_REPORTS_PATH, @@ -96,7 +106,8 @@ def __init__(self, BIOSIMULATIONS_API_AUTH_ENDPOINT=DEFAULT_BIOSIMULATIONS_API_AUTH_ENDPOINT, BIOSIMULATIONS_API_AUDIENCE=DEFAULT_BIOSIMULATIONS_API_AUDIENCE, VERBOSE=False, - DEBUG=False): + DEBUG=False, + STDOUT_LEVEL=DEFAULT_STDOUT_LEVEL): """ Args: OMEX_METADATA_INPUT_FORMAT (:obj:`OmexMetadataInputFormat`, optional): format to validate OMEX Metadata files against @@ -117,7 +128,7 @@ def __init__(self, COLLECT_SED_DOCUMENT_RESULTS (:obj:`bool`, optional): whether to assemble an in memory data structure with all of the simulation results of SED documents SAVE_PLOT_DATA (:obj:`bool`, optional): whether to save data for plots alongside data for reports in CSV/HDF5 files - REPORT_FORMATS (:obj:`list` of :obj:`str`, optional): default formats to generate reports in + REPORT_FORMATS (:obj:`list` of :obj:`str`, optional): default formats to generate reports in-->defaults to 'csv' VIZ_FORMATS (:obj:`list` of :obj:`str`, optional): default formats to generate plots in H5_REPORTS_PATH (:obj:`str`, optional): path to save reports in HDF5 format relative to base output directory REPORTS_PATH (:obj:`str`, optional): path to save zip archive of reports relative to base output directory @@ -132,6 +143,7 @@ def __init__(self, BIOSIMULATIONS_API_AUDIENCE (:obj:`str`, optional): audience for the BioSimulations API VERBOSE (:obj:`bool`, optional): whether to display the detailed output of the execution of each task DEBUG (:obj:`bool`, optional): whether to raise exceptions rather than capturing them + STDOUT_LEVEL (:obj:`StandardOutputErrorCapturerLevel`): level at which to log the output """ self.OMEX_METADATA_INPUT_FORMAT = OMEX_METADATA_INPUT_FORMAT self.OMEX_METADATA_OUTPUT_FORMAT = OMEX_METADATA_OUTPUT_FORMAT @@ -162,21 +174,30 @@ def __init__(self, self.BIOSIMULATIONS_API_AUDIENCE = BIOSIMULATIONS_API_AUDIENCE self.VERBOSE = VERBOSE self.DEBUG = DEBUG + self.STDOUT_LEVEL = STDOUT_LEVEL -def get_config(): +def get_config(report_format: str = 'csv', + viz_format: str = 'pdf'): """ Get the configuration - + Args: + :str:`report_format`: output format for reports + :str:`viz_format`: output format for visualizations Returns: :obj:`Config`: configuration """ - report_formats = os.environ.get('REPORT_FORMATS', 'h5').strip() + + if not verify_formats(report_format, viz_format): + raise Exception + + report_formats = os.environ.get('REPORT_FORMATS', report_format).strip() + if report_formats: report_formats = [ReportFormat(format.strip().lower()) for format in report_formats.split(',')] else: report_formats = [] - viz_formats = os.environ.get('VIZ_FORMATS', 'pdf').strip() + viz_formats = os.environ.get('VIZ_FORMATS', viz_format).strip() if viz_formats: viz_formats = [VizFormat(format.strip().lower()) for format in viz_formats.split(',')] else: @@ -216,6 +237,7 @@ def get_config(): BIOSIMULATIONS_API_AUDIENCE=os.environ.get('BIOSIMULATIONS_API_AUDIENCE', DEFAULT_BIOSIMULATIONS_API_AUDIENCE), VERBOSE=os.environ.get('VERBOSE', '1').lower() in ['1', 'true'], DEBUG=os.environ.get('DEBUG', '0').lower() in ['1', 'true'], + STDOUT_LEVEL=os.environ.get('STDOUT_LEVEL', DEFAULT_STDOUT_LEVEL) ) @@ -244,3 +266,15 @@ def get_app_dirs(): :obj:`appdirs.AppDirs`: application directories """ return appdirs.AppDirs("BioSimulatorsUtils", "BioSimulatorsTeam") + + +def verify_formats(acceptable_format: enum.Enum, form: str, default: str): + acceptable_formats = [v.value for v in acceptable_format] + if not form in acceptable_formats: + print( + f'''Sorry, you must enter one of the following acceptable formats: {acceptable_formats}. + \nSetting to default format: {default}''' + ) + return False + else: + return True \ No newline at end of file From 5250394e7cccbee69bf99a329580e65c2c57ee5a Mon Sep 17 00:00:00 2001 From: alex patrie Date: Mon, 8 May 2023 16:36:40 -0400 Subject: [PATCH 2/5] added custom settings kwargs and optional format args --- biosimulators_utils/config.py | 87 +++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 24 deletions(-) diff --git a/biosimulators_utils/config.py b/biosimulators_utils/config.py index 9cae2378..0d6c34e7 100644 --- a/biosimulators_utils/config.py +++ b/biosimulators_utils/config.py @@ -9,13 +9,13 @@ import enum import os import platform -import appdirs +from typing import Dict, List, Union from kisao import AlgorithmSubstitutionPolicy # noqa: F401 from biosimulators_utils.log.data_model import StandardOutputErrorCapturerLevel from biosimulators_utils.omex_meta.data_model import OmexMetadataInputFormat, OmexMetadataOutputFormat, OmexMetadataSchema from biosimulators_utils.report.data_model import ReportFormat # noqa: F401 from biosimulators_utils.viz.data_model import VizFormat # noqa: F401 - +import appdirs __all__ = ['Config', 'get_config', 'Colors', 'get_app_dirs'] @@ -107,7 +107,8 @@ def __init__(self, BIOSIMULATIONS_API_AUDIENCE=DEFAULT_BIOSIMULATIONS_API_AUDIENCE, VERBOSE=False, DEBUG=False, - STDOUT_LEVEL=DEFAULT_STDOUT_LEVEL): + STDOUT_LEVEL=DEFAULT_STDOUT_LEVEL, + **CUSTOM_SETTINGS): """ Args: OMEX_METADATA_INPUT_FORMAT (:obj:`OmexMetadataInputFormat`, optional): format to validate OMEX Metadata files against @@ -175,31 +176,64 @@ def __init__(self, self.VERBOSE = VERBOSE self.DEBUG = DEBUG self.STDOUT_LEVEL = STDOUT_LEVEL + self.CUSTOM_SETTINGS = self.__getcustomsettings(CUSTOM_SETTINGS) + + def __getcustomsettings(self, settings: Dict = None): + for key in settings.keys(): + setattr(self, key, settings[key]) + return self -def get_config(report_format: str = 'csv', - viz_format: str = 'pdf'): - """ Get the configuration +def get_config(report_format: str = None, + viz_format: str = None, + acceptable_report_formats: Union[List[str], ReportFormat] = ReportFormat, + acceptable_viz_formats: Union[List[str], VizFormat] = VizFormat, + *_default_format_settings): + """ Get the configuration based on specified optional settings. Handles sets default values for + `report_format` and `viz_format` if these respective variables are empty. + Args: - :str:`report_format`: output format for reports - :str:`viz_format`: output format for visualizations + :str:`report_format`: output format for reports. Defaults to `None` + + :str:`viz_format`: output format for visualizations. Defaults to `None` + + :Union:`acceptable_report_formats`: acceptable formats for output report data. Defaults to `biosimulators_utils.report.data_model.ReportFormat` + + :Union:`acceptable_viz_formats`: acceptable formats for output viz data. Defaults to `biosimulators_utils.viz.data_model.VizFormat` + Returns: :obj:`Config`: configuration """ - if not verify_formats(report_format, viz_format): - raise Exception + if not _default_format_settings: #get + _default_format_settings = ('csv', 'pdf') #set + + user_report_format = verify_formats( + report_format, + acceptable_report_formats, + _default_format_settings[0] + ) + + user_viz_format = verify_formats( + viz_format, + acceptable_viz_formats, + _default_format_settings[1] + ) - report_formats = os.environ.get('REPORT_FORMATS', report_format).strip() + report_formats = os.environ.get('REPORT_FORMATS', user_report_format).strip() if report_formats: - report_formats = [ReportFormat(format.strip().lower()) for format in report_formats.split(',')] + report_formats = [ + ReportFormat(format.strip().lower()) for format in report_formats.split(',') + ] else: report_formats = [] - viz_formats = os.environ.get('VIZ_FORMATS', viz_format).strip() + viz_formats = os.environ.get('VIZ_FORMATS', user_viz_format).strip() if viz_formats: - viz_formats = [VizFormat(format.strip().lower()) for format in viz_formats.split(',')] + viz_formats = [ + VizFormat(format.strip().lower()) for format in viz_formats.split(',') + ] else: viz_formats = [] @@ -268,13 +302,18 @@ def get_app_dirs(): return appdirs.AppDirs("BioSimulatorsUtils", "BioSimulatorsTeam") -def verify_formats(acceptable_format: enum.Enum, form: str, default: str): - acceptable_formats = [v.value for v in acceptable_format] - if not form in acceptable_formats: - print( - f'''Sorry, you must enter one of the following acceptable formats: {acceptable_formats}. - \nSetting to default format: {default}''' - ) - return False - else: - return True \ No newline at end of file +def verify_formats(format_type: str, acceptable_format: enum.Enum, default: str): + + def verify_format(format_type, acceptable_format): + acceptable_formats = [v.value for v in acceptable_format] + if not format_type in acceptable_formats: + print( + f'''Sorry, you must enter one of the following acceptable formats: + {acceptable_formats}. \nSetting to default format: {default}''' + ) + return False + else: + return True + + return default if not verify_format(format_type, acceptable_format)\ + else format_type \ No newline at end of file From 22cbeff3922b07a0dc20ca22eddae5a54539b112 Mon Sep 17 00:00:00 2001 From: alex patrie Date: Mon, 8 May 2023 16:40:11 -0400 Subject: [PATCH 3/5] adjusted minor logic --- biosimulators_utils/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biosimulators_utils/config.py b/biosimulators_utils/config.py index 0d6c34e7..ec387366 100644 --- a/biosimulators_utils/config.py +++ b/biosimulators_utils/config.py @@ -306,7 +306,7 @@ def verify_formats(format_type: str, acceptable_format: enum.Enum, default: str) def verify_format(format_type, acceptable_format): acceptable_formats = [v.value for v in acceptable_format] - if not format_type in acceptable_formats: + if format_type not in acceptable_formats: print( f'''Sorry, you must enter one of the following acceptable formats: {acceptable_formats}. \nSetting to default format: {default}''' From 4d17e755841f66577cf751e0cbf7e5939ff28af7 Mon Sep 17 00:00:00 2001 From: alex patrie Date: Mon, 8 May 2023 16:50:22 -0400 Subject: [PATCH 4/5] added lazy evaluation for report and viz formats in Config factory --- biosimulators_utils/config.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/biosimulators_utils/config.py b/biosimulators_utils/config.py index ec387366..c6384d10 100644 --- a/biosimulators_utils/config.py +++ b/biosimulators_utils/config.py @@ -92,8 +92,8 @@ def __init__(self, COLLECT_COMBINE_ARCHIVE_RESULTS=False, COLLECT_SED_DOCUMENT_RESULTS=False, SAVE_PLOT_DATA=True, - REPORT_FORMATS=[ReportFormat.csv], - VIZ_FORMATS=[VizFormat.pdf], + REPORT_FORMATS=None, + VIZ_FORMATS=None, H5_REPORTS_PATH=DEFAULT_H5_REPORTS_PATH, REPORTS_PATH=DEFAULT_REPORTS_PATH, PLOTS_PATH=DEFAULT_PLOTS_PATH, @@ -160,8 +160,8 @@ def __init__(self, self.COLLECT_COMBINE_ARCHIVE_RESULTS = COLLECT_COMBINE_ARCHIVE_RESULTS self.COLLECT_SED_DOCUMENT_RESULTS = COLLECT_SED_DOCUMENT_RESULTS self.SAVE_PLOT_DATA = SAVE_PLOT_DATA - self.REPORT_FORMATS = REPORT_FORMATS - self.VIZ_FORMATS = VIZ_FORMATS + self.REPORT_FORMATS = REPORT_FORMATS or [ReportFormat.csv] + self.VIZ_FORMATS = VIZ_FORMATS or [VizFormat.pdf] self.H5_REPORTS_PATH = H5_REPORTS_PATH self.REPORTS_PATH = REPORTS_PATH self.PLOTS_PATH = PLOTS_PATH From 8997605bbcadf24e6b534c7f45100e8b728ed59f Mon Sep 17 00:00:00 2001 From: alex patrie Date: Tue, 9 May 2023 17:53:01 -0400 Subject: [PATCH 5/5] Added acceptable format helpers. --- biosimulators_utils/config.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/biosimulators_utils/config.py b/biosimulators_utils/config.py index c6384d10..df555b19 100644 --- a/biosimulators_utils/config.py +++ b/biosimulators_utils/config.py @@ -303,9 +303,8 @@ def get_app_dirs(): def verify_formats(format_type: str, acceptable_format: enum.Enum, default: str): - def verify_format(format_type, acceptable_format): - acceptable_formats = [v.value for v in acceptable_format] + acceptable_formats = _get_acceptable_formats(acceptable_format) if format_type not in acceptable_formats: print( f'''Sorry, you must enter one of the following acceptable formats: @@ -316,4 +315,14 @@ def verify_format(format_type, acceptable_format): return True return default if not verify_format(format_type, acceptable_format)\ - else format_type \ No newline at end of file + else format_type + + +def acceptable_viz_formats(): + return _get_acceptable_formats(VizFormat) + +def acceptable_report_formats(): + return _get_acceptable_formats(ReportFormat) + +def _get_acceptable_formats(acceptable_formats: enum.Enum): + return [v.value for v in acceptable_formats] \ No newline at end of file