labfreed 0.2.6a2__py3-none-any.whl → 0.2.6a4__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 +1 -1
- labfreed/labfreed_infrastructure.py +3 -3
- labfreed/pac_id_resolver/cit_common.py +82 -0
- labfreed/pac_id_resolver/cit_v1.py +150 -57
- labfreed/pac_id_resolver/cit_v2.py +6 -3
- {labfreed-0.2.6a2.dist-info → labfreed-0.2.6a4.dist-info}/METADATA +1 -1
- {labfreed-0.2.6a2.dist-info → labfreed-0.2.6a4.dist-info}/RECORD +9 -8
- {labfreed-0.2.6a2.dist-info → labfreed-0.2.6a4.dist-info}/WHEEL +0 -0
- {labfreed-0.2.6a2.dist-info → labfreed-0.2.6a4.dist-info}/licenses/LICENSE +0 -0
labfreed/__init__.py
CHANGED
|
@@ -194,9 +194,9 @@ class LabFREED_BaseModel(PDOC_Workaround_Base):
|
|
|
194
194
|
formatted_msg = list()
|
|
195
195
|
for m in self.validation_messages():
|
|
196
196
|
if m.level == ValidationMsgLevel.ERROR:
|
|
197
|
-
color = '
|
|
197
|
+
color = '#d70000'
|
|
198
198
|
else:
|
|
199
|
-
color = '
|
|
199
|
+
color = '#d78700'
|
|
200
200
|
|
|
201
201
|
match target:
|
|
202
202
|
case 'markdown':
|
|
@@ -218,7 +218,7 @@ class LabFREED_BaseModel(PDOC_Workaround_Base):
|
|
|
218
218
|
br = '<br>'
|
|
219
219
|
|
|
220
220
|
serialized = str(self)
|
|
221
|
-
serialized.replace('\n', br)
|
|
221
|
+
serialized = serialized.replace('\n', br)
|
|
222
222
|
emphazised_highlight = self._emphasize_in(m, serialized, fmt=fmt)
|
|
223
223
|
emphazised_highlight = emphazised_highlight.replace('👈👉','') # removes two consecutive markers, to make it cleaner
|
|
224
224
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
import re
|
|
3
|
+
from labfreed.labfreed_infrastructure import LabFREED_BaseModel, ValidationMsgLevel, _quote_texts
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ServiceType(Enum):
|
|
8
|
+
USER_HANDOVER_GENERIC = 'userhandover-generic'
|
|
9
|
+
ATTRIBUTE_SERVICE_GENERIC = 'attributes-generic'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _validate_service_name(service_name):
|
|
13
|
+
msg_dict = []
|
|
14
|
+
if not_allowed_chars := set(re.sub(r'[A-Za-z0-9\-\x20]', '', service_name)):
|
|
15
|
+
msg_dict.append( {
|
|
16
|
+
"level": ValidationMsgLevel.ERROR,
|
|
17
|
+
"msg": f'Service name ontains invalid characters {_quote_texts(not_allowed_chars)}',
|
|
18
|
+
"highlight_sub": not_allowed_chars
|
|
19
|
+
}
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
if len(service_name) == 0 or len(service_name) > 255:
|
|
23
|
+
msg_dict.append( {
|
|
24
|
+
"level": ValidationMsgLevel.ERROR,
|
|
25
|
+
"msg": 'Service name must be at least one and maximum 255 characters long'
|
|
26
|
+
}
|
|
27
|
+
)
|
|
28
|
+
return msg_dict
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _validate_application_intent(intent):
|
|
32
|
+
msg_dict = []
|
|
33
|
+
if re.fullmatch('.*-generic$', intent):
|
|
34
|
+
msg_dict.append( {
|
|
35
|
+
"level": ValidationMsgLevel.ERROR,
|
|
36
|
+
"msg": "Application intent ends with '-generic'. This is not permitted, since it is reserved for future uses'",
|
|
37
|
+
"highlight_sub": [intent]
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
if not_allowed_chars := set(re.sub(r'[A-Za-z0-9\-]', '', intent)):
|
|
42
|
+
msg_dict.append( {
|
|
43
|
+
"level": ValidationMsgLevel.ERROR,
|
|
44
|
+
"msg": f'Application intent contains invalid characters {_quote_texts(not_allowed_chars)}',
|
|
45
|
+
"highlight_sub": not_allowed_chars
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
if len(intent) == 0 or len(intent) > 255:
|
|
50
|
+
msg_dict.append( {
|
|
51
|
+
"level": ValidationMsgLevel.ERROR,
|
|
52
|
+
"source": f'Application intent {intent}',
|
|
53
|
+
"msg": 'Must be at least one and maximum 255 characters long'
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
return msg_dict
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _validate_service_type(service_type):
|
|
60
|
+
msg_dict = []
|
|
61
|
+
if isinstance(service_type, ServiceType):
|
|
62
|
+
service_type= service_type.value
|
|
63
|
+
else:
|
|
64
|
+
service_type= service_type
|
|
65
|
+
allowed_types = [ServiceType.ATTRIBUTE_SERVICE_GENERIC.value, ServiceType.USER_HANDOVER_GENERIC.value]
|
|
66
|
+
if service_type not in allowed_types:
|
|
67
|
+
msg_dict.append( {
|
|
68
|
+
"level": ValidationMsgLevel.ERROR,
|
|
69
|
+
"msg": f'Invalid service type. Must be {_quote_texts(allowed_types)} must be at least one and maximum 255 characters long',
|
|
70
|
+
"highlight_sub": service_type
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
return msg_dict
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _add_msg_to_cit_entry_model(msg_dict, model):
|
|
77
|
+
for m in msg_dict:
|
|
78
|
+
m.update({"source": model.service_name})
|
|
79
|
+
model._add_validation_message(**m)
|
|
80
|
+
return model
|
|
81
|
+
|
|
82
|
+
|
|
@@ -2,23 +2,73 @@
|
|
|
2
2
|
from enum import Enum
|
|
3
3
|
import logging
|
|
4
4
|
import re
|
|
5
|
+
import traceback
|
|
5
6
|
|
|
6
|
-
from pydantic import Field
|
|
7
|
+
from pydantic import Field, model_validator
|
|
7
8
|
from labfreed.labfreed_infrastructure import LabFREED_BaseModel, ValidationMessage, ValidationMsgLevel
|
|
8
9
|
from labfreed.pac_id.pac_id import PAC_ID
|
|
9
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)
|
|
10
16
|
|
|
11
|
-
class ServiceType(Enum):
|
|
12
|
-
USER_HANDOVER_GENERIC = 'userhandover-generic'
|
|
13
|
-
ATTRIBUTE_SERVICE_GENERIC = 'attributes-generic'
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
class CITEntry_v1(LabFREED_BaseModel):
|
|
17
20
|
applicable_if: str = Field(..., min_length=1)
|
|
18
21
|
service_name: str = Field(..., min_length=1)
|
|
19
22
|
application_intent:str = Field(..., min_length=1)
|
|
20
|
-
service_type:ServiceType
|
|
23
|
+
service_type:ServiceType|str
|
|
21
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
|
+
|
|
22
72
|
|
|
23
73
|
|
|
24
74
|
class CIT_v1(LabFREED_BaseModel):
|
|
@@ -40,11 +90,34 @@ class CIT_v1(LabFREED_BaseModel):
|
|
|
40
90
|
continue
|
|
41
91
|
|
|
42
92
|
cols = [c.strip() for c in line.split('\t')]
|
|
93
|
+
if len(cols) < 5:
|
|
94
|
+
logging.error(f'invalid line {line}')
|
|
95
|
+
msg = ValidationMessage(
|
|
96
|
+
level=ValidationMsgLevel.ERROR,
|
|
97
|
+
source='CIT line',
|
|
98
|
+
source_id=0,
|
|
99
|
+
msg=f'Invalid line in CIT. There are {5 - len(cols)} columns missing.',
|
|
100
|
+
highlight_sub_patterns=line
|
|
101
|
+
)
|
|
102
|
+
errors.append(msg)
|
|
103
|
+
continue
|
|
104
|
+
if len(cols) > 5:
|
|
105
|
+
logging.error(f'invalid line {line}')
|
|
106
|
+
msg = ValidationMessage(
|
|
107
|
+
level=ValidationMsgLevel.ERROR,
|
|
108
|
+
source='CIT line',
|
|
109
|
+
source_id=0,
|
|
110
|
+
msg=f'Invalid line in CIT. There are {len(cols) -5} too many columns',
|
|
111
|
+
highlight_sub_patterns=line
|
|
112
|
+
)
|
|
113
|
+
errors.append(msg)
|
|
114
|
+
continue
|
|
43
115
|
try:
|
|
116
|
+
|
|
44
117
|
entry = CITEntry_v1(
|
|
45
118
|
service_name = cols[0],
|
|
46
119
|
application_intent = cols[1],
|
|
47
|
-
service_type =
|
|
120
|
+
service_type = cols[2],
|
|
48
121
|
applicable_if = cols[3],
|
|
49
122
|
template_url = cols[4]
|
|
50
123
|
)
|
|
@@ -52,23 +125,32 @@ class CIT_v1(LabFREED_BaseModel):
|
|
|
52
125
|
except ValueError:
|
|
53
126
|
logging.error(f'invalid line {line}')
|
|
54
127
|
msg = ValidationMessage(
|
|
55
|
-
level=ValidationMsgLevel.
|
|
128
|
+
level=ValidationMsgLevel.ERROR,
|
|
56
129
|
source='CIT line',
|
|
57
130
|
source_id=0,
|
|
58
|
-
msg='Invalid line in CIT.
|
|
131
|
+
msg='Invalid line in CIT.',
|
|
59
132
|
highlight_sub_patterns=line
|
|
60
133
|
)
|
|
61
134
|
errors.append(msg)
|
|
62
135
|
|
|
63
|
-
|
|
64
136
|
cit = CIT_v1(origin=origin, entries=entries)
|
|
137
|
+
if not cit.is_valid:
|
|
138
|
+
errors.insert(0,
|
|
139
|
+
ValidationMessage(
|
|
140
|
+
level=ValidationMsgLevel.WARNING,
|
|
141
|
+
source='CIT ',
|
|
142
|
+
source_id=0,
|
|
143
|
+
msg='Invalid lines in CIT. The lines were ignored. The rest of the CIT is still functional',
|
|
144
|
+
highlight_sub_patterns=''
|
|
145
|
+
)
|
|
146
|
+
)
|
|
65
147
|
cit._validation_messages.extend(errors)
|
|
66
148
|
cit._csv_original = csv
|
|
67
149
|
return cit
|
|
68
150
|
|
|
69
151
|
def evaluate_pac_id(self, pac:PAC_ID):
|
|
70
|
-
if
|
|
71
|
-
raise ValueError(
|
|
152
|
+
if type(pac) is not PAC_ID:
|
|
153
|
+
raise ValueError('CIT v1 does only handle PAC-IDs. PAC-CAT it does not know what to do')
|
|
72
154
|
cit_evaluated = ServiceGroup(origin=self.origin)
|
|
73
155
|
for e in self.entries:
|
|
74
156
|
conditions = e.applicable_if.split(';')
|
|
@@ -76,18 +158,18 @@ class CIT_v1(LabFREED_BaseModel):
|
|
|
76
158
|
for c in conditions:
|
|
77
159
|
if '=' in c:
|
|
78
160
|
query, expected = c.split('=')
|
|
79
|
-
value =
|
|
161
|
+
value = _find_pattern_in_pac(query.strip(), pac)
|
|
80
162
|
conditions_evaluated.append(value == expected.strip())
|
|
81
163
|
else:
|
|
82
164
|
query = c.strip()
|
|
83
|
-
found =
|
|
165
|
+
found = _find_pattern_in_pac(query, pac)
|
|
84
166
|
conditions_evaluated.append(found)
|
|
85
167
|
is_applicable = all(conditions_evaluated)
|
|
86
168
|
|
|
87
169
|
if not is_applicable:
|
|
88
170
|
continue
|
|
89
171
|
|
|
90
|
-
url = re.sub(r"\{([^}]+)\}", lambda v:
|
|
172
|
+
url = re.sub(r"\{([^}]+)\}", lambda v: _find_pattern_in_pac(v.group(0), pac), e.template_url)
|
|
91
173
|
cit_evaluated.services.append(Service(
|
|
92
174
|
service_name=e.service_name,
|
|
93
175
|
application_intents= [ e.application_intent ],
|
|
@@ -97,49 +179,7 @@ class CIT_v1(LabFREED_BaseModel):
|
|
|
97
179
|
)
|
|
98
180
|
return cit_evaluated
|
|
99
181
|
|
|
100
|
-
|
|
101
|
-
pac_url =pac.to_url()
|
|
102
|
-
if value == '{isu}':
|
|
103
|
-
return pac.issuer
|
|
104
|
-
|
|
105
|
-
elif value == '{pac}':
|
|
106
|
-
return pac_url.split('*')[0]
|
|
107
|
-
|
|
108
|
-
elif value == '{id}':
|
|
109
|
-
m = re.match(r'^HTTPS://.+?/(.+?)(\*.*)*$', pac_url)
|
|
110
|
-
return m.group(1) if m else None
|
|
111
|
-
|
|
112
|
-
elif m := re.match(r'\{idSeg(\d+)\}', value):
|
|
113
|
-
i = int(m.group(1)) - 1 # CIT is 1 based
|
|
114
|
-
seg = pac.identifier[i] if i < len(pac.identifier) else None
|
|
115
|
-
if seg:
|
|
116
|
-
return f"{(seg.key + ':') if seg.key else ''}{seg.value}"
|
|
117
|
-
|
|
118
|
-
elif m := re.match(r'\{idVal(\w+)\}', value):
|
|
119
|
-
k = m.group(1)
|
|
120
|
-
seg = [s for s in pac.identifier if s.key and s.key == k]
|
|
121
|
-
if seg:
|
|
122
|
-
seg = seg[0]
|
|
123
|
-
return seg.value
|
|
124
|
-
else:
|
|
125
|
-
return None
|
|
126
|
-
|
|
127
|
-
elif value == '{ext}':
|
|
128
|
-
m = re.match(r'^.*?(\*.*)*$', pac_url)
|
|
129
|
-
ext_str = m.group(1) if m else None
|
|
130
|
-
return m.group(1)[1:] if ext_str else None
|
|
131
|
-
|
|
132
|
-
elif m := re.match(r'\{ext(\d+)\}', value):
|
|
133
|
-
i = int(m.group(1)) - 1 # CIT is 1 based
|
|
134
|
-
extensions = pac_url.split('*')
|
|
135
|
-
extensions.pop(0)# first element is not extension
|
|
136
|
-
return extensions[i] if i < len(extensions) else None
|
|
137
|
-
else:
|
|
138
|
-
return None
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
182
|
+
|
|
143
183
|
|
|
144
184
|
def __str__(self):
|
|
145
185
|
if csv:=self._csv_original:
|
|
@@ -150,3 +190,56 @@ class CIT_v1(LabFREED_BaseModel):
|
|
|
150
190
|
for e in self.entries:
|
|
151
191
|
s += '\t'.join([e.service_name, e.application_intent, e.service_type.value, e.applicable_if, e.template_url]) + '\n'
|
|
152
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
|
+
|
|
@@ -9,6 +9,12 @@ import jsonpath_ng.ext as jsonpath
|
|
|
9
9
|
|
|
10
10
|
from labfreed.pac_id_resolver.services import Service, ServiceGroup
|
|
11
11
|
from labfreed.labfreed_infrastructure import LabFREED_BaseModel, ValidationMsgLevel, _quote_texts
|
|
12
|
+
from labfreed.pac_id_resolver.cit_common import ( _add_msg_to_cit_entry_model,
|
|
13
|
+
_validate_service_name,
|
|
14
|
+
_validate_application_intent,
|
|
15
|
+
_validate_service_type,
|
|
16
|
+
ServiceType)
|
|
17
|
+
|
|
12
18
|
|
|
13
19
|
__all__ = [
|
|
14
20
|
"CIT_v2",
|
|
@@ -16,9 +22,6 @@ __all__ = [
|
|
|
16
22
|
"CITEntry_v2"
|
|
17
23
|
]
|
|
18
24
|
|
|
19
|
-
class ServiceType(Enum):
|
|
20
|
-
USER_HANDOVER_GENERIC = 'userhandover-generic'
|
|
21
|
-
ATTRIBUTE_SERVICE_GENERIC = 'attributes-generic'
|
|
22
25
|
|
|
23
26
|
|
|
24
27
|
class CITEntry_v2(LabFREED_BaseModel):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
labfreed/__init__.py,sha256=
|
|
2
|
-
labfreed/labfreed_infrastructure.py,sha256=
|
|
1
|
+
labfreed/__init__.py,sha256=wKahqMhTOvdvcU9M6ARgaUBWlM0qEwE7q5qixgJXVsY,338
|
|
2
|
+
labfreed/labfreed_infrastructure.py,sha256=EPDSCaGxWakAoPpHyc6ltf-pOuKyS5829lj_EG6wa74,10072
|
|
3
3
|
labfreed/pac_cat/__init__.py,sha256=KNPtQzBD1XVohvG_ucOs7RJj-oi6biUTGB1k-T2o6pk,568
|
|
4
4
|
labfreed/pac_cat/category_base.py,sha256=lFQNiTUukyhWdaSCAI7CZxLtj6kNtnBCE4UsePwsGqE,1801
|
|
5
5
|
labfreed/pac_cat/pac_cat.py,sha256=AJUYDsyGOHy-sRRpXpY0awtbf3HCvn3RhMax6ofvYRA,5318
|
|
@@ -11,8 +11,9 @@ labfreed/pac_id/pac_id.py,sha256=IWXYlKFjQKB_9U5bINWC5_Lb5pcVbuleocvGs79A28w,530
|
|
|
11
11
|
labfreed/pac_id/url_parser.py,sha256=TAQHxFf7Li8GA517mfOivmnJAJgh782oaSDzmOOkyTE,5942
|
|
12
12
|
labfreed/pac_id/url_serializer.py,sha256=3D5pwcAP4ZrCQ22BRtxIwqWrFtZuY9913hCLPJNeyPI,2845
|
|
13
13
|
labfreed/pac_id_resolver/__init__.py,sha256=RNBlrDOSR42gmSNH9wJVhK_xwEX45cvTKVgWW2bjh7Q,113
|
|
14
|
-
labfreed/pac_id_resolver/
|
|
15
|
-
labfreed/pac_id_resolver/
|
|
14
|
+
labfreed/pac_id_resolver/cit_common.py,sha256=xEkSSumj_IYgnXn3yKvoTBbgExnIfPY7E-RHU-7pcX8,2905
|
|
15
|
+
labfreed/pac_id_resolver/cit_v1.py,sha256=cC-fGWmPxhUMylZYn3MBDrr9Ds1oL6-j88Pw03csB9k,9436
|
|
16
|
+
labfreed/pac_id_resolver/cit_v2.py,sha256=NCJqhYH5viF6iFCmryHhoQXmuKAyFMxgHvvzo4eBAgI,11838
|
|
16
17
|
labfreed/pac_id_resolver/resolver.py,sha256=SQlATlaUsmS6EZlEMyBQsp00ixpN3r-3V5pMXcvHYCw,2739
|
|
17
18
|
labfreed/pac_id_resolver/services.py,sha256=TPoH6YlSwa0hmawHpOiMwIpBAinhoRhMSoexop0YscI,2462
|
|
18
19
|
labfreed/qr/__init__.py,sha256=fdKwP6W2Js--yMbBUdn-g_2uq2VqPpfQJeDLHsMDO-Y,61
|
|
@@ -38,7 +39,7 @@ labfreed/well_known_keys/labfreed/well_known_keys.py,sha256=nqk66kHdSwJTJfMKlP-x
|
|
|
38
39
|
labfreed/well_known_keys/unece/UneceUnits.json,sha256=kwfQSp_nTuWbADfBBgqTWrvPl6XtM5SedEVLbMJrM7M,898953
|
|
39
40
|
labfreed/well_known_keys/unece/__init__.py,sha256=MSP9lmjg9_D9iqG9Yq2_ajYfQSNS9wIT7FXA1c--59M,122
|
|
40
41
|
labfreed/well_known_keys/unece/unece_units.py,sha256=gNDQk6KGl-nGMf9Ycq_fQ8P2xxKITgLkcQWPd4H49gI,1630
|
|
41
|
-
labfreed-0.2.
|
|
42
|
-
labfreed-0.2.
|
|
43
|
-
labfreed-0.2.
|
|
44
|
-
labfreed-0.2.
|
|
42
|
+
labfreed-0.2.6a4.dist-info/licenses/LICENSE,sha256=gHFOv9FRKHxO8cInP3YXyPoJnuNeqrvcHjaE_wPSsQ8,1100
|
|
43
|
+
labfreed-0.2.6a4.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
44
|
+
labfreed-0.2.6a4.dist-info/METADATA,sha256=WvHpUfPKFYz537qACQir3e4tmkngdiHU6E_7APE-jg8,18616
|
|
45
|
+
labfreed-0.2.6a4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|