tabpy.tabpy_tools.query_object   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Test Coverage

Coverage 58.18%

Importance

Changes 0
Metric Value
wmc 18
eloc 58
dl 0
loc 109
ccs 32
cts 55
cp 0.5818
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A QueryObject.get_dependencies() 0 3 1
A QueryObject._save_local() 0 15 5
A QueryObject.save() 0 15 3
A QueryObject.__init__() 0 2 1
A QueryObject.load() 0 10 1
A QueryObject.get_methods() 0 3 1
A QueryObject._make_serializable() 0 13 2
A QueryObject._load_local() 0 5 2
A QueryObject.query() 0 4 1
A QueryObject.get_docstring() 0 8 1
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