labfreed 1.0.0a24__py3-none-any.whl → 1.0.0b26__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.
- labfreed/__init__.py +1 -1
- labfreed/labfreed_extended/app/app_infrastructure.py +2 -5
- labfreed/labfreed_extended/app/pac_info/pac_info.py +6 -8
- labfreed/labfreed_extended/pac_issuer_lib/lib/attribute.py +9 -6
- labfreed/labfreed_extended/pac_issuer_lib/static/external-link.svg +6 -6
- labfreed/labfreed_extended/pac_issuer_lib/static/logo.svg +44 -44
- labfreed/labfreed_extended/pac_issuer_lib/templates/main.jinja.html +4 -3
- labfreed/pac_attributes/api_data_models/request.py +78 -30
- labfreed/pac_attributes/api_data_models/response.py +107 -136
- labfreed/pac_attributes/client/client.py +30 -36
- labfreed/pac_attributes/client/client_attribute_group.py +18 -0
- labfreed/pac_attributes/pythonic/attribute_server_factory.py +39 -13
- labfreed/pac_attributes/pythonic/excel_attribute_data_source.py +1 -1
- labfreed/pac_attributes/pythonic/py_attributes.py +97 -125
- labfreed/pac_attributes/server/attribute_data_sources.py +9 -8
- labfreed/pac_attributes/server/server.py +33 -37
- labfreed/pac_id_resolver/resolver_config.py +2 -1
- {labfreed-1.0.0a24.dist-info → labfreed-1.0.0b26.dist-info}/METADATA +1 -1
- {labfreed-1.0.0a24.dist-info → labfreed-1.0.0b26.dist-info}/RECORD +21 -27
- labfreed/labfreed_extended/app/pac_info/html_renderer/external-link.svg +0 -7
- labfreed/labfreed_extended/app/pac_info/html_renderer/macros.jinja.html +0 -188
- labfreed/labfreed_extended/app/pac_info/html_renderer/pac-info-style.css +0 -176
- labfreed/labfreed_extended/app/pac_info/html_renderer/pac_info.jinja.html +0 -46
- labfreed/labfreed_extended/app/pac_info/html_renderer/pac_info_card.jinja.html +0 -7
- labfreed/pac_attributes/client/__init__.py +0 -0
- labfreed/pac_attributes/client/attribute_cache.py +0 -65
- {labfreed-1.0.0a24.dist-info → labfreed-1.0.0b26.dist-info}/WHEEL +0 -0
- {labfreed-1.0.0a24.dist-info → labfreed-1.0.0b26.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
|
|
2
2
|
from datetime import UTC, date, datetime, time
|
|
3
3
|
import json
|
|
4
|
+
import logging
|
|
4
5
|
from typing import Literal
|
|
5
6
|
from enum import Enum
|
|
6
7
|
import warnings
|
|
7
|
-
from pydantic import RootModel, field_validator
|
|
8
|
+
from pydantic import RootModel, field_validator, model_validator
|
|
8
9
|
|
|
9
10
|
from labfreed.labfreed_infrastructure import LabFREED_BaseModel
|
|
10
|
-
from labfreed.pac_attributes.api_data_models.response import
|
|
11
|
-
|
|
11
|
+
from labfreed.pac_attributes.api_data_models.response import (Attribute, AttributeItemsElementBase, AttributeGroup,
|
|
12
|
+
BoolAttributeItemsElement, DateTimeAttributeItemsElement, NumericAttributeItemsElement,
|
|
13
|
+
ObjectAttributeItemsElement, ReferenceAttributeItemsElement, ResourceAttributeItemsElement,
|
|
14
|
+
TextAttributeItemsElement)
|
|
15
|
+
from labfreed.pac_attributes.client.client_attribute_group import ClientAttributeGroup
|
|
12
16
|
from labfreed.pac_id.pac_id import PAC_ID
|
|
13
17
|
from labfreed.trex.pythonic.quantity import Quantity
|
|
14
18
|
|
|
@@ -33,15 +37,21 @@ AllowedList = list[AllowedValue]
|
|
|
33
37
|
class pyAttribute(LabFREED_BaseModel):
|
|
34
38
|
key:str
|
|
35
39
|
label:str = ""
|
|
36
|
-
|
|
40
|
+
values: AllowedValue | AllowedList
|
|
37
41
|
|
|
38
42
|
@property
|
|
39
43
|
def value_list(self):
|
|
40
44
|
'''helper function to more conveniently iterate over value elements, even if it's scalar'''
|
|
41
|
-
return self.
|
|
45
|
+
return self.values if isinstance(self.values, list) else [self.values]
|
|
42
46
|
|
|
47
|
+
@model_validator(mode='before')
|
|
48
|
+
def value_to_values(cls, d:dict):
|
|
49
|
+
value =d.pop('value', None)
|
|
50
|
+
if value is not None:
|
|
51
|
+
d['values'] = value
|
|
52
|
+
return d
|
|
43
53
|
|
|
44
|
-
@field_validator('
|
|
54
|
+
@field_validator('values', mode='before')
|
|
45
55
|
def handle_one_element_list(v):
|
|
46
56
|
if isinstance(v, list) and len(v)==1:
|
|
47
57
|
return v[0]
|
|
@@ -58,147 +68,109 @@ class pyAttribute(LabFREED_BaseModel):
|
|
|
58
68
|
|
|
59
69
|
|
|
60
70
|
class pyAttributes(RootModel[list[pyAttribute]]):
|
|
61
|
-
def to_payload_attributes(self) ->
|
|
62
|
-
out =
|
|
71
|
+
def to_payload_attributes(self) -> dict[str, Attribute]:
|
|
72
|
+
out = {}
|
|
63
73
|
for e in self.root:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
apt.value = apt.value[0]
|
|
67
|
-
out.append(apt)
|
|
74
|
+
payload_attr = self._attribute_to_attribute_payload_type(e)
|
|
75
|
+
out.update({e.key: payload_attr})
|
|
68
76
|
return out
|
|
69
77
|
|
|
70
78
|
|
|
71
79
|
@staticmethod
|
|
72
|
-
def _attribute_to_attribute_payload_type(attribute:pyAttribute) ->
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"label": attribute.label,
|
|
76
|
-
}
|
|
77
|
-
value_list = attribute.value_list
|
|
78
|
-
first_value = value_list[0]
|
|
79
|
-
if isinstance(first_value, bool):
|
|
80
|
-
if len(value_list) == 1:
|
|
81
|
-
return BoolAttribute(value=value_list[0], **common_args)
|
|
82
|
-
else:
|
|
83
|
-
return BoolListAttribute(value=value_list, **common_args)
|
|
84
|
-
|
|
80
|
+
def _attribute_to_attribute_payload_type(attribute:pyAttribute) -> AttributeItemsElementBase:
|
|
81
|
+
items = []
|
|
82
|
+
for value in attribute.value_list:
|
|
85
83
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
else:
|
|
108
|
-
num_attr = NumericListAttribute(value=values, **common_args)
|
|
109
|
-
num_attr.print_validation_messages()
|
|
110
|
-
|
|
111
|
-
return num_attr
|
|
112
|
-
|
|
113
|
-
elif isinstance(first_value, str):
|
|
114
|
-
# capture quantities in the form of "100.0e5 g/L"
|
|
115
|
-
if Quantity.can_convert_to_quantity(first_value):
|
|
116
|
-
values = []
|
|
117
|
-
for v in value_list:
|
|
118
|
-
q = Quantity.from_str_with_unit(v)
|
|
119
|
-
values.append( NumericValue(numerical_value=q.value_as_str(), unit = q.unit) )
|
|
120
|
-
if len(values) == 1:
|
|
121
|
-
return NumericAttribute(value=values[0], **common_args)
|
|
84
|
+
if isinstance(value, bool):
|
|
85
|
+
items.append(BoolAttributeItemsElement(value=value))
|
|
86
|
+
|
|
87
|
+
elif isinstance(value, datetime | date | time):
|
|
88
|
+
if not value.tzinfo:
|
|
89
|
+
warnings.warn(f'No timezone given for {value}. Assuming it is in UTC.')
|
|
90
|
+
value.replace(tzinfo=UTC)
|
|
91
|
+
items.append(DateTimeAttributeItemsElement(value=value))
|
|
92
|
+
|
|
93
|
+
elif isinstance(value, Quantity|int|float):
|
|
94
|
+
if not isinstance(value, Quantity):
|
|
95
|
+
value = Quantity(value=value, unit='dimensionless')
|
|
96
|
+
v = f"{value.value_as_str()} {value.unit}"
|
|
97
|
+
items.append(NumericAttributeItemsElement(value=v))
|
|
98
|
+
|
|
99
|
+
elif isinstance(value, str):
|
|
100
|
+
# capture quantities in the form of "100.0e5 g/L"
|
|
101
|
+
if Quantity.can_convert_to_quantity(value):
|
|
102
|
+
q = Quantity.from_str_with_unit(value)
|
|
103
|
+
v = f"{q.value_as_str()} {q.unit}"
|
|
104
|
+
items.append(NumericAttributeItemsElement(value=v))
|
|
122
105
|
else:
|
|
123
|
-
|
|
106
|
+
items.append(TextAttributeItemsElement(value=value))
|
|
124
107
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
else:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return ResourceAttribute(value=values[0], **common_args)
|
|
142
|
-
else:
|
|
143
|
-
return ResourceListAttribute(value=values, **common_args)
|
|
144
|
-
|
|
145
|
-
elif isinstance(first_value, PAC_ID):
|
|
146
|
-
values = [v.to_url(include_extensions=False) for v in value_list]
|
|
147
|
-
if len(values) == 1:
|
|
148
|
-
return ReferenceAttribute(value=values[0], **common_args)
|
|
149
|
-
else:
|
|
150
|
-
return ReferenceListAttribute(value=values, **common_args)
|
|
151
|
-
|
|
152
|
-
else: #this covers the last resort case of arbitrary objects. Must be json serializable.
|
|
153
|
-
try :
|
|
154
|
-
values = [json.loads(json.dumps(v)) for v in value_list]
|
|
155
|
-
if len(values) == 1:
|
|
156
|
-
return ObjectAttribute(value=values[0], **common_args)
|
|
157
|
-
else:
|
|
158
|
-
return ObjectListAttribute(value=values, **common_args)
|
|
159
|
-
except TypeError as e: # noqa: F841
|
|
160
|
-
raise ValueError(f'Invalid Type: {type(first_value)} cannot be converted to attribute. You may want to use ObjectAttribute, but would have to implement the conversion from your python type yourself.')
|
|
108
|
+
elif isinstance(value, pyReference):
|
|
109
|
+
items.append(ReferenceAttributeItemsElement(value=value.root))
|
|
110
|
+
|
|
111
|
+
elif isinstance(value, pyResource):
|
|
112
|
+
items.append(ResourceAttributeItemsElement(value=value.root))
|
|
113
|
+
|
|
114
|
+
elif isinstance(value, PAC_ID):
|
|
115
|
+
v = value.to_url(include_extensions=False)
|
|
116
|
+
items.append(ReferenceAttributeItemsElement(value=v))
|
|
117
|
+
|
|
118
|
+
else: #this covers the last resort case of arbitrary objects. Must be json serializable.
|
|
119
|
+
try :
|
|
120
|
+
v = json.loads(json.dumps(value))
|
|
121
|
+
items.append(ObjectAttributeItemsElement(value=v))
|
|
122
|
+
except TypeError as e: # noqa: F841
|
|
123
|
+
raise ValueError(f'Invalid Type: {type(value)} cannot be converted to attribute. You may want to use ObjectAttribute, but would have to implement the conversion from your python type yourself.')
|
|
161
124
|
|
|
125
|
+
|
|
126
|
+
if not all(type(e) is type(items[0]) for e in items):
|
|
127
|
+
logging.warning("Not all elements in items have the same type. This might cause unexpected behaviour in clients.")
|
|
162
128
|
|
|
129
|
+
attr = Attribute(key=attribute.key,
|
|
130
|
+
label= attribute.label,
|
|
131
|
+
items=items)
|
|
132
|
+
return attr
|
|
133
|
+
|
|
134
|
+
|
|
163
135
|
|
|
164
136
|
@staticmethod
|
|
165
|
-
def from_payload_attributes(attributes:
|
|
137
|
+
def from_payload_attributes(attributes:dict[str, Attribute]) -> 'pyAttributes':
|
|
166
138
|
out = list()
|
|
167
|
-
for a in attributes:
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
139
|
+
for a in attributes.values():
|
|
140
|
+
values = []
|
|
141
|
+
for v in a.items:
|
|
142
|
+
match v:
|
|
143
|
+
case ReferenceAttributeItemsElement() :
|
|
144
|
+
values.append(pyReference(v.value))
|
|
145
|
+
|
|
146
|
+
case ResourceAttributeItemsElement() :
|
|
147
|
+
values.append(pyResource(v.value))
|
|
148
|
+
|
|
149
|
+
case NumericAttributeItemsElement() :
|
|
150
|
+
values.append(Quantity.from_str_value(value=v._numerical_value, unit=v._unit))
|
|
178
151
|
|
|
179
|
-
|
|
180
|
-
|
|
152
|
+
case BoolAttributeItemsElement() :
|
|
153
|
+
values.append(v.value)
|
|
154
|
+
|
|
155
|
+
case TextAttributeItemsElement() :
|
|
156
|
+
values.append(v.value)
|
|
157
|
+
|
|
158
|
+
case DateTimeAttributeItemsElement() :
|
|
159
|
+
values.append(v.value)
|
|
181
160
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
case DateTimeAttribute() | DateTimeListAttribute():
|
|
186
|
-
values = value_list
|
|
187
|
-
|
|
188
|
-
case ObjectAttribute() | ObjectListAttribute():
|
|
189
|
-
values = value_list
|
|
190
|
-
|
|
191
|
-
|
|
161
|
+
case ObjectAttributeItemsElement() :
|
|
162
|
+
values.append(v.value)
|
|
163
|
+
|
|
192
164
|
attr = pyAttribute(key=a.key,
|
|
193
|
-
|
|
194
|
-
|
|
165
|
+
label=a.label,
|
|
166
|
+
values=values
|
|
195
167
|
)
|
|
196
168
|
out.append(attr )
|
|
197
169
|
return out
|
|
198
170
|
|
|
199
171
|
|
|
200
172
|
|
|
201
|
-
class pyAttributeGroup(
|
|
173
|
+
class pyAttributeGroup(ClientAttributeGroup):
|
|
202
174
|
attributes:dict[str,pyAttribute]
|
|
203
175
|
|
|
204
176
|
@staticmethod
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod, abstractproperty
|
|
2
|
-
from
|
|
3
|
-
from labfreed.pac_attributes.api_data_models.response import AttributeBase, AttributeGroup
|
|
2
|
+
from labfreed.pac_attributes.api_data_models.response import Attribute, AttributeGroup
|
|
4
3
|
from labfreed.pac_cat.pac_cat import PAC_CAT
|
|
5
|
-
from labfreed.pac_id.pac_id import PAC_ID
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
class AttributeGroupDataSource(ABC):
|
|
@@ -31,8 +29,8 @@ class AttributeGroupDataSource(ABC):
|
|
|
31
29
|
|
|
32
30
|
|
|
33
31
|
class Dict_DataSource(AttributeGroupDataSource):
|
|
34
|
-
def __init__(self, data:dict[str,
|
|
35
|
-
if not all([isinstance(e,
|
|
32
|
+
def __init__(self, data:dict[str, dict[str, Attribute]], uses_pac_cat_short_form=True, pac_to_key: callable = None, *args, **kwargs):
|
|
33
|
+
if not all([isinstance(e, dict) for e in data.values()]):
|
|
36
34
|
raise ValueError('Invalid data')
|
|
37
35
|
|
|
38
36
|
self._data = data
|
|
@@ -44,7 +42,7 @@ class Dict_DataSource(AttributeGroupDataSource):
|
|
|
44
42
|
|
|
45
43
|
@property
|
|
46
44
|
def provides_attributes(self):
|
|
47
|
-
return list(set([a.key for attributes in self._data.values() for a in attributes]))
|
|
45
|
+
return list(set([a.key for attributes in self._data.values() for a in attributes.values()]))
|
|
48
46
|
|
|
49
47
|
|
|
50
48
|
def attributes(self, pac_url: str) -> AttributeGroup:
|
|
@@ -58,9 +56,12 @@ class Dict_DataSource(AttributeGroupDataSource):
|
|
|
58
56
|
lookup_key = self._pac_to_key(pac_url) if self._pac_to_key else pac_url
|
|
59
57
|
attributes = self._data.get(lookup_key)
|
|
60
58
|
if not attributes:
|
|
61
|
-
|
|
59
|
+
if 'default' in self._data.keys():
|
|
60
|
+
attributes = self._data.get('default', None)
|
|
61
|
+
else:
|
|
62
|
+
return None
|
|
62
63
|
|
|
63
|
-
return AttributeGroup(
|
|
64
|
+
return AttributeGroup(group_key=self._attribute_group_key,
|
|
64
65
|
attributes=attributes)
|
|
65
66
|
|
|
66
67
|
|
|
@@ -4,9 +4,10 @@ import traceback
|
|
|
4
4
|
import warnings
|
|
5
5
|
|
|
6
6
|
import rich
|
|
7
|
+
from werkzeug.datastructures.accept import LanguageAccept
|
|
7
8
|
|
|
8
|
-
from labfreed.pac_attributes.api_data_models.request import
|
|
9
|
-
from labfreed.pac_attributes.api_data_models.response import AttributeResponsePayload, AttributesOfPACID,
|
|
9
|
+
from labfreed.pac_attributes.api_data_models.request import AttributeRequestData
|
|
10
|
+
from labfreed.pac_attributes.api_data_models.response import AttributeResponsePayload, AttributesOfPACID, ReferenceAttributeItemsElement
|
|
10
11
|
from labfreed.pac_attributes.api_data_models.server_capabilities_response import ServerCapabilities
|
|
11
12
|
from labfreed.pac_attributes.server.attribute_data_sources import AttributeGroupDataSource
|
|
12
13
|
from labfreed.pac_attributes.server.translation_data_sources import TranslationDataSource
|
|
@@ -55,23 +56,25 @@ class AttributeServerRequestHandler():
|
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
|
|
58
|
-
def handle_attribute_request(self,
|
|
59
|
+
def handle_attribute_request(self, request_data:AttributeRequestData) -> str:
|
|
60
|
+
if not isinstance(request_data, AttributeRequestData):
|
|
61
|
+
raise ValueError('request_data most be of AttributeRequestData')
|
|
59
62
|
try:
|
|
60
|
-
r =
|
|
61
|
-
except Exception:
|
|
63
|
+
r = AttributeRequestData.model_validate(request_data)
|
|
64
|
+
except Exception as e:
|
|
65
|
+
print(e)
|
|
62
66
|
raise InvalidRequestError
|
|
63
67
|
attributes_for_pac_id = []
|
|
64
68
|
referenced_pac_ids = set()
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
referenced_pac_ids.update(ref)
|
|
69
|
+
attributes_for_pac = self._get_attributes_for_pac_id(pac_url=r.pac_id,
|
|
70
|
+
restrict_to_attribute_groups = r.restrict_to_attribute_groups)
|
|
71
|
+
attributes_for_pac_id.append(attributes_for_pac)
|
|
72
|
+
ref = self._get_referenced_pac_ids(attributes_for_pac)
|
|
73
|
+
if ref:
|
|
74
|
+
referenced_pac_ids.update(ref)
|
|
72
75
|
|
|
73
76
|
# also find attributes of referenced pac-ids
|
|
74
|
-
if
|
|
77
|
+
if r.do_forward_lookup:
|
|
75
78
|
for pac_url in referenced_pac_ids:
|
|
76
79
|
attributes_for_pac = self._get_attributes_for_pac_id(pac_url=pac_url,
|
|
77
80
|
restrict_to_attribute_groups = r.restrict_to_attribute_groups)
|
|
@@ -82,7 +85,7 @@ class AttributeServerRequestHandler():
|
|
|
82
85
|
for e in attributes_for_pac_id:
|
|
83
86
|
self._add_display_names(e, response_language)
|
|
84
87
|
|
|
85
|
-
response = AttributeResponsePayload(
|
|
88
|
+
response = AttributeResponsePayload(data=attributes_for_pac_id, language=response_language
|
|
86
89
|
).to_json()
|
|
87
90
|
return response
|
|
88
91
|
|
|
@@ -113,13 +116,14 @@ class AttributeServerRequestHandler():
|
|
|
113
116
|
def _get_referenced_pac_ids(self, attributes_for_pac:AttributesOfPACID):
|
|
114
117
|
referenced_pacs = []
|
|
115
118
|
for ag in attributes_for_pac.attribute_groups:
|
|
116
|
-
for a in ag.attributes :
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
for a in ag.attributes.values() :
|
|
120
|
+
for e in a.items:
|
|
121
|
+
if isinstance(e, ReferenceAttributeItemsElement):
|
|
122
|
+
try:
|
|
123
|
+
PAC_ID.from_url(e.value)
|
|
124
|
+
referenced_pacs.append(e.value)
|
|
125
|
+
except Exception:
|
|
126
|
+
pass
|
|
123
127
|
return referenced_pacs
|
|
124
128
|
|
|
125
129
|
|
|
@@ -131,12 +135,12 @@ class AttributeServerRequestHandler():
|
|
|
131
135
|
this function should never get into the situation not to find translations.
|
|
132
136
|
'''
|
|
133
137
|
for ag in attributes_of_pac.attribute_groups:
|
|
134
|
-
if dn := self._get_display_name_for_key(ag.
|
|
135
|
-
ag.
|
|
138
|
+
if dn := self._get_display_name_for_key(ag.group_key, language):
|
|
139
|
+
ag.group_label = dn
|
|
136
140
|
else:
|
|
137
|
-
ag.
|
|
138
|
-
rich.print(f"[yellow]WARNING:[/yellow] No translation for '{ag.
|
|
139
|
-
for a in ag.attributes:
|
|
141
|
+
ag.group_label = self.fallback_label(ag.group_key)
|
|
142
|
+
rich.print(f"[yellow]WARNING:[/yellow] No translation for '{ag.group_key}' in '{language}'. Falling back to '{ag.group_label}'")
|
|
143
|
+
for a in ag.attributes.values():
|
|
140
144
|
if dn := self._get_display_name_for_key(a.key, language):
|
|
141
145
|
a.label = dn
|
|
142
146
|
else:
|
|
@@ -161,21 +165,13 @@ class AttributeServerRequestHandler():
|
|
|
161
165
|
return None
|
|
162
166
|
|
|
163
167
|
|
|
164
|
-
def _find_response_language(self, requested_languages):
|
|
168
|
+
def _find_response_language(self, requested_languages:LanguageAccept):
|
|
165
169
|
'''finds the language the server will respond in'''
|
|
166
170
|
if not requested_languages:
|
|
167
171
|
return self._default_language
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if language in self._supported_languages:
|
|
171
|
-
return language
|
|
172
|
-
|
|
173
|
-
# remove the country codes and try the again
|
|
174
|
-
for l_fallback in [lang.split('-')[0] for lang in requested_languages]:
|
|
175
|
-
if language in self._supported_languages:
|
|
176
|
-
return l_fallback
|
|
172
|
+
best_match = requested_languages.best_match(self._supported_languages, default="en")
|
|
173
|
+
return best_match
|
|
177
174
|
|
|
178
|
-
return self._default_language
|
|
179
175
|
|
|
180
176
|
|
|
181
177
|
|
|
@@ -299,7 +299,8 @@ class ResolverConfig(LabFREED_BaseModel):
|
|
|
299
299
|
for placeholder in placeholders:
|
|
300
300
|
expanded_placeholder = self._apply_convenience_substitutions(placeholder)
|
|
301
301
|
res = self._evaluate_jsonpath(pac_id_json, expanded_placeholder) or ['']
|
|
302
|
-
url = url.replace(f'{{{placeholder}}}', str(res[0]))
|
|
302
|
+
url:str = url.replace(f'{{{placeholder}}}', str(res[0]))
|
|
303
|
+
url = url.strip()
|
|
303
304
|
# res = self.substitute_jsonpath_expressions(expanded_placeholder, Patterns.jsonpath.value, as_bool=False)
|
|
304
305
|
# url = url.replace(f'{{{placeholder}}}', res)
|
|
305
306
|
return url
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
labfreed/__init__.py,sha256=
|
|
1
|
+
labfreed/__init__.py,sha256=K7LpEGI6O9AnTM4dJgUI30LchIO5KnqPUh3gpWhhY4Q,339
|
|
2
2
|
labfreed/labfreed_infrastructure.py,sha256=ss1PyJl-7Es-lEcxptmdYI9kDAHmh7HB_tAGkPC6UVs,10173
|
|
3
|
-
labfreed/labfreed_extended/app/app_infrastructure.py,sha256=
|
|
3
|
+
labfreed/labfreed_extended/app/app_infrastructure.py,sha256=1867Nq40c8Q4bFyRv48vTIFDXoPeZTfYij9PSog6fkE,4427
|
|
4
4
|
labfreed/labfreed_extended/app/formatted_print.py,sha256=DcwWP0ix1e_wYNIdceIp6cETkJdG2DqpU8Gs3aZAL40,1930
|
|
5
|
-
labfreed/labfreed_extended/app/pac_info/pac_info.py,sha256=
|
|
6
|
-
labfreed/labfreed_extended/app/pac_info/html_renderer/external-link.svg,sha256=KXVLyywqSOhBV4xAiCLsK6yJPUPj8O08M2__qSceM3M,1164
|
|
7
|
-
labfreed/labfreed_extended/app/pac_info/html_renderer/macros.jinja.html,sha256=1S-dxibPwJshtdelsmyA4LpgOm84L6RTXPNO93gmPfg,5964
|
|
8
|
-
labfreed/labfreed_extended/app/pac_info/html_renderer/pac-info-style.css,sha256=C5pyD956fd6pJgUBjGxvxgL0Wbgq0v7ZLY4Vr-sJZ7A,4169
|
|
9
|
-
labfreed/labfreed_extended/app/pac_info/html_renderer/pac_info.jinja.html,sha256=njXE9xexFdMlX65eDiwqE8PzbMATUOJAbwBCh5JvahY,1293
|
|
10
|
-
labfreed/labfreed_extended/app/pac_info/html_renderer/pac_info_card.jinja.html,sha256=6UdsZtqJ3soSAYTKN43OB1Onm93WYz23TfM2GBYzJ-U,152
|
|
5
|
+
labfreed/labfreed_extended/app/pac_info/pac_info.py,sha256=HWTYA20cIBpwUl4eRs5cNghCHs3_SOS9yARt11YN0XY,9078
|
|
11
6
|
labfreed/labfreed_extended/pac_issuer_lib/app_factory.py,sha256=eeIaiCTXV7_aWwDgWhGVjDY4O9uSQoyDQl7YSXVhmA0,20072
|
|
12
|
-
labfreed/labfreed_extended/pac_issuer_lib/lib/attribute.py,sha256=
|
|
7
|
+
labfreed/labfreed_extended/pac_issuer_lib/lib/attribute.py,sha256=Nu2NpaPbFIzDMa17oESJK9pZ3Qv86H3fMmuY5kWre7M,7182
|
|
13
8
|
labfreed/labfreed_extended/pac_issuer_lib/lib/bp_landing_page.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
9
|
labfreed/labfreed_extended/pac_issuer_lib/lib/utils.py,sha256=aUdJGFLx1HDDXGRqMVJuGn7uqzNXHrEb7cCA-nX920Y,651
|
|
15
10
|
labfreed/labfreed_extended/pac_issuer_lib/static/cancel.svg,sha256=pLsrB5Jm5OtG2JXk4jXv7D9z9RmPsNz1eVKrsQT_6zI,1201
|
|
@@ -22,8 +17,8 @@ labfreed/labfreed_extended/pac_issuer_lib/static/cat-MC.svg,sha256=p9r3_N7yDYFDU
|
|
|
22
17
|
labfreed/labfreed_extended/pac_issuer_lib/static/cat-MD.svg,sha256=aBtWtcxbkKkYtzjVfs1koLo6lKdi-mwHYQq0BUACsVQ,1829
|
|
23
18
|
labfreed/labfreed_extended/pac_issuer_lib/static/cat-MS.svg,sha256=ZuFKjoyoDf_69XpYnA-1BhV01vUisPZ2lBDCphXOFGU,740
|
|
24
19
|
labfreed/labfreed_extended/pac_issuer_lib/static/cat-MX.svg,sha256=26wATJTEjIS9jGBHDC9UIHjQL7xvVTLm0YK2gPs9Kr8,816
|
|
25
|
-
labfreed/labfreed_extended/pac_issuer_lib/static/external-link.svg,sha256=
|
|
26
|
-
labfreed/labfreed_extended/pac_issuer_lib/static/logo.svg,sha256=
|
|
20
|
+
labfreed/labfreed_extended/pac_issuer_lib/static/external-link.svg,sha256=KXVLyywqSOhBV4xAiCLsK6yJPUPj8O08M2__qSceM3M,1164
|
|
21
|
+
labfreed/labfreed_extended/pac_issuer_lib/static/logo.svg,sha256=T-uPnEI8ylQAg7t4avCWIcvtybImrwkir8_R3cnzGI4,2296
|
|
27
22
|
labfreed/labfreed_extended/pac_issuer_lib/static/menu.svg,sha256=_gvLbHEGigZKlSRU1VpD67sRpNlXUAB_HtJUQVfXOgc,1251
|
|
28
23
|
labfreed/labfreed_extended/pac_issuer_lib/static/search.svg,sha256=lYyQaukECdUnf3nusxSm5RG_6PdPDknCr6y4Fqs7CWg,577
|
|
29
24
|
labfreed/labfreed_extended/pac_issuer_lib/static/styles.css,sha256=o1rz7bL1z4IoQowS9Lf_umfFZgOe-mYuECSDveIvPWE,7603
|
|
@@ -31,7 +26,7 @@ labfreed/labfreed_extended/pac_issuer_lib/static/styles_brand.css,sha256=0O8lt8z
|
|
|
31
26
|
labfreed/labfreed_extended/pac_issuer_lib/static/styles_pac_info.css,sha256=uARZ5o36O4K3hGDv6WNEqrTd5M-lUBdF-FwYj4iEuIA,5341
|
|
32
27
|
labfreed/labfreed_extended/pac_issuer_lib/templates/flash_error_messages.jinja.html,sha256=qt5HNdDwfpvOVel6SQUAv9EukN6lpCXyL0fDz6sMorw,235
|
|
33
28
|
labfreed/labfreed_extended/pac_issuer_lib/templates/footer.jinja.html,sha256=kt8ifovVWI8ccXrXyzijHZ0Rb4Xj5KhWgXx8wrccNsY,118
|
|
34
|
-
labfreed/labfreed_extended/pac_issuer_lib/templates/main.jinja.html,sha256=
|
|
29
|
+
labfreed/labfreed_extended/pac_issuer_lib/templates/main.jinja.html,sha256=WJDz-Sqa4TnGPb4yxFslffIc3YB3tWJ1QRpIMj6uOPA,2536
|
|
35
30
|
labfreed/labfreed_extended/pac_issuer_lib/templates/navbar.jinja.html,sha256=RXZqyQi8D6Ik17s1-P31GyaEr8Et-3FSbl9RUR68TLM,1751
|
|
36
31
|
labfreed/labfreed_extended/pac_issuer_lib/templates/pac_issuer_error.jinja.html,sha256=WGAEVOTmsUqG2_wi6xkR8Cpof4EnCChwmsw6k1LPqtE,108
|
|
37
32
|
labfreed/labfreed_extended/pac_issuer_lib/templates/pac_issuer_landing_page.jinja.html,sha256=8Rv1_Azxy3BskdEWBvmXr-nRYh3xXngjsGgfRCvOOLM,205
|
|
@@ -41,19 +36,18 @@ labfreed/labfreed_extended/pac_issuer_lib/templates/pac_info/card.jinja.html,sha
|
|
|
41
36
|
labfreed/labfreed_extended/pac_issuer_lib/templates/pac_info/pac_info.jinja.html,sha256=xK0yM_ovRE8QS6N7hiXhGv-ya8C-s19YWhhMqJKYxFM,1518
|
|
42
37
|
labfreed/pac_attributes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
38
|
labfreed/pac_attributes/well_knonw_attribute_keys.py,sha256=Z_QcQdbIil_EMpFqQcBnivEGMDauyoCMW8r62-EN2KM,547
|
|
44
|
-
labfreed/pac_attributes/api_data_models/request.py,sha256=
|
|
45
|
-
labfreed/pac_attributes/api_data_models/response.py,sha256
|
|
39
|
+
labfreed/pac_attributes/api_data_models/request.py,sha256=64BCChFKXA8Z91r5IxAtcVZ6XiCKcw9RQErok2b91cc,4045
|
|
40
|
+
labfreed/pac_attributes/api_data_models/response.py,sha256=Hglfcvb7gC7uZrLsGfPewC290vp4qq4WsuM9S3UHQFI,8188
|
|
46
41
|
labfreed/pac_attributes/api_data_models/server_capabilities_response.py,sha256=ypDm4f8xZZl036fp8PuIe6lJHNW5Zg1fItgUlnV75V0,178
|
|
47
|
-
labfreed/pac_attributes/client/
|
|
48
|
-
labfreed/pac_attributes/client/
|
|
49
|
-
labfreed/pac_attributes/
|
|
50
|
-
labfreed/pac_attributes/pythonic/
|
|
51
|
-
labfreed/pac_attributes/pythonic/
|
|
52
|
-
labfreed/pac_attributes/pythonic/py_attributes.py,sha256=SsZfrCjd6FJFDe_pmpKJQ2PGrpDfNacHlUzFDBxjWwc,8712
|
|
42
|
+
labfreed/pac_attributes/client/client.py,sha256=5d-G-1tHOx2PXW7KP366tWr4k4F1ykGHX9e-bauF6_w,7149
|
|
43
|
+
labfreed/pac_attributes/client/client_attribute_group.py,sha256=lZXbMU_Yp7Q1iKc5WRqS6pzEz_mtwZaQ5fYZqJA6784,375
|
|
44
|
+
labfreed/pac_attributes/pythonic/attribute_server_factory.py,sha256=8OeWuHpJSW1mA0gWKLWPBZvq0n3VEfVOPQSmXNnp5dw,7673
|
|
45
|
+
labfreed/pac_attributes/pythonic/excel_attribute_data_source.py,sha256=IBBGpHgt-HiZeB6dsLcjtqUPP2JdViLz2QMIDMjzmME,8467
|
|
46
|
+
labfreed/pac_attributes/pythonic/py_attributes.py,sha256=VkkgKupJcM-kf0I5qRc5AiLSfi0vwnNgQv6neNtdRR8,7394
|
|
53
47
|
labfreed/pac_attributes/pythonic/py_dict_data_source.py,sha256=nAz6GA7Xx_0IORPPpt_Wl3sFJa1Q5Fnq5vdf1uQiJF8,531
|
|
54
48
|
labfreed/pac_attributes/server/__init__.py,sha256=JvQ2kpQx62OUwP18bGhOWYU9an_nQW59Y8Lh7HyfVxY,301
|
|
55
|
-
labfreed/pac_attributes/server/attribute_data_sources.py,sha256=
|
|
56
|
-
labfreed/pac_attributes/server/server.py,sha256=
|
|
49
|
+
labfreed/pac_attributes/server/attribute_data_sources.py,sha256=92BiQ2QC00PSXeeb6XI0KNcD7ZF7bdOSZZcOrOwPr_o,2406
|
|
50
|
+
labfreed/pac_attributes/server/server.py,sha256=Q5rjWCT6ZicLTMyR59bIC4bCIr8p50kS5p6cwv_wjtw,9114
|
|
57
51
|
labfreed/pac_attributes/server/translation_data_sources.py,sha256=axALOqfP840sOSdVCRYtrens97mm-hpfONMUyuVlCrY,2145
|
|
58
52
|
labfreed/pac_cat/__init__.py,sha256=KNPtQzBD1XVohvG_ucOs7RJj-oi6biUTGB1k-T2o6pk,568
|
|
59
53
|
labfreed/pac_cat/category_base.py,sha256=XAuvfJSCsQ3Ypi5WujtaCmt5isj7Qsx7-zJa9Sm0XVY,2530
|
|
@@ -68,7 +62,7 @@ labfreed/pac_id/url_serializer.py,sha256=01LB30pNMBtv2rYHsiE_4Ga2iVA515Boj4ikOIY
|
|
|
68
62
|
labfreed/pac_id_resolver/__init__.py,sha256=RNBlrDOSR42gmSNH9wJVhK_xwEX45cvTKVgWW2bjh7Q,113
|
|
69
63
|
labfreed/pac_id_resolver/cit_v1.py,sha256=JGlEH2d9awEu3HxPW7vu0uj4ZC3B02IdmFg7aJ4axQw,9833
|
|
70
64
|
labfreed/pac_id_resolver/resolver.py,sha256=anqteWexD7w78wzd1TjT06enkDIU-P-7NVKNWiASXLU,4127
|
|
71
|
-
labfreed/pac_id_resolver/resolver_config.py,sha256=
|
|
65
|
+
labfreed/pac_id_resolver/resolver_config.py,sha256=M52v2ps_dGTxQ6x-AV16m5eCbjg_vzwQARxzGTucdaU,12457
|
|
72
66
|
labfreed/pac_id_resolver/resolver_config_common.py,sha256=JGbgT2YSBc3NQ5x9CV3diqYZgpDGWygGPd5flk4-hWk,2958
|
|
73
67
|
labfreed/pac_id_resolver/services.py,sha256=IGEueWh2UeXKh6dIOs_ZNTvzguHPVuNB7SmV-FHPYns,2650
|
|
74
68
|
labfreed/qr/__init__.py,sha256=fdKwP6W2Js--yMbBUdn-g_2uq2VqPpfQJeDLHsMDO-Y,61
|
|
@@ -96,7 +90,7 @@ labfreed/well_known_keys/labfreed/well_known_keys.py,sha256=p-hXwEEIs7p2SKn9DQeL
|
|
|
96
90
|
labfreed/well_known_keys/unece/UneceUnits.json,sha256=kwfQSp_nTuWbADfBBgqTWrvPl6XtM5SedEVLbMJrM7M,898953
|
|
97
91
|
labfreed/well_known_keys/unece/__init__.py,sha256=MSP9lmjg9_D9iqG9Yq2_ajYfQSNS9wIT7FXA1c--59M,122
|
|
98
92
|
labfreed/well_known_keys/unece/unece_units.py,sha256=J20d64H69qKDE3XlGdJoXIIh0G-d0jKoiIDsg9an5pk,1655
|
|
99
|
-
labfreed-1.0.
|
|
100
|
-
labfreed-1.0.
|
|
101
|
-
labfreed-1.0.
|
|
102
|
-
labfreed-1.0.
|
|
93
|
+
labfreed-1.0.0b26.dist-info/licenses/LICENSE,sha256=gHFOv9FRKHxO8cInP3YXyPoJnuNeqrvcHjaE_wPSsQ8,1100
|
|
94
|
+
labfreed-1.0.0b26.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
95
|
+
labfreed-1.0.0b26.dist-info/METADATA,sha256=K8z2-hmoKb-cimYESItpZrexeEKNvSkvQkReD_W5wD8,19858
|
|
96
|
+
labfreed-1.0.0b26.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
-
<title>icons/external-link</title>
|
|
4
|
-
<g id="icons/external-link" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
5
|
-
<path d="M5.10570888,18.8942911 C4.83722343,18.6258057 4.81484965,18.204406 5.03858752,17.9104349 L5.10570888,17.8336309 L15.9992174,6.94117952 L10.8105793,6.93942074 L10.7088087,6.93257412 C10.3427331,6.8829117 10.0605793,6.5691165 10.0605793,6.18942074 C10.0605793,5.81286295 10.3380887,5.50112097 10.6997498,5.44755266 L10.8105793,5.43942074 L18.5605793,5.43942074 L18.5605793,13.1894207 L18.5537326,13.2911913 C18.5090365,13.6206593 18.2503927,13.8821507 17.9223127,13.9311544 L17.8105793,13.9394207 L17.7088087,13.9325741 C17.3793407,13.8878779 17.1178493,13.6292342 17.0688456,13.3011542 L17.0605793,13.1894207 L17.0598776,8.00183969 L6.16636906,18.8942911 C5.87347584,19.1871843 5.3986021,19.1871843 5.10570888,18.8942911 Z" id="Icons/Navigation/External-Link/Dark" fill="#1C1847" fill-rule="nonzero"></path>
|
|
6
|
-
</g>
|
|
7
|
-
</svg>
|