labfreed 0.0.14__tar.gz → 0.0.16__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.

Potentially problematic release.


This version of labfreed might be problematic. Click here for more details.

Files changed (43) hide show
  1. labfreed-0.0.16/PKG-INFO +194 -0
  2. labfreed-0.0.16/README.md +185 -0
  3. labfreed-0.0.16/examples.py +118 -0
  4. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/PAC_CAT/data_model.py +26 -8
  5. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/TREX/data_model.py +1 -0
  6. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/__init__.py +1 -1
  7. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/parse_pac.py +6 -6
  8. {labfreed-0.0.14 → labfreed-0.0.16}/tests/test_(de)_serialization_incl_extension/test__parse.py +5 -5
  9. {labfreed-0.0.14 → labfreed-0.0.16}/tests/test_PAC_CAT/test_PAC_CAT_parse.py +14 -14
  10. {labfreed-0.0.14 → labfreed-0.0.16}/tests/test_PAC_ID/test_pac_id_parse.py +10 -10
  11. labfreed-0.0.16/update_readme.py +93 -0
  12. labfreed-0.0.14/PKG-INFO +0 -161
  13. labfreed-0.0.14/README.md +0 -152
  14. labfreed-0.0.14/examples.py +0 -114
  15. labfreed-0.0.14/labfreed/PAC_CAT/data_model copy.py +0 -232
  16. labfreed-0.0.14/update_readme.py +0 -27
  17. {labfreed-0.0.14 → labfreed-0.0.16}/.vscode/launch.json +0 -0
  18. {labfreed-0.0.14 → labfreed-0.0.16}/.vscode/settings.json +0 -0
  19. {labfreed-0.0.14 → labfreed-0.0.16}/LICENSE +0 -0
  20. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/DisplayNameExtension/DisplayNameExtension.py +0 -0
  21. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/PAC_CAT/__init__.py +0 -0
  22. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/PAC_ID/__init__.py +0 -0
  23. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/PAC_ID/data_model.py +0 -0
  24. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/PAC_ID/extensions.py +0 -0
  25. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/TREX/UneceUnits.json +0 -0
  26. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/TREX/parse.py +0 -0
  27. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/TREX/unece_units.py +0 -0
  28. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/utilities/base36.py +0 -0
  29. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/utilities/extension_intertpreters.py +0 -0
  30. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/utilities/utility_types.py +0 -0
  31. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/utilities/well_known_keys.py +0 -0
  32. {labfreed-0.0.14 → labfreed-0.0.16}/labfreed/validation.py +0 -0
  33. {labfreed-0.0.14 → labfreed-0.0.16}/main.py +0 -0
  34. {labfreed-0.0.14 → labfreed-0.0.16}/publish.ps1 +0 -0
  35. {labfreed-0.0.14 → labfreed-0.0.16}/publish.sh +0 -0
  36. {labfreed-0.0.14 → labfreed-0.0.16}/publish_commands +0 -0
  37. {labfreed-0.0.14 → labfreed-0.0.16}/pyproject.toml +0 -0
  38. {labfreed-0.0.14 → labfreed-0.0.16}/pytest.ini +0 -0
  39. {labfreed-0.0.14 → labfreed-0.0.16}/tests/test_(de)_serialization_incl_extension/test__serialize.py +0 -0
  40. {labfreed-0.0.14 → labfreed-0.0.16}/tests/test_PAC_CAT/test_PAC_CAT_serialize.py +0 -0
  41. {labfreed-0.0.14 → labfreed-0.0.16}/tests/test_PAC_ID/test_PAC_ID_serialize.py +0 -0
  42. {labfreed-0.0.14 → labfreed-0.0.16}/tests/test_TREX/test_TREX_parse.py +0 -0
  43. {labfreed-0.0.14 → labfreed-0.0.16}/tests/test_TREX/test_TREX_serialize.py +0 -0
