diff --git a/annif/analyzer/__init__.py b/annif/analyzer/__init__.py index 27a2cd79..81f52511 100644 --- a/annif/analyzer/__init__.py +++ b/annif/analyzer/__init__.py @@ -8,7 +8,7 @@ import annif from annif.util import parse_args -from . import simple, simplemma, snowball +from . import simple, simplemma, snowball, spacy, voikko if TYPE_CHECKING: from annif.analyzer.analyzer import Analyzer @@ -17,7 +17,10 @@ def register_analyzer(analyzer): - _analyzers[analyzer.name] = analyzer + if analyzer.is_available(): + _analyzers[analyzer.name] = analyzer + else: + annif.logger.debug(f"{analyzer.name} analyzer not available, not enabling it") def get_analyzer(analyzerspec: str) -> Analyzer: @@ -37,18 +40,5 @@ def get_analyzer(analyzerspec: str) -> Analyzer: register_analyzer(simple.SimpleAnalyzer) register_analyzer(snowball.SnowballAnalyzer) register_analyzer(simplemma.SimplemmaAnalyzer) - -# Optional analyzers -try: - from . import voikko - - register_analyzer(voikko.VoikkoAnalyzer) -except ImportError: - annif.logger.debug("voikko not available, not enabling voikko analyzer") - -try: - from . import spacy - - register_analyzer(spacy.SpacyAnalyzer) -except ImportError: - annif.logger.debug("spaCy not available, not enabling spacy analyzer") +register_analyzer(voikko.VoikkoAnalyzer) +register_analyzer(spacy.SpacyAnalyzer) diff --git a/annif/analyzer/analyzer.py b/annif/analyzer/analyzer.py index 129b882a..612234d9 100644 --- a/annif/analyzer/analyzer.py +++ b/annif/analyzer/analyzer.py @@ -22,6 +22,11 @@ class Analyzer(metaclass=abc.ABCMeta): name = None token_min_length = 3 # default value, can be overridden in instances + @staticmethod + def is_available() -> bool: + """Return True if the analyzer is available for use, False if not.""" + return True # can be overridden in implementations if necessary + def __init__(self, **kwargs) -> None: if _KEY_TOKEN_MIN_LENGTH in kwargs: self.token_min_length = int(kwargs[_KEY_TOKEN_MIN_LENGTH]) diff --git a/annif/analyzer/spacy.py b/annif/analyzer/spacy.py index 184f03ff..407f0d9c 100644 --- a/annif/analyzer/spacy.py +++ b/annif/analyzer/spacy.py @@ -2,6 +2,8 @@ from __future__ import annotations +import importlib + import annif.util from annif.exception import OperationFailedException @@ -13,6 +15,11 @@ class SpacyAnalyzer(analyzer.Analyzer): name = "spacy" + @staticmethod + def is_available() -> bool: + # return True iff spaCy is installed + return importlib.util.find_spec("spacy") is not None + def __init__(self, param: str, **kwargs) -> None: import spacy diff --git a/annif/analyzer/voikko.py b/annif/analyzer/voikko.py index b3e7d500..3722d6b4 100644 --- a/annif/analyzer/voikko.py +++ b/annif/analyzer/voikko.py @@ -3,8 +3,7 @@ from __future__ import annotations import functools - -import voikko.libvoikko +import importlib from . import analyzer @@ -12,6 +11,11 @@ class VoikkoAnalyzer(analyzer.Analyzer): name = "voikko" + @staticmethod + def is_available() -> bool: + # return True iff Voikko is installed + return importlib.util.find_spec("voikko") is not None + def __init__(self, param: str, **kwargs) -> None: self.param = param self.voikko = None @@ -26,6 +30,8 @@ def __getstate__(self) -> dict[str, str | None]: @functools.lru_cache(maxsize=500000) def _normalize_word(self, word: str) -> str: + import voikko.libvoikko + if self.voikko is None: self.voikko = voikko.libvoikko.Voikko(self.param) result = self.voikko.analyze(word)