Sword API

From Archivematica
Revision as of 21:40, 4 November 2013 by Jhs (talk | contribs) (→‎Overview)
Jump to navigation Jump to search

Overview

One of the 1.1 release features is a sponsored project to integrate Archivematica with Islandora. This integration will be accomplished by creating a Sword 2.0 API. Islandora development work will add functionality to Islandora to use this API to deposit digital objects into Archviematica.

As described elsewhere on this wiki, the primary function of Archivematica is to process digital transfers (accessioned digital objects), turn them into SIPs, apply format policies and create high-quality, repository-independent Archival Information Packages (AIP).

The Archivematica Sword API allows 3rd party applications to automate the process of creating Transfers. The process of creating a Transfer is: 1) Create Transfer - set the name and other metadata about a Transfer 2) Populate Transfer - add/edit/update digital objects in a Transfer, and associated metadata 3) Finalize Transfer - indicates that the Transfer is ready to start processing.

Transfers created through the Dashboard (the Archivematica web based user interface) can be manipulated through this api as well.

Once a Transfer has been created, populated and finalized, Archivematica will begin processing that Transfer.

Endpoints

List existing transfers

  • HTTP Get to the Collection IRI
  • optional filters via get parameters (not yet implemented)

Create a new transfer

  • used to start a new transfer in Archivematica
  • HTTP POST of an Atom Entry Document to the Collection IRI (defined by default as: /api/v2/transfer)

Possible HTTP Response Codes

  • HTTP 200 OK - transfer already exists
  • HTTP 201 Created - tranfer has been accepted
  • HTTP 412 Precondition Failed - required metadata missing or invalid

Valid requests will receive a Sword Deposit Receipt in the body of the response.

Required HTTP Headers

The HTTP POST must include certain specific http headers.

Required by http 1.1 specification:

    • Host: Must be set to archivematica host name.
    • Content-Length: Must be set to the length of the atom entry document.
    • Content-Type: Must be set to "application/atom+xml;type=entry".

Required by Archivematica.

    • Authorization: Must include the api key and username assigned by Archivematica.

Required by SWORD 2.0 protocol:

    • In-Progress: Must be set to "true"

Optional in SWORD 2.0 protocol:

    • On-Behalf-Of: not implemented by Archivematica
    • Slug: not implemented by Archivematica

Required in Body

The Body of the request must be a valid Atom Entry Document. The required fields in an Atom Entry Document are:

    • title: used as the transfer name
    • id: used as an accession id
    • author: used as the source of acquisition
    • summary: not implemented yet. Could be used in the future as a description for the Transfer
    • updated: should be set to the current timestamp.

Example

Example HTTP POST request:

POST /api/v2/transfer HTTP/1.1
Host: localhost
Authorization: Archivematica-API api_key="XXXXXXXXXXXXXXXXXXXX", username="timh"
Content-Length: 213
Content-Type: application/atom+xml;type=entry
In-Progress: true

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom"
    <title>Test Transfer 1</title>
    <id>2013-0001</id>
    <author>John Doe</author>
    <summary></summary>
    <updated>2013-11-04T11:00:00Z</updated>
</entry>

Example Response:

201 Created
Location: http://localhost/api/v2/transfer/1225c695-cfb8-4ebb-aaaa-80da344efa6a

<entry xmlns="http://www.w3.org/2005/Atom"
        xmlns:sword="http://purl.org/net/sword/">
       
    <title>Test Transfer</title>
    <id>2013-0001</id>
    <author>
    <updated>2008-08-18T14:27:08Z</updated>
    <summary type="text">A summary</summary>
    
    <!-- EM-IRI -->
    <link rel="edit-media" href="http://localhost/api/v2/transfer/edit/1225c695-cfb8-4ebb-aaaa-80da344efa6a" />

    <!-- Edit-IRI -->
    <link rel="edit" href="http://localhost/api/v2/transfer/edit/1225c695-cfb8-4ebb-aaaa-80da344efa6a" />

    <!-- SE-IRI -->
    <link rel="http://purl.org/net/sword/terms/add" href="http://localhost/api/v2/transfer/add/1225c695-cfb8-4ebb-aaaa-80da344efa6a" />

    <!-- State-IRI -->
    <link rel="http://purl.org/net/sword/terms/statement"
            type="application/atom+xml;type=feed"
            href="http://localhost/api/v2/transfer/feed/1225c695-cfb8-4ebb-aaaa-80da344efa6a" />
    <link rel="http://purl.org/net/sword/terms/statement"
            type="application/rdf+xml"
            href="http://localhost/api/v2/transfer/rdf/1225c695-cfb8-4ebb-aaaa-80da344efa6a" />
