From 695ad5da40d57e63e3720ce397ab84ac1119d12c Mon Sep 17 00:00:00 2001
From: dmt <>
Date: Tue, 12 Nov 2019 18:25:47 +0100
Subject: [PATCH] Clean api endpoints.

---
 cml/controller/api.py | 154 ++++++++++++++++++------------------------
 1 file changed, 67 insertions(+), 87 deletions(-)

diff --git a/cml/controller/api.py b/cml/controller/api.py
index 8a729f3..9575713 100644
--- a/cml/controller/api.py
+++ b/cml/controller/api.py
@@ -1,7 +1,8 @@
 """Entry point.
 
 """
-from os.path import join, expanduser
+import pickle
+from os.path import exists
 from typing import List, Tuple
 
 from cml.usecases.query import KnowledgeSearchUsecase
@@ -10,14 +11,12 @@ from cml.usecases.command import (
     FeatureSelectionUsecase,
     ReconstructionUsecase,
     ConstructionUsecase,
-    DeconstructionUsecase
-)
-from cml.ports.source_adapters import PandasAdapter
+    DeconstructionUsecase)
+from cml.ports.source_adapters import PandasAdapter, Adapter
 from cml.ports.ml_adapter import (
     ConstructionClusteringMLModel,
     FilterMethod,
-    EmbeddedMethod
-)
+    EmbeddedMethod)
 from cml.shared.settings import Settings
 from cml.shared.settings import specific_settings_factory, read_settings
 from cml.shared.request import (
@@ -26,47 +25,34 @@ from cml.shared.request import (
     ConstructionRequest,
     FeatureSelectionRequest,
     ReconstructionRequest,
-    DeconstructionRequest
-)
+    DeconstructionRequest)
 from cml.ports.ml_adapter import (
     KernelDensityEstimator,
     find_relative_extrema,
     Autoencoder,
     ReconstructionConceptualMLModel,
-    ReconstructionProceduralMLModel
-)
+    ReconstructionProceduralMLModel)
+from cml.domain import *
 
 
 __all__ = (
     "load_settings",
     "get_settings",
-    "get_data_source",
+    "get_source",
     "construction",
     "reconstruction",
     "reconstruction",
+    "deconstruction",
     "search_knowledge",
-    "visualizer",
-    "save_knowledge",
+    "visualize",
     "load_knowledge",
     "feature_selection"
 )
 
 
-def default_path(func):
-    def wrapper(path: str = None):
-        if not path:
-            path = join(expanduser("~"), ".cml", "settings.ini")
-
-        try:
-            func(path)
-        except FileNotFoundError as e:
-            # TODO (dmt):Provide proper exception handling!
-            pass
-    return wrapper
-
-
-@default_path
 def load_settings(path: str):
+    assert isinstance(path, str)
+    assert exists(path)
     read_settings(path)
 
 
@@ -74,90 +60,84 @@ def get_settings():
     return Settings
 
 
-def get_data_source(path: str = None):
+def load_knowledge(path: str):
+    assert isinstance(path, str)
+    assert exists(path)
+    with open(path, "rb") as file:
+        return pickle.load(file)
+
+
+def get_source(path: str = None):
     general_settings = specific_settings_factory("general")
     preprocessing_settings = specific_settings_factory("preprocessing")
     block_processing_settings = specific_settings_factory("block_processing")
-    if path:
-        general_settings.input_file = path
-    source_adapter = PandasAdapter.read_csv_data(general_settings.input_file)
-    density_estimator = KernelDensityEstimator()
-    relative_extrema = find_relative_extrema
-
-    preprocessing_req = PreprocessRequest(source_adapter,
-                                          preprocessing_settings,
-                                          block_processing_settings,
-                                          density_estimator,
-                                          relative_extrema)
-    preprocessing_usecase = PreprocessUsecase()
-    return preprocessing_usecase.execute(preprocessing_req)
+    if path: general_settings.input_file = path
+    density_estimator_interface = KernelDensityEstimator
+    relative_extrema_interface = find_relative_extrema
+    request = PreprocessRequest(PandasAdapter,
+                                general_settings,
+                                preprocessing_settings,
+                                block_processing_settings,
+                                density_estimator_interface,
+                                relative_extrema_interface)
+    usecase = PreprocessUsecase()
+    return usecase.execute(request)
 
 
 def construction(mode: str, algorithms: List[Tuple]):
-    if mode == "conceptual":
-        interface = ConstructionClusteringMLModel
-    elif mode == "procedural":
-        interface = None
-        raise ValueError()
-    else:
-        raise ValueError()
-
+    assert mode == "conceptual"
+    interface = ConstructionClusteringMLModel
     settings = specific_settings_factory("construction")
     request = ConstructionRequest(settings, algorithms, interface, mode)
     usecase = ConstructionUsecase()
     return usecase.execute(request)
 
 
-def feature_selection(filter_ml_model, embedded_ml_model):
-    filter_method = FilterMethod(filter_ml_model)
-    embedded_method = EmbeddedMethod(embedded_ml_model)
+def feature_selection(*, filter_method, embedded_method):
+    assert filter_method is not None
+    assert embedded_method is not None
+    filter_method = FilterMethod(filter_method)
+    embedded_method = EmbeddedMethod(embedded_method)
     settings = specific_settings_factory("feature_selection")
-    feature_selection_req = FeatureSelectionRequest(filter_method,
-                                                    embedded_method,
-                                                    settings)
-    feature_selection_usecase = FeatureSelectionUsecase()
-    return feature_selection_usecase.execute(feature_selection_req)
+    request = FeatureSelectionRequest(filter_method, embedded_method, settings)
+    usecase = FeatureSelectionUsecase()
+    return usecase.execute(request)
 
 
 def reconstruction(mode, algorithms: List[Tuple]):
-    if mode == "conceptual":
-        interface = ReconstructionConceptualMLModel
-    elif mode == "procedural":
-        interface = ReconstructionProceduralMLModel
-    else:
-        raise ValueError()
-
+    assert mode == "conceptual"
+    interface = ReconstructionConceptualMLModel
     settings = specific_settings_factory("reconstruction")
     request = ReconstructionRequest(settings, algorithms, interface, mode)
     usecase = ReconstructionUsecase()
     return usecase.execute(request)
 
 
-def search_knowledge(constructor, feature_selector, reconstructor, data_source,
-                     stdout=False):
-    deconstruction_settings = specific_settings_factory("deconstruction")
-    deconstruction_req = DeconstructionRequest(data_source,
-                                               deconstruction_settings,
-                                               constructor.construction_type)
-    deconstruction_usecase = DeconstructionUsecase()
-    deconstructor = deconstruction_usecase.execute(deconstruction_req)
-    knowledge_search_req = KnowledgeSearchRequest(constructor,
-                                                  feature_selector,
-                                                  reconstructor,
-                                                  deconstructor,
-                                                  data_source,
-                                                  stdout)
-    knowledge_search_usecase = KnowledgeSearchUsecase()
-    return knowledge_search_usecase.execute(knowledge_search_req)
-
-
-def visualizer():
-    pass
+def deconstruction(mode, source, knowledge=None):
+    assert mode == "conceptual"
+    settings = specific_settings_factory("deconstruction")
+    request = DeconstructionRequest(mode, source, settings, knowledge)
+    usecase = DeconstructionUsecase()
+    return usecase.execute(request)
 
 
-def save_knowledge():
-    pass
+def search_knowledge(constructor,
+                     selector,
+                     reconstructor,
+                     deconstructor,
+                     *,
+                     stdout=False,
+                     parallel=False):
+    assert isinstance(constructor, Constructor)
+    assert isinstance(selector, FeatureSelector)
+    assert isinstance(reconstructor, Reconstructor)
+    assert isinstance(deconstructor, Deconstructor)
+    assert isinstance(stdout, bool)
+    request = KnowledgeSearchRequest(constructor, selector, reconstructor,
+                                     deconstructor, stdout, parallel)
+    usecase = KnowledgeSearchUsecase()
+    return usecase.execute(request)
 
 
-def load_knowledge():
+def visualize():
     pass
-- 
GitLab