Python implementation of LabFREED building blocks
Project description
LabFREED for Python
This is a Python implementation of LabFREED building blocks.
Supported Building Blocks
-
PAC-ID
- Parsing
- Serialization
-
PAC-CAT
- Interpretation of PAC-ID as categories
-
T-REX
- Parsing
- Serialization
-
Display Extension
- base36 <> str conversions
-
PAC-ID Resolver
- support for CIT v1
- draft support for CIT v2 (improved version)
- combined use of multiple cit in any combination of version
-
Generation of QR codes (PAC-ID with extensions)
-
Validation (with Errors Recommendations)
Installation
You can install LabFREED from PyPI using pip:
pip install labfreed
Usage Examples
⚠️ Note: These examples are building on each other. Imports and parsing are not repeated in each example.
# import built ins
import os
Parse a simple PAC-ID
# Parse the PAC-ID
from labfreed import PAC_ID, LabFREED_ValidationError
pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234'
try:
pac = PAC_ID.from_url(pac_str)
except LabFREED_ValidationError:
pass
# Check validity of this PAC-ID
is_valid = pac.is_valid
print(f'PAC-ID is valid: {is_valid}')
>> PAC-ID is valid: True
Show recommendations:
Note that the PAC-ID -- while valid -- uses characters which are not recommended (results in larger QR code). There is a nice function to highlight problems
pac.print_validation_messages()
>> Validation Results
>> ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
>> │ **RECOMMENDATION** in id segment value bal500 │
>> │ Characters 'a','l','b' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers │
>> │ (0-9), '-' and '+' │
>> │ │
>> │ HTTPS://PAC.METTORIUS.COM/-MD/👉bal👈500/@1234 │
>> ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
>> │ **RECOMMENDATION** in id segment value @1234 │
>> │ Characters '@' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' │
>> │ and '+' │
>> │ │
>> │ HTTPS://PAC.METTORIUS.COM/-MD/bal500/👉@👈1234 │
>> ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
>> │ **RECOMMENDATION** in id segment value bal500 │
>> │ Characters 'a','l','b' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers │
>> │ (0-9), '-' and '+' │
>> │ │
>> │ HTTPS://PAC.METTORIUS.COM/-MD/👉bal👈500/@1234 │
>> ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
>> │ **RECOMMENDATION** in id segment value @1234 │
>> │ Characters '@' should not be used., Characters SHOULD be limited to upper case letters (A-Z), numbers (0-9), '-' │
>> │ and '+' │
>> │ │
>> │ HTTPS://PAC.METTORIUS.COM/-MD/bal500/👉@👈1234 │
>> └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Save as QR Code
from labfreed.qr import save_qr_with_markers
save_qr_with_markers(pac_str, fmt='png')
>> Large QR: Provided URL is not alphanumeric!
>> Size: 29
>> Version: 3
>> Error Level: M
PAC-CAT
PAC-CAT defines a (optional) way how the identifier is structured. PAC_ID.from_url() automatically converts to PAC-CAT if possible.
from labfreed import PAC_CAT
pac_str = 'HTTPS://PAC.METTORIUS.COM/-DR/XQ908756/-MD/bal500/@1234'
pac = PAC_ID.from_url(pac_str)
if isinstance(pac, PAC_CAT):
categories = pac.categories
pac.print_categories()
>> Categories in
>> HTTPS://PAC.METTORIUS.COM/-DR/XQ90
>> 8756/-MD/bal500/@1234
>> ┌────────────────────┬───────────┐
>> │ Main Category │ │
>> │ key () │ -DR │
>> │ id (21) │ XQ908756 │
>> ├────────────────────┼───────────┤
>> │ Category │ │
>> │ key () │ -MD │
>> │ model_number (240) │ bal500 │
>> │ serial_number (21) │ @1234 │
>> └────────────────────┴───────────┘
Parse a PAC-ID with extensions
PAC-ID can have extensions. Here we parse a PAC-ID with attached display names and summary.
pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/BAL500/1234*N$N/WM633OV3E5DGJW2BEG0PDM1EA7*SUM$TREX/WEIGHT$GRM:67.89'
pac = PAC_ID.from_url(pac_str)
Display Name
Note that the Extension is automatically converted to a DisplayNameExtension
display_name = pac.get_extension('N') # display name has name 'N'
print(display_name)
>> Display name: My Balance ❤️
TREX
trexes = pac.get_extension_of_type('TREX')
trex_extension = trexes[0] # there could be multiple trexes. In this example there is only one, though
trex = trex_extension.trex
v = trex.get_segment('WEIGHT')
print(f'WEIGHT = {v.value}')
>> WEIGHT = 67.89
Create a PAC-ID with Extensions
Create PAC-ID
from labfreed import PAC_ID, IDSegment
from labfreed.well_known_keys.labfreed.well_known_keys import WellKnownKeys
pac = PAC_ID(issuer='METTORIUS.COM', identifier=[IDSegment(key=WellKnownKeys.SERIAL, value='1234')])
pac_str = pac.to_url()
print(pac_str)
>> HTTPS://PAC.METTORIUS.COM/21:1234
Create a TREX
TREX can conveniently be created from a python dictionary. Note that utility types for Quantity (number with unit) and table are needed
from datetime import datetime
from labfreed.trex.python_convenience import pyTREX
from labfreed.trex.python_convenience import DataTable
from labfreed.trex.python_convenience import Quantity
# Value segments of different type
segments = {
'STOP': datetime(year=2024,month=5,day=5,hour=13,minute=6),
'TEMP': Quantity(value=10.15, unit= 'K'),
'OK':False,
'COMMENT': 'FOO',
'COMMENT2':'£'
}
mydata = pyTREX(segments)
# Create a table
table = DataTable(col_names=['DURATION', 'Date', 'OK', 'COMMENT'])
table.append([Quantity(value=1, unit= 'hour'), datetime.now(), True, 'FOO'])
table.append([ 1.1, datetime.now(), True, 'BAR'])
table.append([ 1.3, datetime.now(), False, 'BLUBB'])
#add the table to the pytrex
mydata.update({'TABLE': table})
# Create TREX
trex = mydata.to_trex()
# Validation also works the same way for TREX
trex.print_validation_messages()
>> Validation Results
>> ┌────────────────────────────────────────────────────────────┐
>> │ **ERROR** in TREX table column Date │
>> │ Column header key contains invalid characters: 'a','t','e' │
>> │ │
>> │ STOP$T.D:20240505T1306 │
>> │ +TEMP$KEL:10.15 │
>> │ +OK$T.B:F │
>> │ +COMMENT$T.A:FOO │
>> │ +COMMENT2$T.T:12G3 │
>> │ +TABLE$$DURATION$HUR:D👉ate👈$T.D:OK$T.B:COMMENT$T.A:: │
>> │ 1:20250522T180101.575:T:FOO:: │
>> │ 1.1:20250522T180101.575:T:BAR:: │
>> │ 1.3:20250522T180101.575:F:BLUBB │
>> └────────────────────────────────────────────────────────────┘
Combine PAC-ID and TREX and serialize
from labfreed.well_known_extensions import TREX_Extension
pac.extensions = [TREX_Extension(name='MYTREX', trex=trex)]
pac_str = pac.to_url()
print(pac_str)
>> 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:12G3+TABLE$$DURATION$HUR:Date$T.D:OK$T.B:COMMENT$T.A::1:20250522T180101.575:T:FOO::1.1:20250522T180101.575:T:BAR::1.3:20250522T180101.575:F:BLUBB
PAC-ID Resolver
from labfreed import PAC_ID_Resolver, load_cit
import requests_cache
# Get a CIT
dir = os.path.join(os.getcwd(), 'examples')
p = os.path.join(dir, 'cit_mine.yaml')
cit = load_cit(p)
# validate the CIT
cit.is_valid
cit.print_validation_messages()
# get a second cit
p = os.path.join(dir, 'coupling-information-table')
cit2 = load_cit(p)
cit2.origin = 'MY_COMPANY'
# resolve a pac id
pac_str = 'HTTPS://PAC.METTORIUS.COM/-MS/X3511/CAS:7732-18-5'
service_groups = PAC_ID_Resolver(cits=[cit, cit2]).resolve(pac_str, check_service_status=False)
cached_session = requests_cache.CachedSession(backend='memory', expire_after=60)
for sg in service_groups:
sg.update_states(cached_session)
sg.print()
>> Services from origin 'PERSONAL
>> ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
>> ┃ Service Name ┃ URL ┃ Reachable ┃
>> ┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
>> │ CAS Search │ https://pubchem.ncbi.nlm.nih.gov/#query=7732-18-5 │ ACTIVE │
>> └──────────────┴───────────────────────────────────────────────────┴───────────┘
>> Services from origin 'MY_COMPANY
>> ┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
>> ┃ Service Name ┃ URL ┃ Reachable ┃
>> ┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
>> │ Chemical Management │ https://chem-manager.com/METTORIUS.COM/-MS/X3511/CAS:7732-18-5 │ INACTIVE │
>> └─────────────────────┴────────────────────────────────────────────────────────────────┴───────────┘
>> Services from origin 'METTORIUS.COM
>> ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
>> ┃ Service Name ┃ URL ┃ Reachable ┃
>> ┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
>> │ CoA │ https://mettorius.com/CoA.pdf │ ACTIVE │
>> │ MSDS │ https://mettorius.com/MSDS.pdf │ ACTIVE │
>> │ Shop │ https://mettorius.com/shop.html │ ACTIVE │
>> └──────────────┴─────────────────────────────────┴───────────┘
Change Log
v0.2.12
- bugfix:no warning message if PAC-CAT has same segment key in two segments
v0.2.11
- bugfix:added missing well known segment key '250'
v0.2.10
- bugfix:added missing well known segment key '20'
v0.2.9
- bugfix in serialization of PAC-CAT with multiple categories
v0.2.8
- option to pass cache to resolver for speedier check of service availability
v0.2.7
- Improved README. No functional changes
v0.2.6
- PAC_ID.to_url() preserves the identifier as is by default but allows to force short or long notation.
- PAC-ID Resolver does not try to resolve PAC-CAT with CIT v1.
v0.2.5
- resolvers checks service states by default
- improvements and bugfixes in conversion from python types to TREX
- follow better naming conventions in CIT v1
v0.2.4
- improvements in formatting of validation messages
- bugfix in DataTable
v0.2.3
- improvements in formatting of validation messages
- bugfix in DisplayNameExtension
v0.2.2
- minor changes for better access of subfunctions. No change in existing API
v0.2.1
- improved docu. no code changes
v0.2.0b2
- improvements in api consistency and ease of use
- restructured code for better separation of concerns
- support for coupling information table v1
v0.1.1
- minor internal improvements and bugfixes
v0.1.0
- DRAFT Support for PAC-ID Resolver
v0.0.20
- bugfix in TREX table to dict conversion
- markdown compatible validation printing
v0.0.19
- supports PAC-ID, PAC-CAT, TREX and DisplayName
- QR generation
- ok-ish test coverage
Attributions
The following tools were used:
- pdoc was a great help with generating documentation
- Pydantic
- json with UNECE units from (https://github.com/quadient/unece-units/blob/main/python/src/unece_excel_parser/parsedUneceUnits.json)
- json with GS1 codes from (https://ref.gs1.org/ai/GS1_Application_Identifiers.jsonld)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file labfreed-0.2.12.tar.gz.
File metadata
- Download URL: labfreed-0.2.12.tar.gz
- Upload date:
- Size: 120.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: python-requests/2.32.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cabcd51c6cc1517dbbec6fa66dc3526d6b1e1f720e32fe0beff29449a39e3fb5
|
|
| MD5 |
de177e58486461e310faaf37e790e749
|
|
| BLAKE2b-256 |
b80752a4c7062dc6eea80552cdc1ab2ade62376c19973604be0f792186b3f04f
|
File details
Details for the file labfreed-0.2.12-py3-none-any.whl.
File metadata
- Download URL: labfreed-0.2.12-py3-none-any.whl
- Upload date:
- Size: 133.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: python-requests/2.32.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0c6501759efa8086c92efc46fda1a0c81ca906e751c4032c55b0d98c8ea6db4
|
|
| MD5 |
0a7601c142896308ac9cea33743f4a5c
|
|
| BLAKE2b-256 |
7fb04d49c7a93c1f431b91d633327c22055503be7d016ecb43709004825d1210
|