</entry>

Transfer Details

EM-IRI

An HTTP POST to the em-iri for a transfer should include a file as the body (may not be supported in v2, return "not supported" HTTP status)

An HTTP GET should return a list of files in the transfer

An HTTP DELETE to the em-iri will remove all digital objects from the Transfer. This is a valid operation only while the Transfer is being assembled. Once the Transfer has been finalized, attempting to DELETE will return an error.

Edit-IRI

The client can replace the metadata of a resource by performing an HTTP PUT of a new Atom Entry on the Edit-IRI.

This would be used to update metadata about a transfer, such as the transfer name.

SE-IRI

<link rel="http://purl.org/net/sword/terms/add" href="http://localhost/api/v2/transfer/add/1225c695-cfb8-4ebb-aaaa-80da344efa6a" />

State-IRI

Rough notes

Step 1) Add Content

POST a single Fedora Object to Col-IRI

http://localhost/api/v2/transfer/create/

described here: http://swordapp.github.io/SWORDv2-Profile/SWORDProfile.html#protocoloperations_creatingresource_entry

You post will look like the sample below (content in [] should be replaced with appropriate values). Instead of dcterms embedded in the atom entry document, you would embed the fedora mets file for this object.

The <id> tag inside the <entry> should contain the AIP id (generated from user input or based on the collection).

To add additional content to the same AIP, you can either POST another

POST http://localhost/api/v2/transfer/create/ HTTP/1.1
Host: localhost
Authorization: Basic ZGFmZnk6c2VjZXJldA==
Content-Length: [content length]
Content-Type: application/atom+xml;type=entry
In-Progress: true
On-Behalf-Of: [archivematica-user]
Slug: [suggested identifier]

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom"
        xmlns:dcterms="http://purl.org/dc/terms/">
    <title>Title</title>
    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
    <updated>2005-10-07T17:17:08Z</updated>
    <author><name>Contributor</name></author>
    <summary type="text">The abstract</summary>

    <!-- some embedded metadata -->
    <dcterms:abstract>The abstract</dcterms:abstract>
    <dcterms:accessRights>Access Rights</dcterms:accessRights>
    <dcterms:alternative>Alternative Title</dcterms:alternative>
    <dcterms:available>Date Available</dcterms:available>
    <dcterms:bibliographicCitation>Bibliographic Citation</dcterms:bibliographicCitation>
    <dcterms:contributor>Contributor</dcterms:contributor>
    <dcterms:description>Description</dcterms:description>
    <dcterms:hasPart>Has Part</dcterms:hasPart>
    <dcterms:hasVersion>Has Version</dcterms:hasVersion>
    <dcterms:identifier>Identifier</dcterms:identifier>
    <dcterms:isPartOf>Is Part Of</dcterms:isPartOf>
    <dcterms:publisher>Publisher</dcterms:publisher>
    <dcterms:references>References</dcterms:references>
    <dcterms:rightsHolder>Rights Holder</dcterms:rightsHolder>
    <dcterms:source>Source</dcterms:source>
    <dcterms:title>Title</dcterms:title>
    <dcterms:type>Type</dcterms:type>

</entry>

The response back will be in the following form:

201 Created
Location: http://localhost/api/v2/transfer/1225c695-cfb8-4ebb-aaaa-80da344efa6a

<entry xmlns="http://www.w3.org/2005/Atom"
        xmlns:sword="http://purl.org/net/sword/"
        xmlns:dcterms="http://purl.org/dc/terms/">

    <title>My Deposit</title>
    <id>info:something:1</id>
    <updated>2008-08-18T14:27:08Z</updated>
    <summary type="text">A summary</summary>
    <generator uri="http://www.myrepository.ac.uk/sword-plugin" version="1.0"/>

    <!-- the item's metadata -->
    <dcterms:abstract>The abstract</dcterms:abstract>
    <dcterms:accessRights>Access Rights</dcterms:accessRights>
    <dcterms:alternative>Alternative Title</dcterms:alternative>
    <dcterms:available>Date Available</dcterms:available>
    <dcterms:bibliographicCitation>Bibliographic Citation</dcterms:bibliographicCitation>
    <dcterms:contributor>Contributor</dcterms:contributor>
    <dcterms:description>Description</dcterms:description>
    <dcterms:hasPart>Has Part</dcterms:hasPart>
    <dcterms:hasVersion>Has Version</dcterms:hasVersion>
    <dcterms:identifier>Identifier</dcterms:identifier>
    <dcterms:isPartOf>Is Part Of</dcterms:isPartOf>
    <dcterms:publisher>Publisher</dcterms:publisher>
    <dcterms:references>References</dcterms:references>
    <dcterms:rightsHolder>Rights Holder</dcterms:rightsHolder>
    <dcterms:source>Source</dcterms:source>
    <dcterms:title>Title</dcterms:title>
    <dcterms:type>Type</dcterms:type>

    <!-- EM-IRI -->
    <link rel="edit-media" href="http://localhost/api/v2/transfer/edit/1225c695-cfb8-4ebb-aaaa-80da344efa6a/" />
   
    <!-- Edit-IRI -->
    <link rel="edit" href="http://localhost/api/v2/transfer/edit/1225c695-cfb8-4ebb-aaaa-80da344efa6a/" />
   
    <!-- SE-IRI -->
    <link rel="http://purl.org/net/sword/terms/add" href="http://localhost/api/v2/transfer/add/1225c695-cfb8-4ebb-aaaa-80da344efa6a/" />

    <!-- State-IRI -->
    <link rel="http://purl.org/net/sword/terms/statement"
            type="application/atom+xml;type=feed"
            href="http://localhost/api/v2/transfer/feed/1225c695-cfb8-4ebb-aaaa-80da344efa6a/" />
    <link rel="http://purl.org/net/sword/terms/statement"
            type="application/rdf+xml"
            href="http://localhost/api/v2/transfer/rdf/1225c695-cfb8-4ebb-aaaa-80da344efa6a/" />


</entry>

To finalize an AIP

blank HTTP POST to the SE-IRI for the AIP: in this example, the POST would look like:


POST http://localhost/api/v2/transfer/add/1225c695-cfb8-4ebb-aaaa-80da344efa6a/ HTTP/1.1
Host: localhost
Authorization: Basic ZGFmZnk6c2VjZXJldA==
Content-Length: [content length]
Content-Type: application/atom+xml;type=entry
In-Progress: false

response will be HTTP 200/OK or 400/Error


To check Status:

GET the State-IRI in this example:

GET http://localhost/api/v2/transfer/feed/1225c695-cfb8-4ebb-aaaa-80da344efa6a/ HTTP/1.1

response will include:

<sword:state href="http://localhost/api/v2/transfer/feed/1225c695-cfb8-4ebb-aaaa-80da344efa6a/">
    <sword:stateDescription>The item has passed through the workflow and is now archived</sword:stateDescription>
</sword:state>

the list of possible descriptions is not finalized.

Example session

Below is an example session using curl to manipulate the API. In the example a transfer is created, a file is added to it, and it is finalized.

NOTE: While this is in development, change the URL list "mock_object_content_urls" in src/dashboard/src/components/api/view.py to working URL(s).

# create new transfer
curl -v -H "In-Progress: true" -d "some METS XML" --request POST http://localhost/api/v2/transfer/
# response XML includes endpoint for adding addition files, etc.
  
# add another file to the transfer
curl -v -H "Content-Disposition: attachment; filename=horse.jpg" --request POST --data-binary "@horse.jpg" http://localhost/api/v2/transfer/03ce11a5-32c1-445a-83ac-400008894f78/media/
  
# finalize transfer and approve processing
curl -v -H "In-Progress: false" --request POST http://localhost/api/v2/transfer/03ce11a5-32c1-445a-83ac-400008894f78/

You might, at some point, want to list the transfers that have been started. The following curl command will do so.

 # list transfers that have been created by the API
 curl -v http://localhost/api/v2/transfer/

If you're working on a transfer and want to list what files are included in it, the following curl command will list them.

 # list files in transfer
 curl -v http://localhost/api/v2/transfer/03ce11a5-32c1-445a-83ac-400008894f78/media/

If you've started a transfer, but decide not to proceed, you can delete the transfer. The following curl command shows an example.

 curl -v -XDELETE http://localhost/api/v2/transfer/5ac7819a-9ad8-4e59-b9e8-fb0ccf7e167b/03ce11a5-32c1-445a-83ac-400008894f78/