available
Full documentation pages are generated for docstring
reference only and may contain symbols imported from other
modules. Imported symbols are not distinguished from locally
defined symbols and will appear in any module that they are
imported into. For better information on where symbols should
be imported from, review the sourcecode on the
github.
FoSpy.ui.available
AVAILABLE_UIS
module-attribute
AVAILABLE_UIS = [
ui
for ui, req in (_UI_REQUIREMENTS.items())
if _check_requirement(req)
]
_UI_REQUIREMENTS
module-attribute
_UI_REQUIREMENTS = {
"pyqtgraph": (
"pyqtgraph",
["PySide6", "PyQt6", "PySide2", "PyQt5"],
),
"app": ("PySide6", "qdarktheme"),
"native": ("tkinter", "matplotlib"),
}
UINotAvailable
Bases: Exception
Source code in FoSpy/ui/available.py
| class UINotAvailable(Exception):
pass
|
_check_requirement
Source code in FoSpy/ui/available.py
| def _check_requirement(req:str|list|tuple) -> bool:
if isinstance(req, str):
return _is_package_installed(req)
if isinstance(req, tuple):
return all(_check_requirement(dep) for dep in req)
if isinstance(req, list):
return any(_check_requirement(dep) for dep in req)
# shouldn't get here
raise ValueError(f"Unknown logic structure for requirement: {type(req)}. "
"Expected str, list, or tuple.")
|
_is_package_installed
_is_package_installed(package_name)
Source code in FoSpy/ui/available.py
| def _is_package_installed(package_name:str) -> bool:
return imp_util.find_spec(package_name) is not None
|
_summarize_reqs
_summarize_reqs(req, indent=0)
Source code in FoSpy/ui/available.py
| def _summarize_reqs(req:str|list|tuple, indent=0):
txt = f"{' '*indent}- [{'OK' if _check_requirement(req) else 'XX'}] "
if isinstance(req, str):
return txt + req
if isinstance(req, (tuple, list)):
txt += "ALL OF:\n" if isinstance(req, tuple) else "ONE OF:\n"
return txt + "\n".join([_summarize_reqs(dep, indent+1) for dep in req])
# shouldn't get here
raise ValueError(f"Unknown logic structure for requirement: {type(req)}. "
"Expected str, list, or tuple.")
|
discover_ui_options
discover_ui_options(target)
Source code in FoSpy/ui/available.py
| def discover_ui_options(target:str|ModuleType) -> dict[str, ModuleType]:
ui_opts = {}
base_package = target.__name__ if isinstance(target, ModuleType) else str(target)
for ui_name in get_available_uis():
absolute_name = f"{base_package}.{ui_name}"
spec = imp_util.find_spec(absolute_name)
if spec is not None:
ui_opts[ui_name] = import_module(absolute_name)
return ui_opts
|
get_available_uis
Source code in FoSpy/ui/available.py
| def get_available_uis():
return AVAILABLE_UIS
|
get_valid_ui
get_valid_ui(ui_name=None, options=None)
Source code in FoSpy/ui/available.py
| def get_valid_ui(ui_name=None, options=None):
from ..config import values as cfg
from warnings import warn
ui_name = ui_name or cfg.get("ui.default", "native")
if options is None:
options = _UI_REQUIREMENTS.keys()
else:
options = [o.lower() for o in options]
if ui_name.lower() not in options:
new_ui = options[0]
warn_txt = (f"\n\nThe '{ui_name}' backend is not available for the requested context "
f"(See dependency summary below). Attempting to use '{new_ui}' instead.\n\n"
f"===== DEPENDENCIES FOR '{ui_name.upper()}' UI =====\n")
warn_txt += _summarize_reqs(_UI_REQUIREMENTS[ui_name])
warn(warn_txt, RuntimeWarning)
ui_name = new_ui
available_options = [o for o in options if o in AVAILABLE_UIS]
installable_options = {o: _UI_REQUIREMENTS[o] for o in options if o in _UI_REQUIREMENTS}
try:
validate_ui(ui_name)
return ui_name
except UINotAvailable as e:
if len(available_options) > 0:
fallback = available_options[0]
warn(f"\n\nThe '{ui_name}' UI backend is not available (exception below). "
f"Using the first available UI,'{fallback}', instead.\n\n{e}", RuntimeWarning)
return fallback
# proceed to raise if no fallback is available
# Only reached on UINotAvailable and no fallback
summary = (f"The '{ui_name}' UI backend is not available. There are no "
"available UIs to fallback to.\n"
"Refer to the dependency summaries below and install the "
"missing dependencies for your UI of choice.\nNOTE: The "
"'native' UI is the most lightweight and is recommended for "
"users looking for a simple UI or who don't use the UI "
"often.\n\n")
for ui, req in installable_options.items():
summary += f"===== DEPENDENCIES FOR '{ui.upper()}' UI =====\n"
summary += _summarize_reqs(req)
summary += "\n\n"
raise UINotAvailable(summary)
|
is_ui_available
Source code in FoSpy/ui/available.py
| def is_ui_available(ui_name):
return ui_name.lower() in AVAILABLE_UIS
|
validate_ui
Source code in FoSpy/ui/available.py
| def validate_ui(ui_name):
ui_lower = ui_name.lower()
if ui_lower not in _UI_REQUIREMENTS:
valids = ", ".join(_UI_REQUIREMENTS.keys())
raise UINotAvailable(f"UI '{ui_name}' is not a valid UI. Valid options are: {valids}.")
if ui_lower not in AVAILABLE_UIS:
raise UINotAvailable(
f"The '{ui_name}' UI backend cannot be used because it is missing dependencies. "
"Refer to the summary below and install the missing dependencies to use this UI.\n\n"
f"{_summarize_reqs(_UI_REQUIREMENTS[ui_lower])}"
)
|