labfreed 1.0.0a7__py3-none-any.whl → 1.0.0a9__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 CHANGED
@@ -2,7 +2,7 @@
2
2
  Python implementation of LabFREED building blocks
3
3
  '''
4
4
 
5
- __version__ = "1.0.0a7"
5
+ __version__ = "1.0.0a9"
6
6
 
7
7
  from labfreed.pac_id import * # noqa: F403
8
8
  from labfreed.pac_cat import * # noqa: F403
@@ -71,7 +71,7 @@ class Labfreed_App_Infrastructure():
71
71
  ags = {ag.key: pyAttributeGroup.from_attribute_group(ag) for ag in self._attribute_client.get_attributes(url, pac_id=pac.to_url(include_extensions=False), language_preferences=self._language_preferences)}
72
72
  if ags:
73
73
  attribute_groups.update(ags)
74
- pac_info.attributes_groups = attribute_groups
74
+ pac_info.attribute_groups = attribute_groups
75
75
 
76
76
  return pac_info
77
77
 
@@ -5,7 +5,7 @@ from pathlib import Path
5
5
  from urllib.parse import urlparse
6
6
  from jinja2 import Environment, FileSystemLoader, select_autoescape
7
7
  from pydantic import BaseModel, Field
8
- from labfreed.pac_attributes.pythonic.py_attributes import pyAttribute, pyAttributeGroup, pyAttributes, pyReference
8
+ from labfreed.pac_attributes.pythonic.py_attributes import pyAttribute, pyAttributeGroup, pyAttributes, pyReference, pyResource
9
9
  from labfreed.pac_attributes.well_knonw_attribute_keys import MetaAttributeKeys
10
10
  from labfreed.pac_cat.pac_cat import PAC_CAT
11
11
  from labfreed.pac_id.pac_id import PAC_ID
@@ -20,7 +20,7 @@ class PacInfo(BaseModel):
20
20
  """A convenient collection of information about a PAC-ID"""
21
21
  pac_id:PAC_ID
22
22
  user_handovers: list[ServiceGroup] = Field(default_factory=list)
23
- attributes_groups:dict[str, pyAttributeGroup] = Field(default_factory=dict)
23
+ attribute_groups:dict[str, pyAttributeGroup] = Field(default_factory=dict)
24
24
 
25
25
  @property
26
26
  def pac_url(self):
@@ -44,8 +44,10 @@ class PacInfo(BaseModel):
44
44
 
45
45
  @property
46
46
  def image_url(self) -> str:
47
- if meta := self.attributes_groups.get(MetaAttributeKeys.GROUPKEY.value):
48
- image_attr = meta.attributes.get(MetaAttributeKeys.IMAGE.value)
47
+ image_attr = self._all_attributes.get(MetaAttributeKeys.IMAGE.value)
48
+ if isinstance(image_attr.value, pyResource):
49
+ return image_attr.value.root
50
+ if isinstance(image_attr.value, str):
49
51
  return image_attr.value
50
52
 
51
53
 
@@ -68,12 +70,18 @@ class PacInfo(BaseModel):
68
70
  def safety_pictograms(self) -> dict[str, pyAttribute]:
69
71
  pictogram_attributes = {k: a for k, a in self._all_attributes.items() if "https://labfreed.org/ghs/pictogram/" in a.key}
70
72
  return pictogram_attributes
73
+
74
+
75
+ @property
76
+ def qualification_state(self) -> pyAttribute:
77
+ if state := self._all_attributes.get("https://labfreed.org/qualification/status"):
78
+ return state
71
79
 
72
80
 
73
81
  @cached_property
74
82
  def _all_attributes(self) -> dict[str, pyAttribute]:
75
83
  out = {}
76
- for ag in self.attributes_groups.values():
84
+ for ag in self.attribute_groups.values():
77
85
  out.update(ag.attributes)
78
86
  return out
79
87
 
@@ -105,7 +113,7 @@ class PacInfo(BaseModel):
105
113
 
106
114
 
107
115
  printout.title1("Attributes")
108
- for ag in self.attributes_groups.values():
116
+ for ag in self.attribute_groups.values():
109
117
  printout.title2(f'{ag.label} (from {ag.origin})')
110
118
  for v in ag.attributes.values():
111
119
  v:pyAttribute
@@ -1,6 +1,6 @@
1
1
 
2
2
 
3
- from datetime import datetime, timedelta
3
+ from datetime import UTC, datetime, timedelta
4
4
  from typing import Literal, Protocol
5
5
 
6
6
 
@@ -18,7 +18,7 @@ class CacheableAttributeGroup(AttributeGroup):
18
18
  if self.value_from is None:
19
19
  return False
20
20
  else:
21
- return ( datetime.now() - timedelta(min=accept_cache_for_minutes)) > self.value_from
21
+ return ( datetime.now(tz=UTC) - timedelta(minutes=accept_cache_for_minutes)) > self.value_from
22
22
 
23
23
 
24
24
 
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from datetime import datetime
4
+ from datetime import UTC, datetime
5
5
  from typing import Protocol, runtime_checkable
6
6
 
7
7
  import requests
@@ -156,7 +156,7 @@ class AttributeClient():
156
156
  origin=server_url,
157
157
  language=r.language,
158
158
  label=ag.label,
159
- value_from=datetime.now(tz=datetime.UTC))
159
+ value_from=datetime.now(tz=UTC))
160
160
  for ag in ag_for_pac.attribute_groups
161
161
  ]
162
162
  self.cache_store.update(server_url, pac_from_response, ags)
@@ -93,7 +93,7 @@ class AttributeFlaskApp(Flask):
93
93
  def capabilities():
94
94
  doc_text = current_app.config.get('DOC_TEXT', "")
95
95
  capabilities = request_handler.capabilities()
96
- authentication_required = bool(current_app.config['AUTHENTICATOR'])
96
+ authentication_required = bool(current_app.config.get('AUTHENTICATOR'))
97
97
  example_request = AttributeRequestPayload(pac_ids=['HTTPS://PAC.METTORIUS.COM/EXAMPLE'], language_preferences=['fr', 'de']).model_dump_json(indent=2, exclude_none=True, exclude_unset=True)
98
98
  server_address = request.url.rstrip('/')
99
99
  response = f'''
