labfreed 0.2.7__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.
- 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 +84 -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 -79
- 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.7.dist-info → labfreed-0.2.8.dist-info}/METADATA +17 -9
- labfreed-0.2.8.dist-info/RECORD +45 -0
- {labfreed-0.2.7.dist-info → labfreed-0.2.8.dist-info}/licenses/LICENSE +21 -21
- labfreed-0.2.7.dist-info/RECORD +0 -45
- {labfreed-0.2.7.dist-info → labfreed-0.2.8.dist-info}/WHEEL +0 -0
|
@@ -1,245 +1,245 @@
|
|
|
1
|
-
|
|
2
|
-
from enum import Enum
|
|
3
|
-
import logging
|
|
4
|
-
import re
|
|
5
|
-
import traceback
|
|
6
|
-
|
|
7
|
-
from pydantic import Field, model_validator
|
|
8
|
-
from labfreed.labfreed_infrastructure import LabFREED_BaseModel, ValidationMessage, ValidationMsgLevel
|
|
9
|
-
from labfreed.pac_id.pac_id import PAC_ID
|
|
10
|
-
from labfreed.pac_id_resolver.services import Service, ServiceGroup
|
|
11
|
-
from labfreed.pac_id_resolver.cit_common import ( _add_msg_to_cit_entry_model,
|
|
12
|
-
_validate_service_name,
|
|
13
|
-
_validate_application_intent,
|
|
14
|
-
_validate_service_type,
|
|
15
|
-
ServiceType)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class CITEntry_v1(LabFREED_BaseModel):
|
|
20
|
-
applicable_if: str = Field(..., min_length=1)
|
|
21
|
-
service_name: str = Field(..., min_length=1)
|
|
22
|
-
application_intent:str = Field(..., min_length=1)
|
|
23
|
-
service_type:ServiceType|str
|
|
24
|
-
template_url:str = Field(..., min_length=1)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@model_validator(mode='after')
|
|
28
|
-
def _validate_model(self):
|
|
29
|
-
if self.applicable_if:
|
|
30
|
-
conditions = self.applicable_if.split(';')
|
|
31
|
-
for c in conditions:
|
|
32
|
-
if '=' in c:
|
|
33
|
-
query, expected = c.split('=')
|
|
34
|
-
query = query.strip()
|
|
35
|
-
else:
|
|
36
|
-
query = c.strip()
|
|
37
|
-
|
|
38
|
-
try:
|
|
39
|
-
# use this function to check if the pattern is valid. it returns a PatternError if not
|
|
40
|
-
_find_pattern_in_pac(query, '')
|
|
41
|
-
except PatternError:
|
|
42
|
-
self._add_validation_message(
|
|
43
|
-
level=ValidationMsgLevel.ERROR,
|
|
44
|
-
source=f'Service {self.service_name}',
|
|
45
|
-
msg=f'Applicable if contains invalid pattern {query}',
|
|
46
|
-
highlight_sub=query
|
|
47
|
-
)
|
|
48
|
-
except Exception:
|
|
49
|
-
pass # if no PatternError everything is fine
|
|
50
|
-
return self
|
|
51
|
-
|
|
52
|
-
@model_validator(mode='after')
|
|
53
|
-
def _validate_service_name(self):
|
|
54
|
-
msg_dict= _validate_service_name(self.service_name)
|
|
55
|
-
return _add_msg_to_cit_entry_model(msg_dict, self)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@model_validator(mode='after')
|
|
59
|
-
def _validate_application_intent(self):
|
|
60
|
-
msg_dict= _validate_application_intent(self.application_intent)
|
|
61
|
-
return _add_msg_to_cit_entry_model(msg_dict, self)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
@model_validator(mode='after')
|
|
65
|
-
def _validate_service_type(self):
|
|
66
|
-
msg_dict= _validate_service_type(self.service_type)
|
|
67
|
-
return _add_msg_to_cit_entry_model(msg_dict, self)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
class CIT_v1(LabFREED_BaseModel):
|
|
75
|
-
origin:str = ''
|
|
76
|
-
entries:list[CITEntry_v1]
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@classmethod
|
|
80
|
-
def from_csv(cls, csv:str, origin=''):
|
|
81
|
-
lines = csv.splitlines()
|
|
82
|
-
entries = list()
|
|
83
|
-
errors = list()
|
|
84
|
-
for line in lines:
|
|
85
|
-
if not line: # empty line
|
|
86
|
-
continue
|
|
87
|
-
if line.strip()[0] == '#': #comment line
|
|
88
|
-
continue
|
|
89
|
-
if 'Service Name' in line.strip() : #header line
|
|
90
|
-
continue
|
|
91
|
-
|
|
92
|
-
cols = [c.strip() for c in line.split('\t')]
|
|
93
|
-
if len(cols) < 5:
|
|
94
|
-
msg = ValidationMessage(
|
|
95
|
-
level=ValidationMsgLevel.ERROR,
|
|
96
|
-
source='CIT line',
|
|
97
|
-
source_id=0,
|
|
98
|
-
msg=f'Invalid line in CIT. There are {5 - len(cols)} columns missing.',
|
|
99
|
-
highlight_sub_patterns=line
|
|
100
|
-
)
|
|
101
|
-
errors.append(msg)
|
|
102
|
-
continue
|
|
103
|
-
if len(cols) > 5:
|
|
104
|
-
msg = ValidationMessage(
|
|
105
|
-
level=ValidationMsgLevel.ERROR,
|
|
106
|
-
source='CIT line',
|
|
107
|
-
source_id=0,
|
|
108
|
-
msg=f'Invalid line in CIT. There are {len(cols) -5} too many columns',
|
|
109
|
-
highlight_sub_patterns=line
|
|
110
|
-
)
|
|
111
|
-
errors.append(msg)
|
|
112
|
-
continue
|
|
113
|
-
try:
|
|
114
|
-
|
|
115
|
-
entry = CITEntry_v1(
|
|
116
|
-
service_name = cols[0],
|
|
117
|
-
application_intent = cols[1],
|
|
118
|
-
service_type = cols[2],
|
|
119
|
-
applicable_if = cols[3],
|
|
120
|
-
template_url = cols[4]
|
|
121
|
-
)
|
|
122
|
-
entries.append(entry)
|
|
123
|
-
except ValueError:
|
|
124
|
-
msg = ValidationMessage(
|
|
125
|
-
level=ValidationMsgLevel.ERROR,
|
|
126
|
-
source='CIT line',
|
|
127
|
-
source_id=0,
|
|
128
|
-
msg='Invalid line in CIT.',
|
|
129
|
-
highlight_sub_patterns=line
|
|
130
|
-
)
|
|
131
|
-
errors.append(msg)
|
|
132
|
-
|
|
133
|
-
cit = CIT_v1(origin=origin, entries=entries)
|
|
134
|
-
if not cit.is_valid:
|
|
135
|
-
errors.insert(0,
|
|
136
|
-
ValidationMessage(
|
|
137
|
-
level=ValidationMsgLevel.WARNING,
|
|
138
|
-
source='CIT ',
|
|
139
|
-
source_id=0,
|
|
140
|
-
msg='Invalid lines in CIT. The lines were ignored. The rest of the CIT is still functional',
|
|
141
|
-
highlight_sub_patterns=''
|
|
142
|
-
)
|
|
143
|
-
)
|
|
144
|
-
cit._validation_messages.extend(errors)
|
|
145
|
-
cit._csv_original = csv
|
|
146
|
-
return cit
|
|
147
|
-
|
|
148
|
-
def evaluate_pac_id(self, pac:PAC_ID):
|
|
149
|
-
if type(pac) is not PAC_ID:
|
|
150
|
-
raise ValueError('CIT v1 does only handle PAC-IDs. PAC-CAT it does not know what to do')
|
|
151
|
-
cit_evaluated = ServiceGroup(origin=self.origin)
|
|
152
|
-
for e in self.entries:
|
|
153
|
-
if e.errors():
|
|
154
|
-
continue #make this stable against errors in the cit
|
|
155
|
-
|
|
156
|
-
conditions = e.applicable_if.split(';')
|
|
157
|
-
conditions_evaluated = list()
|
|
158
|
-
for c in conditions:
|
|
159
|
-
if '=' in c:
|
|
160
|
-
query, expected = c.split('=')
|
|
161
|
-
value = _find_pattern_in_pac(query.strip(), pac)
|
|
162
|
-
conditions_evaluated.append(value == expected.strip())
|
|
163
|
-
else:
|
|
164
|
-
query = c.strip()
|
|
165
|
-
found = _find_pattern_in_pac(query, pac)
|
|
166
|
-
conditions_evaluated.append(found)
|
|
167
|
-
is_applicable = all(conditions_evaluated)
|
|
168
|
-
|
|
169
|
-
if not is_applicable:
|
|
170
|
-
continue
|
|
171
|
-
|
|
172
|
-
url = re.sub(r"\{([^}]+)\}", lambda v: _find_pattern_in_pac(v.group(0), pac), e.template_url)
|
|
173
|
-
cit_evaluated.services.append(Service(
|
|
174
|
-
service_name=e.service_name,
|
|
175
|
-
application_intents= [ e.application_intent ],
|
|
176
|
-
service_type=e.service_type,
|
|
177
|
-
url = url
|
|
178
|
-
)
|
|
179
|
-
)
|
|
180
|
-
return cit_evaluated
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
def __str__(self):
|
|
185
|
-
if csv:=self._csv_original:
|
|
186
|
-
return csv
|
|
187
|
-
|
|
188
|
-
s = "# coupling information table version: 1.0\n"
|
|
189
|
-
s += "Service Name\tApplication Intent\tService Type\tApplicable If\tTemplate Url\n"
|
|
190
|
-
for e in self.entries:
|
|
191
|
-
s += '\t'.join([e.service_name, e.application_intent, e.service_type.value, e.applicable_if, e.template_url]) + '\n'
|
|
192
|
-
return s
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def _find_pattern_in_pac(value, pac:PAC_ID|str):
|
|
197
|
-
if not isinstance(pac, str):
|
|
198
|
-
pac_url =pac.to_url()
|
|
199
|
-
else:
|
|
200
|
-
pac_url = pac
|
|
201
|
-
|
|
202
|
-
if value == '{isu}':
|
|
203
|
-
return pac.issuer
|
|
204
|
-
|
|
205
|
-
elif value == '{pac}':
|
|
206
|
-
return pac_url.split('*')[0]
|
|
207
|
-
|
|
208
|
-
elif value == '{id}':
|
|
209
|
-
m = re.match(r'^HTTPS://.+?/(.+?)(\*.*)*$', pac_url)
|
|
210
|
-
return m.group(1) if m else None
|
|
211
|
-
|
|
212
|
-
elif m := re.match(r'\{idSeg(\d+)\}', value):
|
|
213
|
-
i = int(m.group(1)) - 1 # CIT is 1 based
|
|
214
|
-
seg = pac.identifier[i] if i < len(pac.identifier) else None
|
|
215
|
-
if seg:
|
|
216
|
-
return f"{(seg.key + ':') if seg.key else ''}{seg.value}"
|
|
217
|
-
|
|
218
|
-
elif m := re.match(r'\{idVal(\w+)\}', value):
|
|
219
|
-
k = m.group(1)
|
|
220
|
-
seg = [s for s in pac.identifier if s.key and s.key == k]
|
|
221
|
-
if seg:
|
|
222
|
-
seg = seg[0]
|
|
223
|
-
return seg.value
|
|
224
|
-
else:
|
|
225
|
-
return None
|
|
226
|
-
|
|
227
|
-
elif value == '{ext}':
|
|
228
|
-
m = re.match(r'^.*?(\*.*)*$', pac_url)
|
|
229
|
-
ext_str = m.group(1) if m else None
|
|
230
|
-
return m.group(1)[1:] if ext_str else None
|
|
231
|
-
|
|
232
|
-
elif m := re.match(r'\{ext(\d+)\}', value):
|
|
233
|
-
i = int(m.group(1)) - 1 # CIT is 1 based
|
|
234
|
-
extensions = pac_url.split('*')
|
|
235
|
-
extensions.pop(0)# first element is not extension
|
|
236
|
-
return extensions[i] if i < len(extensions) else None
|
|
237
|
-
else:
|
|
238
|
-
raise PatternError(f'{value} is not a recognized pattern for applicable if')
|
|
239
|
-
|
|
240
|
-
class PatternError(ValueError):
|
|
241
|
-
pass
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
1
|
+
|
|
2
|
+
from enum import Enum
|
|
3
|
+
import logging
|
|
4
|
+
import re
|
|
5
|
+
import traceback
|
|
6
|
+
|
|
7
|
+
from pydantic import Field, model_validator
|
|
8
|
+
from labfreed.labfreed_infrastructure import LabFREED_BaseModel, ValidationMessage, ValidationMsgLevel
|
|
9
|
+
from labfreed.pac_id.pac_id import PAC_ID
|
|
10
|
+
from labfreed.pac_id_resolver.services import Service, ServiceGroup
|
|
11
|
+
from labfreed.pac_id_resolver.cit_common import ( _add_msg_to_cit_entry_model,
|
|
12
|
+
_validate_service_name,
|
|
13
|
+
_validate_application_intent,
|
|
14
|
+
_validate_service_type,
|
|
15
|
+
ServiceType)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CITEntry_v1(LabFREED_BaseModel):
|
|
20
|
+
applicable_if: str = Field(..., min_length=1)
|
|
21
|
+
service_name: str = Field(..., min_length=1)
|
|
22
|
+
application_intent:str = Field(..., min_length=1)
|
|
23
|
+
service_type:ServiceType|str
|
|
24
|
+
template_url:str = Field(..., min_length=1)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@model_validator(mode='after')
|
|
28
|
+
def _validate_model(self):
|
|
29
|
+
if self.applicable_if:
|
|
30
|
+
conditions = self.applicable_if.split(';')
|
|
31
|
+
for c in conditions:
|
|
32
|
+
if '=' in c:
|
|
33
|
+
query, expected = c.split('=')
|
|
34
|
+
query = query.strip()
|
|
35
|
+
else:
|
|
36
|
+
query = c.strip()
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
# use this function to check if the pattern is valid. it returns a PatternError if not
|
|
40
|
+
_find_pattern_in_pac(query, '')
|
|
41
|
+
except PatternError:
|
|
42
|
+
self._add_validation_message(
|
|
43
|
+
level=ValidationMsgLevel.ERROR,
|
|
44
|
+
source=f'Service {self.service_name}',
|
|
45
|
+
msg=f'Applicable if contains invalid pattern {query}',
|
|
46
|
+
highlight_sub=query
|
|
47
|
+
)
|
|
48
|
+
except Exception:
|
|
49
|
+
pass # if no PatternError everything is fine
|
|
50
|
+
return self
|
|
51
|
+
|
|
52
|
+
@model_validator(mode='after')
|
|
53
|
+
def _validate_service_name(self):
|
|
54
|
+
msg_dict= _validate_service_name(self.service_name)
|
|
55
|
+
return _add_msg_to_cit_entry_model(msg_dict, self)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@model_validator(mode='after')
|
|
59
|
+
def _validate_application_intent(self):
|
|
60
|
+
msg_dict= _validate_application_intent(self.application_intent)
|
|
61
|
+
return _add_msg_to_cit_entry_model(msg_dict, self)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@model_validator(mode='after')
|
|
65
|
+
def _validate_service_type(self):
|
|
66
|
+
msg_dict= _validate_service_type(self.service_type)
|
|
67
|
+
return _add_msg_to_cit_entry_model(msg_dict, self)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class CIT_v1(LabFREED_BaseModel):
|
|
75
|
+
origin:str = ''
|
|
76
|
+
entries:list[CITEntry_v1]
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def from_csv(cls, csv:str, origin=''):
|
|
81
|
+
lines = csv.splitlines()
|
|
82
|
+
entries = list()
|
|
83
|
+
errors = list()
|
|
84
|
+
for line in lines:
|
|
85
|
+
if not line: # empty line
|
|
86
|
+
continue
|
|
87
|
+
if line.strip()[0] == '#': #comment line
|
|
88
|
+
continue
|
|
89
|
+
if 'Service Name' in line.strip() : #header line
|
|
90
|
+
continue
|
|
91
|
+
|
|
92
|
+
cols = [c.strip() for c in line.split('\t')]
|
|
93
|
+
if len(cols) < 5:
|
|
94
|
+
msg = ValidationMessage(
|
|
95
|
+
level=ValidationMsgLevel.ERROR,
|
|
96
|
+
source='CIT line',
|
|
97
|
+
source_id=0,
|
|
98
|
+
msg=f'Invalid line in CIT. There are {5 - len(cols)} columns missing.',
|
|
99
|
+
highlight_sub_patterns=line
|
|
100
|
+
)
|
|
101
|
+
errors.append(msg)
|
|
102
|
+
continue
|
|
103
|
+
if len(cols) > 5:
|
|
104
|
+
msg = ValidationMessage(
|
|
105
|
+
level=ValidationMsgLevel.ERROR,
|
|
106
|
+
source='CIT line',
|
|
107
|
+
source_id=0,
|
|
108
|
+
msg=f'Invalid line in CIT. There are {len(cols) -5} too many columns',
|
|
109
|
+
highlight_sub_patterns=line
|
|
110
|
+
)
|
|
111
|
+
errors.append(msg)
|
|
112
|
+
continue
|
|
113
|
+
try:
|
|
114
|
+
|
|
115
|
+
entry = CITEntry_v1(
|
|
116
|
+
service_name = cols[0],
|
|
117
|
+
application_intent = cols[1],
|
|
118
|
+
service_type = cols[2],
|
|
119
|
+
applicable_if = cols[3],
|
|
120
|
+
template_url = cols[4]
|
|
121
|
+
)
|
|
122
|
+
entries.append(entry)
|
|
123
|
+
except ValueError:
|
|
124
|
+
msg = ValidationMessage(
|
|
125
|
+
level=ValidationMsgLevel.ERROR,
|
|
126
|
+
source='CIT line',
|
|
127
|
+
source_id=0,
|
|
128
|
+
msg='Invalid line in CIT.',
|
|
129
|
+
highlight_sub_patterns=line
|
|
130
|
+
)
|
|
131
|
+
errors.append(msg)
|
|
132
|
+
|
|
133
|
+
cit = CIT_v1(origin=origin, entries=entries)
|
|
134
|
+
if not cit.is_valid:
|
|
135
|
+
errors.insert(0,
|
|
136
|
+
ValidationMessage(
|
|
137
|
+
level=ValidationMsgLevel.WARNING,
|
|
138
|
+
source='CIT ',
|
|
139
|
+
source_id=0,
|
|
140
|
+
msg='Invalid lines in CIT. The lines were ignored. The rest of the CIT is still functional',
|
|
141
|
+
highlight_sub_patterns=''
|
|
142
|
+
)
|
|
143
|
+
)
|
|
144
|
+
cit._validation_messages.extend(errors)
|
|
145
|
+
cit._csv_original = csv
|
|
146
|
+
return cit
|
|
147
|
+
|
|
148
|
+
def evaluate_pac_id(self, pac:PAC_ID):
|
|
149
|
+
if type(pac) is not PAC_ID:
|
|
150
|
+
raise ValueError('CIT v1 does only handle PAC-IDs. PAC-CAT it does not know what to do')
|
|
151
|
+
cit_evaluated = ServiceGroup(origin=self.origin)
|
|
152
|
+
for e in self.entries:
|
|
153
|
+
if e.errors():
|
|
154
|
+
continue #make this stable against errors in the cit
|
|
155
|
+
|
|
156
|
+
conditions = e.applicable_if.split(';')
|
|
157
|
+
conditions_evaluated = list()
|
|
158
|
+
for c in conditions:
|
|
159
|
+
if '=' in c:
|
|
160
|
+
query, expected = c.split('=')
|
|
161
|
+
value = _find_pattern_in_pac(query.strip(), pac)
|
|
162
|
+
conditions_evaluated.append(value == expected.strip())
|
|
163
|
+
else:
|
|
164
|
+
query = c.strip()
|
|
165
|
+
found = _find_pattern_in_pac(query, pac)
|
|
166
|
+
conditions_evaluated.append(found)
|
|
167
|
+
is_applicable = all(conditions_evaluated)
|
|
168
|
+
|
|
169
|
+
if not is_applicable:
|
|
170
|
+
continue
|
|
171
|
+
|
|
172
|
+
url = re.sub(r"\{([^}]+)\}", lambda v: _find_pattern_in_pac(v.group(0), pac), e.template_url)
|
|
173
|
+
cit_evaluated.services.append(Service(
|
|
174
|
+
service_name=e.service_name,
|
|
175
|
+
application_intents= [ e.application_intent ],
|
|
176
|
+
service_type=e.service_type,
|
|
177
|
+
url = url
|
|
178
|
+
)
|
|
179
|
+
)
|
|
180
|
+
return cit_evaluated
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def __str__(self):
|
|
185
|
+
if csv:=self._csv_original:
|
|
186
|
+
return csv
|
|
187
|
+
|
|
188
|
+
s = "# coupling information table version: 1.0\n"
|
|
189
|
+
s += "Service Name\tApplication Intent\tService Type\tApplicable If\tTemplate Url\n"
|
|
190
|
+
for e in self.entries:
|
|
191
|
+
s += '\t'.join([e.service_name, e.application_intent, e.service_type.value, e.applicable_if, e.template_url]) + '\n'
|
|
192
|
+
return s
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _find_pattern_in_pac(value, pac:PAC_ID|str):
|
|
197
|
+
if not isinstance(pac, str):
|
|
198
|
+
pac_url =pac.to_url()
|
|
199
|
+
else:
|
|
200
|
+
pac_url = pac
|
|
201
|
+
|
|
202
|
+
if value == '{isu}':
|
|
203
|
+
return pac.issuer
|
|
204
|
+
|
|
205
|
+
elif value == '{pac}':
|
|
206
|
+
return pac_url.split('*')[0]
|
|
207
|
+
|
|
208
|
+
elif value == '{id}':
|
|
209
|
+
m = re.match(r'^HTTPS://.+?/(.+?)(\*.*)*$', pac_url)
|
|
210
|
+
return m.group(1) if m else None
|
|
211
|
+
|
|
212
|
+
elif m := re.match(r'\{idSeg(\d+)\}', value):
|
|
213
|
+
i = int(m.group(1)) - 1 # CIT is 1 based
|
|
214
|
+
seg = pac.identifier[i] if i < len(pac.identifier) else None
|
|
215
|
+
if seg:
|
|
216
|
+
return f"{(seg.key + ':') if seg.key else ''}{seg.value}"
|
|
217
|
+
|
|
218
|
+
elif m := re.match(r'\{idVal(\w+)\}', value):
|
|
219
|
+
k = m.group(1)
|
|
220
|
+
seg = [s for s in pac.identifier if s.key and s.key == k]
|
|
221
|
+
if seg:
|
|
222
|
+
seg = seg[0]
|
|
223
|
+
return seg.value
|
|
224
|
+
else:
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
elif value == '{ext}':
|
|
228
|
+
m = re.match(r'^.*?(\*.*)*$', pac_url)
|
|
229
|
+
ext_str = m.group(1) if m else None
|
|
230
|
+
return m.group(1)[1:] if ext_str else None
|
|
231
|
+
|
|
232
|
+
elif m := re.match(r'\{ext(\d+)\}', value):
|
|
233
|
+
i = int(m.group(1)) - 1 # CIT is 1 based
|
|
234
|
+
extensions = pac_url.split('*')
|
|
235
|
+
extensions.pop(0)# first element is not extension
|
|
236
|
+
return extensions[i] if i < len(extensions) else None
|
|
237
|
+
else:
|
|
238
|
+
raise PatternError(f'{value} is not a recognized pattern for applicable if')
|
|
239
|
+
|
|
240
|
+
class PatternError(ValueError):
|
|
241
|
+
pass
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
245
|
|