labfreed 1.0.0a14__py3-none-any.whl → 1.0.0a15__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 +3 -2
- labfreed/pac_attributes/api_data_models/response.py +1 -0
- labfreed/pac_attributes/pythonic/excel_attribute_data_source.py +9 -3
- labfreed/pac_attributes/pythonic/py_attributes.py +50 -21
- labfreed/pac_id_resolver/resolver.py +8 -5
- {labfreed-1.0.0a14.dist-info → labfreed-1.0.0a15.dist-info}/METADATA +1 -1
- {labfreed-1.0.0a14.dist-info → labfreed-1.0.0a15.dist-info}/RECORD +10 -10
- {labfreed-1.0.0a14.dist-info → labfreed-1.0.0a15.dist-info}/WHEEL +0 -0
- {labfreed-1.0.0a14.dist-info → labfreed-1.0.0a15.dist-info}/licenses/LICENSE +0 -0
labfreed/__init__.py
CHANGED
|
@@ -17,10 +17,11 @@ from labfreed.pac_id_resolver.services import ServiceGroup
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class Labfreed_App_Infrastructure():
|
|
20
|
-
def __init__(self, markup = 'rich', language_preferences:list[str]|str='en', http_client:requests.Session|None=None):
|
|
20
|
+
def __init__(self, markup = 'rich', language_preferences:list[str]|str='en', http_client:requests.Session|None=None, use_issuer_resolver_config=True):
|
|
21
21
|
if isinstance(language_preferences, str):
|
|
22
22
|
language_preferences = [language_preferences]
|
|
23
23
|
self._language_preferences = language_preferences
|
|
24
|
+
self._use_issuer_resolver_config = use_issuer_resolver_config
|
|
24
25
|
|
|
25
26
|
self._resolver = PAC_ID_Resolver()
|
|
26
27
|
|
|
@@ -48,7 +49,7 @@ class Labfreed_App_Infrastructure():
|
|
|
48
49
|
pac = PAC_ID.from_url(pac_url)
|
|
49
50
|
else:
|
|
50
51
|
pac = pac_url
|
|
51
|
-
service_groups = self._resolver.resolve(pac, check_service_status=False)
|
|
52
|
+
service_groups = self._resolver.resolve(pac, check_service_status=False, use_issuer_resolver_config=self._use_issuer_resolver_config)
|
|
52
53
|
|
|
53
54
|
pac_info = PacInfo(pac_id=pac)
|
|
54
55
|
|
|
@@ -75,9 +75,10 @@ class _BaseExcelAttributeDataSource(AttributeGroupDataSource):
|
|
|
75
75
|
Subclasses implement `_read_rows_and_last_changed()`.
|
|
76
76
|
"""
|
|
77
77
|
|
|
78
|
-
def __init__(self, *, base_url: str = "", cache_duration_seconds: int = 0, uses_pac_cat_short_form:bool=True, **kwargs):
|
|
78
|
+
def __init__(self, *, base_url: str = "", cache_duration_seconds: int = 0, uses_pac_cat_short_form:bool=True, pac_to_key=None, **kwargs):
|
|
79
79
|
self._base_url = base_url
|
|
80
80
|
self._uses_pac_cat_short_form = uses_pac_cat_short_form
|
|
81
|
+
self._pac_to_key = pac_to_key
|
|
81
82
|
# allow instance-level TTL override
|
|
82
83
|
try:
|
|
83
84
|
_cache.ttl = int(cache_duration_seconds)
|
|
@@ -106,11 +107,16 @@ class _BaseExcelAttributeDataSource(AttributeGroupDataSource):
|
|
|
106
107
|
except:
|
|
107
108
|
... # might as well try to match the original input
|
|
108
109
|
|
|
110
|
+
if f:= self._pac_to_key:
|
|
111
|
+
key = f(pac_url)
|
|
112
|
+
else:
|
|
113
|
+
key = pac_url
|
|
114
|
+
|
|
109
115
|
rows, last_changed = self._read_rows_and_last_changed()
|
|
110
|
-
d = _get_row_by_first_cell(rows,
|
|
116
|
+
d = _get_row_by_first_cell(rows, key, self._base_url)
|
|
111
117
|
if not d:
|
|
112
118
|
return None
|
|
113
|
-
attributes = [pyAttribute(key=k, value=v) for k, v in d.items()]
|
|
119
|
+
attributes = [pyAttribute(key=k, value=v) for k, v in d.items() if v is not None]
|
|
114
120
|
return AttributeGroup(
|
|
115
121
|
key=self._attribute_group_key,
|
|
116
122
|
attributes=pyAttributes(attributes).to_payload_attributes()
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
|
|
2
|
-
from datetime import date, datetime, time
|
|
2
|
+
from datetime import UTC, date, datetime, time
|
|
3
3
|
import json
|
|
4
4
|
from typing import Literal
|
|
5
5
|
import warnings
|
|
6
6
|
from pydantic import RootModel, field_validator
|
|
7
7
|
|
|
8
8
|
from labfreed.labfreed_infrastructure import LabFREED_BaseModel
|
|
9
|
-
from labfreed.pac_attributes.api_data_models.response import AttributeBase, AttributeGroup, BoolAttribute, DateTimeAttribute, NumericAttribute, NumericValue, ObjectAttribute, ReferenceAttribute, ResourceAttribute, TextAttribute
|
|
9
|
+
from labfreed.pac_attributes.api_data_models.response import AttributeBase, AttributeGroup, BoolAttribute, BoolListAttribute, DateTimeAttribute, DateTimeListAttribute, NumericAttribute, NumericListAttribute, NumericValue, ObjectAttribute, ReferenceAttribute, ReferenceListAttribute, ResourceAttribute, ResourceListAttribute, TextAttribute, TextListAttribute
|
|
10
10
|
from labfreed.pac_attributes.client.attribute_cache import CacheableAttributeGroup
|
|
11
11
|
from labfreed.pac_id.pac_id import PAC_ID
|
|
12
12
|
from labfreed.trex.pythonic.quantity import Quantity
|
|
@@ -66,13 +66,21 @@ class pyAttributes(RootModel[list[pyAttribute]]):
|
|
|
66
66
|
value_list = attribute.value_list
|
|
67
67
|
first_value = value_list[0]
|
|
68
68
|
if isinstance(first_value, bool):
|
|
69
|
-
|
|
69
|
+
if len(value_list) == 1:
|
|
70
|
+
return BoolAttribute(value=value_list[0], **common_args)
|
|
71
|
+
else:
|
|
72
|
+
return BoolListAttribute(value=value_list, **common_args)
|
|
73
|
+
|
|
70
74
|
|
|
71
75
|
elif isinstance(first_value, datetime | date | time):
|
|
72
76
|
for v in value_list:
|
|
73
77
|
if not v.tzinfo:
|
|
74
78
|
warnings.warn(f'No timezone given for {v}. Assuming it is in UTC.')
|
|
75
|
-
|
|
79
|
+
v.replace(tzinfo=UTC)
|
|
80
|
+
if len(value_list) == 1:
|
|
81
|
+
return DateTimeAttribute(value=value_list[0], **common_args)
|
|
82
|
+
else:
|
|
83
|
+
return DateTimeListAttribute(value=value_list, **common_args)
|
|
76
84
|
# return DateTimeAttribute(value =_date_value_from_python_type(value).value, **common_args)
|
|
77
85
|
|
|
78
86
|
|
|
@@ -83,9 +91,13 @@ class pyAttributes(RootModel[list[pyAttribute]]):
|
|
|
83
91
|
v = Quantity(value=v, unit='dimensionless')
|
|
84
92
|
values.append(NumericValue(numerical_value=v.value_as_str(),
|
|
85
93
|
unit = v.unit))
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
if len(values) == 1:
|
|
95
|
+
num_attr = NumericAttribute(value=values[0], **common_args)
|
|
96
|
+
else:
|
|
97
|
+
num_attr = NumericListAttribute(value=values, **common_args)
|
|
98
|
+
num_attr.print_validation_messages()
|
|
99
|
+
|
|
100
|
+
return num_attr
|
|
89
101
|
|
|
90
102
|
elif isinstance(first_value, str):
|
|
91
103
|
# capture quantities in the form of "100.0e5 g/L"
|
|
@@ -94,20 +106,37 @@ class pyAttributes(RootModel[list[pyAttribute]]):
|
|
|
94
106
|
for v in value_list:
|
|
95
107
|
q = Quantity.from_str_with_unit(v)
|
|
96
108
|
values.append( NumericValue(numerical_value=q.value_as_str(), unit = q.unit) )
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
109
|
+
if len(values) == 1:
|
|
110
|
+
return NumericAttribute(value=values[0], **common_args)
|
|
111
|
+
else:
|
|
112
|
+
return NumericListAttribute(value=values, **common_args)
|
|
113
|
+
|
|
100
114
|
else:
|
|
101
|
-
|
|
115
|
+
if len(value_list) == 1:
|
|
116
|
+
return TextAttribute(value=value_list[0], **common_args)
|
|
117
|
+
else:
|
|
118
|
+
return TextListAttribute(value=value_list, **common_args)
|
|
102
119
|
|
|
103
120
|
elif isinstance(first_value, pyReference):
|
|
104
|
-
|
|
121
|
+
values = [v.root for v in value_list]
|
|
122
|
+
if len(values) == 1:
|
|
123
|
+
return ReferenceAttribute(value=values[0], **common_args)
|
|
124
|
+
else:
|
|
125
|
+
return ReferenceListAttribute(value=values, **common_args)
|
|
105
126
|
|
|
106
127
|
elif isinstance(first_value, pyResource):
|
|
107
|
-
|
|
128
|
+
values = [v.root for v in value_list]
|
|
129
|
+
if len(values) == 1:
|
|
130
|
+
return ResourceAttribute(value=values[0], **common_args)
|
|
131
|
+
else:
|
|
132
|
+
return ResourceListAttribute(value=values, **common_args)
|
|
108
133
|
|
|
109
134
|
elif isinstance(first_value, PAC_ID):
|
|
110
|
-
|
|
135
|
+
values = [v.to_url(include_extensions=False) for v in value_list]
|
|
136
|
+
if len(values) == 1:
|
|
137
|
+
return ReferenceAttribute(value=values[0], **common_args)
|
|
138
|
+
else:
|
|
139
|
+
return ReferenceListAttribute(value=values, **common_args)
|
|
111
140
|
|
|
112
141
|
else: #this covers the last resort case of arbitrary objects. Must be json serializable.
|
|
113
142
|
try :
|
|
@@ -124,25 +153,25 @@ class pyAttributes(RootModel[list[pyAttribute]]):
|
|
|
124
153
|
for a in attributes:
|
|
125
154
|
value_list = a.value if isinstance(a.value, list) else [a.value]
|
|
126
155
|
match a:
|
|
127
|
-
case ReferenceAttribute():
|
|
156
|
+
case ReferenceAttribute() | ReferenceListAttribute():
|
|
128
157
|
values = [pyReference(v) for v in value_list]
|
|
129
158
|
|
|
130
|
-
case ResourceAttribute():
|
|
159
|
+
case ResourceAttribute() | ResourceListAttribute():
|
|
131
160
|
values = [pyResource(v) for v in value_list]
|
|
132
161
|
|
|
133
|
-
case NumericAttribute():
|
|
162
|
+
case NumericAttribute() | NumericListAttribute():
|
|
134
163
|
values = [ Quantity.from_str_value(value=v.numerical_value, unit=v.unit) for v in value_list]
|
|
135
164
|
|
|
136
|
-
case BoolAttribute():
|
|
165
|
+
case BoolAttribute() | BoolAttribute():
|
|
137
166
|
values = value_list
|
|
138
167
|
|
|
139
|
-
case TextAttribute():
|
|
168
|
+
case TextAttribute() | TextListAttribute():
|
|
140
169
|
values = value_list
|
|
141
170
|
|
|
142
|
-
case DateTimeAttribute():
|
|
171
|
+
case DateTimeAttribute() | DateTimeAttribute():
|
|
143
172
|
values = value_list
|
|
144
173
|
|
|
145
|
-
case ObjectAttribute():
|
|
174
|
+
case ObjectAttribute() | ObjectAttribute():
|
|
146
175
|
values = value_list
|
|
147
176
|
|
|
148
177
|
|
|
@@ -101,11 +101,14 @@ class PAC_ID_Resolver():
|
|
|
101
101
|
|
|
102
102
|
matches = []
|
|
103
103
|
for cit in resolver_configs:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
try:
|
|
105
|
+
if isinstance(cit, CIT_v1):
|
|
106
|
+
# cit v1 has no concept of categories and implied keys. It would treat these segments as value segment
|
|
107
|
+
matches.append(cit.evaluate_pac_id(pac_id_catless))
|
|
108
|
+
else:
|
|
109
|
+
matches.append(cit.evaluate_pac_id(pac_id))
|
|
110
|
+
except Exception as e:
|
|
111
|
+
logging.error(f'Failed to resolve pac {pac_id.to_url()} with cit {cit.origin}')
|
|
109
112
|
|
|
110
113
|
if check_service_status:
|
|
111
114
|
for m in matches:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
labfreed/__init__.py,sha256=
|
|
1
|
+
labfreed/__init__.py,sha256=KcYeV-IKg3wMT_uly3-IR3OXlZrdLQS5Ip81OWnjx7s,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=yfxPBDPatxHPrIPmpzdhQB7Yd3lIxGsm8ZXUM04N8nQ,4583
|
|
4
4
|
labfreed/labfreed_extended/app/formatted_print.py,sha256=DcwWP0ix1e_wYNIdceIp6cETkJdG2DqpU8Gs3aZAL40,1930
|
|
5
5
|
labfreed/labfreed_extended/app/pac_info/pac_info.py,sha256=9Wre1wAmMZObeh7Ed46KA38nBWcXhqGD0m9vTHfkkS8,8397
|
|
6
6
|
labfreed/labfreed_extended/app/pac_info/html_renderer/external-link.svg,sha256=H5z9s4VvHq09UnHdqfrYNsx-Whljc0gE4qKJ6-3kfgQ,1158
|
|
@@ -11,14 +11,14 @@ labfreed/labfreed_extended/app/pac_info/html_renderer/pac_info_card.jinja.html,s
|
|
|
11
11
|
labfreed/pac_attributes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
labfreed/pac_attributes/well_knonw_attribute_keys.py,sha256=axE81MeJ3G_Wy1PbmNAXH6SfPtl96NXvQJMyrvK10t4,324
|
|
13
13
|
labfreed/pac_attributes/api_data_models/request.py,sha256=N-kXlJWYqh-F1TzNunCwHUPhme3bSLJMgb9aAHWGOy4,1880
|
|
14
|
-
labfreed/pac_attributes/api_data_models/response.py,sha256=
|
|
14
|
+
labfreed/pac_attributes/api_data_models/response.py,sha256=tdiWHgB8q10S4i2G6urNli6yNE1EMyP620_pdLKeTYM,8496
|
|
15
15
|
labfreed/pac_attributes/api_data_models/server_capabilities_response.py,sha256=ypDm4f8xZZl036fp8PuIe6lJHNW5Zg1fItgUlnV75V0,178
|
|
16
16
|
labfreed/pac_attributes/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
labfreed/pac_attributes/client/attribute_cache.py,sha256=ThUadWqQ5oM8DnAnvZuY4jeA3Mg06ePNEcRP5wCsadc,2222
|
|
18
18
|
labfreed/pac_attributes/client/client.py,sha256=FjvyEpZEGYrZkuaQoqH9QFstrwHmrsIdaymxz8uQjwQ,7510
|
|
19
19
|
labfreed/pac_attributes/pythonic/attribute_server_factory.py,sha256=3OeFjBdlMR4DMIzHVo5-A_y935e2_lOqvFCLKgxjsEY,6159
|
|
20
|
-
labfreed/pac_attributes/pythonic/excel_attribute_data_source.py,sha256=
|
|
21
|
-
labfreed/pac_attributes/pythonic/py_attributes.py,sha256=
|
|
20
|
+
labfreed/pac_attributes/pythonic/excel_attribute_data_source.py,sha256=zbsXiH9vry0ZqmPwUY_cr1t9xP4P3W5o5Khu9IE0e0I,7465
|
|
21
|
+
labfreed/pac_attributes/pythonic/py_attributes.py,sha256=vjRNjg-PpsQSaidpPtkiyQL_10dcD-9JAz89gAYMFJA,8307
|
|
22
22
|
labfreed/pac_attributes/pythonic/py_dict_data_source.py,sha256=nAz6GA7Xx_0IORPPpt_Wl3sFJa1Q5Fnq5vdf1uQiJF8,531
|
|
23
23
|
labfreed/pac_attributes/server/__init__.py,sha256=JvQ2kpQx62OUwP18bGhOWYU9an_nQW59Y8Lh7HyfVxY,301
|
|
24
24
|
labfreed/pac_attributes/server/attribute_data_sources.py,sha256=7-YQeBcn5ndsZWeeW_-YgG7obF5qvXoH-AFPpmXWn1I,2337
|
|
@@ -36,7 +36,7 @@ labfreed/pac_id/url_parser.py,sha256=F3SPiscfbPwZ0uMzgirJ1vwgaXclN546lBW46Ywo3nk
|
|
|
36
36
|
labfreed/pac_id/url_serializer.py,sha256=01LB30pNMBtv2rYHsiE_4Ga2iVA515Boj4ikOIYhiBQ,3511
|
|
37
37
|
labfreed/pac_id_resolver/__init__.py,sha256=RNBlrDOSR42gmSNH9wJVhK_xwEX45cvTKVgWW2bjh7Q,113
|
|
38
38
|
labfreed/pac_id_resolver/cit_v1.py,sha256=JGlEH2d9awEu3HxPW7vu0uj4ZC3B02IdmFg7aJ4axQw,9833
|
|
39
|
-
labfreed/pac_id_resolver/resolver.py,sha256=
|
|
39
|
+
labfreed/pac_id_resolver/resolver.py,sha256=anqteWexD7w78wzd1TjT06enkDIU-P-7NVKNWiASXLU,4127
|
|
40
40
|
labfreed/pac_id_resolver/resolver_config.py,sha256=2j3j5UsVoWqU9NjciN3j-Fs53diGi4FQEvoz8ng103Y,12388
|
|
41
41
|
labfreed/pac_id_resolver/resolver_config_common.py,sha256=jzoDOxog8YW68q7vyvDGCZcVcgIzJHXlMt8KwgVnx6o,2885
|
|
42
42
|
labfreed/pac_id_resolver/services.py,sha256=vtnxLm38t4PNOf73cXh6UZOtWZZOGxfBCfXUDRxGHog,2592
|
|
@@ -65,7 +65,7 @@ labfreed/well_known_keys/labfreed/well_known_keys.py,sha256=p-hXwEEIs7p2SKn9DQeL
|
|
|
65
65
|
labfreed/well_known_keys/unece/UneceUnits.json,sha256=kwfQSp_nTuWbADfBBgqTWrvPl6XtM5SedEVLbMJrM7M,898953
|
|
66
66
|
labfreed/well_known_keys/unece/__init__.py,sha256=MSP9lmjg9_D9iqG9Yq2_ajYfQSNS9wIT7FXA1c--59M,122
|
|
67
67
|
labfreed/well_known_keys/unece/unece_units.py,sha256=J20d64H69qKDE3XlGdJoXIIh0G-d0jKoiIDsg9an5pk,1655
|
|
68
|
-
labfreed-1.0.
|
|
69
|
-
labfreed-1.0.
|
|
70
|
-
labfreed-1.0.
|
|
71
|
-
labfreed-1.0.
|
|
68
|
+
labfreed-1.0.0a15.dist-info/licenses/LICENSE,sha256=gHFOv9FRKHxO8cInP3YXyPoJnuNeqrvcHjaE_wPSsQ8,1100
|
|
69
|
+
labfreed-1.0.0a15.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
70
|
+
labfreed-1.0.0a15.dist-info/METADATA,sha256=H4-dgXHNjGoidqKB1QKwTshKi2Pov7qhbHH8A1v3dwQ,19775
|
|
71
|
+
labfreed-1.0.0a15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|