labfreed 0.2.0b2__tar.gz → 0.2.1__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.
- labfreed-0.2.1/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- labfreed-0.2.1/.github/workflows/run-tests.yml +25 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/CHANGELOG.md +3 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/PKG-INFO +79 -70
- {labfreed-0.2.0b2 → labfreed-0.2.1}/README.md +78 -69
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/__init__.py +1 -1
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_cat/category_base.py +1 -1
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id_resolver/cit_v1.py +1 -1
- {labfreed-0.2.0b2 → labfreed-0.2.1}/pyproject.toml +1 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/.github/workflows/pypi-publish.yml +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/LICENSE +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/labfreed_infrastructure.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_cat/__init__.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_cat/pac_cat.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_cat/predefined_categories.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id/__init__.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id/extension.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id/id_segment.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id/pac_id.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id/url_parser.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id/url_serializer.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id_resolver/__init__.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id_resolver/cit_v2.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id_resolver/resolver.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/pac_id_resolver/services.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/qr/__init__.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/qr/generate_qr.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/trex/__init__.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/trex/python_convenience/__init__.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/trex/python_convenience/data_table.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/trex/python_convenience/pyTREX.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/trex/python_convenience/quantity.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/trex/table_segment.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/trex/trex.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/trex/trex_base_models.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/trex/value_segments.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/utilities/base36.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_extensions/__init__.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_extensions/default_extension_interpreters.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_extensions/display_name_extension.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_extensions/trex_extension.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_keys/gs1/__init__.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_keys/gs1/gs1.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_keys/gs1/gs1_ai_enum_sorted.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_keys/labfreed/well_known_keys.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_keys/unece/UneceUnits.json +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_keys/unece/__init__.py +0 -0
- {labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_keys/unece/unece_units.py +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Describe the bug**
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
**To Reproduce**
|
|
14
|
+
Steps to reproduce the behavior:
|
|
15
|
+
1. Go to '...'
|
|
16
|
+
2. Click on '....'
|
|
17
|
+
3. Scroll down to '....'
|
|
18
|
+
4. See error
|
|
19
|
+
|
|
20
|
+
**Expected behavior**
|
|
21
|
+
A clear and concise description of what you expected to happen.
|
|
22
|
+
|
|
23
|
+
**Screenshots**
|
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
|
25
|
+
|
|
26
|
+
**Environment(please complete the following information):**
|
|
27
|
+
- Python version[e.g. 22]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
**Additional context**
|
|
31
|
+
Add any other context about the problem here.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Test Labfreed
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v3
|
|
14
|
+
- name: Set up Python
|
|
15
|
+
uses: actions/setup-python@v4
|
|
16
|
+
with:
|
|
17
|
+
python-version: '3.11'
|
|
18
|
+
|
|
19
|
+
- name: Install project with dev dependencies
|
|
20
|
+
run: |
|
|
21
|
+
pip install flit
|
|
22
|
+
flit install --deps develop
|
|
23
|
+
|
|
24
|
+
- name: Run tests
|
|
25
|
+
run: pytest
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: labfreed
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Python implementation of LabFREED building blocks
|
|
5
5
|
Author-email: Reto Thürer <thuerer.r@buchi.com>
|
|
6
6
|
Requires-Python: >=3.11
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
9
|
Classifier: Programming Language :: Python
|
|
9
10
|
Classifier: Programming Language :: Python :: 3
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -30,11 +31,8 @@ Provides-Extra: dev
|
|
|
30
31
|
|
|
31
32
|
# LabFREED for Python
|
|
32
33
|
|
|
33
|
-
[](https://pypi.org/project/labfreed/)  [](https://github.com/retothuerer/LabFREED/actions/workflows/run-tests.yml) [](LICENSE)
|
|
34
35
|
|
|
35
|
-
<!--
|
|
36
|
-
[](https://github.com/retothuerer/LabFREED/actions/workflows/ci.yml)
|
|
37
|
-
-->
|
|
38
36
|
|
|
39
37
|
This is a Python implementation of [LabFREED](https://labfreed.wega-it.com) building blocks.
|
|
40
38
|
|
|
@@ -72,14 +70,13 @@ pip install labfreed
|
|
|
72
70
|
# import built ins
|
|
73
71
|
import os
|
|
74
72
|
|
|
75
|
-
|
|
73
|
+
|
|
76
74
|
```
|
|
77
75
|
### Parse a simple PAC-ID
|
|
78
76
|
|
|
79
77
|
```python
|
|
80
78
|
# Parse the PAC-ID
|
|
81
|
-
from labfreed
|
|
82
|
-
from labfreed import PAC_ID, LabFREED_ValidationError # noqa: E402, F811
|
|
79
|
+
from labfreed import PAC_ID, LabFREED_ValidationError
|
|
83
80
|
|
|
84
81
|
pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234'
|
|
85
82
|
try:
|
|
@@ -98,36 +95,38 @@ Note that the PAC-ID -- while valid -- uses characters which are not recommended
|
|
|
98
95
|
There is a nice function to highlight problems
|
|
99
96
|
|
|
100
97
|
```python
|
|
101
|
-
pac.print_validation_messages(
|
|
98
|
+
pac.print_validation_messages()
|
|
102
99
|
```
|
|
103
100
|
```text
|
|
104
|
-
>> Validation Results
|
|
105
|
-
>>
|
|
106
|
-
>> │ RECOMMENDATION in id segment value bal500
|
|
107
|
-
>> │ Characters '
|
|
108
|
-
>> │
|
|
109
|
-
>> │
|
|
110
|
-
>>
|
|
111
|
-
>>
|
|
112
|
-
>> │
|
|
113
|
-
>> │
|
|
114
|
-
>> │
|
|
115
|
-
>>
|
|
116
|
-
>>
|
|
117
|
-
>> │
|
|
118
|
-
>> │
|
|
119
|
-
>> │
|
|
120
|
-
>>
|
|
121
|
-
>> │
|
|
122
|
-
>>
|
|
123
|
-
>> │
|
|
124
|
-
>> │
|
|
125
|
-
>>
|
|
101
|
+
>> Validation Results
|
|
102
|
+
>> ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
103
|
+
>> │ RECOMMENDATION in id segment value bal500 │
|
|
104
|
+
>> │ Characters 'a','l','b' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' and │
|
|
105
|
+
>> │ '+' │
|
|
106
|
+
>> │ │
|
|
107
|
+
>> │ HTTPS://PAC.METTORIUS.COM/-MD/240:👉bal👈500/21:@1234 │
|
|
108
|
+
>> ├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
109
|
+
>> │ RECOMMENDATION in id segment value @1234 │
|
|
110
|
+
>> │ Characters '@' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' and '+' │
|
|
111
|
+
>> │ │
|
|
112
|
+
>> │ HTTPS://PAC.METTORIUS.COM/-MD/240:bal500/21:👉@👈1234 │
|
|
113
|
+
>> ├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
114
|
+
>> │ RECOMMENDATION in id segment value bal500 │
|
|
115
|
+
>> │ Characters 'a','l','b' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' and │
|
|
116
|
+
>> │ '+' │
|
|
117
|
+
>> │ │
|
|
118
|
+
>> │ HTTPS://PAC.METTORIUS.COM/-MD/240:👉bal👈500/21:@1234 │
|
|
119
|
+
>> ├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
120
|
+
>> │ RECOMMENDATION in id segment value @1234 │
|
|
121
|
+
>> │ Characters '@' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' and '+' │
|
|
122
|
+
>> │ │
|
|
123
|
+
>> │ HTTPS://PAC.METTORIUS.COM/-MD/240:bal500/21:👉@👈1234 │
|
|
124
|
+
>> └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
126
125
|
```
|
|
127
126
|
### Save as QR Code
|
|
128
127
|
|
|
129
128
|
```python
|
|
130
|
-
from labfreed.qr import save_qr_with_markers
|
|
129
|
+
from labfreed.qr import save_qr_with_markers
|
|
131
130
|
|
|
132
131
|
save_qr_with_markers(pac_str, fmt='png')
|
|
133
132
|
```
|
|
@@ -142,7 +141,7 @@ PAC-CAT defines a (optional) way how the identifier is structured.
|
|
|
142
141
|
PAC_ID.from_url() automatically converts to PAC-CAT if possible.
|
|
143
142
|
|
|
144
143
|
```python
|
|
145
|
-
from labfreed.pac_cat import PAC_CAT
|
|
144
|
+
from labfreed.pac_cat import PAC_CAT
|
|
146
145
|
pac_str = 'HTTPS://PAC.METTORIUS.COM/-DR/XQ908756/-MD/bal500/@1234'
|
|
147
146
|
pac = PAC_ID.from_url(pac_str)
|
|
148
147
|
if isinstance(pac, PAC_CAT):
|
|
@@ -198,8 +197,8 @@ print(f'WEIGHT = {v.value}')
|
|
|
198
197
|
#### Create PAC-ID
|
|
199
198
|
|
|
200
199
|
```python
|
|
201
|
-
from labfreed.pac_id import PAC_ID, IDSegment
|
|
202
|
-
from labfreed.well_known_keys.labfreed.well_known_keys import WellKnownKeys
|
|
200
|
+
from labfreed.pac_id import PAC_ID, IDSegment
|
|
201
|
+
from labfreed.well_known_keys.labfreed.well_known_keys import WellKnownKeys
|
|
203
202
|
|
|
204
203
|
pac = PAC_ID(issuer='METTORIUS.COM', identifier=[IDSegment(key=WellKnownKeys.SERIAL, value='1234')])
|
|
205
204
|
pac_str = pac.to_url()
|
|
@@ -213,10 +212,10 @@ TREX can conveniently be created from a python dictionary.
|
|
|
213
212
|
Note that utility types for Quantity (number with unit) and table are needed
|
|
214
213
|
|
|
215
214
|
```python
|
|
216
|
-
from datetime import datetime
|
|
217
|
-
from labfreed.trex.python_convenience.pyTREX import pyTREX
|
|
218
|
-
from labfreed.trex.python_convenience.data_table import DataTable
|
|
219
|
-
from labfreed.trex.python_convenience.quantity import Quantity
|
|
215
|
+
from datetime import datetime
|
|
216
|
+
from labfreed.trex.python_convenience.pyTREX import pyTREX
|
|
217
|
+
from labfreed.trex.python_convenience.data_table import DataTable
|
|
218
|
+
from labfreed.trex.python_convenience.quantity import Quantity
|
|
220
219
|
|
|
221
220
|
# Value segments of different type
|
|
222
221
|
segments = {
|
|
@@ -241,40 +240,40 @@ trex = mydata.to_trex()
|
|
|
241
240
|
|
|
242
241
|
|
|
243
242
|
# Validation also works the same way for TREX
|
|
244
|
-
trex.print_validation_messages(
|
|
243
|
+
trex.print_validation_messages()
|
|
245
244
|
```
|
|
246
245
|
```text
|
|
247
246
|
>> Validation Results
|
|
248
247
|
>> ┌────────────────────────────────────────────────────────────┐
|
|
249
248
|
>> │ ERROR in TREX table column Date │
|
|
250
|
-
>> │ Column header key contains invalid characters: 'a','
|
|
249
|
+
>> │ Column header key contains invalid characters: 'a','e','t' │
|
|
251
250
|
>> │ │
|
|
252
251
|
>> │ STOP$T.D:20240505T1306 │
|
|
253
252
|
>> │ +TEMP$KEL:10.15 │
|
|
254
253
|
>> │ +OK$T.B:F │
|
|
255
254
|
>> │ +COMMENT$T.A:FOO │
|
|
256
255
|
>> │ +COMMENT2$T.T:QMDTNXIKU │
|
|
257
|
-
>> │ +TABLE$$DURATION$HUR:
|
|
258
|
-
>> │ 1:
|
|
259
|
-
>> │ 1.1:
|
|
260
|
-
>> │ 1.3:
|
|
256
|
+
>> │ +TABLE$$DURATION$HUR:D👉ate👈$T.D:OK$T.B:COMMENT$T.A:: │
|
|
257
|
+
>> │ 1:20250424T161739.312:T:FOO:: │
|
|
258
|
+
>> │ 1.1:20250424T161739.312:T:BAR:: │
|
|
259
|
+
>> │ 1.3:20250424T161739.312:F:BLUBB │
|
|
261
260
|
>> └────────────────────────────────────────────────────────────┘
|
|
262
261
|
```
|
|
263
262
|
#### Combine PAC-ID and TREX and serialize
|
|
264
263
|
|
|
265
264
|
```python
|
|
266
|
-
from labfreed.well_known_extensions import TREX_Extension
|
|
265
|
+
from labfreed.well_known_extensions import TREX_Extension
|
|
267
266
|
pac.extensions = [TREX_Extension(name='MYTREX', trex=trex)]
|
|
268
267
|
pac_str = pac.to_url()
|
|
269
268
|
print(pac_str)
|
|
270
269
|
```
|
|
271
270
|
```text
|
|
272
|
-
>> HTTPS://PAC.METTORIUS.COM/21:1234*MYTREX$TREX/STOP$T.D:20240505T1306+TEMP$KEL:10.15+OK$T.B:F+COMMENT$T.A:FOO+COMMENT2$T.T:QMDTNXIKU+TABLE$$DURATION$HUR:Date$T.D:OK$T.B:COMMENT$T.A::1:
|
|
271
|
+
>> HTTPS://PAC.METTORIUS.COM/21:1234*MYTREX$TREX/STOP$T.D:20240505T1306+TEMP$KEL:10.15+OK$T.B:F+COMMENT$T.A:FOO+COMMENT2$T.T:QMDTNXIKU+TABLE$$DURATION$HUR:Date$T.D:OK$T.B:COMMENT$T.A::1:20250424T161739.312:T:FOO::1.1:20250424T161739.312:T:BAR::1.3:20250424T161739.312:F:BLUBB
|
|
273
272
|
```
|
|
274
273
|
## PAC-ID Resolver
|
|
275
274
|
|
|
276
275
|
```python
|
|
277
|
-
from labfreed.pac_id_resolver import PAC_ID_Resolver, load_cit
|
|
276
|
+
from labfreed.pac_id_resolver import PAC_ID_Resolver, load_cit
|
|
278
277
|
# Get a CIT
|
|
279
278
|
dir = os.path.join(os.getcwd(), 'examples')
|
|
280
279
|
p = os.path.join(dir, 'cit_mine.yaml')
|
|
@@ -282,7 +281,7 @@ cit = load_cit(p)
|
|
|
282
281
|
|
|
283
282
|
# validate the CIT
|
|
284
283
|
cit.is_valid
|
|
285
|
-
cit.print_validation_messages(
|
|
284
|
+
cit.print_validation_messages()
|
|
286
285
|
```
|
|
287
286
|
```python
|
|
288
287
|
# get a second cit
|
|
@@ -300,31 +299,41 @@ for sg in service_groups:
|
|
|
300
299
|
|
|
301
300
|
```
|
|
302
301
|
```text
|
|
303
|
-
>>
|
|
304
|
-
>> ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
|
|
305
|
-
>> ┃ Service Name ┃ URL ┃ Reachable ┃
|
|
306
|
-
>> ┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
|
|
307
|
-
>> │ CAS Search │ https://pubchem.ncbi.nlm.nih.gov/#query=7732-18-5 │ ACTIVE │
|
|
308
|
-
>> └──────────────┴───────────────────────────────────────────────────┴───────────┘
|
|
309
|
-
>> Services from origin 'MY_COMPANY
|
|
310
|
-
>> ┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
|
|
311
|
-
>> ┃ Service Name ┃ URL ┃ Reachable ┃
|
|
312
|
-
>> ┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
|
|
313
|
-
>> │ Chemical Management │ https://chem-manager.com/METTORIUS.COM/-MS/240:X3511/CAS:7732-18-5 │ INACTIVE │
|
|
314
|
-
>> └─────────────────────┴────────────────────────────────────────────────────────────────────┴───────────┘
|
|
315
|
-
>> Services from origin 'METTORIUS.COM
|
|
316
|
-
>> ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
|
|
317
|
-
>> ┃ Service Name ┃ URL ┃ Reachable ┃
|
|
318
|
-
>> ┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
|
|
319
|
-
>> │ CoA │ https://mettorius.com/CoA.pdf │ ACTIVE │
|
|
320
|
-
>> │ MSDS │ https://mettorius.com/MSDS.pdf │ ACTIVE │
|
|
321
|
-
>> │ Shop │ https://mettorius.com/shop.html │ ACTIVE │
|
|
322
|
-
>> └──────────────┴─────────────────────────────────┴───────────┘
|
|
302
|
+
>> [Error during execution: No Internet Connection]
|
|
323
303
|
```
|
|
324
304
|
<!-- END EXAMPLES -->
|
|
325
305
|
|
|
326
306
|
|
|
327
307
|
|
|
308
|
+
<!-- BEGIN CHANGELOG -->
|
|
328
309
|
## Change Log
|
|
329
|
-
|
|
310
|
+
### v0.2.1
|
|
311
|
+
- improved docu. no code changes
|
|
312
|
+
|
|
313
|
+
### v0.2.0b2
|
|
314
|
+
- improvements in api consistency and ease of use
|
|
315
|
+
- restructured code for better separation of concerns
|
|
316
|
+
- support for coupling information table v1
|
|
330
317
|
|
|
318
|
+
### v0.1.1
|
|
319
|
+
- minor internal improvements and bugfixes
|
|
320
|
+
|
|
321
|
+
### v0.1.0
|
|
322
|
+
- DRAFT Support for PAC-ID Resolver
|
|
323
|
+
|
|
324
|
+
### v0.0.20
|
|
325
|
+
- bugfix in TREX table to dict conversion
|
|
326
|
+
- markdown compatible validation printing
|
|
327
|
+
|
|
328
|
+
### v0.0.19
|
|
329
|
+
- supports PAC-ID, PAC-CAT, TREX and DisplayName
|
|
330
|
+
- QR generation
|
|
331
|
+
- ok-ish test coverage
|
|
332
|
+
|
|
333
|
+
# Attributions
|
|
334
|
+
The following tools were used:
|
|
335
|
+
- [pdoc](https://pdoc.dev/) was a great help with generating documentation
|
|
336
|
+
- [Pydantic](https://docs.pydantic.dev/latest/)
|
|
337
|
+
- json with UNECE units from (https://github.com/quadient/unece-units/blob/main/python/src/unece_excel_parser/parsedUneceUnits.json)
|
|
338
|
+
- json with GS1 codes from (https://ref.gs1.org/ai/GS1_Application_Identifiers.jsonld)
|
|
339
|
+
<!-- END CHANGELOG -->
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
# LabFREED for Python
|
|
2
2
|
|
|
3
|
-
[](https://pypi.org/project/labfreed/)  [](https://github.com/retothuerer/LabFREED/actions/workflows/run-tests.yml) [](LICENSE)
|
|
4
4
|
|
|
5
|
-
<!--
|
|
6
|
-
[](https://github.com/retothuerer/LabFREED/actions/workflows/ci.yml)
|
|
7
|
-
-->
|
|
8
5
|
|
|
9
6
|
This is a Python implementation of [LabFREED](https://labfreed.wega-it.com) building blocks.
|
|
10
7
|
|
|
@@ -42,14 +39,13 @@ pip install labfreed
|
|
|
42
39
|
# import built ins
|
|
43
40
|
import os
|
|
44
41
|
|
|
45
|
-
|
|
42
|
+
|
|
46
43
|
```
|
|
47
44
|
### Parse a simple PAC-ID
|
|
48
45
|
|
|
49
46
|
```python
|
|
50
47
|
# Parse the PAC-ID
|
|
51
|
-
from labfreed
|
|
52
|
-
from labfreed import PAC_ID, LabFREED_ValidationError # noqa: E402, F811
|
|
48
|
+
from labfreed import PAC_ID, LabFREED_ValidationError
|
|
53
49
|
|
|
54
50
|
pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234'
|
|
55
51
|
try:
|
|
@@ -68,36 +64,38 @@ Note that the PAC-ID -- while valid -- uses characters which are not recommended
|
|
|
68
64
|
There is a nice function to highlight problems
|
|
69
65
|
|
|
70
66
|
```python
|
|
71
|
-
pac.print_validation_messages(
|
|
67
|
+
pac.print_validation_messages()
|
|
72
68
|
```
|
|
73
69
|
```text
|
|
74
|
-
>> Validation Results
|
|
75
|
-
>>
|
|
76
|
-
>> │ RECOMMENDATION in id segment value bal500
|
|
77
|
-
>> │ Characters '
|
|
78
|
-
>> │
|
|
79
|
-
>> │
|
|
80
|
-
>>
|
|
81
|
-
>>
|
|
82
|
-
>> │
|
|
83
|
-
>> │
|
|
84
|
-
>> │
|
|
85
|
-
>>
|
|
86
|
-
>>
|
|
87
|
-
>> │
|
|
88
|
-
>> │
|
|
89
|
-
>> │
|
|
90
|
-
>>
|
|
91
|
-
>> │
|
|
92
|
-
>>
|
|
93
|
-
>> │
|
|
94
|
-
>> │
|
|
95
|
-
>>
|
|
70
|
+
>> Validation Results
|
|
71
|
+
>> ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
72
|
+
>> │ RECOMMENDATION in id segment value bal500 │
|
|
73
|
+
>> │ Characters 'a','l','b' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' and │
|
|
74
|
+
>> │ '+' │
|
|
75
|
+
>> │ │
|
|
76
|
+
>> │ HTTPS://PAC.METTORIUS.COM/-MD/240:👉bal👈500/21:@1234 │
|
|
77
|
+
>> ├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
78
|
+
>> │ RECOMMENDATION in id segment value @1234 │
|
|
79
|
+
>> │ Characters '@' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' and '+' │
|
|
80
|
+
>> │ │
|
|
81
|
+
>> │ HTTPS://PAC.METTORIUS.COM/-MD/240:bal500/21:👉@👈1234 │
|
|
82
|
+
>> ├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
83
|
+
>> │ RECOMMENDATION in id segment value bal500 │
|
|
84
|
+
>> │ Characters 'a','l','b' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' and │
|
|
85
|
+
>> │ '+' │
|
|
86
|
+
>> │ │
|
|
87
|
+
>> │ HTTPS://PAC.METTORIUS.COM/-MD/240:👉bal👈500/21:@1234 │
|
|
88
|
+
>> ├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
89
|
+
>> │ RECOMMENDATION in id segment value @1234 │
|
|
90
|
+
>> │ Characters '@' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' and '+' │
|
|
91
|
+
>> │ │
|
|
92
|
+
>> │ HTTPS://PAC.METTORIUS.COM/-MD/240:bal500/21:👉@👈1234 │
|
|
93
|
+
>> └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
96
94
|
```
|
|
97
95
|
### Save as QR Code
|
|
98
96
|
|
|
99
97
|
```python
|
|
100
|
-
from labfreed.qr import save_qr_with_markers
|
|
98
|
+
from labfreed.qr import save_qr_with_markers
|
|
101
99
|
|
|
102
100
|
save_qr_with_markers(pac_str, fmt='png')
|
|
103
101
|
```
|
|
@@ -112,7 +110,7 @@ PAC-CAT defines a (optional) way how the identifier is structured.
|
|
|
112
110
|
PAC_ID.from_url() automatically converts to PAC-CAT if possible.
|
|
113
111
|
|
|
114
112
|
```python
|
|
115
|
-
from labfreed.pac_cat import PAC_CAT
|
|
113
|
+
from labfreed.pac_cat import PAC_CAT
|
|
116
114
|
pac_str = 'HTTPS://PAC.METTORIUS.COM/-DR/XQ908756/-MD/bal500/@1234'
|
|
117
115
|
pac = PAC_ID.from_url(pac_str)
|
|
118
116
|
if isinstance(pac, PAC_CAT):
|
|
@@ -168,8 +166,8 @@ print(f'WEIGHT = {v.value}')
|
|
|
168
166
|
#### Create PAC-ID
|
|
169
167
|
|
|
170
168
|
```python
|
|
171
|
-
from labfreed.pac_id import PAC_ID, IDSegment
|
|
172
|
-
from labfreed.well_known_keys.labfreed.well_known_keys import WellKnownKeys
|
|
169
|
+
from labfreed.pac_id import PAC_ID, IDSegment
|
|
170
|
+
from labfreed.well_known_keys.labfreed.well_known_keys import WellKnownKeys
|
|
173
171
|
|
|
174
172
|
pac = PAC_ID(issuer='METTORIUS.COM', identifier=[IDSegment(key=WellKnownKeys.SERIAL, value='1234')])
|
|
175
173
|
pac_str = pac.to_url()
|
|
@@ -183,10 +181,10 @@ TREX can conveniently be created from a python dictionary.
|
|
|
183
181
|
Note that utility types for Quantity (number with unit) and table are needed
|
|
184
182
|
|
|
185
183
|
```python
|
|
186
|
-
from datetime import datetime
|
|
187
|
-
from labfreed.trex.python_convenience.pyTREX import pyTREX
|
|
188
|
-
from labfreed.trex.python_convenience.data_table import DataTable
|
|
189
|
-
from labfreed.trex.python_convenience.quantity import Quantity
|
|
184
|
+
from datetime import datetime
|
|
185
|
+
from labfreed.trex.python_convenience.pyTREX import pyTREX
|
|
186
|
+
from labfreed.trex.python_convenience.data_table import DataTable
|
|
187
|
+
from labfreed.trex.python_convenience.quantity import Quantity
|
|
190
188
|
|
|
191
189
|
# Value segments of different type
|
|
192
190
|
segments = {
|
|
@@ -211,40 +209,40 @@ trex = mydata.to_trex()
|
|
|
211
209
|
|
|
212
210
|
|
|
213
211
|
# Validation also works the same way for TREX
|
|
214
|
-
trex.print_validation_messages(
|
|
212
|
+
trex.print_validation_messages()
|
|
215
213
|
```
|
|
216
214
|
```text
|
|
217
215
|
>> Validation Results
|
|
218
216
|
>> ┌────────────────────────────────────────────────────────────┐
|
|
219
217
|
>> │ ERROR in TREX table column Date │
|
|
220
|
-
>> │ Column header key contains invalid characters: 'a','
|
|
218
|
+
>> │ Column header key contains invalid characters: 'a','e','t' │
|
|
221
219
|
>> │ │
|
|
222
220
|
>> │ STOP$T.D:20240505T1306 │
|
|
223
221
|
>> │ +TEMP$KEL:10.15 │
|
|
224
222
|
>> │ +OK$T.B:F │
|
|
225
223
|
>> │ +COMMENT$T.A:FOO │
|
|
226
224
|
>> │ +COMMENT2$T.T:QMDTNXIKU │
|
|
227
|
-
>> │ +TABLE$$DURATION$HUR:
|
|
228
|
-
>> │ 1:
|
|
229
|
-
>> │ 1.1:
|
|
230
|
-
>> │ 1.3:
|
|
225
|
+
>> │ +TABLE$$DURATION$HUR:D👉ate👈$T.D:OK$T.B:COMMENT$T.A:: │
|
|
226
|
+
>> │ 1:20250424T161739.312:T:FOO:: │
|
|
227
|
+
>> │ 1.1:20250424T161739.312:T:BAR:: │
|
|
228
|
+
>> │ 1.3:20250424T161739.312:F:BLUBB │
|
|
231
229
|
>> └────────────────────────────────────────────────────────────┘
|
|
232
230
|
```
|
|
233
231
|
#### Combine PAC-ID and TREX and serialize
|
|
234
232
|
|
|
235
233
|
```python
|
|
236
|
-
from labfreed.well_known_extensions import TREX_Extension
|
|
234
|
+
from labfreed.well_known_extensions import TREX_Extension
|
|
237
235
|
pac.extensions = [TREX_Extension(name='MYTREX', trex=trex)]
|
|
238
236
|
pac_str = pac.to_url()
|
|
239
237
|
print(pac_str)
|
|
240
238
|
```
|
|
241
239
|
```text
|
|
242
|
-
>> HTTPS://PAC.METTORIUS.COM/21:1234*MYTREX$TREX/STOP$T.D:20240505T1306+TEMP$KEL:10.15+OK$T.B:F+COMMENT$T.A:FOO+COMMENT2$T.T:QMDTNXIKU+TABLE$$DURATION$HUR:Date$T.D:OK$T.B:COMMENT$T.A::1:
|
|
240
|
+
>> HTTPS://PAC.METTORIUS.COM/21:1234*MYTREX$TREX/STOP$T.D:20240505T1306+TEMP$KEL:10.15+OK$T.B:F+COMMENT$T.A:FOO+COMMENT2$T.T:QMDTNXIKU+TABLE$$DURATION$HUR:Date$T.D:OK$T.B:COMMENT$T.A::1:20250424T161739.312:T:FOO::1.1:20250424T161739.312:T:BAR::1.3:20250424T161739.312:F:BLUBB
|
|
243
241
|
```
|
|
244
242
|
## PAC-ID Resolver
|
|
245
243
|
|
|
246
244
|
```python
|
|
247
|
-
from labfreed.pac_id_resolver import PAC_ID_Resolver, load_cit
|
|
245
|
+
from labfreed.pac_id_resolver import PAC_ID_Resolver, load_cit
|
|
248
246
|
# Get a CIT
|
|
249
247
|
dir = os.path.join(os.getcwd(), 'examples')
|
|
250
248
|
p = os.path.join(dir, 'cit_mine.yaml')
|
|
@@ -252,7 +250,7 @@ cit = load_cit(p)
|
|
|
252
250
|
|
|
253
251
|
# validate the CIT
|
|
254
252
|
cit.is_valid
|
|
255
|
-
cit.print_validation_messages(
|
|
253
|
+
cit.print_validation_messages()
|
|
256
254
|
```
|
|
257
255
|
```python
|
|
258
256
|
# get a second cit
|
|
@@ -270,30 +268,41 @@ for sg in service_groups:
|
|
|
270
268
|
|
|
271
269
|
```
|
|
272
270
|
```text
|
|
273
|
-
>>
|
|
274
|
-
>> ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
|
|
275
|
-
>> ┃ Service Name ┃ URL ┃ Reachable ┃
|
|
276
|
-
>> ┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
|
|
277
|
-
>> │ CAS Search │ https://pubchem.ncbi.nlm.nih.gov/#query=7732-18-5 │ ACTIVE │
|
|
278
|
-
>> └──────────────┴───────────────────────────────────────────────────┴───────────┘
|
|
279
|
-
>> Services from origin 'MY_COMPANY
|
|
280
|
-
>> ┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
|
|
281
|
-
>> ┃ Service Name ┃ URL ┃ Reachable ┃
|
|
282
|
-
>> ┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
|
|
283
|
-
>> │ Chemical Management │ https://chem-manager.com/METTORIUS.COM/-MS/240:X3511/CAS:7732-18-5 │ INACTIVE │
|
|
284
|
-
>> └─────────────────────┴────────────────────────────────────────────────────────────────────┴───────────┘
|
|
285
|
-
>> Services from origin 'METTORIUS.COM
|
|
286
|
-
>> ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
|
|
287
|
-
>> ┃ Service Name ┃ URL ┃ Reachable ┃
|
|
288
|
-
>> ┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
|
|
289
|
-
>> │ CoA │ https://mettorius.com/CoA.pdf │ ACTIVE │
|
|
290
|
-
>> │ MSDS │ https://mettorius.com/MSDS.pdf │ ACTIVE │
|
|
291
|
-
>> │ Shop │ https://mettorius.com/shop.html │ ACTIVE │
|
|
292
|
-
>> └──────────────┴─────────────────────────────────┴───────────┘
|
|
271
|
+
>> [Error during execution: No Internet Connection]
|
|
293
272
|
```
|
|
294
273
|
<!-- END EXAMPLES -->
|
|
295
274
|
|
|
296
275
|
|
|
297
276
|
|
|
277
|
+
<!-- BEGIN CHANGELOG -->
|
|
298
278
|
## Change Log
|
|
299
|
-
|
|
279
|
+
### v0.2.1
|
|
280
|
+
- improved docu. no code changes
|
|
281
|
+
|
|
282
|
+
### v0.2.0b2
|
|
283
|
+
- improvements in api consistency and ease of use
|
|
284
|
+
- restructured code for better separation of concerns
|
|
285
|
+
- support for coupling information table v1
|
|
286
|
+
|
|
287
|
+
### v0.1.1
|
|
288
|
+
- minor internal improvements and bugfixes
|
|
289
|
+
|
|
290
|
+
### v0.1.0
|
|
291
|
+
- DRAFT Support for PAC-ID Resolver
|
|
292
|
+
|
|
293
|
+
### v0.0.20
|
|
294
|
+
- bugfix in TREX table to dict conversion
|
|
295
|
+
- markdown compatible validation printing
|
|
296
|
+
|
|
297
|
+
### v0.0.19
|
|
298
|
+
- supports PAC-ID, PAC-CAT, TREX and DisplayName
|
|
299
|
+
- QR generation
|
|
300
|
+
- ok-ish test coverage
|
|
301
|
+
|
|
302
|
+
# Attributions
|
|
303
|
+
The following tools were used:
|
|
304
|
+
- [pdoc](https://pdoc.dev/) was a great help with generating documentation
|
|
305
|
+
- [Pydantic](https://docs.pydantic.dev/latest/)
|
|
306
|
+
- json with UNECE units from (https://github.com/quadient/unece-units/blob/main/python/src/unece_excel_parser/parsedUneceUnits.json)
|
|
307
|
+
- json with GS1 codes from (https://ref.gs1.org/ai/GS1_Application_Identifiers.jsonld)
|
|
308
|
+
<!-- END CHANGELOG -->
|
|
@@ -41,7 +41,7 @@ class Category(LabFREED_BaseModel):
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
def __str__(self):
|
|
44
|
-
s = '\n'.join( [f
|
|
44
|
+
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)])
|
|
45
45
|
return s
|
|
46
46
|
|
|
47
47
|
|
|
@@ -110,7 +110,7 @@ class CIT_v1(LabFREED_BaseModel):
|
|
|
110
110
|
i = int(m.group(1)) - 1 # CIT is 1 based
|
|
111
111
|
seg = pac.identifier[i] if i < len(pac.identifier) else None
|
|
112
112
|
if seg:
|
|
113
|
-
return f"{(seg.key + ':') if seg.key else
|
|
113
|
+
return f"{(seg.key + ':') if seg.key else ''}{seg.value}"
|
|
114
114
|
|
|
115
115
|
elif m := re.match(r'\{idVal(\w+)\}', value):
|
|
116
116
|
k = m.group(1)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_extensions/default_extension_interpreters.py
RENAMED
|
File without changes
|
{labfreed-0.2.0b2 → labfreed-0.2.1}/labfreed/well_known_extensions/display_name_extension.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|