labfreed 0.0.18__py2.py3-none-any.whl → 0.0.19__py2.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.

@@ -0,0 +1,81 @@
1
+ import os
2
+
3
+ from .generate_qr import generate_qr_with_markers_svg
4
+
5
+ from labfreed.PAC_ID.data_model import PACID
6
+ from labfreed.DisplayNameExtension.DisplayNameExtension import DisplayNames
7
+ from labfreed.IO.parse_pac import PACID_With_Extensions
8
+
9
+
10
+
11
+
12
+
13
+ def generate_label_200_100(pac_url, pac:PACID_With_Extensions):
14
+ title, infos = get_label_fields(pac)
15
+ pac_svg = generate_qr_with_markers_svg(pac_url, height=60, width=100, border=0)
16
+ label = _generate_label(pac_svg, 200, 100, title, infos)
17
+ return label
18
+
19
+ def generate_label_credit_card_size(pac_url, pac:PACID_With_Extensions):
20
+ title, infos = get_label_fields(pac)
21
+ pac_svg = generate_qr_with_markers_svg(pac_url, height=100, width=200, border=0)
22
+ label = _generate_label(pac_svg, 240, 150, title, infos)
23
+ return label
24
+
25
+
26
+ def _generate_label(qr_svg, width, height, title=None, infos=[]):
27
+ if not qr_svg:
28
+ raise ValueError("no valid qr given")
29
+ env = Environment(
30
+ loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), "templates")),
31
+ autoescape=select_autoescape()
32
+ )
33
+ template = env.get_template("pac_label.jinja.svg")
34
+ svg = template.render(width=width, height= height, pac_qr=qr_svg, title=title, info1=infos[0], info2=infos[1], info3=infos[2])
35
+
36
+ return svg
37
+
38
+
39
+
40
+ def get_label_fields(pac:PACID_With_Extensions) -> tuple[str, list[tuple[str, str]]]:
41
+ '''
42
+ returns a list of exactly length 3. Containing either info tuples (key value) or None
43
+ '''
44
+ if dn_extension := next((e for e in pac.extensions if isinstance(e, DisplayNames)), None): #find extension of type DisplayName
45
+ title = dn_extension.display_names[0]
46
+ else:
47
+ title = ""
48
+
49
+ infos = []
50
+ cat = pac.pac_id.identifier.categories[0]
51
+ for s in cat.segments:
52
+ lbl = pretty_print_segment_label(cat.key, s.key)
53
+ infos.append((lbl, s.value))
54
+
55
+ while len(infos) < 3:
56
+ infos.append(None)
57
+
58
+ if len(infos) > 3:
59
+ infos = infos[0:3]
60
+
61
+ return title,infos
62
+
63
+
64
+ def pretty_print_segment_label(category:str, segment_key:str):
65
+ if not segment_key:
66
+ return 'no key'
67
+
68
+ cat = CAT_from_category_key(category)
69
+ if cat:
70
+ alias_to_field = {v.alias: k for k, v in cat.model_fields.items() if v.alias}
71
+ segment_label = alias_to_field.get(segment_key, segment_key)
72
+ segment_label = segment_label.replace('_', ' ').title()
73
+
74
+ segment_label = segment_label.replace('Id', 'ID')
75
+
76
+ else:
77
+ segment_label = segment_key
78
+
79
+ return segment_label
80
+
81
+
@@ -364,16 +364,16 @@ class VisualMarker:
364
364
  app = typer.Typer()
365
365
 
366
366
 
367
- def generate_qr_with_markers(url, text="PAC", title=None, direction = Direction.LEFT_TO_RIGHT):
367
+ def _generate_qr_with_markers(qr_str, text, title, direction):
368
368
  if title:
369
369
  #try to use standard size 10. Go bigger if 10 does not fit the data
370
370
  try:
371
- qr = segno.make_qr(url, error="L", version=10)
371
+ qr = segno.make_qr(qr_str, error="L", version=10)
372
372
  except DataOverflowError as e:
373
- qr = segno.make_qr(url, error="L")
373
+ qr = segno.make_qr(qr_str, error="L")
374
374
  v = qr.version
375
375
  else:
376
- qr = segno.make_qr(url, error="L")
376
+ qr = segno.make_qr(qr_str, error="L")
377
377
  v = qr.version
378
378
 