@@ -109,7 +109,7 @@ class AttributeFlaskApp(Flask):
109
109
  <h2>How to use</h2>
110
110
  Make a <b>POST</b> request to <a href="{server_address}">{server_address}</a> with the following body:
111
111
  <pre>{example_request}</pre>
112
- Consult {'<a href="https://github.com/ApiniLabs/PAC-Attributes"> the specification </a>' if doc_text else ""} for details. <br>
112
+ Consult <a href="https://github.com/ApiniLabs/PAC-Attributes"> the specification </a> for details. <br>
113
113
 
114
114
 
115
115
  {'This server <b> requires authentication </b> ' if authentication_required else ''}
@@ -31,12 +31,13 @@ class AttributeGroupDataSource(ABC):
31
31
 
32
32
 
33
33
  class Dict_DataSource(AttributeGroupDataSource):
34
- def __init__(self, data:dict[str, list[AttributeBase]], uses_pac_cat_short_form=True, *args, **kwargs):
34
+ def __init__(self, data:dict[str, list[AttributeBase]], uses_pac_cat_short_form=True, pac_to_key: callable = None, *args, **kwargs):
35
35
  if not all([isinstance(e, list) for e in data.values()]):
36
36
  raise ValueError('Invalid data')
37
37
 
38
38
  self._data = data
39
39
  self.uses_pac_cat_short_form = uses_pac_cat_short_form
40
+ self._pac_to_key = pac_to_key
40
41
 
41
42
  super().__init__(*args, **kwargs)
42
43
 
@@ -53,7 +54,9 @@ class Dict_DataSource(AttributeGroupDataSource):
53
54
  except:
54
55
  ... # might as well try to match the original input
55
56
 
56
- attributes = self._data.get(pac_url)
57
+
58
+ lookup_key = self._pac_to_key(pac_url) if self._pac_to_key else pac_url
59
+ attributes = self._data.get(lookup_key)
57
60
  if not attributes:
58
61
  return None
59
62
 
@@ -134,20 +134,22 @@ class AttributeServerRequestHandler():
134
134
  if dn := self._get_display_name_for_key(ag.key, language):
135
135
  ag.label = dn
136
136
  else:
