hl7apy 1.4.0b1__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.
Files changed (100) hide show
  1. hl7apy/__init__.py +331 -0
  2. hl7apy/base_datatypes.py +461 -0
  3. hl7apy/consts.py +80 -0
  4. hl7apy/core.py +2140 -0
  5. hl7apy/exceptions.py +350 -0
  6. hl7apy/factories.py +335 -0
  7. hl7apy/mllp.py +209 -0
  8. hl7apy/parser.py +809 -0
  9. hl7apy/utils.py +163 -0
  10. hl7apy/v2_1/__init__.py +88 -0
  11. hl7apy/v2_1/base_datatypes.py +37 -0
  12. hl7apy/v2_1/datatypes.py +98 -0
  13. hl7apy/v2_1/fields.py +440 -0
  14. hl7apy/v2_1/groups.py +88 -0
  15. hl7apy/v2_1/messages.py +215 -0
  16. hl7apy/v2_1/segments.py +477 -0
  17. hl7apy/v2_2/__init__.py +89 -0
  18. hl7apy/v2_2/datatypes.py +438 -0
  19. hl7apy/v2_2/fields.py +791 -0
  20. hl7apy/v2_2/groups.py +199 -0
  21. hl7apy/v2_2/messages.py +554 -0
  22. hl7apy/v2_2/segments.py +896 -0
  23. hl7apy/v2_3/__init__.py +90 -0
  24. hl7apy/v2_3/datatypes.py +787 -0
  25. hl7apy/v2_3/fields.py +1472 -0
  26. hl7apy/v2_3/groups.py +1789 -0
  27. hl7apy/v2_3/messages.py +864 -0
  28. hl7apy/v2_3/segments.py +1693 -0
  29. hl7apy/v2_3_1/__init__.py +91 -0
  30. hl7apy/v2_3_1/datatypes.py +901 -0
  31. hl7apy/v2_3_1/fields.py +1489 -0
  32. hl7apy/v2_3_1/groups.py +1866 -0
  33. hl7apy/v2_3_1/messages.py +894 -0
  34. hl7apy/v2_3_1/segments.py +1710 -0
  35. hl7apy/v2_3_1/tables.py +564 -0
  36. hl7apy/v2_4/__init__.py +91 -0
  37. hl7apy/v2_4/datatypes.py +925 -0
  38. hl7apy/v2_4/fields.py +1815 -0
  39. hl7apy/v2_4/groups.py +2360 -0
  40. hl7apy/v2_4/messages.py +1339 -0
  41. hl7apy/v2_4/segments.py +2092 -0
  42. hl7apy/v2_4/tables.py +824 -0
  43. hl7apy/v2_5/__init__.py +92 -0
  44. hl7apy/v2_5/datatypes.py +962 -0
  45. hl7apy/v2_5/fields.py +2120 -0
  46. hl7apy/v2_5/groups.py +3275 -0
  47. hl7apy/v2_5/messages.py +1810 -0
  48. hl7apy/v2_5/segments.py +2400 -0
  49. hl7apy/v2_5/tables.py +5263 -0
  50. hl7apy/v2_5_1/__init__.py +95 -0
  51. hl7apy/v2_5_1/datatypes.py +962 -0
  52. hl7apy/v2_5_1/fields.py +2129 -0
  53. hl7apy/v2_5_1/groups.py +3263 -0
  54. hl7apy/v2_5_1/messages.py +1798 -0
  55. hl7apy/v2_5_1/segments.py +2408 -0
  56. hl7apy/v2_5_1/tables.py +5271 -0
  57. hl7apy/v2_6/__init__.py +94 -0
  58. hl7apy/v2_6/base_datatypes.py +29 -0
  59. hl7apy/v2_6/datatypes.py +965 -0
  60. hl7apy/v2_6/fields.py +2470 -0
  61. hl7apy/v2_6/groups.py +3611 -0
  62. hl7apy/v2_6/messages.py +2082 -0
  63. hl7apy/v2_6/segments.py +2811 -0
  64. hl7apy/v2_6/tables.py +5266 -0
  65. hl7apy/v2_7/__init__.py +97 -0
  66. hl7apy/v2_7/base_datatypes.py +132 -0
  67. hl7apy/v2_7/datatypes.py +1043 -0
  68. hl7apy/v2_7/fields.py +2544 -0
  69. hl7apy/v2_7/groups.py +4233 -0
  70. hl7apy/v2_7/messages.py +1989 -0
  71. hl7apy/v2_7/segments.py +2896 -0
  72. hl7apy/v2_7/tables.py +5892 -0
  73. hl7apy/v2_8/__init__.py +97 -0
  74. hl7apy/v2_8/datatypes.py +991 -0
  75. hl7apy/v2_8/fields.py +2664 -0
  76. hl7apy/v2_8/groups.py +4606 -0
  77. hl7apy/v2_8/messages.py +2060 -0
  78. hl7apy/v2_8/segments.py +3043 -0
  79. hl7apy/v2_8/tables.py +6006 -0
  80. hl7apy/v2_8_1/__init__.py +97 -0
  81. hl7apy/v2_8_1/datatypes.py +991 -0
  82. hl7apy/v2_8_1/fields.py +2705 -0
  83. hl7apy/v2_8_1/groups.py +4552 -0
  84. hl7apy/v2_8_1/messages.py +1959 -0
  85. hl7apy/v2_8_1/segments.py +3048 -0
  86. hl7apy/v2_8_1/tables.py +6006 -0
  87. hl7apy/v2_8_2/__init__.py +97 -0
  88. hl7apy/v2_8_2/datatypes.py +1000 -0
  89. hl7apy/v2_8_2/fields.py +2743 -0
  90. hl7apy/v2_8_2/groups.py +4566 -0
  91. hl7apy/v2_8_2/messages.py +1967 -0
  92. hl7apy/v2_8_2/segments.py +3115 -0
  93. hl7apy/v2_8_2/tables.py +6170 -0
  94. hl7apy/validation.py +314 -0
  95. hl7apy-1.4.0b1.data/scripts/hl7apy_profile_parser +197 -0
  96. hl7apy-1.4.0b1.dist-info/METADATA +109 -0
  97. hl7apy-1.4.0b1.dist-info/RECORD +100 -0
  98. hl7apy-1.4.0b1.dist-info/WHEEL +5 -0
  99. hl7apy-1.4.0b1.dist-info/licenses/LICENSE +18 -0
  100. hl7apy-1.4.0b1.dist-info/top_level.txt +1 -0
