Skip to content

Commit 2f99ee1

Browse files
committed
add patch_item function
1 parent a238eb5 commit 2f99ee1

File tree

1 file changed

+90
-8
lines changed

1 file changed

+90
-8
lines changed

dspace_rest_client/client.py

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ def search_objects(
487487
size=20,
488488
sort=None,
489489
dso_type=None,
490-
configuration='default',
490+
configuration="default",
491491
embeds=None,
492492
):
493493
"""
@@ -521,7 +521,7 @@ def search_objects(
521521
if sort is not None:
522522
params["sort"] = sort
523523
if configuration is not None:
524-
params['configuration'] = configuration
524+
params["configuration"] = configuration
525525

526526
r_json = self.fetch_resource(url=url, params={**params, **filters})
527527

@@ -552,7 +552,7 @@ def search_objects_iter(
552552
filters=None,
553553
dso_type=None,
554554
sort=None,
555-
configuration='default',
555+
configuration="default",
556556
embeds=None,
557557
):
558558
"""
@@ -579,7 +579,7 @@ def search_objects_iter(
579579
if sort is not None:
580580
params["sort"] = sort
581581
if configuration is not None:
582-
params['configuration'] = configuration
582+
params["configuration"] = configuration
583583

584584
return do_paginate(url, {**params, **filters})
585585

@@ -1255,6 +1255,86 @@ def update_item(self, item, embeds=None):
12551255
return None
12561256
return self.update_dso(item, params=parse_params(embeds=embeds))
12571257

1258+
def patch_item(
1259+
self,
1260+
item_uuid,
1261+
operation,
1262+
field,
1263+
value=None,
1264+
language=None,
1265+
authority=None,
1266+
confidence=-1,
1267+
place="",
1268+
):
1269+
"""
1270+
Patch item. This method performs a partial update operation (PATCH) on the given Item object.
1271+
Supports operations: 'add', 'remove', 'replace'. Does not support 'move'.
1272+
1273+
@param item: Python Item object containing all the necessary data, identifiers, and links.
1274+
@param operation: Operation to perform ('add', 'remove', 'replace').
1275+
@param path: Path to the field or property to patch.
1276+
@param value: New value for the specified path (required for 'add' and 'replace'). Ignored for 'remove'.
1277+
@return: The API response or None in case of an error.
1278+
"""
1279+
try:
1280+
if not item_uuid:
1281+
logging.error("Item UUID is required")
1282+
return None
1283+
1284+
if not field or not value:
1285+
logging.error("Field and value are required")
1286+
return None
1287+
1288+
if not operation or operation not in [
1289+
self.PatchOperation.ADD,
1290+
self.PatchOperation.REPLACE,
1291+
self.PatchOperation.REMOVE,
1292+
]:
1293+
logging.error("Unsupported operation: %s", operation)
1294+
return None
1295+
1296+
if (
1297+
operation in [self.PatchOperation.ADD, self.PatchOperation.REPLACE]
1298+
and value is None
1299+
):
1300+
logging.error("Value is required for 'add' and 'replace' operations")
1301+
return None
1302+
1303+
# Construct the item URI
1304+
item_uri = f"{self.API_ENDPOINT}/core/items/{item_uuid}"
1305+
1306+
path = f"/metadata/{field}/{place}"
1307+
patch_value = {
1308+
"value": value,
1309+
"language": language,
1310+
"authority": authority,
1311+
"confidence": confidence,
1312+
}
1313+
1314+
# Perform the patch operation
1315+
response = self.api_patch(
1316+
url=item_uri,
1317+
operation=operation,
1318+
path=path,
1319+
value=patch_value,
1320+
)
1321+
1322+
if response.status_code in [200, 204]:
1323+
logging.info("Successfully patched item: %s", item_uuid)
1324+
return response
1325+
else:
1326+
logging.error(
1327+
"Failed to patch item: %s (Status: %s, Response: %s)",
1328+
item_uuid,
1329+
response.status_code,
1330+
response.text,
1331+
)
1332+
return None
1333+
1334+
except ValueError:
1335+
logging.error("Error processing patch operation", exc_info=True)
1336+
return None
1337+
12581338
def add_metadata(
12591339
self,
12601340
dso,
@@ -1468,13 +1548,15 @@ def resolve_identifier_to_dso(self, identifier=None):
14681548
@return: resolved DSpaceObject or error
14691549
"""
14701550
if identifier is not None:
1471-
url = f'{self.API_ENDPOINT}/pid/find'
1472-
r = self.api_get(url, params={'id': identifier})
1551+
url = f"{self.API_ENDPOINT}/pid/find"
1552+
r = self.api_get(url, params={"id": identifier})
14731553
if r.status_code == 200:
14741554
r_json = parse_json(r)
1475-
if r_json is not None and 'uuid' in r_json:
1555+
if r_json is not None and "uuid" in r_json:
14761556
return DSpaceObject(api_resource=r_json)
14771557
elif r.status_code == 404:
14781558
logging.error(f"Not found: {identifier}")
14791559
else:
1480-
logging.error(f"Error resolving identifier {identifier} to DSO: {r.status_code}")
1560+
logging.error(
1561+
f"Error resolving identifier {identifier} to DSO: {r.status_code}"
1562+
)

0 commit comments

Comments
 (0)