137
- ag.label = string.capwords(
138
- re.sub(r'([a-z])([A-Z])', r'\1 \2',
139
- re.sub('-_', '',
140
- ag.key.split('/')[-1])
141
- )
142
- )
137
+ ag.label = self.fallback_label(ag.key)
143
138
  rich.print(f"[yellow]WARNING:[/yellow] No translation for '{ag.key}' in '{language}'. Falling back to '{ag.label}'")
144
139
  for a in ag.attributes:
145
140
  if dn := self._get_display_name_for_key(a.key, language):
146
141
  a.label = dn
147
142
  else:
148
- a.label = a.key.split('/')[-1]
143
+ a.label = self.fallback_label(a.key)
149
144
  rich.print(f"[yellow]WARNING:[/yellow] No translation for '{a.key}' in '{language}'. Falling back to '{a.label}' ")
150
145
 
146
+
147
+ def fallback_label(self, key:str):
148
+ l = key.split('/')[-1]
149
+ l = re.sub(r'([a-z])([A-Z])', r'\1 \2', l)
150
+ l = re.sub(r'[-_]', ' ', l)
151
+ l = string.capwords(l)
152
+ return l
151
153
 
152
154
 
153
155
  def _get_display_name_for_key(self, key, language:str):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: labfreed
3
- Version: 1.0.0a7
3
+ Version: 1.0.0a9
4
4
  Summary: Python implementation of LabFREED building blocks
5
5
  Author-email: Reto Thürer <thuerer.r@buchi.com>
6
6
  Requires-Python: >=3.11
@@ -1,8 +1,8 @@
1
- labfreed/__init__.py,sha256=2M8GLQGnuUWBRUGzOt9MJDSVqxWBbFRcTDuQhOuTu6M,338
1
+ labfreed/__init__.py,sha256=wQI1Zn83JUEA_A8Tdaf1P78-Pa_Lg_T5uxCPmj46wN8,338
2
2
  labfreed/labfreed_infrastructure.py,sha256=YZmU-kgopyB1tvpTR_k_uIt1Q2ezexMrWvu-HaP65IE,10104
3
- labfreed/labfreed_extended/app/app_infrastructure.py,sha256=0dO1dXu1DZykRH3gnta34vz5MzEEXUfK1D-tsjNqCaE,4036
3
+ labfreed/labfreed_extended/app/app_infrastructure.py,sha256=F5UHHt8-r7jigQudOsJ-yV4lWKHFsxNhI4uGP_h53lE,4035
4
4
  labfreed/labfreed_extended/app/formatted_print.py,sha256=DcwWP0ix1e_wYNIdceIp6cETkJdG2DqpU8Gs3aZAL40,1930
5
- labfreed/labfreed_extended/app/pac_info/pac_info.py,sha256=rb5mraJNsPsm7ujhk6WJmm9tXByhv0E8QTOCcgSaO_U,6159
5
+ labfreed/labfreed_extended/app/pac_info/pac_info.py,sha256=hsJunO4adKcLi7PBZNAJYeqzOH31_j95JzuvEV8lNVY,6427
6
6
  labfreed/labfreed_extended/app/pac_info/html_renderer/external-link.svg,sha256=H5z9s4VvHq09UnHdqfrYNsx-Whljc0gE4qKJ6-3kfgQ,1158
7
7
  labfreed/labfreed_extended/app/pac_info/html_renderer/macros.jinja.html,sha256=1S-dxibPwJshtdelsmyA4LpgOm84L6RTXPNO93gmPfg,5964
8
8
  labfreed/labfreed_extended/app/pac_info/html_renderer/pac-info-style.css,sha256=C5pyD956fd6pJgUBjGxvxgL0Wbgq0v7ZLY4Vr-sJZ7A,4169
