Web-API (nativ)

DeepGreen bietet eine (rudimentäre) REST-Schnittstelle an. Die aktuelle Version der DeepGreen REST API ist v1. Diese kann über die Web-Adresse https://www.oa-deepgreen.de/api/v1 angesprochen werden, z.B. mit dem Kommando curl in einer Shell (bash, tcsh, etc.):

$ curl -s [-X GET|POST|PUT|HEADER] https://www.oa-deepgreen.de/api/v1/...

Dabei werden in den nun nachfolgende Beispielen die ... ersetzt durch die konkreten REST-Resourcen validate, notification und routed der Web-API-Schnittstelle. Eine weitere, für die GUI-lose Bedienung von Repositorienkonten gedachte REST-Resource ist durch den Endpunkt config gegeben. Diese Resource ist insbesondere für Repositorienbetreiber, die eigene Skripte zur Verwaltung ihrer Konten entwickeln möchten. Sie ist hier der Vollständigkeit halber mit aufgeführt.

Im Folgenden soll der Übersichtlichkeit halber GET, POST, usw. für die gesamte, wie oben angegebene curl-Zeile geschrieben werden. Hier ein kleiner Überblick der möglichen Aufrufe in dieser Kurzform:

  • Aufruf : POST /validate

    Angabe von Metadaten durch „Incoming Notification JSON“ (internes DeepGreen-Format)
    POST /validate?api_key=<api_key>
    Content-Type: application/json
    
    [Incoming Notification JSON]
    
  • Aufruf : POST /notification

    http-POST: Bündelung durch „Content-Type: multipart/form-data; ...
    POST /notification?api_key=<api_key>
    Content-Type: multipart/form-data; boundary=FulltextBoundary
    
    --FulltextBoundary
    
    Content-Disposition: form-data; name="metadata"
    Content-Type: application/json
    
    [Incoming Notification JSON]
    
    --FulltextBoundary
    
    Content-Disposition: form-data; name="content"
    Content-Type: application/zip
    
    [Package]
    
    --FulltextBoundary--
    
  • Aufruf : GET /routed

    1. Liste aller erfolgreich zugestellten Notifikationen
      GET /routed[?<params>]
      
    2. Liste der zugestellten Notifikationen einer Einrichtung
      GET /routed/<repo_id>[?<params>]
      
  • Aufruf : GET /notification

    Eine bestimmte Notification, geliefert im Format „Outgoing Notification JSON“ (internes DeepGreen-Format)
    GET /notification/<notification_id>
    

Daneben gibt es, wie eingangs schon erwähnt, einen weiteren Aufruf ausschließlich für Repositorienbetreiber gedacht:

  • Aufruf: POST /config

    Eine neue „match-config“-Datei für das eigene Konto installieren (JSON-Format)
    POST /config?api_key=<api_key>
    Content-Type: application/json; charset=utf-8
    
    [New (overwriting!) match config settings JSON]
    
  • Aufruf: GET /config

    Die aktuellen „match-config“-Setzungen des eigenen Kontos abfragen (JSON-Format)
    GET /config?api_key=<api_key>
    

All diese Aufrufmöglichkeiten der Web-API sollen nun im Folgenden näher erläutert werden.

Artikeldaten an DeepGreen liefern

Vor der Übertragung eines Datenpakets einer Publikation zu DeepGreen kann das Paket von der Datendrehscheibe überprüft werden. Es sind also zwei REST-Resourcen des Web-APIs verfügbar,

  1. Validierung eines Datenpakets (validation),

  2. Übertragung eines Datenpakets (notification).

Für ganz ungeduldige Leser hier zwei (funktionierende!) bash-Beispielskripte, die zip-Pakete mit einem api_key an DeepGreen liefert bzw. validiert. Die Skripte analysieren zunächst jeweils die angegeben zip-Datei, welches Metadatenschema im Datenpaket vorliegt. Momentan werden von DeepGreen drei Schemata verarbeitet, DTD JATS, DTD Journal (dies ist eine Variante des DTD JATS-Schema) und DTD RSC.

bash-Skript zur Validierung
#! /usr/bin/env bash

host_url="https://www.oa-deepgreen.de"

