Passed
Push — dependabot/pip/flake8-bugbear-... ( 5c5892...6076c0 )
by
unknown
01:34
created

mandos.model.hits.AbstractHit.universal_id()   A

Complexity

Conditions 1

Size

Total Lines 19
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nop 1
dl 0
loc 19
rs 10
c 0
b 0
f 0
1
import dataclasses
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
from dataclasses import dataclass
3
from typing import Optional, Sequence
4
5
from typeddfs import TypedDfs
0 ignored issues
show
introduced by
Unable to import 'typeddfs'
Loading history...
6
7
8
@dataclass(frozen=True, repr=True, order=True)
9
class Triple:
10
    """
11
    Compound, predicate, object.
12
    """
13
14
    inchikey: str
15
    compound_id: str
16
    compound_name: str
17
    predicate: str
18
    object_name: str
19
    object_id: str
20
21
    @property
22
    def statement(self) -> str:
23
        """
24
        Returns a simple text statement.
25
        """
26
        return f'"{self.inchikey}"\t"{self.predicate}"\t"{self.object_name}"'
27
28
29
@dataclass(frozen=True, order=True, repr=True)
0 ignored issues
show
best-practice introduced by
Too many instance attributes (11/7)
Loading history...
30
class AbstractHit:
31
    """
32
    An abstract annotation (statement type), which may support additional fields.
33
    """
34
35
    record_id: Optional[str]
36
    origin_inchikey: str
37
    matched_inchikey: str
38
    compound_id: str
39
    compound_name: str
40
    predicate: str
41
    object_id: str
42
    object_name: str
43
    search_key: str
44
    search_class: str
45
    data_source: str
46
47
    def to_triple(self) -> Triple:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
48
        return Triple(
49
            inchikey=self.origin_inchikey,
50
            compound_id=self.compound_id,
51
            compound_name=self.compound_name,
52
            predicate=self.predicate,
53
            object_id=self.object_id,
54
            object_name=self.object_name,
55
        )
56
57
    def __hash__(self):
58
        return hash(self.record_id)
59
60
    @property
61
    def universal_id(self) -> str:
62
        """
63
        Gets an identifier (a hex key) that uniquely identifies the record by its unique attributes.
64
        Does **NOT** distinguish between hits with duplicate information and does **NOT**
65
        include ``record_id``.
66
67
        Returns:
68
            A 64-character hexadecimal string
69
        """
70
        # excluding record_id only because it's not available for some hit types
71
        # we'd rather immediately see duplicates if the exist
72
        fields = {
73
            field
74
            for field in self.fields()
75
            if field
76
            not in {"record_id", "origin_inchikey", "compound_name", "search_key", "search_class"}
77
        }
78
        return hex(hash(tuple([getattr(self, f) for f in fields])))
79
80
    @classmethod
81
    def fields(cls) -> Sequence[str]:
82
        """
83
        Finds the list of fields in this class by reflection.
84
        """
85
        return [f.name for f in dataclasses.fields(cls)]
86
87
88
HitFrame = (
89
    TypedDfs.typed("HitFrame")
90
    .require("record_id")
91
    .require("inchikey", "compound_id", "compound_name")
92
    .require("predicate")
93
    .require("object_id", "object_name")
94
    .require("search_key", "search_class", "data_source")
95
).build()
96
97
98
__all__ = ["AbstractHit", "Triple", "HitFrame"]
99