labfreed 1.0.0a7__tar.gz → 1.0.0a8__tar.gz

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.
Files changed (74) hide show
  1. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/PKG-INFO +1 -1
  2. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/__init__.py +1 -1
  3. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/labfreed_extended/app/app_infrastructure.py +1 -1
  4. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/labfreed_extended/app/pac_info/pac_info.py +14 -6
  5. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/client/attribute_cache.py +2 -2
  6. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/client/client.py +2 -2
  7. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/server/attribute_data_sources.py +5 -2
  8. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/server/server.py +9 -7
  9. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  10. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/.github/workflows/pypi-publish.yml +0 -0
  11. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/.github/workflows/run-tests.yml +0 -0
  12. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/CHANGELOG.md +0 -0
  13. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/LICENSE +0 -0
  14. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/README.md +0 -0
  15. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/labfreed_extended/app/formatted_print.py +0 -0
  16. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/labfreed_extended/app/pac_info/html_renderer/external-link.svg +0 -0
  17. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/labfreed_extended/app/pac_info/html_renderer/macros.jinja.html +0 -0
  18. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/labfreed_extended/app/pac_info/html_renderer/pac-info-style.css +0 -0
  19. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/labfreed_extended/app/pac_info/html_renderer/pac_info.jinja.html +0 -0
  20. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/labfreed_extended/app/pac_info/html_renderer/pac_info_card.jinja.html +0 -0
  21. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/labfreed_infrastructure.py +0 -0
  22. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/__init__.py +0 -0
  23. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/api_data_models/request.py +0 -0
  24. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/api_data_models/response.py +0 -0
  25. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/api_data_models/server_capabilities_response.py +0 -0
  26. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/client/__init__.py +0 -0
  27. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/pythonic/attribute_server_factory.py +0 -0
  28. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/pythonic/excel_attribute_data_source.py +0 -0
  29. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/pythonic/py_attributes.py +0 -0
  30. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/pythonic/py_dict_data_source.py +0 -0
  31. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/server/__init__.py +0 -0
  32. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/server/translation_data_sources.py +0 -0
  33. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_attributes/well_knonw_attribute_keys.py +0 -0
  34. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_cat/__init__.py +0 -0
  35. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_cat/category_base.py +0 -0
  36. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_cat/pac_cat.py +0 -0
  37. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_cat/predefined_categories.py +0 -0
  38. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id/__init__.py +0 -0
  39. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id/extension.py +0 -0
  40. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id/id_segment.py +0 -0
  41. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id/pac_id.py +0 -0
  42. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id/url_parser.py +0 -0
  43. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id/url_serializer.py +0 -0
  44. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id_resolver/__init__.py +0 -0
  45. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id_resolver/cit_common.py +0 -0
  46. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id_resolver/cit_v1.py +0 -0
  47. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id_resolver/cit_v2.py +0 -0
  48. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id_resolver/resolver.py +0 -0
  49. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/pac_id_resolver/services.py +0 -0
  50. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/qr/__init__.py +0 -0
  51. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/qr/generate_qr.py +0 -0
  52. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/trex/__init__.py +0 -0
  53. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/trex/pythonic/__init__.py +0 -0
  54. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/trex/pythonic/data_table.py +0 -0
  55. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/trex/pythonic/pyTREX.py +0 -0
  56. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/trex/pythonic/quantity.py +0 -0
  57. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/trex/table_segment.py +0 -0
  58. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/trex/trex.py +0 -0
  59. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/trex/trex_base_models.py +0 -0
  60. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/trex/value_segments.py +0 -0
  61. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/utilities/base36.py +0 -0
  62. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/utilities/ensure_utc_time.py +0 -0
  63. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/utilities/translations.py +0 -0
  64. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_extensions/__init__.py +0 -0
  65. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_extensions/default_extension_interpreters.py +0 -0
  66. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_extensions/display_name_extension.py +0 -0
  67. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_extensions/trex_extension.py +0 -0
  68. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_keys/gs1/__init__.py +0 -0
  69. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_keys/gs1/gs1_ai_enum_sorted.py +0 -0
  70. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_keys/labfreed/well_known_keys.py +0 -0
  71. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_keys/unece/UneceUnits.json +0 -0
  72. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_keys/unece/__init__.py +0 -0
  73. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/labfreed/well_known_keys/unece/unece_units.py +0 -0
  74. {labfreed-1.0.0a7 → labfreed-1.0.0a8}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: labfreed
3
- Version: 1.0.0a7
3
+ Version: 1.0.0a8
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
@@ -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.0a8"
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)
@@ -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):
File without changes
File without changes
File without changes
File without changes