compressedfhir 1.0.4__tar.gz → 1.0.5__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.
Potentially problematic release.
This version of compressedfhir might be problematic. Click here for more details.
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/Makefile +18 -0
- {compressedfhir-1.0.4/compressedfhir.egg-info → compressedfhir-1.0.5}/PKG-INFO +1 -1
- compressedfhir-1.0.5/VERSION +1 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_resource.py +13 -28
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_resource_map.py +1 -1
- compressedfhir-1.0.5/compressedfhir/fhir/test/test_fhir_resource.py +104 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/compressed_dict/v1/compressed_dict.py +32 -6
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/compressed_dict/v1/test/test_compressed_dict.py +4 -4
- {compressedfhir-1.0.4 → compressedfhir-1.0.5/compressedfhir.egg-info}/PKG-INFO +1 -1
- compressedfhir-1.0.4/VERSION +0 -1
- compressedfhir-1.0.4/compressedfhir/fhir/test/test_fhir_resource.py +0 -225
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/LICENSE +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/MANIFEST.in +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/README.md +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/base_resource_list.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_bundle.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_bundle_entry.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_bundle_entry_list.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_bundle_entry_request.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_bundle_entry_response.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_bundle_entry_search.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_identifier.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_link.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_meta.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_resource_list.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_bundle_entry.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_bundle_entry_list.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_bundle_entry_request.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_bundle_entry_response.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_fhir_bundle.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_fhir_resource_list.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_fhir_resource_map.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/py.typed +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/compressed_dict/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/compressed_dict/v1/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/compressed_dict/v1/compressed_dict_access_error.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/compressed_dict/v1/compressed_dict_storage_mode.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/compressed_dict/v1/test/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/fhir_json_encoder.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_helpers.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_serializers/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_serializers/test/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_serializers/test/test_type_preservation_decoder.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_serializers/test/test_type_preservation_encoder.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_serializers/test/test_type_preservation_serializer.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_serializers/type_preservation_decoder.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_serializers/type_preservation_encoder.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_serializers/type_preservation_serializer.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/ordered_dict_to_dict_converter/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/ordered_dict_to_dict_converter/ordered_dict_to_dict_converter.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/string_compressor/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/string_compressor/v1/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/string_compressor/v1/string_compressor.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/string_compressor/v1/test/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/string_compressor/v1/test/test_string_compressor.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/test/__init__.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/test/test_fhir_json_encoder.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/test/test_json_helpers.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir.egg-info/SOURCES.txt +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir.egg-info/dependency_links.txt +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir.egg-info/not-zip-safe +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir.egg-info/requires.txt +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir.egg-info/top_level.txt +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/setup.cfg +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/setup.py +0 -0
- {compressedfhir-1.0.4 → compressedfhir-1.0.5}/tests/__init__.py +0 -0
|
@@ -73,3 +73,21 @@ help: ## Show this help.
|
|
|
73
73
|
pipenv-setup:devdocker ## Run pipenv-setup to update setup.py with latest dependencies
|
|
74
74
|
docker compose run --rm dev sh -c "pipenv run pipenv install --skip-lock --categories \"pipenvsetup\" && pipenv run pipenv-setup sync --pipfile" && \
|
|
75
75
|
make run-pre-commit
|
|
76
|
+
|
|
77
|
+
.PHONY: coverage
|
|
78
|
+
coverage: up ## Run code coverage and generate reports
|
|
79
|
+
mkdir -p reports
|
|
80
|
+
docker compose run --rm \
|
|
81
|
+
-v $(PWD)/reports:/reports \
|
|
82
|
+
--name compressedfhir_coverage \
|
|
83
|
+
dev pytest \
|
|
84
|
+
--cov=. \
|
|
85
|
+
--cov-report=term-missing \
|
|
86
|
+
--cov-report=xml:/reports/coverage.xml \
|
|
87
|
+
--cov-report=html:/reports/htmlcov \
|
|
88
|
+
--cov-fail-under=80 \
|
|
89
|
+
tests compressedfhir
|
|
90
|
+
|
|
91
|
+
.PHONY: clean-coverage
|
|
92
|
+
clean-coverage: ## Remove coverage reports
|
|
93
|
+
rm -rf reports/coverage.xml reports/htmlcov .coverage
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.5
|
|
@@ -61,14 +61,10 @@ class FhirResource(CompressedDict[str, Any]):
|
|
|
61
61
|
else None
|
|
62
62
|
)
|
|
63
63
|
|
|
64
|
-
def json(self) -> str:
|
|
65
|
-
"""Convert the resource to a JSON string."""
|
|
66
|
-
return json.dumps(obj=self.dict(), cls=FhirJSONEncoder)
|
|
67
|
-
|
|
68
64
|
def __deepcopy__(self, memo: Dict[int, Any]) -> "FhirResource":
|
|
69
65
|
"""Create a copy of the resource."""
|
|
70
66
|
return FhirResource(
|
|
71
|
-
initial_dict=super().
|
|
67
|
+
initial_dict=super().raw_dict(),
|
|
72
68
|
storage_mode=self._storage_mode,
|
|
73
69
|
)
|
|
74
70
|
|
|
@@ -84,29 +80,6 @@ class FhirResource(CompressedDict[str, Any]):
|
|
|
84
80
|
"""
|
|
85
81
|
return copy.deepcopy(self)
|
|
86
82
|
|
|
87
|
-
@override
|
|
88
|
-
def dict(self, *, remove_nulls: bool = True) -> OrderedDict[str, Any]:
|
|
89
|
-
"""
|
|
90
|
-
Converts the FhirResource object to a dictionary.
|
|
91
|
-
|
|
92
|
-
:param remove_nulls: If True, removes None values from the dictionary.
|
|
93
|
-
:return: A dictionary representation of the FhirResource object.
|
|
94
|
-
"""
|
|
95
|
-
ordered_dict = super().dict()
|
|
96
|
-
result: OrderedDict[str, Any] = copy.deepcopy(ordered_dict)
|
|
97
|
-
if remove_nulls:
|
|
98
|
-
result = FhirClientJsonHelpers.remove_empty_elements_from_ordered_dict(
|
|
99
|
-
result
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
return result
|
|
103
|
-
|
|
104
|
-
def remove_nulls(self) -> None:
|
|
105
|
-
"""
|
|
106
|
-
Removes None values from the resource dictionary.
|
|
107
|
-
"""
|
|
108
|
-
self.replace(value=self.dict(remove_nulls=True))
|
|
109
|
-
|
|
110
83
|
@property
|
|
111
84
|
def id(self) -> Optional[str]:
|
|
112
85
|
"""Get the ID from the resource dictionary."""
|
|
@@ -171,3 +144,15 @@ class FhirResource(CompressedDict[str, Any]):
|
|
|
171
144
|
properties_to_cache=properties_to_cache,
|
|
172
145
|
),
|
|
173
146
|
)
|
|
147
|
+
|
|
148
|
+
@override
|
|
149
|
+
def json(self) -> str:
|
|
150
|
+
"""Convert the resource to a JSON string."""
|
|
151
|
+
|
|
152
|
+
# working_dict preserves the python types so create a fhir friendly version
|
|
153
|
+
raw_dict: OrderedDict[str, Any] = self.raw_dict()
|
|
154
|
+
|
|
155
|
+
raw_dict = FhirClientJsonHelpers.remove_empty_elements_from_ordered_dict(
|
|
156
|
+
raw_dict
|
|
157
|
+
)
|
|
158
|
+
return json.dumps(obj=raw_dict, cls=FhirJSONEncoder)
|
|
@@ -43,7 +43,7 @@ class FhirResourceMap:
|
|
|
43
43
|
"""
|
|
44
44
|
result: OrderedDict[str, Any] = OrderedDict[str, Any]()
|
|
45
45
|
for key, value in self._resource_map.items():
|
|
46
|
-
result[key] = [resource.dict(
|
|
46
|
+
result[key] = [resource.dict() for resource in value]
|
|
47
47
|
return result
|
|
48
48
|
|
|
49
49
|
def get(self, *, resource_type: str) -> Optional[FhirResourceList]:
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
|
|
4
|
+
from compressedfhir.fhir.fhir_resource import FhirResource
|
|
5
|
+
from compressedfhir.utilities.compressed_dict.v1.compressed_dict_storage_mode import (
|
|
6
|
+
CompressedDictStorageMode,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestFhirResource:
|
|
11
|
+
def test_init_empty(self) -> None:
|
|
12
|
+
"""Test initializing FhirResource with no initial dictionary."""
|
|
13
|
+
resource = FhirResource(storage_mode=CompressedDictStorageMode())
|
|
14
|
+
assert len(resource) == 0
|
|
15
|
+
assert resource.resource_type is None
|
|
16
|
+
assert resource.id is None
|
|
17
|
+
assert resource.resource_type_and_id is None
|
|
18
|
+
|
|
19
|
+
def test_init_with_data(self) -> None:
|
|
20
|
+
"""Test initializing FhirResource with a dictionary."""
|
|
21
|
+
initial_data: Dict[str, Any] = {
|
|
22
|
+
"resourceType": "Patient",
|
|
23
|
+
"id": "123",
|
|
24
|
+
"name": [{"given": ["John"]}],
|
|
25
|
+
}
|
|
26
|
+
resource = FhirResource(
|
|
27
|
+
initial_dict=initial_data, storage_mode=CompressedDictStorageMode()
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
with resource.transaction():
|
|
31
|
+
assert resource.resource_type == "Patient"
|
|
32
|
+
assert resource.id == "123"
|
|
33
|
+
assert resource.resource_type_and_id == "Patient/123"
|
|
34
|
+
assert resource["name"][0]["given"][0] == "John"
|
|
35
|
+
|
|
36
|
+
def test_resource_type_and_id_property(self) -> None:
|
|
37
|
+
"""Test resource_type_and_id property with various scenarios."""
|
|
38
|
+
# Scenario 1: Both resource type and id present
|
|
39
|
+
resource1 = FhirResource(
|
|
40
|
+
initial_dict={"resourceType": "Observation", "id": "456"},
|
|
41
|
+
storage_mode=CompressedDictStorageMode(),
|
|
42
|
+
)
|
|
43
|
+
assert resource1.resource_type_and_id == "Observation/456"
|
|
44
|
+
|
|
45
|
+
# Scenario 2: Missing resource type
|
|
46
|
+
resource2 = FhirResource(
|
|
47
|
+
initial_dict={"id": "789"}, storage_mode=CompressedDictStorageMode()
|
|
48
|
+
)
|
|
49
|
+
assert resource2.resource_type_and_id is None
|
|
50
|
+
|
|
51
|
+
# Scenario 3: Missing id
|
|
52
|
+
resource3 = FhirResource(
|
|
53
|
+
initial_dict={"resourceType": "Patient"},
|
|
54
|
+
storage_mode=CompressedDictStorageMode(),
|
|
55
|
+
)
|
|
56
|
+
assert resource3.resource_type_and_id is None
|
|
57
|
+
|
|
58
|
+
def test_equality(self) -> None:
|
|
59
|
+
"""Test equality comparison between FhirResource instances."""
|
|
60
|
+
# Scenario 1: Equal resources
|
|
61
|
+
resource1 = FhirResource(
|
|
62
|
+
initial_dict={"resourceType": "Patient", "id": "123"},
|
|
63
|
+
storage_mode=CompressedDictStorageMode(),
|
|
64
|
+
)
|
|
65
|
+
resource2 = FhirResource(
|
|
66
|
+
initial_dict={"resourceType": "Patient", "id": "123"},
|
|
67
|
+
storage_mode=CompressedDictStorageMode(),
|
|
68
|
+
)
|
|
69
|
+
assert resource1 == resource2
|
|
70
|
+
|
|
71
|
+
# Scenario 2: Different resource types
|
|
72
|
+
resource3 = FhirResource(
|
|
73
|
+
initial_dict={"resourceType": "Observation", "id": "123"},
|
|
74
|
+
storage_mode=CompressedDictStorageMode(),
|
|
75
|
+
)
|
|
76
|
+
assert resource1 != resource3
|
|
77
|
+
|
|
78
|
+
# Scenario 3: Different ids
|
|
79
|
+
resource4 = FhirResource(
|
|
80
|
+
initial_dict={"resourceType": "Patient", "id": "456"},
|
|
81
|
+
storage_mode=CompressedDictStorageMode(),
|
|
82
|
+
)
|
|
83
|
+
assert resource1 != resource4
|
|
84
|
+
|
|
85
|
+
# Scenario 4: Comparing with non-FhirResource
|
|
86
|
+
assert resource1 != "Not a FhirResource"
|
|
87
|
+
|
|
88
|
+
def test_to_json(self) -> None:
|
|
89
|
+
"""Test JSON serialization of FhirResource."""
|
|
90
|
+
initial_data: Dict[str, Any] = {
|
|
91
|
+
"resourceType": "Patient",
|
|
92
|
+
"id": "123",
|
|
93
|
+
"name": [{"given": ["John"]}],
|
|
94
|
+
}
|
|
95
|
+
resource = FhirResource(
|
|
96
|
+
initial_dict=initial_data, storage_mode=CompressedDictStorageMode()
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
json_str = resource.json()
|
|
100
|
+
parsed_json = json.loads(json_str)
|
|
101
|
+
|
|
102
|
+
assert parsed_json == initial_data
|
|
103
|
+
assert "resourceType" in parsed_json
|
|
104
|
+
assert "id" in parsed_json
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import copy
|
|
2
|
+
import json
|
|
2
3
|
from collections.abc import KeysView, ValuesView, ItemsView, MutableMapping
|
|
3
4
|
from contextlib import contextmanager
|
|
4
5
|
from typing import Dict, Optional, Iterator, cast, List, Any, overload, OrderedDict
|
|
@@ -13,6 +14,7 @@ from compressedfhir.utilities.compressed_dict.v1.compressed_dict_storage_mode im
|
|
|
13
14
|
CompressedDictStorageMode,
|
|
14
15
|
CompressedDictStorageType,
|
|
15
16
|
)
|
|
17
|
+
from compressedfhir.utilities.fhir_json_encoder import FhirJSONEncoder
|
|
16
18
|
from compressedfhir.utilities.json_serializers.type_preservation_serializer import (
|
|
17
19
|
TypePreservationSerializer,
|
|
18
20
|
)
|
|
@@ -423,19 +425,43 @@ class CompressedDict[K, V](MutableMapping[K, V]):
|
|
|
423
425
|
"""
|
|
424
426
|
return self._get_dict().items()
|
|
425
427
|
|
|
426
|
-
def
|
|
428
|
+
def raw_dict(self) -> OrderedDict[K, V]:
|
|
427
429
|
"""
|
|
428
|
-
|
|
430
|
+
Returns the raw dictionary. Deserializes if necessary.
|
|
431
|
+
Note that this dictionary preserves the python types so it is not FHIR friendly.
|
|
432
|
+
Use dict() if you want a FHIR friendly version.
|
|
429
433
|
|
|
430
434
|
Returns:
|
|
431
|
-
|
|
435
|
+
raw dictionary
|
|
432
436
|
"""
|
|
433
437
|
if self._working_dict:
|
|
434
438
|
return self._working_dict
|
|
435
439
|
else:
|
|
436
|
-
# if the working dict is None, return it but don't store it in the self._working_dict to keep memory low
|
|
440
|
+
# if the working dict is not None, return it but don't store it in the self._working_dict to keep memory low
|
|
437
441
|
return self.create_working_dict()
|
|
438
442
|
|
|
443
|
+
def dict(self) -> OrderedDict[K, V]:
|
|
444
|
+
"""
|
|
445
|
+
Convert to a FHIR friendly dictionary where the python types like datetime are converted to string versions
|
|
446
|
+
|
|
447
|
+
Returns:
|
|
448
|
+
FHIR friendly dictionary
|
|
449
|
+
"""
|
|
450
|
+
return cast(
|
|
451
|
+
OrderedDict[K, V],
|
|
452
|
+
json.loads(
|
|
453
|
+
self.json(),
|
|
454
|
+
object_pairs_hook=lambda pairs: OrderedDict(pairs),
|
|
455
|
+
),
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
def json(self) -> str:
|
|
459
|
+
"""Convert the resource to a JSON string."""
|
|
460
|
+
|
|
461
|
+
raw_dict: OrderedDict[K, V] = self.raw_dict()
|
|
462
|
+
|
|
463
|
+
return json.dumps(obj=raw_dict, cls=FhirJSONEncoder)
|
|
464
|
+
|
|
439
465
|
def __repr__(self) -> str:
|
|
440
466
|
"""
|
|
441
467
|
String representation of the dictionary
|
|
@@ -559,7 +585,7 @@ class CompressedDict[K, V](MutableMapping[K, V]):
|
|
|
559
585
|
"""
|
|
560
586
|
# Create a new instance with the same storage mode
|
|
561
587
|
new_instance = CompressedDict(
|
|
562
|
-
initial_dict=copy.deepcopy(self.
|
|
588
|
+
initial_dict=copy.deepcopy(self.raw_dict()),
|
|
563
589
|
storage_mode=self._storage_mode,
|
|
564
590
|
properties_to_cache=self._properties_to_cache,
|
|
565
591
|
)
|
|
@@ -633,7 +659,7 @@ class CompressedDict[K, V](MutableMapping[K, V]):
|
|
|
633
659
|
Returns:
|
|
634
660
|
Plain dictionary
|
|
635
661
|
"""
|
|
636
|
-
return OrderedDictToDictConverter.convert(self.
|
|
662
|
+
return OrderedDictToDictConverter.convert(self.raw_dict())
|
|
637
663
|
|
|
638
664
|
@classmethod
|
|
639
665
|
def from_json(cls, json_str: str) -> "CompressedDict[K, V]":
|
|
@@ -234,7 +234,7 @@ def test_transaction_basic_raw_storage() -> None:
|
|
|
234
234
|
|
|
235
235
|
# After transaction
|
|
236
236
|
assert compressed_dict._transaction_depth == 0
|
|
237
|
-
assert compressed_dict.
|
|
237
|
+
assert compressed_dict.raw_dict() == {
|
|
238
238
|
"key1": "value1",
|
|
239
239
|
"key2": "value2",
|
|
240
240
|
"key3": "value3",
|
|
@@ -262,7 +262,7 @@ def test_transaction_nested_context() -> None:
|
|
|
262
262
|
assert compressed_dict._transaction_depth == 1
|
|
263
263
|
|
|
264
264
|
assert compressed_dict._transaction_depth == 0
|
|
265
|
-
assert compressed_dict.
|
|
265
|
+
assert compressed_dict.raw_dict() == {"key1": "value1", "key2": "value2"}
|
|
266
266
|
|
|
267
267
|
|
|
268
268
|
def test_transaction_access_error() -> None:
|
|
@@ -311,7 +311,7 @@ def test_transaction_different_storage_modes() -> None:
|
|
|
311
311
|
with compressed_dict.transaction() as d:
|
|
312
312
|
d["key2"] = "value2"
|
|
313
313
|
|
|
314
|
-
assert compressed_dict.
|
|
314
|
+
assert compressed_dict.raw_dict() == {"key1": "value1", "key2": "value2"}
|
|
315
315
|
|
|
316
316
|
|
|
317
317
|
def test_transaction_with_properties_to_cache() -> None:
|
|
@@ -330,7 +330,7 @@ def test_transaction_with_properties_to_cache() -> None:
|
|
|
330
330
|
with compressed_dict.transaction() as d:
|
|
331
331
|
d["key2"] = "value2"
|
|
332
332
|
|
|
333
|
-
assert compressed_dict.
|
|
333
|
+
assert compressed_dict.raw_dict() == {
|
|
334
334
|
"key1": "value1",
|
|
335
335
|
"important_prop": "cached_value",
|
|
336
336
|
"key2": "value2",
|
compressedfhir-1.0.4/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.0.4
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from typing import Dict, Any
|
|
3
|
-
|
|
4
|
-
from compressedfhir.fhir.fhir_resource import FhirResource
|
|
5
|
-
from compressedfhir.utilities.compressed_dict.v1.compressed_dict_storage_mode import (
|
|
6
|
-
CompressedDictStorageMode,
|
|
7
|
-
)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class TestFhirResource:
|
|
11
|
-
def test_init_empty(self) -> None:
|
|
12
|
-
"""Test initializing FhirResource with no initial dictionary."""
|
|
13
|
-
resource = FhirResource(storage_mode=CompressedDictStorageMode())
|
|
14
|
-
assert len(resource) == 0
|
|
15
|
-
assert resource.resource_type is None
|
|
16
|
-
assert resource.id is None
|
|
17
|
-
assert resource.resource_type_and_id is None
|
|
18
|
-
|
|
19
|
-
def test_init_with_data(self) -> None:
|
|
20
|
-
"""Test initializing FhirResource with a dictionary."""
|
|
21
|
-
initial_data: Dict[str, Any] = {
|
|
22
|
-
"resourceType": "Patient",
|
|
23
|
-
"id": "123",
|
|
24
|
-
"name": [{"given": ["John"]}],
|
|
25
|
-
}
|
|
26
|
-
resource = FhirResource(
|
|
27
|
-
initial_dict=initial_data, storage_mode=CompressedDictStorageMode()
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
with resource.transaction():
|
|
31
|
-
assert resource.resource_type == "Patient"
|
|
32
|
-
assert resource.id == "123"
|
|
33
|
-
assert resource.resource_type_and_id == "Patient/123"
|
|
34
|
-
assert resource["name"][0]["given"][0] == "John"
|
|
35
|
-
|
|
36
|
-
def test_resource_type_and_id_property(self) -> None:
|
|
37
|
-
"""Test resource_type_and_id property with various scenarios."""
|
|
38
|
-
# Scenario 1: Both resource type and id present
|
|
39
|
-
resource1 = FhirResource(
|
|
40
|
-
initial_dict={"resourceType": "Observation", "id": "456"},
|
|
41
|
-
storage_mode=CompressedDictStorageMode(),
|
|
42
|
-
)
|
|
43
|
-
assert resource1.resource_type_and_id == "Observation/456"
|
|
44
|
-
|
|
45
|
-
# Scenario 2: Missing resource type
|
|
46
|
-
resource2 = FhirResource(
|
|
47
|
-
initial_dict={"id": "789"}, storage_mode=CompressedDictStorageMode()
|
|
48
|
-
)
|
|
49
|
-
assert resource2.resource_type_and_id is None
|
|
50
|
-
|
|
51
|
-
# Scenario 3: Missing id
|
|
52
|
-
resource3 = FhirResource(
|
|
53
|
-
initial_dict={"resourceType": "Patient"},
|
|
54
|
-
storage_mode=CompressedDictStorageMode(),
|
|
55
|
-
)
|
|
56
|
-
assert resource3.resource_type_and_id is None
|
|
57
|
-
|
|
58
|
-
def test_equality(self) -> None:
|
|
59
|
-
"""Test equality comparison between FhirResource instances."""
|
|
60
|
-
# Scenario 1: Equal resources
|
|
61
|
-
resource1 = FhirResource(
|
|
62
|
-
initial_dict={"resourceType": "Patient", "id": "123"},
|
|
63
|
-
storage_mode=CompressedDictStorageMode(),
|
|
64
|
-
)
|
|
65
|
-
resource2 = FhirResource(
|
|
66
|
-
initial_dict={"resourceType": "Patient", "id": "123"},
|
|
67
|
-
storage_mode=CompressedDictStorageMode(),
|
|
68
|
-
)
|
|
69
|
-
assert resource1 == resource2
|
|
70
|
-
|
|
71
|
-
# Scenario 2: Different resource types
|
|
72
|
-
resource3 = FhirResource(
|
|
73
|
-
initial_dict={"resourceType": "Observation", "id": "123"},
|
|
74
|
-
storage_mode=CompressedDictStorageMode(),
|
|
75
|
-
)
|
|
76
|
-
assert resource1 != resource3
|
|
77
|
-
|
|
78
|
-
# Scenario 3: Different ids
|
|
79
|
-
resource4 = FhirResource(
|
|
80
|
-
initial_dict={"resourceType": "Patient", "id": "456"},
|
|
81
|
-
storage_mode=CompressedDictStorageMode(),
|
|
82
|
-
)
|
|
83
|
-
assert resource1 != resource4
|
|
84
|
-
|
|
85
|
-
# Scenario 4: Comparing with non-FhirResource
|
|
86
|
-
assert resource1 != "Not a FhirResource"
|
|
87
|
-
|
|
88
|
-
def test_to_json(self) -> None:
|
|
89
|
-
"""Test JSON serialization of FhirResource."""
|
|
90
|
-
initial_data: Dict[str, Any] = {
|
|
91
|
-
"resourceType": "Patient",
|
|
92
|
-
"id": "123",
|
|
93
|
-
"name": [{"given": ["John"]}],
|
|
94
|
-
}
|
|
95
|
-
resource = FhirResource(
|
|
96
|
-
initial_dict=initial_data, storage_mode=CompressedDictStorageMode()
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
json_str = resource.json()
|
|
100
|
-
parsed_json = json.loads(json_str)
|
|
101
|
-
|
|
102
|
-
assert parsed_json == initial_data
|
|
103
|
-
assert "resourceType" in parsed_json
|
|
104
|
-
assert "id" in parsed_json
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
class TestFhirResourceRemoveNulls:
|
|
108
|
-
def test_remove_nulls_simple_dict(self) -> None:
|
|
109
|
-
"""
|
|
110
|
-
Test removing None values from a simple dictionary
|
|
111
|
-
"""
|
|
112
|
-
initial_dict: Dict[str, Any] = {
|
|
113
|
-
"name": "John Doe",
|
|
114
|
-
"age": None,
|
|
115
|
-
"active": True,
|
|
116
|
-
"email": None,
|
|
117
|
-
}
|
|
118
|
-
resource = FhirResource(initial_dict=initial_dict)
|
|
119
|
-
resource.remove_nulls()
|
|
120
|
-
|
|
121
|
-
with resource.transaction():
|
|
122
|
-
# Check that None values are removed
|
|
123
|
-
assert "age" not in resource
|
|
124
|
-
assert "email" not in resource
|
|
125
|
-
assert resource.get("name") == "John Doe"
|
|
126
|
-
assert resource.get("active") is True
|
|
127
|
-
|
|
128
|
-
def test_remove_nulls_nested_dict(self) -> None:
|
|
129
|
-
"""
|
|
130
|
-
Test removing None values from a nested dictionary
|
|
131
|
-
"""
|
|
132
|
-
initial_dict: Dict[str, Any] = {
|
|
133
|
-
"patient": {
|
|
134
|
-
"name": "Jane Smith",
|
|
135
|
-
"contact": None,
|
|
136
|
-
"address": {"street": None, "city": "New York"},
|
|
137
|
-
},
|
|
138
|
-
"status": None,
|
|
139
|
-
}
|
|
140
|
-
resource = FhirResource(initial_dict=initial_dict)
|
|
141
|
-
resource.remove_nulls()
|
|
142
|
-
|
|
143
|
-
with resource.transaction():
|
|
144
|
-
assert "status" not in resource
|
|
145
|
-
assert "contact" not in resource.get("patient", {})
|
|
146
|
-
assert resource.get("patient", {}).get("address", {}).get("street") is None
|
|
147
|
-
assert (
|
|
148
|
-
resource.get("patient", {}).get("address", {}).get("city") == "New York"
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
def test_remove_nulls_list_of_dicts(self) -> None:
|
|
152
|
-
"""
|
|
153
|
-
Test removing None values from a list of dictionaries
|
|
154
|
-
"""
|
|
155
|
-
initial_dict: Dict[str, Any] = {
|
|
156
|
-
"patients": [
|
|
157
|
-
{"name": "Alice", "age": None},
|
|
158
|
-
{"name": "Bob", "age": 30},
|
|
159
|
-
{"name": None, "active": False},
|
|
160
|
-
]
|
|
161
|
-
}
|
|
162
|
-
resource = FhirResource(initial_dict=initial_dict)
|
|
163
|
-
resource.remove_nulls()
|
|
164
|
-
|
|
165
|
-
with resource.transaction():
|
|
166
|
-
assert len(resource.get("patients", [])) == 3
|
|
167
|
-
assert resource.get("patients", [])[0].get("name") == "Alice"
|
|
168
|
-
assert resource.get("patients", [])[1].get("name") == "Bob"
|
|
169
|
-
assert resource.get("patients", [])[1].get("age") == 30
|
|
170
|
-
|
|
171
|
-
def test_remove_nulls_empty_dict(self) -> None:
|
|
172
|
-
"""
|
|
173
|
-
Test removing None values from an empty dictionary
|
|
174
|
-
"""
|
|
175
|
-
resource = FhirResource(initial_dict={})
|
|
176
|
-
resource.remove_nulls()
|
|
177
|
-
|
|
178
|
-
assert len(resource) == 0
|
|
179
|
-
|
|
180
|
-
def test_remove_nulls_no_changes(self) -> None:
|
|
181
|
-
"""
|
|
182
|
-
Test removing None values when no None values exist
|
|
183
|
-
"""
|
|
184
|
-
initial_dict: Dict[str, Any] = {
|
|
185
|
-
"name": "Test User",
|
|
186
|
-
"active": True,
|
|
187
|
-
"score": 100,
|
|
188
|
-
}
|
|
189
|
-
resource = FhirResource(initial_dict=initial_dict)
|
|
190
|
-
original_dict = resource.copy()
|
|
191
|
-
resource.remove_nulls()
|
|
192
|
-
|
|
193
|
-
assert resource == original_dict
|
|
194
|
-
|
|
195
|
-
def test_remove_nulls_with_custom_storage_mode(self) -> None:
|
|
196
|
-
"""
|
|
197
|
-
Test removing None values with a custom storage mode
|
|
198
|
-
"""
|
|
199
|
-
initial_dict: Dict[str, Any] = {
|
|
200
|
-
"name": "Custom Mode User",
|
|
201
|
-
"email": None,
|
|
202
|
-
"active": True,
|
|
203
|
-
}
|
|
204
|
-
resource = FhirResource(
|
|
205
|
-
initial_dict=initial_dict, storage_mode=CompressedDictStorageMode.default()
|
|
206
|
-
)
|
|
207
|
-
resource.remove_nulls()
|
|
208
|
-
|
|
209
|
-
with resource.transaction():
|
|
210
|
-
assert "email" not in resource
|
|
211
|
-
assert resource.get("name") == "Custom Mode User"
|
|
212
|
-
assert resource.get("active") is True
|
|
213
|
-
|
|
214
|
-
def test_remove_nulls_preserves_false_and_zero_values(self) -> None:
|
|
215
|
-
"""
|
|
216
|
-
Test that False and 0 values are not removed
|
|
217
|
-
"""
|
|
218
|
-
initial_dict: Dict[str, Any] = {"active": False, "score": 0, "name": None}
|
|
219
|
-
resource = FhirResource(initial_dict=initial_dict)
|
|
220
|
-
resource.remove_nulls()
|
|
221
|
-
|
|
222
|
-
with resource.transaction():
|
|
223
|
-
assert resource.get("active") is False
|
|
224
|
-
assert resource.get("score") == 0
|
|
225
|
-
assert "name" not in resource
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_bundle_entry_request.py
RENAMED
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_bundle_entry_response.py
RENAMED
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/fhir_bundle_entry_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_bundle_entry_list.py
RENAMED
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_bundle_entry_request.py
RENAMED
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_bundle_entry_response.py
RENAMED
|
File without changes
|
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_fhir_resource_list.py
RENAMED
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/fhir/test/test_fhir_resource_map.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/compressed_dict/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/json_serializers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/string_compressor/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{compressedfhir-1.0.4 → compressedfhir-1.0.5}/compressedfhir/utilities/test/test_json_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|