Skip to content

Commit f00a017

Browse files
committed
Add set_by_path function
1 parent 08fcacc commit f00a017

4 files changed

Lines changed: 59 additions & 2 deletions

File tree

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ You can test this library by interactive FHIR course in the repository [Aidbox/j
4545
- [Validate resource using operation $validate](#validate-resource-using-operation-validate)
4646
- [Accessing resource attributes](#accessing-resource-attributes)
4747
- [get_by_path(path, default=None)](#get_by_pathpath-defaultnone)
48+
- [set_by_path(obj, path, value)](#set_by_pathpath)
4849
- [serialize()](#serialize)
4950
- [Reference](#reference-1)
5051
- [Main class structure](#main-class-structure)
@@ -403,6 +404,18 @@ base_value = invoice.get_by_path([
403404
'amount', 'value'], 0)
404405
```
405406

407+
## set_by_path(obj, path, value)
408+
```python
409+
resource = {
410+
"name": [{"given": ["Firstname"], "family": "Lastname"}],
411+
}
412+
413+
set_by_path(resource, ["name", 0, "given", 0], "FirstnameUpdated")
414+
415+
# resource
416+
# {"name": [{"given": ["FirstnameUpdated"], "family": "Lastname"}]}
417+
```
418+
406419
## serialize()
407420
```Python
408421
# Returns resources as dict

fhirpy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from .lib import SyncFHIRClient, AsyncFHIRClient
22

33
__title__ = "fhir-py"
4-
__version__ = "1.3.1"
4+
__version__ = "1.3.2"
55
__author__ = "beda.software"
66
__license__ = "None"
77
__copyright__ = "Copyright 2022 beda.software"

fhirpy/base/utils.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,5 +202,26 @@ def get_by_path(data, path, default=None):
202202
return default
203203

204204

205+
def set_by_path(obj, path, value):
206+
cursor = obj
207+
last_part = path.pop()
208+
209+
for index, part in enumerate(path):
210+
if isinstance(cursor, dict) and part not in cursor:
211+
nextpart = (path + [last_part])[index + 1]
212+
try:
213+
nnextpart = (path + [last_part])[index + 2]
214+
except IndexError:
215+
nnextpart = ""
216+
217+
if isinstance(nextpart, int):
218+
cursor[part] = [[] if isinstance(nnextpart, int) else {}]
219+
else:
220+
cursor[part] = {}
221+
222+
cursor = cursor[part]
223+
cursor[last_part] = value
224+
225+
205226
def remove_prefix(s, prefix):
206227
return s[len(prefix) :] if s.startswith(prefix) else s

tests/test_lib_base.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
22
from fhirpy import SyncFHIRClient, AsyncFHIRClient
33
from fhirpy.lib import BaseFHIRReference
4-
from fhirpy.base.utils import AttrDict, SearchList, parse_pagination_url
4+
from fhirpy.base.utils import AttrDict, SearchList, parse_pagination_url, set_by_path
55

66

77
@pytest.mark.parametrize("client", [SyncFHIRClient("mock"), AsyncFHIRClient("mock")])
@@ -146,6 +146,29 @@ def test_get_by_path(self, client):
146146
assert isinstance(name, AttrDict)
147147
assert name.get_by_path(["given", 0]) == "Firstname"
148148

149+
def test_set_by_path(self, client):
150+
resource = {
151+
"name": [{"given": ["Firstname"], "family": "Lastname"}],
152+
}
153+
154+
resource1 = resource.copy()
155+
set_by_path(resource1, ["name", 0, "given", 0], "FirstnameUpdated")
156+
assert resource1["name"][0]["given"][0] == "FirstnameUpdated"
157+
158+
resource2 = resource.copy()
159+
with pytest.raises(IndexError):
160+
set_by_path(resource2, ["name", 1, "given", 0], "FirstnameUpdated")
161+
162+
resource3 = resource.copy()
163+
set_by_path(resource3, ["name"], None)
164+
assert resource3["name"] == None
165+
166+
resource4 = resource.copy()
167+
set_by_path(resource4, ["name", 0], {"text": "Firstname Lastname"})
168+
assert resource4["name"][0]["text"] == "Firstname Lastname"
169+
with pytest.raises(KeyError):
170+
assert resource4["name"][0]["given"]
171+
149172
def test_set_resource_setdefault(self, client):
150173
resource = client.resource("Patient", id="patient")
151174
resource.setdefault("id", "new_patient")

0 commit comments

Comments
 (0)