@@ -14,15 +14,15 @@ labfreed/pac_attributes/api_data_models/request.py,sha256=-CI3rU_Bzw2DZGSS06Jl4z
14
14
  labfreed/pac_attributes/api_data_models/response.py,sha256=eGh474ILEcBC1ijhs1ZZfdhNWRxiPeccGS8aw0zzt0U,6934
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
- labfreed/pac_attributes/client/attribute_cache.py,sha256=DbVk6MTOmzNhaf1IDVhzmnlBXiSMPX9Gur43tlBOSdM,2207
18
- labfreed/pac_attributes/client/client.py,sha256=psOvlYsnK4zPp2jFHHgTPpwjRo8-uJOGLEESXyi-e_I,7510
19
- labfreed/pac_attributes/pythonic/attribute_server_factory.py,sha256=_wasafjBlwvzOaM6-uPgqPethsDQHEpaXoiRW7w9aV0,5759
17
+ labfreed/pac_attributes/client/attribute_cache.py,sha256=ThUadWqQ5oM8DnAnvZuY4jeA3Mg06ePNEcRP5wCsadc,2222
18
+ labfreed/pac_attributes/client/client.py,sha256=DcD9wG3Zc7Iznr5Wlrwp17QgE2tjPxITgmjmSQonvAo,7506
19
+ labfreed/pac_attributes/pythonic/attribute_server_factory.py,sha256=DatCagOpbuURssP5M6sjvhPK-yilq8xSjuHTGaKCVJ0,5739
20
20
  labfreed/pac_attributes/pythonic/excel_attribute_data_source.py,sha256=oP4OHj0DTlH4dD7OlL1qxtX4y9KcuDTCd9Bi_FruP6A,7276
21
21
  labfreed/pac_attributes/pythonic/py_attributes.py,sha256=FXSp9_P0o-GuZSDvXtD2fU4g82lglMu9f_-8KPMkEP0,6821
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
- labfreed/pac_attributes/server/attribute_data_sources.py,sha256=CAPoEc6OQycfc9jU66aL7K4K90ZDrEGG8fXfbVfDKao,2175
25
- labfreed/pac_attributes/server/server.py,sha256=HKfy5XbDM4AOpfeGrkxqGcfMtaMCoWP_qkJ-etBRROg,9077
24
+ labfreed/pac_attributes/server/attribute_data_sources.py,sha256=7-YQeBcn5ndsZWeeW_-YgG7obF5qvXoH-AFPpmXWn1I,2337
25
+ labfreed/pac_attributes/server/server.py,sha256=tPOPezRC3YEE0i-MJIc23Me6EARaSqzyFdUNjUzqtdI,9117
26
26
  labfreed/pac_attributes/server/translation_data_sources.py,sha256=axALOqfP840sOSdVCRYtrens97mm-hpfONMUyuVlCrY,2145
27
27
  labfreed/pac_cat/__init__.py,sha256=KNPtQzBD1XVohvG_ucOs7RJj-oi6biUTGB1k-T2o6pk,568
28
28
  labfreed/pac_cat/category_base.py,sha256=D7BzsdF0-JIgag5L2XZJRF4T2LOH5RLh1MMszflkmV8,2526
@@ -64,7 +64,7 @@ labfreed/well_known_keys/labfreed/well_known_keys.py,sha256=p-hXwEEIs7p2SKn9DQeL
64
64
  labfreed/well_known_keys/unece/UneceUnits.json,sha256=kwfQSp_nTuWbADfBBgqTWrvPl6XtM5SedEVLbMJrM7M,898953
65
65
  labfreed/well_known_keys/unece/__init__.py,sha256=MSP9lmjg9_D9iqG9Yq2_ajYfQSNS9wIT7FXA1c--59M,122
66
66
  labfreed/well_known_keys/unece/unece_units.py,sha256=J20d64H69qKDE3XlGdJoXIIh0G-d0jKoiIDsg9an5pk,1655
67
- labfreed-1.0.0a7.dist-info/licenses/LICENSE,sha256=gHFOv9FRKHxO8cInP3YXyPoJnuNeqrvcHjaE_wPSsQ8,1100
68
- labfreed-1.0.0a7.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
69
- labfreed-1.0.0a7.dist-info/METADATA,sha256=D-1dE3dyCXPqcuD860PyNHInj0MAu0b3eezsHvy2pV0,19740
70
- labfreed-1.0.0a7.dist-info/RECORD,,
67
+ labfreed-1.0.0a9.dist-info/licenses/LICENSE,sha256=gHFOv9FRKHxO8cInP3YXyPoJnuNeqrvcHjaE_wPSsQ8,1100
68
+ labfreed-1.0.0a9.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
69
+ labfreed-1.0.0a9.dist-info/METADATA,sha256=QdAoKgVWGUOJHTaWiyq4FExbgpzuIqY3jTFNjcyuXus,19740
70
+ labfreed-1.0.0a9.dist-info/RECORD,,