labfreed 0.2.8__py3-none-any.whl → 0.2.9__py3-none-any.whl
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/__init__.py +11 -11
- labfreed/labfreed_infrastructure.py +258 -258
- labfreed/pac_cat/__init__.py +19 -19
- labfreed/pac_cat/category_base.py +51 -51
- labfreed/pac_cat/pac_cat.py +150 -150
- labfreed/pac_cat/predefined_categories.py +200 -200
- labfreed/pac_id/__init__.py +19 -19
- labfreed/pac_id/extension.py +48 -48
- labfreed/pac_id/id_segment.py +89 -89
- labfreed/pac_id/pac_id.py +140 -140
- labfreed/pac_id/url_parser.py +155 -155
- labfreed/pac_id/url_serializer.py +85 -84
- labfreed/pac_id_resolver/__init__.py +2 -2
- labfreed/pac_id_resolver/cit_common.py +81 -81
- labfreed/pac_id_resolver/cit_v1.py +244 -244
- labfreed/pac_id_resolver/cit_v2.py +313 -313
- labfreed/pac_id_resolver/resolver.py +97 -97
- labfreed/pac_id_resolver/services.py +82 -82
- labfreed/qr/__init__.py +1 -1
- labfreed/qr/generate_qr.py +422 -422
- labfreed/trex/__init__.py +16 -16
- labfreed/trex/python_convenience/__init__.py +3 -3
- labfreed/trex/python_convenience/data_table.py +87 -87
- labfreed/trex/python_convenience/pyTREX.py +248 -248
- labfreed/trex/python_convenience/quantity.py +66 -66
- labfreed/trex/table_segment.py +245 -245
- labfreed/trex/trex.py +69 -69
- labfreed/trex/trex_base_models.py +209 -209
- labfreed/trex/value_segments.py +99 -99
- labfreed/utilities/base36.py +82 -82
- labfreed/well_known_extensions/__init__.py +4 -4
- labfreed/well_known_extensions/default_extension_interpreters.py +6 -6
- labfreed/well_known_extensions/display_name_extension.py +40 -40
- labfreed/well_known_extensions/trex_extension.py +30 -30
- labfreed/well_known_keys/gs1/__init__.py +5 -5
- labfreed/well_known_keys/gs1/gs1.py +3 -3
- labfreed/well_known_keys/labfreed/well_known_keys.py +15 -15
- labfreed/well_known_keys/unece/__init__.py +3 -3
- labfreed/well_known_keys/unece/unece_units.py +67 -67
- {labfreed-0.2.8.dist-info → labfreed-0.2.9.dist-info}/METADATA +11 -8
- labfreed-0.2.9.dist-info/RECORD +45 -0
- {labfreed-0.2.8.dist-info → labfreed-0.2.9.dist-info}/licenses/LICENSE +21 -21
- labfreed-0.2.8.dist-info/RECORD +0 -45
- {labfreed-0.2.8.dist-info → labfreed-0.2.9.dist-info}/WHEEL +0 -0
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
from functools import lru_cache
|
|
2
|
-
import logging
|
|
3
|
-
import traceback
|
|
4
|
-
from typing import Self
|
|
5
|
-
import yaml
|
|
6
|
-
from requests import get
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
from labfreed.pac_cat.pac_cat import PAC_CAT
|
|
11
|
-
from labfreed.pac_id.pac_id import PAC_ID
|
|
12
|
-
from labfreed.pac_id_resolver.services import ServiceGroup
|
|
13
|
-
from labfreed.pac_id_resolver.cit_v1 import CIT_v1
|
|
14
|
-
from labfreed.pac_id_resolver.cit_v2 import CIT_v2
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
''' Configure pdoc'''
|
|
19
|
-
__all__ = ["PAC_ID_Resolver"]
|
|
20
|
-
|
|
21
|
-
def load_cit(path):
|
|
22
|
-
with open(path, 'r') as f:
|
|
23
|
-
s = f.read()
|
|
24
|
-
return cit_from_str(s)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def cit_from_str(s:str, origin:str='') -> CIT_v1|CIT_v2:
|
|
28
|
-
try:
|
|
29
|
-
cit2 = CIT_v2.from_yaml(s)
|
|
30
|
-
cit_version = 'v2'
|
|
31
|
-
except Exception:
|
|
32
|
-
cit2 = None
|
|
33
|
-
try:
|
|
34
|
-
cit1 = CIT_v1.from_csv(s, origin)
|
|
35
|
-
cit_version = 'v1'
|
|
36
|
-
except Exception:
|
|
37
|
-
cit1 = None
|
|
38
|
-
|
|
39
|
-
cit = cit2 or cit1 or None
|
|
40
|
-
return cit
|
|
41
|
-
|
|
42
|
-
@lru_cache
|
|
43
|
-
def _get_issuer_cit(issuer:str):
|
|
44
|
-
'''Gets the issuer's cit.'''
|
|
45
|
-
url = 'HTTPS://PAC.' + issuer + '/coupling-information-table'
|
|
46
|
-
try:
|
|
47
|
-
r = get(url, timeout=2)
|
|
48
|
-
if r.status_code < 400:
|
|
49
|
-
cit_str = r.text
|
|
50
|
-
else:
|
|
51
|
-
logging.error(f"Could not get CIT form {issuer}")
|
|
52
|
-
cit_str = None
|
|
53
|
-
except Exception:
|
|
54
|
-
logging.error(f"Could not get CIT form {issuer}")
|
|
55
|
-
cit_str = None
|
|
56
|
-
cit = cit_from_str(cit_str, origin=issuer)
|
|
57
|
-
return cit
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
class PAC_ID_Resolver():
|
|
62
|
-
def __init__(self, cits:list[CIT_v2|CIT_v1]=None) -> Self:
|
|
63
|
-
'''Initialize the resolver with coupling information tables'''
|
|
64
|
-
if not cits:
|
|
65
|
-
cits = []
|
|
66
|
-
self._cits = cits
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def resolve(self, pac_url:PAC_ID|str, check_service_status=True, use_issuer_cit=True) -> list[ServiceGroup]:
|
|
70
|
-
'''Resolve a PAC-ID'''
|
|
71
|
-
if isinstance(pac_url, str):
|
|
72
|
-
pac_id = PAC_CAT.from_url(pac_url)
|
|
73
|
-
pac_id_catless = PAC_ID.from_url(pac_url, try_pac_cat=False)
|
|
74
|
-
|
|
75
|
-
cits = self._cits.copy()
|
|
76
|
-
if use_issuer_cit:
|
|
77
|
-
if issuer_cit := _get_issuer_cit(pac_id.issuer):
|
|
78
|
-
cits.append(issuer_cit)
|
|
79
|
-
|
|
80
|
-
matches = []
|
|
81
|
-
for cit in cits:
|
|
82
|
-
if isinstance(cit, CIT_v1):
|
|
83
|
-
# cit v1 has no concept of categories and implied keys. It would treat these segments as value segment
|
|
84
|
-
matches.append(cit.evaluate_pac_id(pac_id_catless))
|
|
85
|
-
else:
|
|
86
|
-
matches.append(cit.evaluate_pac_id(pac_id))
|
|
87
|
-
|
|
88
|
-
if check_service_status:
|
|
89
|
-
for m in matches:
|
|
90
|
-
m.update_states()
|
|
91
|
-
return matches
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if __name__ == '__main__':
|
|
96
|
-
r = PAC_ID_Resolver()
|
|
97
|
-
r.resolve()
|
|
1
|
+
from functools import lru_cache
|
|
2
|
+
import logging
|
|
3
|
+
import traceback
|
|
4
|
+
from typing import Self
|
|
5
|
+
import yaml
|
|
6
|
+
from requests import get
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from labfreed.pac_cat.pac_cat import PAC_CAT
|
|
11
|
+
from labfreed.pac_id.pac_id import PAC_ID
|
|
12
|
+
from labfreed.pac_id_resolver.services import ServiceGroup
|
|
13
|
+
from labfreed.pac_id_resolver.cit_v1 import CIT_v1
|
|
14
|
+
from labfreed.pac_id_resolver.cit_v2 import CIT_v2
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
''' Configure pdoc'''
|
|
19
|
+
__all__ = ["PAC_ID_Resolver"]
|
|
20
|
+
|
|
21
|
+
def load_cit(path):
|
|
22
|
+
with open(path, 'r') as f:
|
|
23
|
+
s = f.read()
|
|
24
|
+
return cit_from_str(s)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def cit_from_str(s:str, origin:str='') -> CIT_v1|CIT_v2:
|
|
28
|
+
try:
|
|
29
|
+
cit2 = CIT_v2.from_yaml(s)
|
|
30
|
+
cit_version = 'v2'
|
|
31
|
+
except Exception:
|
|
32
|
+
cit2 = None
|
|
33
|
+
try:
|
|
34
|
+
cit1 = CIT_v1.from_csv(s, origin)
|
|
35
|
+
cit_version = 'v1'
|
|
36
|
+
except Exception:
|
|
37
|
+
cit1 = None
|
|
38
|
+
|
|
39
|
+
cit = cit2 or cit1 or None
|
|
40
|
+
return cit
|
|
41
|
+
|
|
42
|
+
@lru_cache
|
|
43
|
+
def _get_issuer_cit(issuer:str):
|
|
44
|
+
'''Gets the issuer's cit.'''
|
|
45
|
+
url = 'HTTPS://PAC.' + issuer + '/coupling-information-table'
|
|
46
|
+
try:
|
|
47
|
+
r = get(url, timeout=2)
|
|
48
|
+
if r.status_code < 400:
|
|
49
|
+
cit_str = r.text
|
|
50
|
+
else:
|
|
51
|
+
logging.error(f"Could not get CIT form {issuer}")
|
|
52
|
+
cit_str = None
|
|
53
|
+
except Exception:
|
|
54
|
+
logging.error(f"Could not get CIT form {issuer}")
|
|
55
|
+
cit_str = None
|
|
56
|
+
cit = cit_from_str(cit_str, origin=issuer)
|
|
57
|
+
return cit
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class PAC_ID_Resolver():
|
|
62
|
+
def __init__(self, cits:list[CIT_v2|CIT_v1]=None) -> Self:
|
|
63
|
+
'''Initialize the resolver with coupling information tables'''
|
|
64
|
+
if not cits:
|
|
65
|
+
cits = []
|
|
66
|
+
self._cits = cits
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def resolve(self, pac_url:PAC_ID|str, check_service_status=True, use_issuer_cit=True) -> list[ServiceGroup]:
|
|
70
|
+
'''Resolve a PAC-ID'''
|
|
71
|
+
if isinstance(pac_url, str):
|
|
72
|
+
pac_id = PAC_CAT.from_url(pac_url)
|
|
73
|
+
pac_id_catless = PAC_ID.from_url(pac_url, try_pac_cat=False)
|
|
74
|
+
|
|
75
|
+
cits = self._cits.copy()
|
|
76
|
+
if use_issuer_cit:
|
|
77
|
+
if issuer_cit := _get_issuer_cit(pac_id.issuer):
|
|
78
|
+
cits.append(issuer_cit)
|
|
79
|
+
|
|
80
|
+
matches = []
|
|
81
|
+
for cit in cits:
|
|
82
|
+
if isinstance(cit, CIT_v1):
|
|
83
|
+
# cit v1 has no concept of categories and implied keys. It would treat these segments as value segment
|
|
84
|
+
matches.append(cit.evaluate_pac_id(pac_id_catless))
|
|
85
|
+
else:
|
|
86
|
+
matches.append(cit.evaluate_pac_id(pac_id))
|
|
87
|
+
|
|
88
|
+
if check_service_status:
|
|
89
|
+
for m in matches:
|
|
90
|
+
m.update_states()
|
|
91
|
+
return matches
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
if __name__ == '__main__':
|
|
96
|
+
r = PAC_ID_Resolver()
|
|
97
|
+
r.resolve()
|
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
|
|
2
|
-
from enum import auto, Enum
|
|
3
|
-
|
|
4
|
-
from pydantic import Field
|
|
5
|
-
import requests
|
|
6
|
-
|
|
7
|
-
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
8
|
-
|
|
9
|
-
import requests
|
|
10
|
-
from rich import print
|
|
11
|
-
from rich.table import Table
|
|
12
|
-
|
|
13
|
-
from labfreed.labfreed_infrastructure import LabFREED_BaseModel
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class ServiceStatus(Enum):
|
|
17
|
-
ACTIVE = auto()
|
|
18
|
-
INACTIVE = auto()
|
|
19
|
-
UNKNOWN = auto()
|
|
20
|
-
|
|
21
|
-
class Service(LabFREED_BaseModel):
|
|
22
|
-
service_name: str
|
|
23
|
-
application_intents:list[str]
|
|
24
|
-
service_type:str
|
|
25
|
-
url:str
|
|
26
|
-
status:ServiceStatus =ServiceStatus.UNKNOWN
|
|
27
|
-
|
|
28
|
-
def check_service_status(self, session:requests.Session = None):
|
|
29
|
-
'''Checks the availability of the service.'''
|
|
30
|
-
s = session or requests
|
|
31
|
-
|
|
32
|
-
try:
|
|
33
|
-
r = s.head(self.url, timeout=2)
|
|
34
|
-
if r.status_code < 400:
|
|
35
|
-
self.status = ServiceStatus.ACTIVE
|
|
36
|
-
else:
|
|
37
|
-
self.status = ServiceStatus.INACTIVE
|
|
38
|
-
except requests.RequestException as e:
|
|
39
|
-
print(f"Request failed: {e}")
|
|
40
|
-
self.status = ServiceStatus.INACTIVE
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class ServiceGroup(LabFREED_BaseModel):
|
|
44
|
-
""" Services with common origin. The result of resolving a PAC-ID against a CIT"""
|
|
45
|
-
origin: str = ""
|
|
46
|
-
services: list[Service] = Field(default_factory=list)
|
|
47
|
-
|
|
48
|
-
def update_states(self, session:requests.Session = None):
|
|
49
|
-
'''Triggers each service to check if the url can be reached'''
|
|
50
|
-
if not _has_internet_connection():
|
|
51
|
-
raise ConnectionError("No Internet Connection")
|
|
52
|
-
with ThreadPoolExecutor(max_workers=10) as executor:
|
|
53
|
-
futures = [executor.submit(s.check_service_status, session=session) for s in self.services]
|
|
54
|
-
for _ in as_completed(futures):
|
|
55
|
-
pass # just wait for all to finish
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def __str__(self):
|
|
60
|
-
out = [f'CIT (origin {self.origin})']
|
|
61
|
-
for s in self.services:
|
|
62
|
-
out.append(f'{s.service_name}\t\t\t{s.url}')
|
|
63
|
-
return '\n'.join(out)
|
|
64
|
-
|
|
65
|
-
def print(self):
|
|
66
|
-
table = Table(title=f"Services from origin '{self.origin}")
|
|
67
|
-
|
|
68
|
-
table.add_column("Service Name")
|
|
69
|
-
table.add_column("URL")
|
|
70
|
-
table.add_column('Reachable')
|
|
71
|
-
|
|
72
|
-
for s in self.services:
|
|
73
|
-
table.add_row(s.service_name, s.url, s.status.name)
|
|
74
|
-
|
|
75
|
-
print(table)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def _has_internet_connection():
|
|
79
|
-
try:
|
|
80
|
-
requests.get("https://1.1.1.1", timeout=3)
|
|
81
|
-
return True
|
|
82
|
-
except requests.RequestException:
|
|
1
|
+
|
|
2
|
+
from enum import auto, Enum
|
|
3
|
+
|
|
4
|
+
from pydantic import Field
|
|
5
|
+
import requests
|
|
6
|
+
|
|
7
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
from rich import print
|
|
11
|
+
from rich.table import Table
|
|
12
|
+
|
|
13
|
+
from labfreed.labfreed_infrastructure import LabFREED_BaseModel
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ServiceStatus(Enum):
|
|
17
|
+
ACTIVE = auto()
|
|
18
|
+
INACTIVE = auto()
|
|
19
|
+
UNKNOWN = auto()
|
|
20
|
+
|
|
21
|
+
class Service(LabFREED_BaseModel):
|
|
22
|
+
service_name: str
|
|
23
|
+
application_intents:list[str]
|
|
24
|
+
service_type:str
|
|
25
|
+
url:str
|
|
26
|
+
status:ServiceStatus =ServiceStatus.UNKNOWN
|
|
27
|
+
|
|
28
|
+
def check_service_status(self, session:requests.Session = None):
|
|
29
|
+
'''Checks the availability of the service.'''
|
|
30
|
+
s = session or requests
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
r = s.head(self.url, timeout=2)
|
|
34
|
+
if r.status_code < 400:
|
|
35
|
+
self.status = ServiceStatus.ACTIVE
|
|
36
|
+
else:
|
|
37
|
+
self.status = ServiceStatus.INACTIVE
|
|
38
|
+
except requests.RequestException as e:
|
|
39
|
+
print(f"Request failed: {e}")
|
|
40
|
+
self.status = ServiceStatus.INACTIVE
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ServiceGroup(LabFREED_BaseModel):
|
|
44
|
+
""" Services with common origin. The result of resolving a PAC-ID against a CIT"""
|
|
45
|
+
origin: str = ""
|
|
46
|
+
services: list[Service] = Field(default_factory=list)
|
|
47
|
+
|
|
48
|
+
def update_states(self, session:requests.Session = None):
|
|
49
|
+
'''Triggers each service to check if the url can be reached'''
|
|
50
|
+
if not _has_internet_connection():
|
|
51
|
+
raise ConnectionError("No Internet Connection")
|
|
52
|
+
with ThreadPoolExecutor(max_workers=10) as executor:
|
|
53
|
+
futures = [executor.submit(s.check_service_status, session=session) for s in self.services]
|
|
54
|
+
for _ in as_completed(futures):
|
|
55
|
+
pass # just wait for all to finish
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def __str__(self):
|
|
60
|
+
out = [f'CIT (origin {self.origin})']
|
|
61
|
+
for s in self.services:
|
|
62
|
+
out.append(f'{s.service_name}\t\t\t{s.url}')
|
|
63
|
+
return '\n'.join(out)
|
|
64
|
+
|
|
65
|
+
def print(self):
|
|
66
|
+
table = Table(title=f"Services from origin '{self.origin}")
|
|
67
|
+
|
|
68
|
+
table.add_column("Service Name")
|
|
69
|
+
table.add_column("URL")
|
|
70
|
+
table.add_column('Reachable')
|
|
71
|
+
|
|
72
|
+
for s in self.services:
|
|
73
|
+
table.add_row(s.service_name, s.url, s.status.name)
|
|
74
|
+
|
|
75
|
+
print(table)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _has_internet_connection():
|
|
79
|
+
try:
|
|
80
|
+
requests.get("https://1.1.1.1", timeout=3)
|
|
81
|
+
return True
|
|
82
|
+
except requests.RequestException:
|
|
83
83
|
return False
|
labfreed/qr/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
from .generate_qr import save_qr_with_markers # noqa: F401
|
|
1
|
+
from .generate_qr import save_qr_with_markers # noqa: F401
|