Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declaring FOQUS Optional Dependencies #1013

Open
Tracked by #1085
boverhof opened this issue Mar 1, 2022 · 6 comments
Open
Tracked by #1085

Declaring FOQUS Optional Dependencies #1013

boverhof opened this issue Mar 1, 2022 · 6 comments
Assignees
Labels
Priority:Normal Normal Priority Issue or PR

Comments

@boverhof
Copy link
Member

boverhof commented Mar 1, 2022

Description

Discuss and explore a means of marking up methods that require certain plugins/extensions.

Possiblities:

Set of decorators:

def require_psuade(f, *args, **kw):
    def _require_psuade(*args, **kw):
        raise RuntimeError("Missing Psuade")

    _psuade_path = shutil.which("psuade")
    if _psuade_path is None:
        return _require_psuade
    return f
...
...
@pytest.fixture(scope="session")
@require_psuade
def psuade_path():
    _psuade_path = shutil.which("psuade")
    assert _psuade_path is not None
    return Path(_psuade_path).resolve()

Class Hierarchies

Class Mixins

Metaclass

@boverhof
Copy link
Member Author

boverhof commented Mar 1, 2022

PSUADE Example Test Code

(py3.9) joshuas-mbp:foqus-boverhof boverhof$ pytest -k test_uq
_________________________ ERROR at setup of TestUQ.test_rs_validation[UQ/Rosenbrock.foqus-rs_combo_values1] _________________________

args = (), kw = {}

    def _require_psuade(*args, **kw):
>       raise RuntimeError("Missing Psuade")
E       RuntimeError: Missing Psuade

foqus_lib/conftest.py:10: RuntimeError

@boverhof
Copy link
Member Author

boverhof commented Mar 1, 2022

Wrapper Plugin Module

class Plugin:
    plugin_modules_available = []
    plugin_modules_unavailable = []
    @classmethod
    def available(cls):
        return tuple(plugin_modules_available)
    @classmethod
    def unavailable(cls):
        return tuple(plugin_modules_unavailable)
    @classmethod
    def load(cls):
        try:
            exec('import %s' %(cls.python_module_name))
        except ModuleNotFoundError:
            cls.plugin_modules_unavailable.append(cls.python_module_name)
            return False
        cls.plugin_modules_available.append(cls.python_module_name)
        return True

class PsuadePlugin(Plugin):
    python_module_name='psuade'

class TensorFlowPlugin(Plugin):
    python_module_name='tensorflow'

if __name__ == '__main__':
    loaded = TensorFlowPlugin.load()
    print("%s %s" %(TensorFlowPlugin, loaded))

@boverhof
Copy link
Member Author

#1015 This PR removes a few lines of code because PSUADE/NOMAD is not available.

Think this would make a good start for the plugin architecture that wraps these lines with a "is_available"

@boverhof
Copy link
Member Author

boverhof commented Mar 15, 2022

@sotorrio1 and @lbianchi-lbl I added a "Plugin" module and show how to use it in the OUU UI class and wrapped the button code you removed. I think this is a reasonable way to handle this, and it also demonstrates the frailty of having UI specific modules with underlying dependencies that are not enforced or checked in any meaningful way.

There is nothing in the OUU UI that says "hey we need PSUADE".

@boverhof boverhof changed the title Declaring FOQUS Plugin/Extensions Declaring FOQUS Optional Dependencies May 10, 2022
@boverhof
Copy link
Member Author

#1030

@ksbeattie
Copy link
Member

A sample implementation is in #1032

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority:Normal Normal Priority Issue or PR
Projects
None yet
Development

No branches or pull requests

3 participants