commonlib-reader 1.3.0__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/PKG-INFO +16 -1
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/README.md +15 -0
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/pyproject.toml +1 -1
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/pyproject.toml.orig +1 -1
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/code.py +2 -3
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/discipline.py +3 -26
- commonlib_reader-1.4.0/src/commonlib_reader/unit.py +285 -0
- commonlib_reader-1.3.0/src/commonlib_reader/unit.py +0 -82
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/__init__.py +0 -0
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/connector.py +0 -0
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/facility.py +0 -0
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/ims.py +0 -0
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/library.py +0 -0
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/project.py +0 -0
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/tag.py +0 -0
- {commonlib_reader-1.3.0 → commonlib_reader-1.4.0}/src/commonlib_reader/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: commonlib-reader
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Reader for Equinor commonlib api.
|
|
5
5
|
Author: Åsmund Våge Fannemel
|
|
6
6
|
Author-email: Åsmund Våge Fannemel <asmf@equinor.com>
|
|
@@ -14,9 +14,12 @@ Description-Content-Type: text/markdown
|
|
|
14
14
|
# commonlib-reader
|
|
15
15
|
Connector package for Equinor [Commonlib](https://commonlib.equinor.com/) [api](https://commonlibapi.equinor.com/swagger/index.html).
|
|
16
16
|
|
|
17
|
+
See the [changelog](CHANGELOG.md) for release history.
|
|
18
|
+
|
|
17
19
|
Current features:
|
|
18
20
|
- Reading any code table with the `Code` class
|
|
19
21
|
- Reading library definitions and attribute definitions with the `Library` and `AttributeDefinition` classes
|
|
22
|
+
- Reading projects with the `Project` class
|
|
20
23
|
- Getting facility data using the [Facility](commonlib_reader/facility.py) class
|
|
21
24
|
- [IMS source ](commonlib_reader/ims.py) lookup tables for facilities
|
|
22
25
|
- Getting Tag category, Tag type, Tag format, and Tag format element data. See [tag.py](commonlib_reader/tag.py)
|
|
@@ -71,6 +74,18 @@ Each entry provides `name`, `description`, `identity`, `is_valid`, `attributes`,
|
|
|
71
74
|
other CommonLib metadata. Use `Code.get_names()` or `Code.get_name_and_desc()` when
|
|
72
75
|
only dropdown-friendly names or name/description data is required.
|
|
73
76
|
|
|
77
|
+
### Projects
|
|
78
|
+
|
|
79
|
+
Use `Project.get_all()` to retrieve projects and optionally filter by name or
|
|
80
|
+
abbreviation.
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from commonlib_reader import Project
|
|
84
|
+
|
|
85
|
+
projects = Project.get_all(name="M.IGLED.6I.X.0010")
|
|
86
|
+
matching_projects = Project.get_all(abbreviation="IGLED")
|
|
87
|
+
```
|
|
88
|
+
|
|
74
89
|
## Installing
|
|
75
90
|
|
|
76
91
|
Install package from pypi using `pip install commonlib_reader`
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# commonlib-reader
|
|
2
2
|
Connector package for Equinor [Commonlib](https://commonlib.equinor.com/) [api](https://commonlibapi.equinor.com/swagger/index.html).
|
|
3
3
|
|
|
4
|
+
See the [changelog](CHANGELOG.md) for release history.
|
|
5
|
+
|
|
4
6
|
Current features:
|
|
5
7
|
- Reading any code table with the `Code` class
|
|
6
8
|
- Reading library definitions and attribute definitions with the `Library` and `AttributeDefinition` classes
|
|
9
|
+
- Reading projects with the `Project` class
|
|
7
10
|
- Getting facility data using the [Facility](commonlib_reader/facility.py) class
|
|
8
11
|
- [IMS source ](commonlib_reader/ims.py) lookup tables for facilities
|
|
9
12
|
- Getting Tag category, Tag type, Tag format, and Tag format element data. See [tag.py](commonlib_reader/tag.py)
|
|
@@ -58,6 +61,18 @@ Each entry provides `name`, `description`, `identity`, `is_valid`, `attributes`,
|
|
|
58
61
|
other CommonLib metadata. Use `Code.get_names()` or `Code.get_name_and_desc()` when
|
|
59
62
|
only dropdown-friendly names or name/description data is required.
|
|
60
63
|
|
|
64
|
+
### Projects
|
|
65
|
+
|
|
66
|
+
Use `Project.get_all()` to retrieve projects and optionally filter by name or
|
|
67
|
+
abbreviation.
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from commonlib_reader import Project
|
|
71
|
+
|
|
72
|
+
projects = Project.get_all(name="M.IGLED.6I.X.0010")
|
|
73
|
+
matching_projects = Project.get_all(abbreviation="IGLED")
|
|
74
|
+
```
|
|
75
|
+
|
|
61
76
|
## Installing
|
|
62
77
|
|
|
63
78
|
Install package from pypi using `pip install commonlib_reader`
|
|
@@ -8,9 +8,8 @@ class Code:
|
|
|
8
8
|
"""A generic representation of one entry in a CommonLib library.
|
|
9
9
|
|
|
10
10
|
A Library defines the code table and its attribute schema; a Code stores one
|
|
11
|
-
value from that table. Use this class
|
|
12
|
-
a
|
|
13
|
-
Discipline, Unit, TagType, TagCategory, or TagFormat.
|
|
11
|
+
value from that table. Use this class directly for generic libraries, or as
|
|
12
|
+
a base class for dedicated readers that add library-specific behavior.
|
|
14
13
|
|
|
15
14
|
Attributes:
|
|
16
15
|
library (str): Name of the library the code belongs to.
|
|
@@ -3,38 +3,15 @@ from typing import List
|
|
|
3
3
|
from commonlib_reader.code import Code
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class Discipline:
|
|
6
|
+
class Discipline(Code):
|
|
7
7
|
def __init__(self, data: dict):
|
|
8
8
|
if not isinstance(data, dict):
|
|
9
9
|
raise ValueError("Input data shall be dictionary.")
|
|
10
|
-
|
|
11
|
-
self._data = data
|
|
12
|
-
|
|
13
|
-
def __eq__(self, other):
|
|
14
|
-
if isinstance(other, Discipline):
|
|
15
|
-
return self._data == other._data
|
|
16
|
-
|
|
17
|
-
return False
|
|
10
|
+
super().__init__(data, library="Discipline")
|
|
18
11
|
|
|
19
12
|
def __str__(self):
|
|
20
13
|
return f"Discipline: {self.name}-{self.description}"
|
|
21
14
|
|
|
22
|
-
@property
|
|
23
|
-
def name(self) -> str:
|
|
24
|
-
return self._data.get("name", "")
|
|
25
|
-
|
|
26
|
-
@property
|
|
27
|
-
def description(self) -> str:
|
|
28
|
-
return self._data.get("description", "")
|
|
29
|
-
|
|
30
|
-
@property
|
|
31
|
-
def identity(self) -> str:
|
|
32
|
-
return self._data.get("identity", "")
|
|
33
|
-
|
|
34
|
-
@property
|
|
35
|
-
def is_valid(self) -> bool:
|
|
36
|
-
return self._data.get("isValid", False)
|
|
37
|
-
|
|
38
15
|
@classmethod
|
|
39
16
|
def get_all(cls, scope: str, only_valid: bool = True) -> List["Discipline"]:
|
|
40
17
|
"""Get all disciplines for
|
|
@@ -57,7 +34,7 @@ class Discipline:
|
|
|
57
34
|
f"No discipline data found for scope {scope}. Verify that scope is correct."
|
|
58
35
|
)
|
|
59
36
|
|
|
60
|
-
dis = [
|
|
37
|
+
dis = [cls(x) for x in dis_data]
|
|
61
38
|
if only_valid:
|
|
62
39
|
dis = [x for x in dis if x.is_valid]
|
|
63
40
|
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
from typing import List, Union
|
|
2
|
+
|
|
3
|
+
from commonlib_reader.code import Code
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Unit(Code):
|
|
7
|
+
"""A class representing a unit of measurement.
|
|
8
|
+
|
|
9
|
+
Properties:
|
|
10
|
+
name (str): The name of the unit.
|
|
11
|
+
description (str): A description of the unit.
|
|
12
|
+
identity (str): The unique identifier for the unit.
|
|
13
|
+
quantity (str): The quantity this unit measures.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# In memory cache for units and conversion codes
|
|
17
|
+
_units = None
|
|
18
|
+
_conversion_codes = None
|
|
19
|
+
|
|
20
|
+
def __init__(self, data: Union[dict, str]):
|
|
21
|
+
if isinstance(data, str):
|
|
22
|
+
matches = [unit for unit in self.get_units() if unit.name == data]
|
|
23
|
+
if not matches:
|
|
24
|
+
raise ValueError(f"No unit named {data} found.")
|
|
25
|
+
data = matches[0]._data
|
|
26
|
+
|
|
27
|
+
super().__init__(data, library="UnitOfMeasure")
|
|
28
|
+
self.__dict__.update(self.attributes)
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def name(self) -> str:
|
|
32
|
+
"""Get or set the unit symbol."""
|
|
33
|
+
return self._data.get("name", "")
|
|
34
|
+
|
|
35
|
+
@name.setter
|
|
36
|
+
def name(self, value: str):
|
|
37
|
+
self._data["name"] = value
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def description(self) -> str:
|
|
41
|
+
"""Get or set the unit description."""
|
|
42
|
+
return self._data.get("description", "")
|
|
43
|
+
|
|
44
|
+
@description.setter
|
|
45
|
+
def description(self, value: str):
|
|
46
|
+
self._data["description"] = value
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def identity(self) -> str:
|
|
50
|
+
"""Get or set the unit identity."""
|
|
51
|
+
return self._data.get("identity", "")
|
|
52
|
+
|
|
53
|
+
@identity.setter
|
|
54
|
+
def identity(self, value: str):
|
|
55
|
+
self._data["identity"] = value
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def _as_bool(value) -> bool:
|
|
59
|
+
if isinstance(value, bool):
|
|
60
|
+
return value
|
|
61
|
+
return str(value).strip().lower() == "true"
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def quantity(self) -> str:
|
|
65
|
+
"""Get the quantity measured by this unit."""
|
|
66
|
+
return self.attributes.get("Quantity", "")
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def conversion(self) -> str:
|
|
70
|
+
"""Get the unit's conversion reference."""
|
|
71
|
+
return self.attributes.get("Conversion", "")
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def measure_system(self) -> str:
|
|
75
|
+
"""Get the measurement system this unit belongs to."""
|
|
76
|
+
return self.attributes.get("MeasureSystem", "")
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def alias_of_uom(self) -> str:
|
|
80
|
+
"""Get the unit symbol this unit aliases, if any."""
|
|
81
|
+
return self.attributes.get("AliasOfUoM", "")
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def alternate_symbols(self) -> str:
|
|
85
|
+
"""Get alternate symbols for this unit."""
|
|
86
|
+
return self.attributes.get("AlternateSymbols", "")
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def is_in_base_units(self) -> bool:
|
|
90
|
+
"""Whether the unit is expressed using the seven base units."""
|
|
91
|
+
return self._as_bool(self.attributes.get("IsInBaseUnits", False))
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def is_to_be_translated_to_alias(self) -> bool:
|
|
95
|
+
"""Whether incoming values should be translated to the alias symbol."""
|
|
96
|
+
return self._as_bool(
|
|
97
|
+
self.attributes.get("IsToBeTranslatedToAlias", False)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def is_default_for_transport(self) -> bool:
|
|
102
|
+
"""Whether this is the default unit for transport."""
|
|
103
|
+
return self._as_bool(self.attributes.get("IsDefaultForTransport", False))
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def is_default_for_print(self) -> bool:
|
|
107
|
+
"""Whether this is the default unit for print."""
|
|
108
|
+
return self._as_bool(self.attributes.get("IsDefaultForPrint", False))
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def definition(self) -> str:
|
|
112
|
+
"""Get the unit definition, if provided."""
|
|
113
|
+
return self.attributes.get("Definition", "")
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def remark(self) -> str:
|
|
117
|
+
"""Get general notes about the unit."""
|
|
118
|
+
return self.attributes.get("Remark", "")
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def iec61360_code(self) -> str:
|
|
122
|
+
"""Get the IEC 61360 identifier, if provided."""
|
|
123
|
+
return self.attributes.get("IEC61360Code", "")
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def dexpi_name(self) -> str:
|
|
127
|
+
"""Get the DEXPI unit name, if provided."""
|
|
128
|
+
return self.attributes.get("DEXPIName", "")
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def iso15926_name(self) -> str:
|
|
132
|
+
"""Get the ISO 15926 unit name, if provided."""
|
|
133
|
+
return self.attributes.get("ISO15926Name", "")
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def iso15926_url(self) -> str:
|
|
137
|
+
"""Get the ISO 15926 reference URL, if provided."""
|
|
138
|
+
return self.attributes.get("ISO15926URL", "")
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def is_cfihos(self) -> bool:
|
|
142
|
+
"""Whether this unit is used by CFIHOS."""
|
|
143
|
+
return self._as_bool(self.attributes.get("IsCFIHOS", False))
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def internal_comments(self) -> str:
|
|
147
|
+
"""Get internal maintenance comments, if provided."""
|
|
148
|
+
return self.attributes.get("InternalComments", "")
|
|
149
|
+
|
|
150
|
+
@classmethod
|
|
151
|
+
def _get_conversion_codes(cls):
|
|
152
|
+
if cls._conversion_codes is None:
|
|
153
|
+
codes = Code.get_codes("UnitOfMeasureConversion")
|
|
154
|
+
cls._conversion_codes = {code.identity: code for code in codes}
|
|
155
|
+
return cls._conversion_codes
|
|
156
|
+
|
|
157
|
+
def _get_conversion_factors(self):
|
|
158
|
+
"""Return the API's ``(FactorA, FactorB)`` conversion coefficients.
|
|
159
|
+
|
|
160
|
+
``FactorA`` is the scale factor and ``FactorB`` is the offset. The API
|
|
161
|
+
converts a value to its base unit as ``(value - FactorB) / FactorA``;
|
|
162
|
+
the inverse is ``base_value * FactorA + FactorB``.
|
|
163
|
+
"""
|
|
164
|
+
reference = self.conversion
|
|
165
|
+
conversion_code = self._get_conversion_codes().get(reference)
|
|
166
|
+
if conversion_code is None:
|
|
167
|
+
raise ValueError(
|
|
168
|
+
f"No conversion factors found for unit {self.name} ({reference})."
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
try:
|
|
172
|
+
factor_a = float(conversion_code.attributes["FactorA"])
|
|
173
|
+
factor_b = float(conversion_code.attributes["FactorB"])
|
|
174
|
+
except (KeyError, TypeError, ValueError):
|
|
175
|
+
raise ValueError(
|
|
176
|
+
f"Invalid conversion factors for unit {self.name} ({reference})."
|
|
177
|
+
) from None
|
|
178
|
+
return factor_a, factor_b
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def factor_a(self) -> float:
|
|
182
|
+
"""Get the unit's multiplicative conversion factor."""
|
|
183
|
+
return self._get_conversion_factors()[0]
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def factor_b(self) -> float:
|
|
187
|
+
"""Get the unit's additive conversion factor."""
|
|
188
|
+
return self._get_conversion_factors()[1]
|
|
189
|
+
|
|
190
|
+
def convert(self, value: float, to_unit: Union[str, "Unit"]) -> float:
|
|
191
|
+
"""Convert a value from this unit to another unit of the same quantity.
|
|
192
|
+
|
|
193
|
+
A string target may be either a unit identity (for example,
|
|
194
|
+
``"Pa|pressure"``) or an unambiguous symbol for this quantity.
|
|
195
|
+
"""
|
|
196
|
+
if isinstance(to_unit, str):
|
|
197
|
+
matches = [unit for unit in self.get_units() if unit.identity == to_unit]
|
|
198
|
+
if not matches:
|
|
199
|
+
symbol_matches = [
|
|
200
|
+
unit for unit in self.get_units() if unit.name == to_unit
|
|
201
|
+
]
|
|
202
|
+
quantity_matches = [
|
|
203
|
+
unit
|
|
204
|
+
for unit in symbol_matches
|
|
205
|
+
if unit.quantity == self.quantity
|
|
206
|
+
]
|
|
207
|
+
matches = quantity_matches or symbol_matches
|
|
208
|
+
if not matches:
|
|
209
|
+
raise ValueError(f"No target unit {to_unit} found for {self.name}.")
|
|
210
|
+
if len(matches) > 1:
|
|
211
|
+
raise ValueError(f"Target unit {to_unit} is ambiguous.")
|
|
212
|
+
to_unit = matches[0]
|
|
213
|
+
elif not isinstance(to_unit, Unit):
|
|
214
|
+
raise ValueError("Target unit must be a unit symbol, identity, or Unit.")
|
|
215
|
+
|
|
216
|
+
if self.quantity != to_unit.quantity:
|
|
217
|
+
raise ValueError(
|
|
218
|
+
f"Cannot convert between {self.quantity} and {to_unit.quantity}."
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
source_a, source_b = self._get_conversion_factors()
|
|
222
|
+
target_a, target_b = to_unit._get_conversion_factors()
|
|
223
|
+
if source_a == 0:
|
|
224
|
+
raise ValueError(f"Conversion factor A is zero for unit {self.name}.")
|
|
225
|
+
|
|
226
|
+
base_value = (float(value) - source_b) / source_a
|
|
227
|
+
return base_value * target_a + target_b
|
|
228
|
+
|
|
229
|
+
@classmethod
|
|
230
|
+
def get_convertible_units(cls, unit: Union[str, "Unit"]) -> List["Unit"]:
|
|
231
|
+
"""List units with usable conversion factors for the same quantity.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
unit: A Unit instance, unit identity, or unambiguous unit symbol.
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
List[Unit]: Compatible units, including the input unit when valid.
|
|
238
|
+
|
|
239
|
+
Raises:
|
|
240
|
+
ValueError: If the input cannot be resolved or has no usable factors.
|
|
241
|
+
"""
|
|
242
|
+
if isinstance(unit, str):
|
|
243
|
+
matches = [candidate for candidate in cls.get_units() if candidate.identity == unit]
|
|
244
|
+
if not matches:
|
|
245
|
+
matches = [candidate for candidate in cls.get_units() if candidate.name == unit]
|
|
246
|
+
if not matches:
|
|
247
|
+
raise ValueError(f"No unit named or identified by {unit} found.")
|
|
248
|
+
if len(matches) > 1:
|
|
249
|
+
raise ValueError(f"Unit symbol {unit} is ambiguous; use its identity.")
|
|
250
|
+
unit = matches[0]
|
|
251
|
+
elif not isinstance(unit, cls):
|
|
252
|
+
raise ValueError("Input must be a Unit instance, unit symbol, or identity.")
|
|
253
|
+
|
|
254
|
+
source_a, _ = unit._get_conversion_factors()
|
|
255
|
+
if source_a == 0:
|
|
256
|
+
raise ValueError(f"Conversion factor A is zero for unit {unit.name}.")
|
|
257
|
+
|
|
258
|
+
convertible_units = []
|
|
259
|
+
for candidate in cls.get_units():
|
|
260
|
+
if candidate.quantity != unit.quantity:
|
|
261
|
+
continue
|
|
262
|
+
try:
|
|
263
|
+
factor_a, _ = candidate._get_conversion_factors()
|
|
264
|
+
except ValueError:
|
|
265
|
+
continue
|
|
266
|
+
if factor_a != 0:
|
|
267
|
+
convertible_units.append(candidate)
|
|
268
|
+
|
|
269
|
+
return convertible_units
|
|
270
|
+
|
|
271
|
+
def convertible_units(self) -> List["Unit"]:
|
|
272
|
+
"""List units convertible with this unit's quantity."""
|
|
273
|
+
return type(self).get_convertible_units(self)
|
|
274
|
+
|
|
275
|
+
@classmethod
|
|
276
|
+
def get_units(cls) -> List["Unit"]:
|
|
277
|
+
"""Get list of Unit objects of entries in code library. Caches locally in memory.
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
List[Unit]: List of Unit objects from entries in code library.
|
|
281
|
+
"""
|
|
282
|
+
if cls._units is None:
|
|
283
|
+
cls._units = Code._get_code_data("UnitOfMeasure")
|
|
284
|
+
|
|
285
|
+
return [cls(x) for x in cls._units]
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
from typing import List, Union
|
|
2
|
-
|
|
3
|
-
from commonlib_reader.code import Code
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class Unit:
|
|
7
|
-
"""A class representing a unit of measurement.
|
|
8
|
-
|
|
9
|
-
Properties:
|
|
10
|
-
name (str): The name of the unit.
|
|
11
|
-
description (str): A description of the unit.
|
|
12
|
-
identity (str): The unique identifier for the unit.
|
|
13
|
-
quantity (str): The quantity this unit measures.
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
_units = None
|
|
17
|
-
|
|
18
|
-
def __init__(self, data: Union[dict, str]):
|
|
19
|
-
if isinstance(data, str):
|
|
20
|
-
s = [x for x in Unit.get_units() if x.name == data]
|
|
21
|
-
if len(s) > 0:
|
|
22
|
-
data = s[0]._data
|
|
23
|
-
else:
|
|
24
|
-
raise ValueError(f"No unit named {data} found.")
|
|
25
|
-
|
|
26
|
-
if isinstance(data, dict):
|
|
27
|
-
self._data = data
|
|
28
|
-
for key in data.keys():
|
|
29
|
-
if key == "attributes":
|
|
30
|
-
for attr in data["attributes"]:
|
|
31
|
-
self.__setattr__(attr["definitionName"], attr["displayValue"])
|
|
32
|
-
else:
|
|
33
|
-
self.__setattr__(key, data[key])
|
|
34
|
-
else:
|
|
35
|
-
raise ValueError("Input data must be a dict from codetable")
|
|
36
|
-
|
|
37
|
-
@property
|
|
38
|
-
def name(self) -> str:
|
|
39
|
-
"""Get the unit name."""
|
|
40
|
-
return getattr(self, "_name", "")
|
|
41
|
-
|
|
42
|
-
@name.setter
|
|
43
|
-
def name(self, value: str):
|
|
44
|
-
"""Set the unit name."""
|
|
45
|
-
self._name = value
|
|
46
|
-
|
|
47
|
-
@property
|
|
48
|
-
def description(self) -> str:
|
|
49
|
-
"""Get the unit description."""
|
|
50
|
-
return getattr(self, "_description", "")
|
|
51
|
-
|
|
52
|
-
@description.setter
|
|
53
|
-
def description(self, value: str):
|
|
54
|
-
"""Set the unit description."""
|
|
55
|
-
self._description = value
|
|
56
|
-
|
|
57
|
-
@property
|
|
58
|
-
def identity(self) -> str:
|
|
59
|
-
"""Get the unit identity."""
|
|
60
|
-
return getattr(self, "_identity", "")
|
|
61
|
-
|
|
62
|
-
@identity.setter
|
|
63
|
-
def identity(self, value: str):
|
|
64
|
-
"""Set the unit identity."""
|
|
65
|
-
self._identity = value
|
|
66
|
-
|
|
67
|
-
@property
|
|
68
|
-
def quantity(self) -> str:
|
|
69
|
-
"""Get the quantity measured by this unit."""
|
|
70
|
-
return getattr(self, "Quantity", "")
|
|
71
|
-
|
|
72
|
-
@classmethod
|
|
73
|
-
def get_units(cls) -> List["Unit"]:
|
|
74
|
-
"""Get list of Unit objects of entries in code library. Caches locally in memory.
|
|
75
|
-
|
|
76
|
-
Returns:
|
|
77
|
-
List[Unit]: List of Unit objects from entries in code library.
|
|
78
|
-
"""
|
|
79
|
-
if cls._units is None:
|
|
80
|
-
cls._units = Code._get_code_data("UnitOfMeasure")
|
|
81
|
-
|
|
82
|
-
return [Unit(x) for x in cls._units]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|