labfreed 0.2.6a6__py3-none-any.whl → 0.2.8__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.

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