diff --git a/biosimulators_utils/combine/exec.py b/biosimulators_utils/combine/exec.py index ba4742ca..4e5737a0 100644 --- a/biosimulators_utils/combine/exec.py +++ b/biosimulators_utils/combine/exec.py @@ -6,6 +6,13 @@ :License: MIT """ +import copy +import datetime +import glob +import os +import tempfile +import shutil +import types # noqa: F401 from ..archive.io import ArchiveWriter from ..archive.utils import build_archive_from_paths from ..config import get_config, Config # noqa: F401 @@ -22,13 +29,7 @@ from .utils import get_sedml_contents, get_summary_sedml_contents from .validation import validate from ..viz.data_model import VizFormat # noqa: F401 -import copy -import datetime -import glob -import os -import tempfile -import shutil -import types # noqa: F401 + __all__ = [ 'exec_sedml_docs_in_archive', @@ -38,8 +39,8 @@ def exec_sedml_docs_in_archive(sed_doc_executer, archive_filename, out_dir, apply_xml_model_changes=False, sed_doc_executer_supported_features=(Task, Report, DataSet, Plot2D, Curve, Plot3D, Surface), sed_doc_executer_logged_features=(Task, Report, DataSet, Plot2D, Curve, Plot3D, Surface), - log_level=StandardOutputErrorCapturerLevel.c, - config=None): + log_level: StandardOutputErrorCapturerLevel = None, + config: Config = None): """ Execute the SED-ML files in a COMBINE/OMEX archive (execute tasks and save outputs) Args: @@ -94,7 +95,10 @@ def sed_doc_executer(doc, working_dir, base_out_path, rel_out_path=None, * :obj:`CombineArchiveLog`: log """ if not config: - config = get_config() + config = get_config(easy_log=True) + + if not log_level: + log_level = config.STDOUT_LEVEL with StandardOutputErrorCapturer(relay=True, level=log_level, disabled=not config.LOG) as archive_captured: verbose = config.VERBOSE diff --git a/biosimulators_utils/config.py b/biosimulators_utils/config.py index 3e530a9a..f61c1d0c 100644 --- a/biosimulators_utils/config.py +++ b/biosimulators_utils/config.py @@ -6,16 +6,31 @@ :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 json +import platform +from datetime import datetime +from typing import Dict, List, Union +from kisao import AlgorithmSubstitutionPolicy # noqa: F401 +import appdirs +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'] +__all__ = [ + 'Config', 'get_config', 'Colors', + 'get_app_dirs', 'get_acceptable_report_formats', + 'get_acceptable_viz_formats', 'EasyLog' +] + + +CURRENT_PLATFORM = platform.system() +DEFAULT_STDOUT_LEVEL = StandardOutputErrorCapturerLevel.c if "Darwin" not in CURRENT_PLATFORM \ + else StandardOutputErrorCapturerLevel.python DEFAULT_OMEX_METADATA_INPUT_FORMAT = OmexMetadataInputFormat.rdfxml DEFAULT_OMEX_METADATA_OUTPUT_FORMAT = OmexMetadataOutputFormat.rdfxml_abbrev DEFAULT_OMEX_METADATA_SCHEMA = OmexMetadataSchema.biosimulations @@ -65,6 +80,8 @@ 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 + CUSTOM_SETTINGS (:obj:`**kwargs`) """ def __init__(self, @@ -82,8 +99,8 @@ def __init__(self, COLLECT_COMBINE_ARCHIVE_RESULTS=False, COLLECT_SED_DOCUMENT_RESULTS=False, SAVE_PLOT_DATA=True, - REPORT_FORMATS=[ReportFormat.h5], - 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, @@ -96,7 +113,9 @@ 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, + **CUSTOM_SETTINGS): """ Args: OMEX_METADATA_INPUT_FORMAT (:obj:`OmexMetadataInputFormat`, optional): format to validate OMEX Metadata files against @@ -117,7 +136,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,8 +151,10 @@ 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_INPUT_FORMAT = OMEX_METADATA_INPUT_FORMAT # noqa C0103 self.OMEX_METADATA_OUTPUT_FORMAT = OMEX_METADATA_OUTPUT_FORMAT self.OMEX_METADATA_SCHEMA = OMEX_METADATA_SCHEMA self.VALIDATE_OMEX_MANIFESTS = VALIDATE_OMEX_MANIFESTS @@ -147,8 +168,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 = [ReportFormat.csv] if not REPORT_FORMATS else REPORT_FORMATS + self.VIZ_FORMATS = [VizFormat.pdf] if not VIZ_FORMATS else VIZ_FORMATS self.H5_REPORTS_PATH = H5_REPORTS_PATH self.REPORTS_PATH = REPORTS_PATH self.PLOTS_PATH = PLOTS_PATH @@ -162,23 +183,71 @@ def __init__(self, self.BIOSIMULATIONS_API_AUDIENCE = BIOSIMULATIONS_API_AUDIENCE self.VERBOSE = VERBOSE self.DEBUG = DEBUG + self.STDOUT_LEVEL = STDOUT_LEVEL + self.CUSTOM_SETTINGS = self.__getcustomsettings(CUSTOM_SETTINGS) + if "EASY_LOG" in CUSTOM_SETTINGS: + self.logger = self.easy_log() + + def __getcustomsettings(self, settings: Dict = None): + for key in settings.keys(): + setattr(self, key, settings[key]) + return self + def easy_log(self): + return EasyLog(os.getcwd()) -def get_config(): - """ Get the configuration + +def get_config(report_format: str = None, + viz_format: str = None, + easy_log: bool = False, + acceptable_report_formats: Union[List[str], ReportFormat] = ReportFormat, + acceptable_viz_formats: Union[List[str], VizFormat] = VizFormat, + *_default_format_settings) -> Config: + """ 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. 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 """ - report_formats = os.environ.get('REPORT_FORMATS', 'h5').strip() + + 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', user_report_format).strip() + if report_formats: - report_formats = [ReportFormat(format.strip().lower()) for format in report_formats.split(',')] + report_formats = [ + ReportFormat(f.strip().lower()) for f in report_formats.split(',') + ] else: report_formats = [] - viz_formats = os.environ.get('VIZ_FORMATS', 'pdf').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(f.strip().lower()) for f in viz_formats.split(',') + ] else: viz_formats = [] @@ -189,17 +258,22 @@ def get_config(): 'OMEX_METADATA_OUTPUT_FORMAT', DEFAULT_OMEX_METADATA_OUTPUT_FORMAT)), OMEX_METADATA_SCHEMA=OmexMetadataSchema(os.environ.get( 'OMEX_METADATA_SCHEMA', DEFAULT_OMEX_METADATA_SCHEMA)), - VALIDATE_OMEX_MANIFESTS=os.environ.get('VALIDATE_OMEX_MANIFESTS', '1').lower() in ['1', 'true'], + VALIDATE_OMEX_MANIFESTS=os.environ.get( + 'VALIDATE_OMEX_MANIFESTS', '1').lower() in ['1', 'true'], VALIDATE_SEDML=os.environ.get('VALIDATE_SEDML', '1').lower() in ['1', 'true'], VALIDATE_SEDML_MODELS=os.environ.get('VALIDATE_SEDML_MODELS', '1').lower() in ['1', 'true'], - VALIDATE_IMPORTED_MODEL_FILES=os.environ.get('VALIDATE_IMPORTED_MODEL_FILES', '1').lower() in ['1', 'true'], - VALIDATE_OMEX_METADATA=os.environ.get('VALIDATE_OMEX_METADATA', '1').lower() in ['1', 'true'], + VALIDATE_IMPORTED_MODEL_FILES=os.environ.get( + 'VALIDATE_IMPORTED_MODEL_FILES', '1').lower() in ['1', 'true'], + VALIDATE_OMEX_METADATA=os.environ.get( + 'VALIDATE_OMEX_METADATA', '1').lower() in ['1', 'true'], VALIDATE_IMAGES=os.environ.get('VALIDATE_IMAGES', '1').lower() in ['1', 'true'], VALIDATE_RESULTS=os.environ.get('VALIDATE_RESULTS', '1').lower() in ['1', 'true'], ALGORITHM_SUBSTITUTION_POLICY=AlgorithmSubstitutionPolicy(os.environ.get( 'ALGORITHM_SUBSTITUTION_POLICY', DEFAULT_ALGORITHM_SUBSTITUTION_POLICY)), - COLLECT_COMBINE_ARCHIVE_RESULTS=os.environ.get('COLLECT_COMBINE_ARCHIVE_RESULTS', '0').lower() in ['1', 'true'], - COLLECT_SED_DOCUMENT_RESULTS=os.environ.get('COLLECT_SED_DOCUMENT_RESULTS', '0').lower() in ['1', 'true'], + COLLECT_COMBINE_ARCHIVE_RESULTS=os.environ.get( + 'COLLECT_COMBINE_ARCHIVE_RESULTS', '0').lower() in ['1', 'true'], + COLLECT_SED_DOCUMENT_RESULTS=os.environ.get( + 'COLLECT_SED_DOCUMENT_RESULTS', '0').lower() in ['1', 'true'], SAVE_PLOT_DATA=os.environ.get('SAVE_PLOT_DATA', '1').lower() in ['1', 'true'], REPORT_FORMATS=report_formats, VIZ_FORMATS=viz_formats, @@ -207,15 +281,22 @@ def get_config(): REPORTS_PATH=os.environ.get('REPORTS_PATH', DEFAULT_REPORTS_PATH), PLOTS_PATH=os.environ.get('PLOTS_PATH', DEFAULT_PLOTS_PATH), BUNDLE_OUTPUTS=os.environ.get('BUNDLE_OUTPUTS', '1').lower() in ['1', 'true'], - KEEP_INDIVIDUAL_OUTPUTS=os.environ.get('KEEP_INDIVIDUAL_OUTPUTS', '1').lower() in ['1', 'true'], + KEEP_INDIVIDUAL_OUTPUTS=os.environ.get( + 'KEEP_INDIVIDUAL_OUTPUTS', '1').lower() in ['1', 'true'], LOG=os.environ.get('LOG', '1').lower() in ['1', 'true'], LOG_PATH=os.environ.get('LOG_PATH', DEFAULT_LOG_PATH), - BIOSIMULATORS_API_ENDPOINT=os.environ.get('BIOSIMULATORS_API_ENDPOINT', DEFAULT_BIOSIMULATORS_API_ENDPOINT), - BIOSIMULATIONS_API_ENDPOINT=os.environ.get('BIOSIMULATIONS_API_ENDPOINT', DEFAULT_BIOSIMULATIONS_API_ENDPOINT), - BIOSIMULATIONS_API_AUTH_ENDPOINT=os.environ.get('BIOSIMULATIONS_API_AUTH_ENDPOINT', DEFAULT_BIOSIMULATIONS_API_AUTH_ENDPOINT), - BIOSIMULATIONS_API_AUDIENCE=os.environ.get('BIOSIMULATIONS_API_AUDIENCE', DEFAULT_BIOSIMULATIONS_API_AUDIENCE), + BIOSIMULATORS_API_ENDPOINT=os.environ.get( + 'BIOSIMULATORS_API_ENDPOINT', DEFAULT_BIOSIMULATORS_API_ENDPOINT), + BIOSIMULATIONS_API_ENDPOINT=os.environ.get( + 'BIOSIMULATIONS_API_ENDPOINT', DEFAULT_BIOSIMULATIONS_API_ENDPOINT), + BIOSIMULATIONS_API_AUTH_ENDPOINT=os.environ.get('BIOSIMULATIONS_API_AUTH_ENDPOINT', + DEFAULT_BIOSIMULATIONS_API_AUTH_ENDPOINT), + 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), + EASY_LOG=None if not easy_log else easy_log ) @@ -238,9 +319,135 @@ def get_config(): def get_app_dirs(): - """ Get the directories for the application + """ + Get the directories for the application Returns: :obj:`appdirs.AppDirs`: application directories """ return appdirs.AppDirs("BioSimulatorsUtils", "BioSimulatorsTeam") + + +def get_acceptable_viz_formats() -> List[str]: + """ + Return a list of all the acceptable visualization formats. + + Wrapper for `get_acceptable_formats`. + + Returns: + :func:`get_acceptable_formats()`: list of acceptable viz formats + """ + return get_acceptable_formats(VizFormat) + + +def get_acceptable_report_formats() -> List[str]: + """ + Return a list of all the acceptable report formats. + + Wrapper for `get_acceptable_formats`. + + Returns: + :func:`get_acceptable_formats()`: list of acceptable report formats + """ + return get_acceptable_formats(ReportFormat) + + +def get_acceptable_formats(acceptable_formats: enum.Enum) -> List[str]: + """ + Return a list of all the acceptable formats for a given format type. + + Args: + :enum.Enum:`acceptable_formats`: instance of either `ReportFormat` or `VizFormat`. + + Returns: + :list: list of acceptable formats for the given `acceptable_format` + """ + return [v.value for v in acceptable_formats] + + +def _verify_formats(format_type: str, acceptable_format: enum.Enum, default: str): + def verify_format(form_type, acceptable_form): + acceptable_formats = get_acceptable_formats(acceptable_form) + if form_type not 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 + + +class EasyLog: + """Utility class for quickly logging and capturing executed actions. + + Attributes: + working_file: (:obj:`str`): currently executed file. Defaults to `__file__` + + log: (:obj:`dict`): collection of all logs. + + index: (:obj:`list`): a list of indexes that directly correspond to the cardinality of the log. + """ + + def __init__(self, log_dir, fresh: bool = False): + """ + Args: + log_dir: (:obj:`str`): filepath of logging dir. + + fresh: (:obj:`bool`): If `True`, destroy previous log, logdir and creates a new one. + """ + self.working_file = __file__ + self._make_logdir(log_dir, fresh) + self.log = {} + self._index = list(range(self.__getsize__())) + + def __getsize__(self): + return len(self.log) + + def __getnow__(self): + return datetime.now().strftime("%d.%m.%Y..%H.%M.%S") + + def _make_logdir(self, log_dir: str, fresh_log: bool): + def make_dir(): + return os.mkdir(log_dir) if not os.path.exists(log_dir) else None + if fresh_log: + filepaths = [] + for root, _, files in os.walk(log_dir): + filepaths.append(os.path.join(root, f) for f in files) + for f in filepaths: + os.remove(f) + os.rmdir(log_dir) + make_dir() + else: + make_dir() + + def add_msg(self, message, func="none", status="none"): + size = self.__getsize__() + entry_number = 1 if size < 1 else size + now = self.__getnow__() + def verify(v): return v != "none" + func = func.__name__ if verify(func) else func + status = str(status) + entry = f"""{now} | NOTES: {message} | CALLED FROM: {self.working_file} + | METHOD CALLED: {func} | STATUS: {status.upper()}""" + self.log[entry_number] = entry + return self.log + + def flush(self): + for n in self._index: + self.log.pop(n) + return self.log + + def write(self, log_fp: str = None): + if not log_fp: + now = self.__getnow__() + log_fp = f"log_{now}.json" + with open(log_fp, "w") as f: + json.dump(self.log, f, indent=4) + + def flush_log(self, log_fp: str = None): + self.write(log_fp) + self.flush() diff --git a/biosimulators_utils/log/data_model.py b/biosimulators_utils/log/data_model.py index 0e0434e6..76e4ea0e 100644 --- a/biosimulators_utils/log/data_model.py +++ b/biosimulators_utils/log/data_model.py @@ -5,8 +5,9 @@ :Copyright: 2020, Center for Reproducible Biomedical Modeling :License: MIT """ - -from ..config import get_config +import sys +sys.path.insert(0, "C:/Users/apatrie/Desktop/wip-biosimulators-utils-repo/Biosimulators_utils") +from biosimulators_utils.config import get_config import enum import os import yaml diff --git a/biosimulators_utils/sedml/exec.py b/biosimulators_utils/sedml/exec.py index 2e688fc9..170e624a 100644 --- a/biosimulators_utils/sedml/exec.py +++ b/biosimulators_utils/sedml/exec.py @@ -6,6 +6,18 @@ :License: MIT """ + +import copy +import datetime +import numpy +import os +import sys +import tempfile +import termcolor +import types # noqa: F401 +from lxml import etree # noqa: F401 +from types import FunctionType +from typing import List, Tuple, Union from ..config import get_config, Config, Colors # noqa: F401 from ..log.data_model import Status, SedDocumentLog, TaskLog, ReportLog, Plot2DLog, Plot3DLog, StandardOutputErrorCapturerLevel # noqa: F401 from ..log.utils import init_sed_document_log, StandardOutputErrorCapturer @@ -24,15 +36,7 @@ apply_changes_to_xml_model, get_first_last_models_executed_by_task, is_model_language_encoded_in_xml) from .warnings import NoTasksWarning, NoOutputsWarning, SedmlFeatureNotSupportedWarning -from lxml import etree # noqa: F401 -import copy -import datetime -import numpy -import os -import sys -import tempfile -import termcolor -import types # noqa: F401 + __all__ = [ @@ -47,11 +51,11 @@ ] -def exec_sed_doc(task_executer, doc, working_dir, base_out_path, rel_out_path=None, - apply_xml_model_changes=False, - log=None, indent=0, pretty_print_modified_xml_models=False, - log_level=StandardOutputErrorCapturerLevel.c, - config=None): +def exec_sed_doc(task_executer: FunctionType, doc: Union[SedDocument, str], + working_dir: str, base_out_path: str, rel_out_path: str = None, + apply_xml_model_changes: bool = False, log: SedDocumentLog = None, + indent: int = 0, pretty_print_modified_xml_models: bool = False, + log_level: StandardOutputErrorCapturerLevel = None, config: Config = None): """ Execute the tasks specified in a SED document and generate the specified outputs Args: @@ -101,16 +105,19 @@ def exec_task(task, variables, preprocessed_task=None, log=None, config=None, ** * :obj:`ReportResults`: results of each report * :obj:`SedDocumentLog`: log of the document """ - if not config: - config = get_config() + if not config: # python:S3776 + config = get_config(easy_log=True) + + if not log_level: # python:S3776 + log_level = config.STDOUT_LEVEL # process arguments - if not isinstance(doc, SedDocument): + if not isinstance(doc, SedDocument): # python:S3776 doc = SedmlSimulationReader().run(doc, config=config) else: doc = copy.deepcopy(doc) - if config.LOG and not log: + if config.LOG and not log: # python:S3776 log = init_sed_document_log(doc) verbose = config.VERBOSE @@ -119,7 +126,7 @@ def exec_task(task, variables, preprocessed_task=None, log=None, config=None, ** exceptions = [] # execute tasks - if not doc.tasks: + if not doc.tasks: # python:S3776 warn('SED document does not describe any tasks.', NoTasksWarning) # TODO: initialize reports with their eventual shapes; this requires individual simulation tools to pass @@ -755,7 +762,9 @@ def exec_plot_2d(plot, variable_results, base_out_path, rel_out_path, formats, t return status, data_gen_exceptions, task_contributes_to_plot -def exec_plot_3d(plot, variable_results, base_out_path, rel_out_path, formats, task, log): +def exec_plot_3d(plot: Plot3D, variable_results: VariableResults, + base_out_path: str, rel_out_path: str, formats: List[VizFormat], + task: Task, log: ReportLog) -> Tuple[Status, Exception, bool]: """ Execute a 3D plot, generating the surfaces which are available Args: diff --git a/biosimulators_utils/warnings.py b/biosimulators_utils/warnings.py index ba19ec47..66893295 100644 --- a/biosimulators_utils/warnings.py +++ b/biosimulators_utils/warnings.py @@ -6,7 +6,7 @@ :License: MIT """ -from .config import Colors +from wip_config import Colors import termcolor import warnings diff --git a/tests/test_config.py b/tests/test_config.py index fadb48d8..3b9548fb 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,9 +1,9 @@ -from biosimulators_utils.config import get_config, get_app_dirs -from biosimulators_utils.report.data_model import ReportFormat -from biosimulators_utils.viz.data_model import VizFormat from unittest import mock -import os import unittest +import os +from biosimulators_utils.config import get_config, get_app_dirs, Config +from biosimulators_utils.report.data_model import ReportFormat +from biosimulators_utils.viz.data_model import VizFormat class ConfigTestCase(unittest.TestCase): @@ -20,3 +20,46 @@ def test_get_config(self): def test_get_app_dirs(self): self.assertIn('BioSimulatorsUtils', get_app_dirs().user_data_dir) + + +class TestConfig(unittest.TestCase): + def test_init(self): + with mock.patch('appdirs.user_config_dir') as mock_app_dirs: + mock_app_dirs.return_value = '/fake/config/dir' + config = Config( + REPORT_FORMATS='csv', + VIZ_FORMATS='pdf', + CUSTOM_SETTINGS={'MY_CUSTOM_SETTING': 'my_custom_value'} + ) + self.assertEqual(config.OMEX_METADATA_INPUT_FORMAT, 'rdfxml') + self.assertEqual(config.OMEX_METADATA_OUTPUT_FORMAT, 'rdfxml_abbrev') + self.assertEqual(config.OMEX_METADATA_SCHEMA, 'biosimulations') + self.assertTrue(config.VALIDATE_OMEX_MANIFESTS) + self.assertTrue(config.VALIDATE_SEDML) + self.assertTrue(config.VALIDATE_SEDML_MODELS) + self.assertTrue(config.VALIDATE_IMPORTED_MODEL_FILES) + self.assertTrue(config.VALIDATE_OMEX_METADATA) + self.assertTrue(config.VALIDATE_IMAGES) + self.assertTrue(config.VALIDATE_RESULTS) + self.assertEqual(config.ALGORITHM_SUBSTITUTION_POLICY, 'similarVariables') + self.assertFalse(config.COLLECT_COMBINE_ARCHIVE_RESULTS) + self.assertFalse(config.COLLECT_SED_DOCUMENT_RESULTS) + self.assertTrue(config.SAVE_PLOT_DATA) + self.assertEqual(config.REPORT_FORMATS, [ReportFormat.h5.value]) + self.assertEqual(config.VIZ_FORMATS, [VizFormat.pdf.value]) + self.assertEqual(config.H5_REPORTS_PATH, 'reports.h5') + self.assertEqual(config.REPORTS_PATH, 'reports.zip') + self.assertEqual(config.PLOTS_PATH, 'plots.zip') + self.assertTrue(config.BUNDLE_OUTPUTS) + self.assertTrue(config.KEEP_INDIVIDUAL_OUTPUTS) + self.assertTrue(config.LOG) + self.assertEqual(config.LOG_PATH, 'log.yml') + self.assertEqual(config.BIOSIMULATORS_API_ENDPOINT, 'https://api.biosimulators.org/') + self.assertEqual(config.BIOSIMULATIONS_API_ENDPOINT, 'https://api.biosimulations.org/') + self.assertEqual(config.BIOSIMULATIONS_API_AUTH_ENDPOINT, 'https://auth.biosimulations.org/oauth/token') + self.assertEqual(config.BIOSIMULATIONS_API_AUDIENCE, 'api.biosimulations.org') + self.assertFalse(config.VERBOSE) + self.assertFalse(config.DEBUG) + self.assertEqual(config.STDOUT_LEVEL, 'python') + self.assertEqual(config.CUSTOM_SETTINGS, {'MY_CUSTOM_SETTING': 'my_custom_value'}) + self.assertEqual(config.logger.handlers[0].baseFilename, '/fake/config/dir/logs/app.log')