hl7apy/__init__.py ADDED
@@ -0,0 +1,331 @@
1
+ #
2
+ # Copyright (c) 2012-2018, CRS4
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+
21
+ import importlib
22
+ import os
23
+ import pickle
24
+ from collections.abc import MutableMapping
25
+ from importlib.metadata import PackageNotFoundError
26
+ from importlib.metadata import version as _get_version
27
+
28
+ from hl7apy.consts import DEFAULT_ENCODING_CHARS, DEFAULT_ENCODING_CHARS_27, DEFAULT_VERSION, VALIDATION_LEVEL
29
+ from hl7apy.exceptions import InvalidEncodingChars, UnknownValidationLevel, UnsupportedVersion
30
+
31
+ try:
32
+ __version__ = _get_version('hl7apy')
33
+ except PackageNotFoundError: # not installed, e.g. used directly from a source checkout
34
+ __version__ = 'unknown'
35
+ __author__ = 'Daniela Ghironi, Vittorio Meloni, Alessandro Sulis, Federico Caboni'
36
+ __author_email__ = '<ghiron@gmail.com>, <vittorio.meloni@crs4.it>, <alessandro.sulis@crs4.it>, <federico.caboni@me.com>'
37
+ __url__ = 'https://crs4.github.io/hl7apy/'
38
+
39
+ _DEFAULT_ENCODING_CHARS = DEFAULT_ENCODING_CHARS
40
+ _DEFAULT_ENCODING_CHARS_27 = DEFAULT_ENCODING_CHARS_27
41
+ _DEFAULT_VERSION = DEFAULT_VERSION
42
+ _DEFAULT_VALIDATION_LEVEL = VALIDATION_LEVEL.TOLERANT
43
+
44
+
45
+ def check_encoding_chars(encoding_chars):
46
+ """
47
+ Validate the given encoding chars
48
+
49
+ :type encoding_chars: ``dict``
50
+ :param encoding_chars: the encoding chars (see :func:`hl7apy.set_default_encoding_chars`)
51
+ :raises: :exc:`hl7apy.exceptions.InvalidEncodingChars` if the given encoding chars are not valid
52
+ """
53
+ if not isinstance(encoding_chars, MutableMapping):
54
+ raise InvalidEncodingChars
55
+ required = {'FIELD', 'COMPONENT', 'SUBCOMPONENT', 'REPETITION', 'ESCAPE'}
56
+ missing = required - set(encoding_chars.keys())
57
+ if missing:
58
+ raise InvalidEncodingChars('Missing required encoding chars')
59
+
60
+ values = [v for k, v in encoding_chars.items() if k in required]
61
+ if len(values) > len(set(values)):
62
+ raise InvalidEncodingChars('Found duplicate encoding chars')
63
+
64
+
65
+ def check_validation_level(validation_level):
66
+ """
67
+ Validate the given validation level
68
+
69
+ :type validation_level: ``int``
70
+ :param validation_level: validation level (see :class:`hl7apy.consts.VALIDATION_LEVEL`)
71
+ :raises: :exc:`hl7apy.exceptions.UnknownValidationLevel` if the given validation level is unsupported
72
+ """
73
+ if validation_level not in (VALIDATION_LEVEL.QUIET, VALIDATION_LEVEL.STRICT, VALIDATION_LEVEL.TOLERANT):
74
+ raise UnknownValidationLevel
75
+
76
+
77
+ def check_version(version):
78
+ """
79
+ Validate the given version number
80
+
81
+ :type version: ``str``
82
+ :param version: the version to validate (e.g. ``2.6``)
83
+ :raises: :class:`hl7apy.exceptions.UnsupportedVersion` if the given version is unsupported
84
+ """
85
+ if version not in SUPPORTED_LIBRARIES:
86
+ raise UnsupportedVersion(version)
87
+
88
+
89
+ def get_default_encoding_chars(version=None):
90
+ """
91
+ Get the default encoding chars
92
+
93
+ :rtype: ``dict``
94
+ :returns: the encoding chars (see :func:`hl7apy.set_default_encoding_chars`)
95
+
96
+ >>> print(get_default_encoding_chars('2.6')['FIELD'])
97
+ |
98
+ """
99
+ if version and version >= '2.7':
100
+ return _DEFAULT_ENCODING_CHARS_27
101
+ return _DEFAULT_ENCODING_CHARS
102
+
103
+
104
+ def get_default_version():
105
+ """
106
+ Get the default version
107
+
108
+ :rtype: ``str``
109
+ :returns: the default version
110
+
111
+ >>> print(get_default_version())
112
+ 2.5
113
+ """
114
+ return _DEFAULT_VERSION
115
+
116
+
117
+ def get_default_validation_level():
118
+ """
119
+ Get the default validation level
120
+
121
+ :rtype: ``str``
122
+ :returns: the default validation level
123
+
124
+ >>> print(get_default_validation_level())
125
+ 2
126
+ """
127
+ return _DEFAULT_VALIDATION_LEVEL
128
+
129
+
130
+ def set_default_validation_level(validation_level):
131
+ """
132
+ Set the given validation level as default
133
+
134
+ :type validation_level: ``int``
135
+ :param validation_level: validation level (see :class:`hl7apy.consts.VALIDATION_LEVEL`)
136
+ :raises: :exc:`hl7apy.exceptions.UnknownValidationLevel` if the given validation level is unsupported
137
+
138
+ >>> set_default_validation_level(3) # doctest: +IGNORE_EXCEPTION_DETAIL
139
+ Traceback (most recent call last):
140
+ ...
141
+ UnknownValidationLevel
142
+ >>> set_default_validation_level(VALIDATION_LEVEL.TOLERANT)
143
+ >>> print(get_default_validation_level())
144
+ 2
145
+ """
146
+ check_validation_level(validation_level)
147
+
148
+ global _DEFAULT_VALIDATION_LEVEL
149
+
150
+ _DEFAULT_VALIDATION_LEVEL = validation_level
151
+
152
+
153
+ def set_default_version(version):
154
+ """
155
+ Set the given version as default
156
+
157
+ :type version: ``str``
158
+ :param version: the new default version (e.g. ``2.6``)
159
+ :raises: :class:`hl7apy.exceptions.UnsupportedVersion` if the given version is unsupported
160
+
161
+ >>> set_default_version('22') # doctest: +IGNORE_EXCEPTION_DETAIL
162
+ Traceback (most recent call last):
163
+ ...
164
+ UnsupportedVersion: The version 22 is not supported
165
+ >>> set_default_version('2.3')
166
+ >>> print(get_default_version())
167
+ 2.3
168
+ """
169
+ check_version(version)
170
+
171
+ global _DEFAULT_VERSION
172
+
173
+ _DEFAULT_VERSION = version
174
+
175
+
176
+ def set_default_encoding_chars(encoding_chars):
177
+ """
178
+ Set the given encoding chars as default
179
+
180
+ :type encoding_chars: ``dict``
181
+ :param encoding_chars: the new encoding chars
182
+ :raises: :class:`hl7apy.exceptions.InvalidEncodingChars` if the given encoding chars are not valid
183
+
184
+ The *encoding_chars* dictionary should contain the following keys:
185
+
186
+ +--------------+-----------------+
187
+ |Key |Default |
188
+ +==============+=================+
189
+ |GROUP |``\\r`` |
190
+ +--------------+-----------------+
191
+ |SEGMENT |``\\r`` |
192
+ +--------------+-----------------+
193
+ |FIELD |``|`` |
194
+ +--------------+-----------------+
195
+ |COMPONENT |``^`` |
196
+ +--------------+-----------------+
197
+ |SUBCOMPONENT |``&`` |
198
+ +--------------+-----------------+
199
+ |REPETITION |``~`` |
200
+ +--------------+-----------------+
201
+ |ESCAPE |``\\`` |
202
+ +--------------+-----------------+
203
+
204
+ >>> set_default_encoding_chars({'FIELD': '!'}) # doctest: +IGNORE_EXCEPTION_DETAIL
205
+ Traceback (most recent call last):
206
+ ...
207
+ InvalidEncodingChars: Missing required encoding chars
208
+ >>> set_default_encoding_chars({'FIELD': '!', 'COMPONENT': 'C', 'SUBCOMPONENT': 'S', \
209
+ 'REPETITION': 'R', 'ESCAPE': '\\\\'})
210
+ >>> print(get_default_encoding_chars('2.5')['FIELD'])
211
+ !
212
+ """
213
+ check_encoding_chars(encoding_chars)
214
+
215
+ encoding_chars.update({'GROUP': '\r', 'SEGMENT': '\r'})
216
+
217
+ global _DEFAULT_ENCODING_CHARS
218
+
219
+ _DEFAULT_ENCODING_CHARS = encoding_chars
220
+
221
+
222
+ def load_library(version):
223
+ """
224
+ Load the correct module according to the version
225
+
226
+ :type version: ``str``
227
+ :param version: the version of the library to be loaded (e.g. '2.6')
228
+ :rtype: module object
229
+ """
230
+ check_version(version)
231
+ module_name = SUPPORTED_LIBRARIES[version]
232
+ lib = importlib.import_module(module_name)
233
+ return lib
234
+
235
+
236
+ def load_reference(name, element_type, version):
237
+ """
238
+ Look for an element of the given type, name and version and return its reference structure
239
+
240
+ :type element_type: ``str``
241
+ :param element_type: the element type to look for (e.g. 'Segment')
242
+ :type name: ``str``
243
+ :param name: the element name to look for (e.g. 'MSH')
244
+ :type version: ``str``
245
+ :param version: the version of the library where to search the element (e.g. '2.6')
246
+ :rtype: ``dict``
247
+ :return: a dictionary describing the element structure
248
+ :raise: ``KeyError`` if the element has not been found
249
+
250
+ The returned dictionary will contain the following keys:
251
+
252
+ +--------------+--------------------------------------------+
253
+ |Key |Value |
254
+ +==============+============================================+
255
+ |cls |an :class:`hl7apy.core.Element` subclass |
256
+ +--------------+--------------------------------------------+
257
+ |name |the Element name (e.g. PID) |
258
+ +--------------+--------------------------------------------+
259
+ |ref |a tuple of one of the following format: |
260
+ | | |
261
+ | |('leaf', <datatype>, <longName>, <table>) |
262
+ | |('sequence', (<child>, (<min>, <max>), ...))|
263
+ +--------------+--------------------------------------------+
264
+
265
+ >>> load_reference('UNKNOWN', 'Segment', '2.5') # doctest: +IGNORE_EXCEPTION_DETAIL
266
+ Traceback (most recent call last):
267
+ ...
268
+ ChildNotFound: No child named UNKNOWN
269
+ >>> r = load_reference('ADT_A01', 'Message', '2.5')
270
+ >>> print(r[0])
271
+ sequence
272
+ >>> r = load_reference('MSH_3', 'Field', '2.5')
273
+ >>> print(r[0])
274
+ sequence
275
+ """
276
+ lib = load_library(version)
277
+ ref = lib.get(name, element_type)
278
+ return ref
279
+
280
+
281
+ def find_reference(name, element_types, version):
282
+ """
283
+ Look for an element of the given name and version into the given types and return its reference structure
284
+
285
+ :type name: ``str``
286
+ :param name: the element name to look for (e.g. 'MSH')
287
+ :type types: ``list`` or ``tuple``
288
+ :param types: the element classes where to look for the element (e.g. (Group, Segment))
289
+ :type version: ``str``
290
+ :param version: the version of the library where to search the element (e.g. '2.6')
291
+ :rtype: ``dict``
292
+ :return: a dictionary describing the element structure
293
+ :raise: :class:`hl7apy.exceptions.ChildNotFound` if the element has not been found
294
+
295
+ >>> from hl7apy.core import Message, Segment
296
+ >>> find_reference('UNKNOWN', (Segment, ), '2.5') # doctest: +IGNORE_EXCEPTION_DETAIL
297
+ Traceback (most recent call last):
298
+ ...
299
+ ChildNotFound: No child named UNKNOWN
300
+ >>> find_reference('ADT_A01', (Segment,), '2.5') # doctest: +IGNORE_EXCEPTION_DETAIL
301
+ Traceback (most recent call last):
302
+ ...
303
+ ChildNotFound: No child named ADT_A01
304
+ >>> r = find_reference('ADT_A01', (Message,), '2.5')
305
+ >>> print('%s %s' % (r['name'], r['cls']))
306
+ ADT_A01 <class 'hl7apy.core.Message'>
307
+ """
308
+ lib = load_library(version)
309
+ ref = lib.find(name, element_types)
310
+ return ref
311
+
312
+
313
+ def load_message_profile(path):
314
+ with open(path, 'rb') as f:
315
+ mp = pickle.load(f)
316
+
317
+ return mp
318
+
319
+
320
+ def _discover_libraries():
321
+ current_dir = os.path.dirname(__file__)
322
+ return {o[1:].replace("_", "."): "hl7apy.{}".format(o) for o in os.listdir(current_dir) if o.startswith("v2_")}
323
+
324
+
325
+ SUPPORTED_LIBRARIES = _discover_libraries()
326
+
327
+
328
+ if __name__ == '__main__':
329
+ import doctest
330
+
331
+ doctest.testmod()