Skip to main content

Python implementation of LabFREED building blocks

Project description

LabFREED for Python

PyPI Python Version Test Labfreed License: MIT

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:

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

labfreed-0.2.12.tar.gz (120.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

labfreed-0.2.12-py3-none-any.whl (133.8 kB view details)

Uploaded Python 3

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

Hashes for labfreed-0.2.12.tar.gz
Algorithm Hash digest
SHA256 cabcd51c6cc1517dbbec6fa66dc3526d6b1e1f720e32fe0beff29449a39e3fb5
MD5 de177e58486461e310faaf37e790e749
BLAKE2b-256 b80752a4c7062dc6eea80552cdc1ab2ade62376c19973604be0f792186b3f04f

See more details on using hashes here.

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

Hashes for labfreed-0.2.12-py3-none-any.whl
Algorithm Hash digest
SHA256 d0c6501759efa8086c92efc46fda1a0c81ca906e751c4032c55b0d98c8ea6db4
MD5 0a7601c142896308ac9cea33743f4a5c
BLAKE2b-256 7fb04d49c7a93c1f431b91d633327c22055503be7d016ecb43709004825d1210

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page