if [ $# -ge 2 ]; then
  api_key=$1
  zip_file=$2
else
  echo "usage: `basename $0` {api-key} {zip-file}"
  exit -1
fi

curl=`which curl`
zipgrep=`which zipgrep`
wc=`which wc`

pkg_fmt="https://datahub.deepgreen.org/FilesAndJATS"
has_xml=`${zipgrep} "DOCTYPE article" ${zip_file} | ${wc} -l`

if [ ${has_xml} -eq 1 ]; then
  is_jrnl=`${zipgrep} "//NLM//DTD Journal " ${zip_file} | ${wc} -l`
  is_jats=`${zipgrep} "//NLM//DTD JATS " ${zip_file} | ${wc} -l`
  is_rsc=`${zipgrep} "//RSC//DTD RSC " ${zip_file} | ${wc} -l`
  if [ ${is_jrnl} -eq 1 ]; then
    pkg_fmt="https://datahub.deepgreen.org/FilesAndJATS"
  elif [ ${is_jats} -eq 1 ]; then
    pkg_fmt="https://datahub.deepgreen.org/FilesAndJATS"
  elif [ ${is_rsc} -eq 1 ]; then
    pkg_fmt="https://datahub.deepgreen.org/FilesAndRSC"
  else
    echo "error: no valid .xml (JATS or RSC) in zip archive found: stop."
    exit -2
  fi
else
  echo "error: no valid (or too many?!) .xml (JATS xor RSC) in zip archive found: stop."
  exit -3
fi

echo "`basename $0`: packaging format in zip archive found:"
echo "`basename $0`: ${pkg_fmt}"

${curl} -i -k -s -XPOST "${host_url}/api/v1/validate?api_key=${api_key}" -F "content=@${zip_file};type=application/zip" -F "metadata=@-;type=application/json" <<EOF
{
  "content" : {
     "packaging_format" : "${pkg_fmt}"
  }
}
EOF

echo
bash-Skript zur Datenpaketübertragung
#! /usr/bin/env bash

host_url="https://www.oa-deepgreen.de"

if [ $# -ge 2 ]; then
  api_key=$1
  zip_file=$2
else
  echo "usage: `basename $0` {api-key} {zip-file}"
  exit -1
fi

curl=`which curl`
zipgrep=`which zipgrep`
wc=`which wc`

pkg_fmt="https://datahub.deepgreen.org/FilesAndJATS"
has_xml=`${zipgrep} "DOCTYPE article" ${zip_file} | ${wc} -l`

if [ ${has_xml} -eq 1 ]; then
  is_jrnl=`${zipgrep} "//NLM//DTD Journal " ${zip_file} | ${wc} -l`
  is_jats=`${zipgrep} "//NLM//DTD JATS " ${zip_file} | ${wc} -l`
  is_rsc=`${zipgrep} "//RSC//DTD RSC " ${zip_file} | ${wc} -l`
  if [ ${is_jrnl} -eq 1 ]; then
    pkg_fmt="https://datahub.deepgreen.org/FilesAndJATS"
  elif [ ${is_jats} -eq 1 ]; then
    pkg_fmt="https://datahub.deepgreen.org/FilesAndJATS"
  elif [ ${is_rsc} -eq 1 ]; then
    pkg_fmt="https://datahub.deepgreen.org/FilesAndRSC"
  else
    echo "error: no valid .xml (JATS or RSC) in zip archive found: stop."
    exit -2
  fi
else
  echo "error: no valid (or too many?!) .xml (JATS xor RSC) in zip archive found: stop."
  exit -3
fi

echo "`basename $0`: packaging format in zip archive found:"
echo "`basename $0`: ${pkg_fmt}"

${curl} -i -k -s -XPOST "${host_url}/api/v1/notification?api_key=${api_key}" -F "content=@${zip_file};type=application/zip" -F "metadata=@-;type=application/json" <<EOF
{
    "content" : {
        "packaging_format" : "${pkg_fmt}"
    }
}
EOF

echo

Es können somit unterschiedliche Rückgabeantworten von DeepGreen erscheinen, je nachdem, ob eine Verifikation oder eine tatsächliche Datenablieferung vorgenommen wird. Der Einfachheit halber werden hier die beiden Funktionen auch nur mit den für sie typischen Anwendungsfälle dokumentiert. Selbstverständlich ist es auch möglich, ein komplettes Datenpaket mit Metadaten samt Volltext(e) validieren zu lassen, ebenso nur Metadaten abzuliefern. Zu beachten bleibt dabei, dass jeweils immer nur ein Artikel (!) pro Datenpaket verwendet wird. Nun die Erklärung der Rückgabewerte im Einzelnen:

Rückgabewerte bei validation (hier am Beispiel: Nur Metadaten abliefern)

Für die Verifikation einer Datenlieferung macht es durchaus Sinn, nur die Metadaten der Lieferung zu schicken. Dazu wird das json-Format „Incoming Notification JSON“ zur Beschreibung der zu überprüfenden Metadaten verwendet. Mit Binärdaten gebündelte Lieferungen können natürlich ebenso geprüft werden. Dies funktioniert genau wie im Beispiel notification unten angegeben.

Angabe von Metadaten durch „Incoming Notification JSON“ (internes DeepGreen-Format)
POST /validate?api_key=<api_key>
Content-Type: application/json

[Incoming Notification JSON]
  • http-Header Rückgabewerte

    Code

    Beschreibung

    204 No Content

    Datenpaket ok!

    400 Bad Request

    HTTP 1.1  400 Bad Request
    Content-Type: application/json
    
    {
      "error" : "<verständliche(!) Fehlermeldung (auf englisch)>"
    }
    

    401 Unauthorised

    z.B. ungültiger api_key, falsche Benutzertyp

Soweit die Dokumentation der http-Rückgabewerte der Funktion validation. Nun folgt die Beschreibung der Rückgabewerte bei der Verwendung der Funktion notification.

Rückgabewerte bei notification (am Beispiel: Metadaten samt Volltext(e) abliefern)

Artikellieferungen, die binären Inhalt enthalten sollen (z.B. der Volltext als pdf), werden durch die Kennzeichnung „multipart/form-data“ im http-Header gebündelt. Dabei muss im json des Metadatenteil („Incoming Notifikation JSON“) das Feld content.packaging_format zwingend vorhanden sein.

http-POST: Bündelung durch „Content-Type: multipart/form-data; ...
POST /notification?api_key=<api_key>
Content-Type: multipart/form-data; boundary=FulltextBoundary

--FulltextBoundary

Content-Disposition: form-data; name="metadata"
Content-Type: application/json

[Incoming Notification JSON]

--FulltextBoundary

Content-Disposition: form-data; name="content"
Content-Type: application/zip

[Package]

--FulltextBoundary--
Minimale Angabe der Metadaten durch „packaging_format
POST /notification?api_key=<api_key>
Content-Type: multipart/form-data; boundary=FulltextBoundary

--FulltextBoundary

Content-Disposition: form-data; name="metadata"
Content-Type: application/json

{
    "content" : {
        "packaging_format" : "https://datahub.deepgreen.org/FilesAndJATS"
    }
}

--FulltextBoundary

Content-Disposition: form-data; name="content"
Content-Type: application/zip

[Package]

--FulltextBoundary--
  • http-Header Rückgabewerte

    Code

    Beschreibung

    202 Accepted

    HTTP 1.1  202 Accepted
    Content-Type: application/json
    Location: <URL des api-Endpunkts der akzeptierten Lieferung>
    
    {
      "status" : "accepted",
      "id" : "<eindeutige ID dieser neuen Notifikation>",
      "location" : "<URL des api-Endpunkts dieser Notifikation>"
    }
    

    400 Bad Request

    HTTP 1.1  400 Bad Request
    Content-Type: application/json
    
    {
      "error" : "<verständliche(!) Fehlermeldung (auf englisch)>"
    }
    

    401 Unauthorised

    z.B. ungültiger api_key, falscher Benutzertyp

Artikeldaten von DeepGreen erhalten

Naturgemäß gibt es mehrere Optionen, die Datensammlungen von DeepGreen abzufragen und zu listen. Diese verschiedenen Möglichkeiten werden durch unterschiedliche Aufrufe, aber auch durch bestimmte Parameter festgelegt und gesteuert. Als Parameter für die http-Adressen sind vorgesehen:

Mögliche Parameter bei GET-Funktionen von DeepGreen
GET <http-Adresse/...>?since=<YYYY-MM-DD>
#
# Angabe erforderlich; bestimmt, von wann ab die Notifikationen gelistet werden
#

GET <http-Adresse/...>?pageSize=<number>
#
# Angabe optional, voreingestellt auf 25, maximal 100; bestimmt, wieviele Datensätze auf einmal ausgegeben werden
#

GET <http-Adresse/...>?page=<number>
#
# Angabe optional, voreingestellt auf 1; bestimmt, welche Seite der Resultate ausgegeben wird
#

GET <http-Adresse/...>?api_key=<api_key>
#
# Angabe optional; mit der Angabe wird die Anfrage authentifiziert (z.B. für den Bezug von Volltexten)
#

Mehrere Parameterangaben hintereinander können mit dem &-Zeichen verbunden werden.

Die Notifikationlisten der zugestellten Artikel, die von DeepGreen innerhalb eines gewissen Zeitfensters (typischerweise drei Monate) bereitgestellt werden, sind JSON-Listen des DeepGreen-spezifischen Schemas „Outgoing Notification“.

Volles JSON-Schema für Outgoing Notification (alphabetisch sortiert nach den Schlüsseln)

{
  "analysis_date": "2016-08-09T14:22:11Z",
  "content": {
    "packaging_format": "string"
  },
  "created_date": "2016-08-09T14:22:11Z",
  "embargo": {
    "duration": 0
  },
  "id": "string",
  "issn_data": "string",
  "links": [
    {
      "format": "string",
      "packaging": "string",
      "type": "string",
      "url": "string"
    }
  ],
  "metadata": {
    "author": [
      {
        "affiliation": "string",
        "firstname": "string",
        "identifier": [
          {
            "id": "string",
            "type": "string"
          }
        ],
        "lastname": "string",
        "name": "string"
      }
    ],
    "date_accepted": "2016-08-09T14:22:11Z",
    "date_submitted": "2016-08-09T14:22:11Z",
    "fpage", "string",
    "identifier": [
      {
        "id": "string",
        "type": "string"
      }
    ],
    "issue", "string",
    "journal", "string",
    "license_ref": {
      "title": "string",
      "type": "string",
      "url": "string",
      "version": "string"
    },
    "lpage", "string",
    "project": [
      {
        "grant_number": "string",
        "identifier": [
          {
            "id": "string",
            "type": "string"
          }
        ],
        "name": "string"
      }
    ],
    "publication_date": "2016-08-09T14:22:11Z",
    "publisher": "string",
    "source": {
      "identifier": [
        {
          "id": "string",
          "type": "string"
        }
      ],
      "name": "string"
    },
    "subject": [
      "string"
    ],
    "title": "string",
    "volume": "string"
  }
}

Die folgende Tabelle gibt eine prägnante Beschreibung für alle im Schema genannten Felder. Sämtliche Felder sind optional; und es sei der Hinweis gestattet, dass weder das Schema noch die Feldbeschreibungen in der Tabelle unter Umständen vollständig sind. Es können in einer weiteren Version von DeepGreen durchaus weitere Felder hinzutreten oder einzelne Felder gelöscht werden.

  • Feldbeschreibung für ausgehende Benachrichtungen (in alphabetischer Reihenfolge)

    Feldbezeichner

    Beschreibung

    analysis_date

    Zeitpunkt der Zustellanalyse

    content.packaging_format

    Format der zugehörigen Binärpakets (meist .zip)

    created_date

    Zeitpunkt, wann die Notifikation angelegt wurde

    embargo.duration

    Sperrzeit (Embargo; angegeben in Monaten)

    id

    Persistenter System-ID für diese Notifikation

    links.format

    MIME-Typ der Quelle

    links.packaging

    Paketformat der Quelle

    links.type

    Schlagwort für den Typ der Quelle (z.B. package)

    links.url

    URL für die Quelle (verlags- oder systemseitig)

    metadata.author.affiliation

    Affiliationsangabe, ermittelt aus den Metadaten

    metadata.author.firstname

    Vorname eines Autors/Urhebers

    metadata.author.lastname

    Nachname eines Autors/Urhebers

    metadata.author.name

    Zusammengesetzter Name eines Autors/Urhebers

    metadata.date_accepted

    Datum, wann die Publikation akzeptiert wurde

    metadata.date_submitted

    Datum, wann die Publikation eingereicht wurde

    metadata.fpage

    Erste Seitenzahl der Publikation

    metadata.identifier.id

    ID für die Publikation (z.B. DOI)

    metadata.identifier.type

    ID-Typ (z.B. „doi“; allerdings kein Vokabular)

    metadata.issue

    Heftzählung (Journalheft)

    metadata.journal

    Name des Journals der Publikation (Journaltitel)

    metadata.license_ref.title

    Name einer Lizenz (Freifeldtext)

    metadata.license_ref.type

    Lizenz-Typ (Freifeldtext)

    metadata.license_ref.url

    URL, die zu weiteren Lizenzinformationen führt

    metadata.license_ref.version

    Version einer Lizenz

    metadata.lpage

    Letzte Seitenzahl der Publikation

    metadata.project.grant_number

    Förderkürzel, sofern in den Metadaten angeführt

    metadata.project.identifier.id

    ID einer Förderung (z.B. Ringold)

    metadata.project.identifier.type

    ID-Typ in Bezug auf die Förder-ID

    metadata.project.name

    Name eines Förders / einer Förderinstitution

    metadata.publication_date

    Publikationsdatum

    metadata.publisher

    Verlagsname bzw. Verlag

    metadata.source.identifier.id

    ID der Veröffentlichungsquelle (z.B. ISSN)

    metadata.source.identifier.type

    ID-Typ der Veröffentlichungsquelle

    metadata.source.name

    Name der Veröffentlichungsquelle (Journaltitel)

    metadata.subject

    Schlagwort

    metadata.title

    Titel der Veröffentlichung

    metadata.volume

    Bandzählung (Journalband)

Liste aller erfolgreich zugestellten Artikel

Liste aller erfolgreich zugestellten Notifikationen
GET /routed?since=<YYYY-MM-DD>[&<other params>]
  • http-Header Rückgabewerte

    Code

    Beschreibung

    200 OK

    HTTP 1.1  200 OK
    Content-Type: application/json
    
    {
      "since" : "<Datumsangabe der Form YYYY-MM-DDThh:mm:ssZ>",
      "page" : "<Seitenzahl dieser Trefferausgabe>",
      "pageSize" : "<Anzahl der Trefferausgabe pro Seite>",
      "timestamp" : "<Zeitstempel der Anfrage>",
      "total" : "<Anzahl der Treffer zu dieser Zeit>",
      "notifications" : [
         "<Liste der 'Outgoing Notification'-JSON-Objekte>"
      ]
    }
    

    400 Bad Request

    HTTP 1.1  400 Bad Request
    Content-Type: application/json
    
    {
      "error" : "<verständliche(!) Fehlermeldung (auf englisch)>"
    }
    

Liste der einer Einrichtung zugestellten Artikel

Liste der zugestellten Notifikationen einer Einrichtung
GET /routed/<repo_id>?since=<YYYY-MM-DD>[&<other params>]
  • http-Header Rückgabewerte

    Code

    Beschreibung

    200 OK

    HTTP 1.1  200 OK
    Content-Type: application/json
    
    {
      "since" : "<Datumsangabe der Form YYYY-MM-DDThh:mm:ssZ>",
      "page" : "<Seitenzahl dieser Trefferausgabe>",
      "pageSize" : "<Anzahl der Trefferausgabe pro Seite>",
      "timestamp" : "<Zeitstempel der Anfrage>",
      "total" : "<Anzahl der Treffer zu dieser Zeit>",
      "notifications" : [
         "<Liste der 'Outgoing Notification'-JSON-Objekte>"
      ]
    }
    

    400 Bad Request

    HTTP 1.1  400 Bad Request
    Content-Type: application/json
    
    {
      "error" : "<verständliche(!) Fehlermeldung (auf englisch)>"
    }
    

Abfrage eines bestimmten Artikels

Jede Notifikation zu einem Artikel, der von DeepGreen erfolgreich zugestellt werden konnte, ist mit einer eindeutigen ID, der sogenannten Notifikations-ID, gekennzeichnet. Diese ID ist in den Ausgabelisten der vorherigen Abfragen zu finden. Mit der folgenden Anfarge erhält man den individuellen JSON Datensatz einer bestimmten Notifikations-ID.

Abfrage einer bestimmten Notifikation, geliefert im Format „Outgoing Notification JSON“ (internes DeepGreen-Format)
GET /notification/<notification_id>
  • http-Header Rückgabewerte

    Code

    Beschreibung

    200 OK

    HTTP 1.1  200 OK
    Content-Type: application/json
    
    [Outgoing Notification JSON]
    

    404 Not Found

    z.B. die notification_id existiert nicht, oder die Notifikation konnte (noch) nicht zugestellt werden und man ist nicht der Verfasser (d.h. Verlag) der Notifikation (authentifiziert via api_key)

Abruf der Binärdaten einer Notifikation

Über ein spezielles links-Feld im Outgoing Notification JSON, wenn es gesetzt ist, kann dann der entsprechende Volltext bezogen werden, sofern man dazu berechtigt ist. Angenommen, die Notifikation enthielte den JSON-Abschnitt

"links" : [
   {
     "type" : "package",
     "format" : "application/zip",
     "url" : "https://www.oa-deepgreen.de/api/v1/notification/123456789/content",
     "packaging" : "https://datahub.deepgreen.org/FilesAndJATS"
   },
   {
     "type" : "package",
     "format" : "application/zip",
     "url" : "https://www.oa-deepgreen.de/api/v1/notification/123456789/content/SimpleZip",
     "packaging" : "http://purl.org/net/sword/package/SimpleZip"
   }
 ]

dann lautete der Abruf des Volltextes wie folgt:

Abfrage der Binärdaten eines Datenpakets, i.d.R. eine .zip-Datei mit dem/den Volltext(en)
GET <links url>?api_key=<api_key>
  • http-Header Rückgabewerte

    Code

    Beschreibung

    200 OK

    HTTP 1.1  200 OK
    Content-Type: application/zip
    
    [(binäres) Paket]
    

    401 Unauthorised

    z.B. ungültiger api_key, falsche Benutzertyp oder die entsprechende Notifikation wurde (noch) nicht zugestellt

    404 Not Found

    unter der angegebenen URL gibt es keinen Inhalt bzw. die URL ist schlicht nicht existent

Abfrage und Update der match-config-Setzungen bei Repositorien

Zur Abfrage der aktuellen Affiliations- und weiteren Treffer-Einstellungen eines Repositorienkontos benötigt man natürlich einen gültigen api_key:

Abfrage der aktuellen matching-Kriterien
GET /config?api_key=<api_key>
  • http-Header Rückgabewerte

    Code

    Beschreibung

    200 OK

    HTTP 1.1  200 OK
    Content-Type: application/json
    
    [matching Kriterien JSON]
    

    401 Unauthorised

    z.B. ungültiger api_key

    404 Not Found

    unter der angegebenen URL gibt es keinen Inhalt bzw. die URL ist schlicht nicht existent (z.B. durch GET /config/)

Update der matching-Kriterien eines Repositorienkontos

Um neue Affiliations- und Treffer-Angaben für ein Repositorium in das zugehörige Konto laden zu können, benötigt man (wie gewohnt) einen gültigen api_key:

Überschreiben der matching-Kriterien mit neuen Werten
POST /config?api_key=<api_key>
Content-Type: application/json; charset=utf-8

[Overwriting new match config settings JSON]
  • http-Header Rückgabewerte

    Code

    Beschreibung

    200 OK

    HTTP 1.1  200 OK
    Content-Length: 0
    

    401 Unauthorised

    z.B. ungültiger api_key

    400 Bad Request

    Im JSON-Format, das hochgeladen wurde, ist ein Syntax-Fehler festgestellt worden (z.B. ein fehlendes Komma in Aufzählungen)

Beispielhafte, korrekte match-config-Datei im internen JSON-Format

{
  "name_variants": [
    "Academia Fridericiana Erlangensis",
    "Academia Friderico Alexandrina Erlangen-Nürnberg",
    "Academia Friderico-Alexandrina",
    "Academia Regia Bavarica Friderico-Alexandrina",
    "Academia Regia Friderico-Alexandrina",
    "Bayerische Friedrich-Alexanders-Universität",
    "F.A.U. Erlangen-Nürnberg",
    "University of Erlangen"
  ],
  "grants": [
    "2491691", "2673762", "6273863"
  ],
  "domains": [
    "fau.de", "uk-erlangen.de", "uni-erlangen.de"
  ],
  "keywords": [
    "research", "bavarian", "erlangen"
  ]
}