diff --git a/dspace_rest_client/client.py b/dspace_rest_client/client.py index 3f8a643..8e91cd4 100644 --- a/dspace_rest_client/client.py +++ b/dspace_rest_client/client.py @@ -34,6 +34,8 @@ Community, Collection, Item, + Version, + WorkspaceItem, Bundle, Bitstream, User, @@ -1294,7 +1296,7 @@ def create_item_version(self, item_uuid, summary=None, embeds=None): if response.status_code == 201: # 201 Created - Success - new_version = parse_json(response) + new_version = Version(api_resource=parse_json(response)) logging.info("Created new version for item %s", item_uuid) return new_version else: @@ -1485,6 +1487,26 @@ def create_group(self, group, embeds=None): ) ) + def get_workspace_item(self, id=None, item_uuid=None): + """ + Get workspace item for a given integer ID + or by passing the wrapped DSpace Item UUID (useful if you have + an item reference from e.g. a new version, but not the workspace + item ID) + """ + params = {} + url = None + if isinstance(id, int): + url = f"{self.API_ENDPOINT}/submission/workspaceitems/{id}" + elif item_uuid is not None: + url = f"{self.API_ENDPOINT}/submission/workspaceitems/search/item" + params = {"uuid": item_uuid} + + res = parse_json(self.api_get(url, params=params)) + if res is not None: + # TODO: WorkspaceItem is just a stub right now + return WorkspaceItem(res) + def start_workflow(self, workspace_item): """ Start workflow for a given workspace item (provided in url-list body) @@ -1493,6 +1515,7 @@ def start_workflow(self, workspace_item): """ url = f"{self.API_ENDPOINT}/workflow/workflowitems" res = parse_json(self.api_post_uri(url, params=None, uri_list=workspace_item)) + return res def update_token(self, r): """ diff --git a/dspace_rest_client/models.py b/dspace_rest_client/models.py index 7674d79..725831a 100644 --- a/dspace_rest_client/models.py +++ b/dspace_rest_client/models.py @@ -13,7 +13,7 @@ from typing import Any __all__ = ['DSpaceObject', 'HALResource', 'ExternalDataObject', 'SimpleDSpaceObject', 'Community', - 'Collection', 'Item', 'Bundle', 'Bitstream', 'BitstreamFormat', 'User', 'Group', + 'Collection', 'Item', 'Version', 'Bundle', 'Bitstream', 'BitstreamFormat', 'User', 'Group', 'WorkspaceItem', 'InProgressSubmission', 'SearchResult', 'EntityType', 'ResourcePolicy'] @@ -428,6 +428,40 @@ def as_dict(self): } return {**parent_dict, **dict} + +class Version(AddressableHALResource): + """ + Version of a DSpace item + Links include versionhistory, item + """ + type = 'version' + + def __init__(self, api_resource=None): + super().__init__(api_resource) + self.version = None + self.created = None + self.summary = None + self.submitterName = None + + if api_resource is not None: + self.version = api_resource.get('version') + self.created = api_resource.get('created') + self.summary = api_resource.get('summary') + self.submitterName = api_resource.get('submitterName') + + def as_dict(self): + """ + Return a dict representation of this Group, based on super with group-specific attributes added + @return: dict of Group for API use + """ + parent_dict = super().as_dict() + this_dict = {'version': self.version, + 'created': self.created, + 'summary': self.summary, + 'submitterName': self.submitterName} + return {**parent_dict, **this_dict} + + class Group(DSpaceObject): """ Extends DSpaceObject to implement specific attributes and methods for groups (aka. EPersonGroups). diff --git a/example_workflow.py b/example_workflow.py new file mode 100644 index 0000000..ea0a55a --- /dev/null +++ b/example_workflow.py @@ -0,0 +1,83 @@ +# This software is licenced under the BSD 3-Clause licence +# available at https://opensource.org/licenses/BSD-3-Clause +# and described in the LICENCE file in the root of this project + +""" +Example Python 3 application using the dspace.py API client library to retrieve basic DSOs in a +DSpace repository +""" + +import sys + +from dspace_rest_client.client import DSpaceClient +from dspace_rest_client.models import Collection, Item, WorkspaceItem, Version +import pprint + +# Import models as below if needed +# from dspace_rest_client.models import Community, Collection, Item, Bundle, Bitstream + +# Example variables needed for authentication and basic API requests +# SET THESE TO MATCH YOUR TEST SYSTEM BEFORE RUNNING THE EXAMPLE SCRIPT +# You can also leave them out of the constructor and set environment variables instead: +# DSPACE_API_ENDPOINT= +# DSPACE_API_USERNAME= +# DSPACE_API_PASSWORD= +# USER_AGENT= +URL = "http://localhost:8080/server/api" +USERNAME = "" +PASSWORD = "" + +# Instantiate DSpace client +# Note the 'fake_user_agent' setting here -- this will set a string like the following, +# to get by Cloudfront: +# Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) \ +# Chrome/39.0.2171.95 Safari/537.36 +# The default is to *not* fake the user agent, and instead use the default of +# DSpace-Python-REST-Client/x.y.z. +# To specify a custom user agent, set the USER_AGENT env variable and leave/set +# fake_user_agent as False +d = DSpaceClient( + api_endpoint=URL, username=USERNAME, password=PASSWORD, fake_user_agent=True +) + +# Authenticate against the DSpace client +authenticated = d.authenticate() +if not authenticated: + print("Error logging in! Giving up.") + sys.exit(1) + +# Start with an original item UUID, make a new version, get the new item from that, get the workspace item +# for that new item, and start workflow +original_item_uuid = '3449284d-3871-4b7a-913a-c21da13fc43f'; +original_item = d.get_item(original_item_uuid) +new_version = d.create_item_version(original_item_uuid, "test", embeds=['item']) + +#pprint.pprint(new_version) +if isinstance(new_version, Version): + #pprint.pprint(new_version.as_dict()) + #pprint.pprint(new_version.embedded) + new_version_item = Item(api_resource=new_version.embedded['item']) + new_version_workspace_item = d.get_workspace_item(item_uuid=new_version_item.id) + if isinstance(new_version_workspace_item, WorkspaceItem): + workspace_item_uri = new_version_workspace_item.links['self']['href'] + + # Do any extra validation here -- I ran into some testing trouble + # because some of my archived test items happened to be missing fields + # that were required in the submission forms/definition that I sent + # them to... + + # If required, accept the license + res = d.api_patch(url=workspace_item_uri, + operation=d.PatchOperation.ADD, + path="/sections/license/granted", + value=True, + params=None + ) + #pprint.pprint(res) + # Start the workflow. If it has no roles you shoudl get an archived + # item, otherwise you'll have to claim the pooled task and progress + res = d.start_workflow(workspace_item_uri) + pprint.pprint(res) + + +