@@ -0,0 +1,194 @@
1
+ Metadata-Version: 2.4
2
+ Name: labfreed
3
+ Version: 0.0.16
4
+ Summary: Python implementation of LabFREED building blocks
5
+ Author-email: Reto Thürer <thuerer.r@buchi.com>
6
+ Description-Content-Type: text/markdown
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+
10
+ # LabFREED for Python
11
+
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![PyPI](https://img.shields.io/pypi/v/labfreed.svg)](https://pypi.org/project/labfreed/) ![Python Version](https://img.shields.io/pypi/pyversions/labfreed)
13
+
14
+ <!--
15
+ [![Tests](https://github.com/retothuerer/LabFREED/actions/workflows/ci.yml/badge.svg)](https://github.com/retothuerer/LabFREED/actions/workflows/ci.yml)
16
+ -->
17
+
18
+ This is a Python implementation of [LabFREED](www.labfreed.wega-it.com) building blocks.
19
+
20
+ ## Supported Building Blocks
21
+ - PAC-ID
22
+ - PAC-CAT
23
+ - TREX
24
+ - Display Extension
25
+
26
+ ## Installation
27
+ You can install LabFREED from [PyPI](https://pypi.org/project/labfreed/) using pip:
28
+
29
+ ```bash
30
+ pip install labfreed
31
+ ```
32
+
33
+
34
+ ## Usage Examples
35
+ > ⚠️ **Note:** These examples are building on each other. Imports and parsing are not repeated in each example.
36
+ <!-- BEGIN EXAMPLES -->
37
+ ### Parse a simple PAC-ID
38
+
39
+ ```python
40
+ from labfreed.parse_pac import PAC_Parser
41
+
42
+ # Parse the PAC-ID
43
+ pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234'
44
+ pac_id = PAC_Parser().parse(pac_str).pac_id
45
+
46
+ # Check validity of this PAC-ID
47
+ pac_id = PAC_Parser().parse(pac_str).pac_id
48
+ is_valid = pac_id.is_valid()
49
+ print('PAC-ID is valid: {is_valid}')
50
+ ```
51
+ ```text
52
+ >> PAC-ID is valid: {is_valid}
53
+ ```
54
+ ### Show recommendations:
55
+ Note that the PAC-ID -- while valid -- uses characters which are not recommended (results in larger QR code).
56
+ There is a nice function to highlight problems
57
+
58
+ ```python
59
+ pac_id.print_validation_messages()
60
+ ```
61
+ ```text
62
+ >> =======================================
63
+ >> Validation Results
64
+ >> ---------------------------------------
65
+ >>
66
+ >> Recommendation in id segment value bal500
67
+ >> HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234
68
+ >> Characters a b l should not be used.
69
+ >>
70
+ >> Recommendation in id segment value @1234
71
+ >> HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234
72
+ >> Characters @ should not be used.
73
+ >>
74
+ >> Warning in Category -MD
75
+ >> HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234
76
+ >> Category key -MD is not a well known key. It is recommended to use well known keys only
77
+ ```
78
+ ### PAC-CAT
79
+
80
+ ```python
81
+ from labfreed.PAC_CAT.data_model import PAC_CAT
82
+ pac_str = 'HTTPS://PAC.METTORIUS.COM/-DR/XQ908756/-MD/bal500/@1234'
83
+ pac_id = PAC_Parser().parse(pac_str).pac_id
84
+ if isinstance(pac_id, PAC_CAT):
85
+ pac_id.print_categories()
86
+ ```
87
+ ```text
88
+ >> Main Category
89
+ >> ----------
90
+ >> key (): -DR
91
+ >> id (21): XQ908756
92
+ >> Category
93
+ >> ------
94
+ >> key (): -MD
95
+ >> model_number (240): bal500
96
+ >> serial_number (21): @1234
97
+ ```
98
+ ### Parse a PAC-ID with extensions
99
+ PAC-ID can have extensions. Here we parse a PAC-ID with attached display names and summary.
100
+
101
+ ```python
102
+ pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/BAL500/1234*N$N/WM633OV3E5DGJW2BEG0PDM1EA7*SUM$TREX/WEIGHT$GRM:67.89'
103
+ pac_id = PAC_Parser().parse(pac_str)
104
+
105
+ # Display Name
106
+ display_names = pac_id.get_extension('N') # display name has name 'N'
107
+ print(display_names)
108
+ ```
109
+ ```text
110
+ >> Display names: My Balance ❤️
111
+ ```
112
+ ```python
113
+ # TREX
114
+ trexes = pac_id.get_extension_of_type('TREX')
115
+ trex = trexes[0] # there could be multiple trexes. In this example there is only one, though
116
+ v = trex.get_segment('WEIGHT').to_python_type()
117
+ print(f'WEIGHT = {v}')
118
+ ```
119
+ ```text
120
+ >> WEIGHT = 67.89 g
121
+ ```
122
+ ### Create a PAC-ID with Extensions
123
+
124
+ #### Create PAC-ID
125
+
126
+ ```python
127
+ from labfreed.PAC_ID.data_model import PACID, IDSegment
128
+ from labfreed.utilities.well_known_keys import WellKnownKeys
129
+
130
+ pac_id = PACID(issuer='METTORIUS:COM', identifier=[IDSegment(key=WellKnownKeys.SERIAL, value='1234')])
131
+ pac_str = pac_id.serialize()
132
+ print(pac_str)
133
+ ```
134
+ ```text
135
+ >> HTTPS://PAC.METTORIUS:COM/21:1234
136
+ ```
137
+ #### Create a TREX
138
+ TREX can conveniently be created from a python dictionary.
139
+ Note that utility types for Quantity (number with unit) and table are needed
140
+
141
+ ```python
142
+ from datetime import datetime
143
+ from labfreed.TREX.data_model import TREX
144
+ from labfreed.utilities.utility_types import Quantity, DataTable, Unit
145
+
146
+ # Create TREX
147
+ trex = TREX(name_='DEMO')
148
+ # Add value segments of different type
149
+ trex.update(
150
+ {
151
+ 'STOP': datetime(year=2024,month=5,day=5,hour=13,minute=6),
152
+ 'TEMP': Quantity(value=10.15, unit=Unit(name='kelvin', symbol='K')),
153
+ 'OK':False,
154
+ 'COMMENT': 'FOO',
155
+ 'COMMENT2':'£'
156
+ }
157
+ )
158
+
159
+ # Create a table
160
+ table = DataTable(['DURATION', 'DATE', 'OK', 'COMMENT'])
161
+ table.append([Quantity(value=1, unit=Unit(symbol='h', name='hour')), datetime.now(), True, 'FOO'])
162
+ table.append([ 1.1, datetime.now(), True, 'BAR'])
163
+ table.append([ 1.3, datetime.now(), False, 'BLUBB'])
164
+ #add the table to the trex
165
+ trex.update({'TABLE': table})
166
+
167
+ # Validation also works the same way for TREX
168
+ if trex.get_nested_validation_messages():
169
+ trex.print_validation_messages()
170
+
171
+ # Side Note: The TREX can be turned back into a dict
172
+ d = trex.dict()
173
+ ```
174
+ #### Combine PAC-ID and TREX and serialize
175
+
176
+ ```python
177
+ from labfreed.parse_pac import PACID_With_Extensions
178
+
179
+ pac_with_trex = PACID_With_Extensions(pac_id=pac_id, extensions=[trex])
180
+ pac_str = pac_with_trex.serialize()
181
+ print(pac_str)
182
+ ```
183
+ ```text
184
+ >> HTTPS://PAC.METTORIUS:COM/21:1234*DEMO$TREX/STOP$T.D:20240505T1306+TEMP$KEL:10.15+OK$T.B:F+COMMENT$T.A:FOO+COMMENT2$T.T:12G3+TABLE$$DURATION$HUR:DATE$T.D:OK$T.B:COMMENT$T.A::1:20250408T204437.738:T:FOO::1.1:20250408T204437.739:T:BAR::1.3:20250408T204437.739:F:BLUBB
185
+ ```
186
+ <!-- END EXAMPLES -->
187
+
188
+
189
+
190
+ ## Change Log
191
+
192
+ ### v0.0.16
193
+ - supports PAC-ID, PAC-CAT, TREX and DisplayName
194
+ - ok-ish test coverage
@@ -0,0 +1,185 @@
1
+ # LabFREED for Python
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![PyPI](https://img.shields.io/pypi/v/labfreed.svg)](https://pypi.org/project/labfreed/) ![Python Version](https://img.shields.io/pypi/pyversions/labfreed)
4
+
5
+ <!--
6
+ [![Tests](https://github.com/retothuerer/LabFREED/actions/workflows/ci.yml/badge.svg)](https://github.com/retothuerer/LabFREED/actions/workflows/ci.yml)
7
+ -->
8
+
9
+ This is a Python implementation of [LabFREED](www.labfreed.wega-it.com) building blocks.
10
+
11
+ ## Supported Building Blocks
12
+ - PAC-ID
13
+ - PAC-CAT
14
+ - TREX
15
+ - Display Extension
16
+
17
+ ## Installation
18
+ You can install LabFREED from [PyPI](https://pypi.org/project/labfreed/) using pip:
19
+
20
+ ```bash
21
+ pip install labfreed
22
+ ```
23
+
24
+
25
+ ## Usage Examples
26
+ > ⚠️ **Note:** These examples are building on each other. Imports and parsing are not repeated in each example.
27
+ <!-- BEGIN EXAMPLES -->
28
+ ### Parse a simple PAC-ID
29
+
30
+ ```python
31
+ from labfreed.parse_pac import PAC_Parser
32
+
33
+ # Parse the PAC-ID
34
+ pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234'
35
+ pac_id = PAC_Parser().parse(pac_str).pac_id
36
+
37
+ # Check validity of this PAC-ID
38
+ pac_id = PAC_Parser().parse(pac_str).pac_id
39
+ is_valid = pac_id.is_valid()
40
+ print('PAC-ID is valid: {is_valid}')
41
+ ```
42
+ ```text
43
+ >> PAC-ID is valid: {is_valid}
44
+ ```
45
+ ### Show recommendations:
46
+ Note that the PAC-ID -- while valid -- uses characters which are not recommended (results in larger QR code).
47
+ There is a nice function to highlight problems
48
+
49
+ ```python
50
+ pac_id.print_validation_messages()
51
+ ```
52
+ ```text
53
+ >> =======================================
54
+ >> Validation Results
55
+ >> ---------------------------------------
56
+ >>
57
+ >> Recommendation in id segment value bal500
58
+ >> HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234
59
+ >> Characters a b l should not be used.
60
+ >>
61
+ >> Recommendation in id segment value @1234
62
+ >> HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234
63
+ >> Characters @ should not be used.
64
+ >>
65
+ >> Warning in Category -MD
66
+ >> HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234
67
+ >> Category key -MD is not a well known key. It is recommended to use well known keys only
68
+ ```
69
+ ### PAC-CAT
70
+
71
+ ```python
72
+ from labfreed.PAC_CAT.data_model import PAC_CAT
73
+ pac_str = 'HTTPS://PAC.METTORIUS.COM/-DR/XQ908756/-MD/bal500/@1234'
74
+ pac_id = PAC_Parser().parse(pac_str).pac_id
75
+ if isinstance(pac_id, PAC_CAT):
76
+ pac_id.print_categories()
77
+ ```
78
+ ```text
79
+ >> Main Category
80
+ >> ----------
81
+ >> key (): -DR
82
+ >> id (21): XQ908756
83
+ >> Category
84
+ >> ------
85
+ >> key (): -MD
86
+ >> model_number (240): bal500
87
+ >> serial_number (21): @1234
88
+ ```
89
+ ### Parse a PAC-ID with extensions
90
+ PAC-ID can have extensions. Here we parse a PAC-ID with attached display names and summary.
91
+
92
+ ```python
93
+ pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/BAL500/1234*N$N/WM633OV3E5DGJW2BEG0PDM1EA7*SUM$TREX/WEIGHT$GRM:67.89'
94
+ pac_id = PAC_Parser().parse(pac_str)
95
+
96
+ # Display Name
97
+ display_names = pac_id.get_extension('N') # display name has name 'N'
98
+ print(display_names)
99
+ ```
100
+ ```text
101
+ >> Display names: My Balance ❤️
102
+ ```
103
+ ```python
104
+ # TREX
105
+ trexes = pac_id.get_extension_of_type('TREX')
106
+ trex = trexes[0] # there could be multiple trexes. In this example there is only one, though
107
+ v = trex.get_segment('WEIGHT').to_python_type()
108
+ print(f'WEIGHT = {v}')
109
+ ```
110
+ ```text
111
+ >> WEIGHT = 67.89 g
112
+ ```
113
+ ### Create a PAC-ID with Extensions
114
+
115
+ #### Create PAC-ID
116
+
117
+ ```python
118
+ from labfreed.PAC_ID.data_model import PACID, IDSegment
119
+ from labfreed.utilities.well_known_keys import WellKnownKeys
120
+
121
+ pac_id = PACID(issuer='METTORIUS:COM', identifier=[IDSegment(key=WellKnownKeys.SERIAL, value='1234')])
122
+ pac_str = pac_id.serialize()
123
+ print(pac_str)
124
+ ```
125
+ ```text
126
+ >> HTTPS://PAC.METTORIUS:COM/21:1234
127
+ ```
128
+ #### Create a TREX
129
+ TREX can conveniently be created from a python dictionary.
130
+ Note that utility types for Quantity (number with unit) and table are needed
131
+
132
+ ```python
133
+ from datetime import datetime
134
+ from labfreed.TREX.data_model import TREX
135
+ from labfreed.utilities.utility_types import Quantity, DataTable, Unit
136
+
137
+ # Create TREX
138
+ trex = TREX(name_='DEMO')
139
+ # Add value segments of different type
140
+ trex.update(
141
+ {
142
+ 'STOP': datetime(year=2024,month=5,day=5,hour=13,minute=6),
143
+ 'TEMP': Quantity(value=10.15, unit=Unit(name='kelvin', symbol='K')),
144
+ 'OK':False,
145
+ 'COMMENT': 'FOO',
146
+ 'COMMENT2':'£'
147
+ }
148
+ )
149
+
150
+ # Create a table
151
+ table = DataTable(['DURATION', 'DATE', 'OK', 'COMMENT'])
152
+ table.append([Quantity(value=1, unit=Unit(symbol='h', name='hour')), datetime.now(), True, 'FOO'])
153
+ table.append([ 1.1, datetime.now(), True, 'BAR'])
154
+ table.append([ 1.3, datetime.now(), False, 'BLUBB'])
155
+ #add the table to the trex
156
+ trex.update({'TABLE': table})
157
+
158
+ # Validation also works the same way for TREX
159
+ if trex.get_nested_validation_messages():
160
+ trex.print_validation_messages()
161
+
162
+ # Side Note: The TREX can be turned back into a dict
163
+ d = trex.dict()
164
+ ```
165
+ #### Combine PAC-ID and TREX and serialize
166
+
167
+ ```python
168
+ from labfreed.parse_pac import PACID_With_Extensions
169
+
170
+ pac_with_trex = PACID_With_Extensions(pac_id=pac_id, extensions=[trex])
171
+ pac_str = pac_with_trex.serialize()
172
+ print(pac_str)
173
+ ```
174
+ ```text
175
+ >> HTTPS://PAC.METTORIUS:COM/21:1234*DEMO$TREX/STOP$T.D:20240505T1306+TEMP$KEL:10.15+OK$T.B:F+COMMENT$T.A:FOO+COMMENT2$T.T:12G3+TABLE$$DURATION$HUR:DATE$T.D:OK$T.B:COMMENT$T.A::1:20250408T204437.738:T:FOO::1.1:20250408T204437.739:T:BAR::1.3:20250408T204437.739:F:BLUBB
176
+ ```
177
+ <!-- END EXAMPLES -->
178
+
179
+
180
+
181
+ ## Change Log
182
+
183
+ ### v0.0.16
184
+ - supports PAC-ID, PAC-CAT, TREX and DisplayName
185
+ - ok-ish test coverage
@@ -0,0 +1,118 @@
1
+ '''
2
+ ### Parse a simple PAC-ID
3
+ '''
4
+ from labfreed.parse_pac import PAC_Parser
5
+
6
+ # Parse the PAC-ID
7
+ pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234'
8
+ pac_id = PAC_Parser().parse(pac_str).pac_id
9
+
10
+ # Check validity of this PAC-ID
11
+ pac_id = PAC_Parser().parse(pac_str).pac_id
12
+ is_valid = pac_id.is_valid()
13
+ print('PAC-ID is valid: {is_valid}')
14
+
15
+ '''
16
+ ### Show recommendations:
17
+ Note that the PAC-ID -- while valid -- uses characters which are not recommended (results in larger QR code).
18
+ There is a nice function to highlight problems
19
+ '''
20
+ pac_id.print_validation_messages()
21
+
22
+
23
+ '''
24
+ ### PAC-CAT
25
+ '''
26
+ from labfreed.PAC_CAT.data_model import PAC_CAT
27
+ pac_str = 'HTTPS://PAC.METTORIUS.COM/-DR/XQ908756/-MD/bal500/@1234'
28
+ pac_id = PAC_Parser().parse(pac_str).pac_id
29
+ if isinstance(pac_id, PAC_CAT):
30
+ pac_id.print_categories()
31
+
32
+
33
+
34
+
35
+
36
+ '''
37
+ ### Parse a PAC-ID with extensions
38
+ PAC-ID can have extensions. Here we parse a PAC-ID with attached display names and summary.
39
+ '''
40
+ pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/BAL500/1234*N$N/WM633OV3E5DGJW2BEG0PDM1EA7*SUM$TREX/WEIGHT$GRM:67.89'
41
+ pac_id = PAC_Parser().parse(pac_str)
42
+
43
+ # Display Name
44
+ display_names = pac_id.get_extension('N') # display name has name 'N'
45
+ print(display_names)
46
+
47
+ ''''''
48
+ # TREX
49
+ trexes = pac_id.get_extension_of_type('TREX')
50
+ trex = trexes[0] # there could be multiple trexes. In this example there is only one, though
51
+ v = trex.get_segment('WEIGHT').to_python_type()
52
+ print(f'WEIGHT = {v}')
53
+
54
+
55
+
56
+ '''
57
+ ### Create a PAC-ID with Extensions
58
+
59
+ #### Create PAC-ID
60
+ '''
61
+ from labfreed.PAC_ID.data_model import PACID, IDSegment
62
+ from labfreed.utilities.well_known_keys import WellKnownKeys
63
+
64
+ pac_id = PACID(issuer='METTORIUS:COM', identifier=[IDSegment(key=WellKnownKeys.SERIAL, value='1234')])
65
+ pac_str = pac_id.serialize()
66
+ print(pac_str)
67
+
68
+
69
+ '''
70
+ #### Create a TREX
71
+ TREX can conveniently be created from a python dictionary.
72
+ Note that utility types for Quantity (number with unit) and table are needed
73
+ '''
74
+ from datetime import datetime
75
+ from labfreed.TREX.data_model import TREX
76
+ from labfreed.utilities.utility_types import Quantity, DataTable, Unit
77
+
78
+ # Create TREX
79
+ trex = TREX(name_='DEMO')
80
+ # Add value segments of different type
81
+ trex.update(
82
+ {
83
+ 'STOP': datetime(year=2024,month=5,day=5,hour=13,minute=6),
84
+ 'TEMP': Quantity(value=10.15, unit=Unit(name='kelvin', symbol='K')),
85
+ 'OK':False,
86
+ 'COMMENT': 'FOO',
87
+ 'COMMENT2':'£'
88
+ }
89
+ )
90
+
91
+ # Create a table
92
+ table = DataTable(['DURATION', 'DATE', 'OK', 'COMMENT'])
93
+ table.append([Quantity(value=1, unit=Unit(symbol='h', name='hour')), datetime.now(), True, 'FOO'])
94
+ table.append([ 1.1, datetime.now(), True, 'BAR'])
95
+ table.append([ 1.3, datetime.now(), False, 'BLUBB'])
96
+ #add the table to the trex
97
+ trex.update({'TABLE': table})
98
+
99
+ # Validation also works the same way for TREX
100
+ if trex.get_nested_validation_messages():
101
+ trex.print_validation_messages()
102
+
103
+ # Side Note: The TREX can be turned back into a dict
104
+ d = trex.dict()
105
+
106
+ '''
107
+ #### Combine PAC-ID and TREX and serialize
108
+ '''
109
+ from labfreed.parse_pac import PACID_With_Extensions
110
+
111
+ pac_with_trex = PACID_With_Extensions(pac_id=pac_id, extensions=[trex])
112
+ pac_str = pac_with_trex.serialize()
113
+ print(pac_str)
114
+
115
+
116
+
117
+
118
+
@@ -138,6 +138,19 @@ class PAC_CAT(PACID):
138
138
  )
139
139
  return self
140
140
 
141
+ def print_categories(self):
142
+ s = ''
143
+ for i, c in enumerate(self.categories):
144
+ if i == 0:
145
+ title = 'Main Category\n----------'
146
+ else:
147
+ title = 'Category\n------ '
148
+
149
+ s += f'{title}\n'
150
+ s += str(c)
151
+ s += '\n'
152
+ print(s)
153
+
141
154
 
142
155
  # @classmethod
143
156
  # def from_categories(cls, issuer:str, categories:list[Category]):
@@ -198,6 +211,11 @@ class Category(BaseModelWithValidationMessages):
198
211
  return self
199
212
 
200
213
 
214
+ def __str__(self):
215
+ s = '\n'.join( [f'{field_name} \t ({field_info.alias or ''}): \t {getattr(self, field_name)}' for field_name, field_info in self.model_fields.items() if getattr(self, field_name)])
216
+ return s
217
+
218
+
201
219
  # def to_identifier_category(self, use_short_notation=False):
202
220
  # '''Creates a Category with the correct segments.
203
221
  # Segments are in order of the Pydantic model fields.
@@ -261,14 +279,14 @@ class Material_Device(Category):
261
279
  self.add_validation_message(
262
280
  source=f"Category {self.key}",
263
281
  type="Error",
264
- msg=f'Category key {self.key} is missing mandatory field Model NUmber',
282
+ msg=f'Category key {self.key} is missing mandatory field Model Number',
265
283
  highlight_pattern = f"{self.key}"
266
284
  )
267
285
  if not self.serial_number:
268
286
  self.add_validation_message(
269
287
  source=f"Category {self.key}",
270
288
  type="Error",
271
- msg=f'Category key {self.key} is missing mandatory field Serial NUmber',
289
+ msg=f'Category key {self.key} is missing mandatory field Serial Number',
272
290
  highlight_pattern = f"{self.key}"
273
291
  )
274
292
 
@@ -286,7 +304,7 @@ class Material_Substance(Category):
286
304
  self.add_validation_message(
287
305
  source=f"Category {self.key}",
288
306
  type="Error",
289
- msg=f'Category key {self.key} is missing mandatory field Product NUmber',
307
+ msg=f'Category key {self.key} is missing mandatory field Product Number',
290
308
  highlight_pattern = f"{self.key}"
291
309
  )
292
310
 
@@ -328,19 +346,19 @@ class Data_Abstract(Category, ABC):
328
346
  highlight_pattern = f"{self.key}"
329
347
  )
330
348
 
331
- class Data_Result(Category):
349
+ class Data_Result(Data_Abstract):
332
350
  key: str = Field(default='-DR', frozen=True)
333
351
 
334
- class Data_Method(Category):
352
+ class Data_Method(Data_Abstract):
335
353
  key: str = Field(default='-DM', frozen=True)
336
354
 
337
- class Data_Calibration(Category):
355
+ class Data_Calibration(Data_Abstract):
338
356
  key: str = Field(default='-DC', frozen=True)
339
357
 
340
- class Data_Progress(Category):
358
+ class Data_Progress(Data_Abstract):
341
359
  key: str = Field(default='-DP', frozen=True)
342
360
 
343
- class Data_Static(Category):
361
+ class Data_Static(Data_Abstract):
344
362
  key: str = Field(default='-DS', frozen=True)
345
363
 
346
364
 
@@ -654,6 +654,7 @@ class TREX(Extension, BaseModelWithValidationMessages):
654
654
  data.append(r)
655
655
 
656
656
  self.segments.append(TREX_Table(key=k, column_headers=headers, data=data))
657
+ return self
657
658
 
658
659
 
659
660
  def dict(self):
@@ -2,4 +2,4 @@
2
2
  Python implementation of LabFREED building blocks
3
3
  '''
4
4
 
5
- __version__ = "0.0.14"
5
+ __version__ = "0.0.16"
@@ -49,7 +49,7 @@ class PACID_With_Extensions(BaseModelWithValidationMessages):
49
49
  @classmethod
50
50
  def deserialize(cls, url, extension_interpreters ):
51
51
  parser = PAC_Parser(extension_interpreters)
52
- return parser.parse_pac_with_extensions(url)
52
+ return parser.parse(url)
53
53
 
54
54
 
55
55
 
@@ -87,15 +87,15 @@ class PAC_Parser():
87
87
  def __init__(self, extension_interpreters:dict[str, Extension]=None):
88
88
  self.extension_interpreters = extension_interpreters or {'TREX': TREX, 'N': DisplayNames}
89
89
 
90
- def parse_pac_with_extensions(self, pac_url:str) -> PACID_With_Extensions:
90
+ def parse(self, pac_url:str) -> PACID_With_Extensions:
91
91
  if '*' in pac_url:
92
92
  id_str, ext_str = pac_url.split('*', 1)
93
93
  else:
94
94
  id_str = pac_url
95
95
  ext_str = ""
96
96
 
97
- pac_id = self.parse_pac_id(id_str)
98
- extensions = self.parse_extensions(ext_str)
97
+ pac_id = self._parse_pac_id(id_str)
98
+ extensions = self._parse_extensions(ext_str)
99
99
 
100
100
  pac_with_extension = PACID_With_Extensions(pac_id=pac_id, extensions=extensions)
101
101
  if not pac_with_extension.is_valid():
@@ -104,7 +104,7 @@ class PAC_Parser():
104
104
  return pac_with_extension
105
105
 
106
106
 
107
- def parse_pac_id(self,id_str:str) -> PACID:
107
+ def _parse_pac_id(self,id_str:str) -> PACID:
108
108
  m = re.match(f'(HTTPS://)?(PAC.)?(?P<issuer>.+?\..+?)/(?P<identifier>.*)', id_str)
109
109
  d = m.groupdict()
110
110
 
@@ -148,7 +148,7 @@ class PAC_Parser():
148
148
 
149
149
 
150
150
 
151
- def parse_extensions(self, extensions_str:str|None) -> list[Extension]:
151
+ def _parse_extensions(self, extensions_str:str|None) -> list[Extension]:
152
152
 
153
153
  extensions = list()
154
154
 
@@ -11,7 +11,7 @@ parser = PAC_Parser()
11
11
 
12
12
  # Extensions
13
13
  def test_valid_extensions():
14
- pac = parser.parse_pac_with_extensions(valid_base + valid_standard_segments + "*name1$t1/data1*name2$t2/data2")
14
+ pac = parser.parse(valid_base + valid_standard_segments + "*name1$t1/data1*name2$t2/data2")
15
15
  extensions = pac.extensions
16
16
  ext: Extension = extensions[0]
17
17
  assert ext.name == 'name1'
@@ -45,7 +45,7 @@ def test_known_extension_types_are_parsed():
45
45
  'KNOWN_EXTENSION': ExtensionMockType,
46
46
  }
47
47
  parser_with_known_extension = PAC_Parser(extension_interpreters)
48
- pac = parser_with_known_extension.parse_pac_with_extensions(valid_base + valid_standard_segments + "*name1$KNOWN_EXTENSION/data1")
48
+ pac = parser_with_known_extension.parse(valid_base + valid_standard_segments + "*name1$KNOWN_EXTENSION/data1")
49
49
  extensions= pac.extensions
50
50
  ext: Extension = extensions[0]
51
51
  assert isinstance(ext, ExtensionMockType)
@@ -55,7 +55,7 @@ def test_known_extension_types_are_parsed():
55
55
 
56
56
 
57
57
  def test_imply_display_name_and_summary_extension():
58
- pac = parser.parse_pac_with_extensions(valid_base + valid_standard_segments + "*data1*data2")
58
+ pac = parser.parse(valid_base + valid_standard_segments + "*data1*data2")
59
59
  extensions = pac.extensions
60
60
  ext: Extension = extensions[0]
61
61
  assert ext.name == 'N'
@@ -67,13 +67,13 @@ def test_imply_display_name_and_summary_extension():
67
67
 
68
68
  def test_stop_imply_extensions_after_explicit():
69
69
  with pytest.raises(Exception):
70
- pac = parser.parse_pac_with_extensions(valid_base + valid_standard_segments + "*N$T/data1*data2")
70
+ pac = parser.parse(valid_base + valid_standard_segments + "*N$T/data1*data2")
71
71
  pac.extensions
72
72
 
73
73
 
74
74
  def test_extension_parsing():
75
75
  s = '*NAME$MYFORMAT/AUGDSJGTZFRDGJHDSFRTZGHJAAUTZSGADT*NAME$ANOTHERFORMAT/BLUBBER'
76
- extensions = parser.parse_extensions(s)
76
+ extensions = parser._parse_extensions(s)
77
77
  ext: Extension = extensions[0]
78
78
  assert ext.name == 'NAME'
79
79
  assert ext.type == 'MYFORMAT'