-
Notifications
You must be signed in to change notification settings - Fork 13
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
Making FabSim3 installable as a Python package using an existing build backend #250
Comments
@matt-graham Thank you very much for raising this issue! We've looked into pip-ifying FabSim3 with @arabnejad about 3 years ago, and back then we concluded it wasn't a viable option due to a number of low-level configuration steps not being adequately supported in package form, the presence of in-package configuration files such as machines_user.yml, and the integration of code files with simulation configurations. However, from your analysis I tend to conclude that that situation has now changed. :) Now I am in favour of making these changes, but unfortunately I currently do not possess the technical expertise to make these modifications (Hamid made the initial packaging structure at the time). If you are attending the Hackathon, then could we perhaps discuss how we could make such a revision happen? Most likely writing a support proposal will take me an order of magnitude less time as opposed to learning myself how restructure and package, and incorporating these modifications. Lastly, automated testing with FabSim3 is certainly possible. Although I am not familiar with tox, we do perform automated tests with Flee and FabFlee (one of the plugins) using pytest. See https://www.github.com/djgroen/flee for details on that :). |
Hi @djgroen. Yep I will be remotely attending some of the hackathon, and it was partly because of this I thought it was worth raising this as an issue as I'd be interested in discussing and exploring how viable this would be to implement, and possibly trying to work on a PR to try to address these points at least partially 🙂. Appreciate this would be a fairly major change and it would need to be done in a way that is as backwards compatible as possible, but equally I think it would help with wider adoption if FabSim3 and plugins could be directly installed using With regards to automated testing - while I agree that it is possible, at the moment I believe it would require manually installing FabSim3 in the test environment. While certainly not impossible to do on a GitHub Actions test runner, I think it would be non-trivial and I think this probably deters plugin writers from having automated tests set up to run using GitHub Actions workflows (or an alternative CI/CD service). From a quick check through of the plugins currently listed in https://github.com/djgroen/FabSim3/blob/master/fabsim/deploy/plugins.yml, I could only spot a |
Possible task breakdown
|
@matt-graham This looks really good to me overall. I can't tell whether there are essential bits missing, but for sure I feel able to tackle many of these tasks. Today I am focused a bit more on EasyVVUQ and the Flee validation, but I will start to tackle this tomorrow. If you like you could already make a branch for this, so that I (we?) hit the ground running tomorrow? |
For "Change to a src layout" there is a slight conceptual issue in that plugins are not imported with this design. To resolve this for now I will add the plugins folder to the Pythonpath as well for the time being. ....actually, this is resulting in a few other issues. May be worth having a quick chat about. |
Okay, after some deliberation we believe that it is better to first pip-ify the plugins, as moving FabSim3 to a src layout will change the way plugins are imported quite fundamentally. The plan now is to start pip-ifying FabDummy. |
I've attempted to make a pipable version of FabDummy here: djgroen/FabDummy#3 And I've modified machines.py in FabSim3 so that it can support both old and new style plugin imports in the Some debugging may well still be required. In addition, I am wondering how to discover plugins that are not placed in the |
Is your feature request related to a problem? Please describe.
Currently FabSim3 uses a bespoke approach for having users install the application via the
configure_fabsim.py
script, and thefabsim
directory is not structured as a regular Python package due to the lack of__init__.py
files in the top-level and sub directories.This creates a few related issues:
pip
,conda
,poetry
orpdm
. This means it cannot be specified as a dependency for other packages and libraries using standard approaches (for example within apyproject.toml
file,setup.py
script,requirements.txt
or other tool specific format such asconda
environment YAML or lock files). This also makes it difficult to use tools liketox
, which are designed to help automating running Python tests in isolated environments, with FabSim3 itself or packages / modules (such as FabSim3 plugins) which themselves depend on FabSim. For example we have hit against precisely this issue when trying to run tests for the FabNESO plugin usingtox
(First draft of tests on the ensemble_tools UCL/FabNESO#23).PYTHONPATH
in.bashrc
(or equivalent for other shells), all of the directories within this root directory that are valid Python package / module names (that isdocs
,fabsim
,lists
,plugins
,tests
) will be importable as namespace packages in all Python environments that the user runs that do not otherwise overwritePYTHONPATH
. Polluting the Python import namespace globally like this is not ideal, and given the very generic names of some of these directories could lead to confusion for example if a user importslists
and finds that nothing is defined there.configure_fabsim.py
script reimplements standard functionality available in build backends such assetuptools
by manually installing dependencies in a way which makes it difficult to flexibly used FabSim with an environment management system of the users choice (the script forces use ofpip
to install dependencies and uses the--user
argument unless theVIRTUALENV
variable is set - this means if installing in aconda
environment for example, the packages will still be installed in the user directory rather than isolated to theconda
environment).fabsim
importable, plugins are recommended to use a verbose approach of importing names fromfabsim.base.fab
, which shouldn't be necessary iffabsim
was installed into thesite-packages
directory as a regular package.__init__.py
files infabsim
and its subdirectories, any imports from that namespace will be resolved as an (implicit) namespace package which carries a performance penalty compared to imporing a regular package.Describe the solution you'd like
fabsim
directory to be made in a regular Python package by including__init__.py
files in the top-level and all subdirectories.configure_fabsim.py
script approach used for installing FabSim3 to be changed to instead use a modernpyproject.toml
based approach for declaring package metadata combined with a build backend such assetuptools
orpoetry
.fabsim
package to register a console script entrypoint for its command line interface rather than having the user add thefabsim/bin
directory manually to search path.fabsim.plugins
entrypoint as a (potentially alternative to while maintaining current) approach for allowing FabSim3 to discover available plugins.machines_{plugin_name}_user.yml
file and the top-levelmachines_user.yml
file to be located in an appropriate platform specific application data directory using something likeplatformdirs
.FabSim3/configure_fabsim.py
Lines 209 to 221 in 7d80396
something the user separately explicitly opts in to post install by running a
fabsim
command, as some users may not want FabSim3 to make changes to these files.Describe alternatives you've considered
An alternative to making
fabsim
a regular package, would be to keep it as a namespace package as currently and either use asrc
layout plus auomatic package discovery or explicitly specify the package directory in apyproject.toml
/setup.cfg
/setup.py
file. This would then allow FabSim3 plugins to 'register' themselves by making themselves part of the same namespace package and thepkguti.iter_modules()
function used to discover all registered modules in a particular namespace (for examplefabsim.plugins
). The disadvantage of this approach is the aforementioned slight performance disadvantage at import time of namespace versus regular packages, and that this approach will force all plugins which wish to use this approach of registering themselves to be namespace packages as a plugin created as regular package with an__init__.py
would make other subpackages in namespace non-importable.The text was updated successfully, but these errors were encountered: