Passed
Pull Request — master (#652)
by
unknown
16:42
created

QueryObject.get_docstring()   A

Complexity

Conditions 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1.037

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 1
dl 0
loc 8
ccs 2
cts 3
cp 0.6667
crap 1.037
rs 10
c 0
b 0
f 0
1 1
import abc
2 1
import logging
3 1
import os
4 1
import json
5 1
import shutil
6
7 1
import cloudpickle as _cloudpickle
8
9
10 1
logger = logging.getLogger(__name__)
11
12
13 1
class QueryObject(abc.ABC):
14
    """
15
    Derived class needs to implement the following interface:
16
      * query() -- given input, return query result
17
      * get_docstring() -- returns documentation for the Query Object
18
    """
19
20 1
    def __init__(self, description=""):
21 1
        self.description = description
22
23 1
    def get_dependencies(self):
24
        """All endpoints this endpoint depends on"""
25 1
        return []
26
27 1
    @abc.abstractmethod
28 1
    def query(self, input):
29
        """execute query on the provided input"""
30
        pass
31
32 1
    @abc.abstractmethod
33 1
    def get_docstring(self):
34
        """Returns documentation for the query object
35
36
        By default, this method returns the docstring for 'query' method
37
        Derived class may overwrite this method to dynamically create docstring
38
        """
39
        pass
40
41 1
    def save(self, path):
42
        """ Save query object to the given local path
43
44
        Parameters
45
        ----------
46
        path : str
47
          The location to save the query object to
48
        """
49 1
        if os.path.exists(path):
50
            logger.warning(
51
                f'Overwriting existing file "{path}" when saving query object'
52
            )
53
            rm_fn = os.remove if os.path.isfile(path) else shutil.rmtree
54
            rm_fn(path)
55 1
        self._save_local(path)
56
57 1
    def _save_local(self, path):
58
        """Save current query object to local path
59
        """
60 1
        try:
61 1
            os.makedirs(path)
62
        except OSError as e:
63
            import errno
64
65
            if e.errno == errno.EEXIST and os.path.isdir(path):
66
                pass
67
            else:
68
                raise
69
70 1
        with open(os.path.join(path, "pickle_archive"), "wb") as f:
71 1
            _cloudpickle.dump(self, f)
72
73 1
    @classmethod
74 1
    def load(cls, path):
75
        """ Load query object from given path
76
        """
77
        new_po = None
78
        new_po = cls._load_local(path)
79
80
        logger.info(f'Loaded query object "{type(new_po).__name__}" successfully')
81
82
        return new_po
83
84 1
    @classmethod
85 1
    def _load_local(cls, path):
86
        path = os.path.abspath(os.path.expanduser(path))
87
        with open(os.path.join(path, "pickle_archive"), "rb") as f:
88
            return _cloudpickle.load(f)
89
90 1
    @classmethod
91 1
    def _make_serializable(cls, result):
92
        """Convert a result from object query to python data structure that can
93
        easily serialize over network
94
        """
95
        try:
96
            json.dumps(result)
97
        except TypeError:
98
            raise TypeError(
99
                "Result from object query is not json serializable: " f"{result}"
100
            )
101
102
        return result
103
104
    # Returns an array of dictionary that contains the methods and their
105
    # corresponding schema information.
106 1
    @abc.abstractmethod
107 1
    def get_methods(self):
108
        return None
109