379
379
  if(qr.mode != "alphanumeric"):
@@ -396,42 +396,18 @@ def generate_qr_with_markers(url, text="PAC", title=None, direction = Direction.
396
396
  combined_matrix = np.concatenate((title_marker, padding, qr_matrix, padding, visual_marker), axis=append_axis)
397
397
  else:
398
398
  combined_matrix = np.concatenate((qr_matrix, padding, visual_marker), axis=append_axis)
399
-
399
+
400
400
  return combined_matrix
401
-
402
- def generate_qr_with_markers_file(url, text="PAC", title=None, direction = Direction.LEFT_TO_RIGHT, fmt='svg', path=str):
403
- combined_matrix = generate_qr_with_markers(url, text="PAC", title=None, direction = Direction.LEFT_TO_RIGHT)
404
- outfile = f'{path}.{fmt}'
405
- match fmt:
406
- case 'png':
407
- segno.writers.write_png(combined_matrix, combined_matrix.shape[::-1], out=outfile, border=9)
408
- case 'svg':
409
- segno.writers.write_svg(combined_matrix, combined_matrix.shape[::-1], out=outfile, border=9)
410
401
 
411
-
412
- def generate_qr_with_markers_uri(url, text="PAC", title=None, direction = Direction.LEFT_TO_RIGHT, fmt='svg'):
413
- combined_matrix = generate_qr_with_markers(url, text="PAC", title=None, direction = Direction.LEFT_TO_RIGHT)
402
+ def save_qr_with_markers(url, text="PAC", title=None, direction = Direction.LEFT_TO_RIGHT, fmt='png', path='qr'):
403
+ combined_matrix = _generate_qr_with_markers(url, text="PAC", title=None, direction = Direction.LEFT_TO_RIGHT)
404
+ outfile = f'{path}.{fmt}'
414
405
  match fmt:
415
406
  case 'png':
416
- out = segno.writers.as_png_data_uri(combined_matrix, combined_matrix.shape[::-1], border=9)
407
+ writers.write_png(combined_matrix, combined_matrix.shape[::-1], out=outfile, border=9)
417
408
  case 'svg':
418
- out = segno.writers.as_svg_data_uri(combined_matrix, combined_matrix.shape[::-1], border=9)
419
- return out
420
-
421
- def generate_qr_with_markers_svg(url, text="PAC", title=None, direction = Direction.LEFT_TO_RIGHT, width=None, height=None, border=9, svg_omitsize=False):
422
- combined_matrix = generate_qr_with_markers(url, text="PAC", title=None, direction = Direction.LEFT_TO_RIGHT)
423
- with io.BytesIO() as out:
424
- version = combined_matrix.shape[::-1]
425
- scalex = width / (version[0] + 2*border) if width else 1
426
- scaley = height / (version[1] + 2*border) if height else 1
427
- scale = min(scalex, scaley)
428
- segno.writers.write_svg(combined_matrix, version, out, border=border,
429
- xmldecl=False, svgns=True, scale=scale, omitsize=svg_omitsize
430
- )
431
- s = out.getvalue().decode()
432
- return s
433
-
434
-
409
+ writers.write_svg(combined_matrix, combined_matrix.shape[::-1], out=outfile, border=9)
410
+
435
411
 
436
412
 
437
413
 
@@ -440,8 +416,7 @@ def main(url: Annotated[str, typer.Argument(help="The PAC-ID to be rendered as Q
440
416
  text: Annotated[str, typer.Option(help="The text of the PAC decoration.")] = "PAC",
441
417
  direction: Annotated[Direction, typer.Option(help="The position/direction of the PAC decoration.")] = Direction.TOP_TO_BOTTOM):
442
418
 
443
- img = generate_qr_with_markers(url, text=text, direction=direction)
444
- img.save('generated_codes', f"{outfile}.svg", format='svg')
419
+ save_qr_with_markers(url, text=text, direction=direction, path=outfile)
445
420
 
446
421
 
447
422
 
@@ -9,9 +9,9 @@ from labfreed.PAC_ID.extensions import Extension, UnknownExtension
9
9
  from labfreed.TREX.data_model import TREX
10
10
 
11
11
 
12
- from .PAC_ID.data_model import *
12
+ from ..PAC_ID.data_model import *
13
13
 
14
- from .validation import ValidationMessage, LabFREEDValidationError
14
+ from ..validation import ValidationMessage, LabFREEDValidationError
15
15
 
16
16
 
17
17
 
@@ -1,8 +1,5 @@
1
1
 
2
2
  from abc import ABC, abstractproperty, abstractstaticmethod
3
- from types import MappingProxyType
4
-
5
- from pydantic import Field
6
3
 
7
4
  from labfreed.validation import BaseModelWithValidationMessages
8
5
  from labfreed.PAC_ID.data_model import PACID
labfreed/__init__.py CHANGED
@@ -2,4 +2,4 @@
2
2
  Python implementation of LabFREED building blocks
3
3
  '''
4
4
 
5
- __version__ = "0.0.18"
5
+ __version__ = "0.0.19"
@@ -1,37 +1,7 @@
1
- from functools import cache
2
- import json
3
- from pathlib import Path
4
-
5
- from rich import print
6
-
7
- from typing import Any, Tuple
8
- from typing_extensions import Annotated
9
- from pydantic import BaseModel, AfterValidator
10
- import quantities as pq
11
- from quantities import units
1
+ from pydantic import BaseModel
12
2
 
13
3
  from labfreed.TREX.unece_units import unece_units
14
4
 
15
- def validate_unit(unit_name:str) -> str :
16
- """
17
- Pydantic validator function for the unit.
18
- Checks if the unit is a valid unit.
19
-
20
-
21
- Args:
22
- unit (str): unit symbol, e.g. 'kg'
23
-
24
- Returns:
25
- str: the input unit.
26
-
27
- Errors:
28
- raises an AssertionError if validation fails
29
- """
30
- if hasattr(pq, unit_name):
31
- return unit_name
32
- else:
33
- assert False
34
-
35
5
 
36
6
  class Unit(BaseModel):
37
7
  name: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: labfreed
3
- Version: 0.0.18
3
+ Version: 0.0.19
4
4
  Summary: Python implementation of LabFREED building blocks
5
5
  Author-email: Reto Thürer <thuerer.r@buchi.com>
6
6
  Description-Content-Type: text/markdown
@@ -41,7 +41,7 @@ pip install labfreed
41
41
  ### Parse a simple PAC-ID
42
42
 
43
43
  ```python
44
- from labfreed.parse_pac import PAC_Parser
44
+ from labfreed.IO.parse_pac import PAC_Parser
45
45
 
46
46
  # Parse the PAC-ID
47
47
  pac_str = 'HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234'
@@ -53,7 +53,7 @@ is_valid = pac_id.is_valid()
53
53
  print(f'PAC-ID is valid: {is_valid}')
54
54
  ```
55
55
  ```text
56
- >> [Error during execution: No module named 'quantities']
56
+ >> PAC-ID is valid: True
57
57
  ```
58
58
  ### Show recommendations:
59
59
  Note that the PAC-ID -- while valid -- uses characters which are not recommended (results in larger QR code).
@@ -63,7 +63,34 @@ There is a nice function to highlight problems
63
63
  pac_id.print_validation_messages()
64
64
  ```
65
65
  ```text
66
- >> [Error during execution: name 'pac_id' is not defined]
66
+ >> =======================================
67
+ >> Validation Results
68
+ >> ---------------------------------------
69
+ >>
70
+ >> Recommendation in id segment value bal500
71
+ >> HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234
72
+ >> Characters l a b should not be used.
73
+ >>
74
+ >> Recommendation in id segment value @1234
75
+ >> HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234
76
+ >> Characters @ should not be used.
77
+ >>
78
+ >> Warning in Category -MD
79
+ >> HTTPS://PAC.METTORIUS.COM/-MD/bal500/@1234
80
+ >> Category key -MD is not a well known key. It is recommended to use well known keys only
81
+ ```
82
+ ### Save as QR Code
83
+
84
+ ```python
85
+ from labfreed.IO.generate_qr import save_qr_with_markers
86
+
87
+ save_qr_with_markers(pac_str, fmt='png')
88
+ ```
89
+ ```text
90
+ >> Large QR: Provided URL is not alphanumeric!
91
+ >> Size: 29
92
+ >> Version: 3
93
+ >> Error Level: M
67
94
  ```
68
95
  ### PAC-CAT
69
96
 
@@ -75,7 +102,15 @@ if isinstance(pac_id, PAC_CAT):
75
102
  pac_id.print_categories()
76
103
  ```
77
104
  ```text
78
- >> [Error during execution: name 'PAC_Parser' is not defined]
105
+ >> Main Category
106
+ >> ----------
107
+ >> key (): -DR
108
+ >> id (21): XQ908756
109
+ >> Category
110
+ >> ------
111
+ >> key (): -MD
112
+ >> model_number (240): bal500
113
+ >> serial_number (21): @1234
79
114
  ```
80
115
  ### Parse a PAC-ID with extensions
81
116
  PAC-ID can have extensions. Here we parse a PAC-ID with attached display names and summary.
@@ -89,7 +124,7 @@ display_names = pac_id.get_extension('N') # display name has name 'N'
89
124
  print(display_names)
90
125
  ```
91
126
  ```text
92
- >> [Error during execution: name 'PAC_Parser' is not defined]
127
+ >> Display names: My Balance ❤️
93
128
  ```
94
129
  ```python
95
130
  # TREX
@@ -99,7 +134,7 @@ v = trex.get_segment('WEIGHT').to_python_type()
99
134
  print(f'WEIGHT = {v}')
100
135
  ```
101
136
  ```text
102
- >> [Error during execution: name 'pac_id' is not defined]
137
+ >> WEIGHT = 67.89 g
103
138
  ```
104
139
  ### Create a PAC-ID with Extensions
105
140
 
@@ -153,20 +188,17 @@ if trex.get_nested_validation_messages():
153
188
  # Side Note: The TREX can be turned back into a dict
154
189
  d = trex.dict()
155
190
  ```
156
- ```text
157
- >> [Error during execution: No module named 'quantities']
158
- ```
159
191
  #### Combine PAC-ID and TREX and serialize
160
192
 
161
193
  ```python
162
- from labfreed.parse_pac import PACID_With_Extensions
194
+ from labfreed.IO.parse_pac import PACID_With_Extensions
163
195
 
164
196
  pac_with_trex = PACID_With_Extensions(pac_id=pac_id, extensions=[trex])
165
197
  pac_str = pac_with_trex.serialize()
166
198
  print(pac_str)
167
199
  ```
168
200
  ```text
169
- >> [Error during execution: No module named 'quantities']
201
+ >> HTTPS://PAC.METTORIUS:COM/21:1234*DEMO$TREX/STOP$T.D:20240505T1306+TEMP$KEL:10.15+OK$T.B:F+COMMENT$T.A:FOO+COMMENT2$T.T:12G3+TABLE$$DURATION$HUR:DATE$T.D:OK$T.B:COMMENT$T.A::1:20250409T082814.766:T:FOO::1.1:20250409T082814.766:T:BAR::1.3:20250409T082814.766:F:BLUBB
170
202
  ```
171
203
  <!-- END EXAMPLES -->
172
204
 
@@ -174,9 +206,7 @@ print(pac_str)
174
206
 
175
207
  ## Change Log
176
208
 
177
- ### v0.0.17
178
- - dependencies are installed automatically
179
-
180
- ### v0.0.16
209
+ ### v0.0.19
181
210
  - supports PAC-ID, PAC-CAT, TREX and DisplayName
211
+ - QR generation
182
212
  - ok-ish test coverage
@@ -1,22 +1,22 @@
1
- labfreed/__init__.py,sha256=reRp78_6uZrtmaZRtPjFWADn6svJqLZMou47EfBjrmU,88
2
- labfreed/parse_pac.py,sha256=7y65HO1A3OEr5zftiEtrCaiLLI_8LoRPtQpPcKUNVik,6251
1
+ labfreed/__init__.py,sha256=6YWGHiMitcGiwwX9TPLO5MUlsimAgua8aP-e6yoW8-k,88
3
2
  labfreed/validation.py,sha256=QwkZWJhAjWbPUZtJJwjVYsw9TxeFhdbZaKjrPPIpuAA,5937
4
3
  labfreed/DisplayNameExtension/DisplayNameExtension.py,sha256=l9JZY2eRS0V-H5h3-WXIHiiBJuljns-_e_t9Bp84_CU,1155
4
+ labfreed/IO/generate_label.py,sha256=9ydpD68E7ztecEPXydw40eT7KV4FhAHvzmLidvYxHWI,2661
5
+ labfreed/IO/generate_qr.py,sha256=wdZSf51Id03xSY8liK2RfB7WyGAw9O4s0VhZzrkAa-g,16680
6
+ labfreed/IO/parse_pac.py,sha256=2c-HXkiQdUrGTL8zGb5CmO9l6ZrCb07rrTMMKdMi3_o,6253
5
7
  labfreed/PAC_CAT/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
6
8
  labfreed/PAC_CAT/data_model.py,sha256=dGwcQGLy1Dk6SFbs9utxKQKm_4ROZrXdv618APlQg7M,14308
7
9
  labfreed/PAC_ID/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
10
  labfreed/PAC_ID/data_model.py,sha256=g09qgC-TV6fjJw9VyDF6mTJ6co2i2RKZc0Z-BmiiUIQ,7483
9
- labfreed/PAC_ID/extensions.py,sha256=bvuZnlNKUdwsDLrPm8fyifqPn_PR4wCVkkScFnvRiuM,1158
10
- labfreed/QR_Generator/generate_qr.py,sha256=A4Bw_UESaB_igTDV2Y7a5T7vdz2Sb3yZCfHM0qKnu0M,18091
11
+ labfreed/PAC_ID/extensions.py,sha256=YKIE-aFf1jdL4sqCqUe3txjnP8-dA2zCJrT5lBSjvuE,1092
11
12
  labfreed/TREX/UneceUnits.json,sha256=kwfQSp_nTuWbADfBBgqTWrvPl6XtM5SedEVLbMJrM7M,898953
12
13
  labfreed/TREX/data_model.py,sha256=neKYBc5_S4t-v86DSaWLq81VJF4oS6eFUch3ChPTYJA,29705
13
14
  labfreed/TREX/parse.py,sha256=86962VEJpkrTcT436iFIB5dNed5WHABzpjxRjkA3PXo,2043
14
15
  labfreed/TREX/unece_units.py,sha256=scPKdsPzY1neAdFOhA08_tRZaR-yplM8mBhIzzDqZBk,3006
15
16
  labfreed/utilities/base36.py,sha256=_yX8aQ1OwrK5tnJU1NUEzQSFGr9xAVnNvPObpNzCPYs,2895
16
- labfreed/utilities/extension_intertpreters.py,sha256=B3IFJLfVMJQuPfBBtX6ywlDUZEi7_x6tY4g8V7SpWSs,124
17
- labfreed/utilities/utility_types.py,sha256=Zhk8Mu4hHjkn1gs8oh7vOxxaT7L7wLMVG40ZOWCKGK4,2865
17
+ labfreed/utilities/utility_types.py,sha256=dM0qZgshF3cHJThVzia7UIAOdkNLKukAaaduLqKSaMY,2195
18
18
  labfreed/utilities/well_known_keys.py,sha256=nqk66kHdSwJTJfMKlP-xQbBglS8F_NoWsGkfOVITFN0,331
19
- labfreed-0.0.18.dist-info/licenses/LICENSE,sha256=gHFOv9FRKHxO8cInP3YXyPoJnuNeqrvcHjaE_wPSsQ8,1100
20
- labfreed-0.0.18.dist-info/WHEEL,sha256=Dyt6SBfaasWElUrURkknVFAZDHSTwxg3PaTza7RSbkY,100
21
- labfreed-0.0.18.dist-info/METADATA,sha256=FiS8P177t3OE6BwQMsQCUhg4y4GQihwmU4-U98WacAU,5382
22
- labfreed-0.0.18.dist-info/RECORD,,
19
+ labfreed-0.0.19.dist-info/licenses/LICENSE,sha256=gHFOv9FRKHxO8cInP3YXyPoJnuNeqrvcHjaE_wPSsQ8,1100
20
+ labfreed-0.0.19.dist-info/WHEEL,sha256=Dyt6SBfaasWElUrURkknVFAZDHSTwxg3PaTza7RSbkY,100
21
+ labfreed-0.0.19.dist-info/METADATA,sha256=hxfeVBwFlFMSA9-tGCnva---qoMx6KQvgmf6z9tyjP4,6255
22
+ labfreed-0.0.19.dist-info/RECORD,,
@@ -1,4 +0,0 @@
1
- from labfreed.DisplayNameExtension.DisplayNameExtension import DisplayNames
2
- from labfreed.TREX.data_model import TREX
3
-
4
-