Schlagwort-Archive: Projekt

picserv unterstützt WebID-Login

Meine in Entwicklung befindliche Bilder-Plattform picserv unterstützt nun auch ein WebID-Login.

WebID ist ein aufstrebender Standard, der uns losgelöst von zentralen Netzwerken wie Facebook und Google+ eine Identität im Social Web geben kann. WebID ist gleichzeitig ein Login-Verfahren und euer Profil im Social Web. Ein solches Profil könnt ihr z.B. bei my-profile.eu mit wenigen Klicks einrichten, ihr seid aber nicht von einzelnen Anbietern abhängig. Wer mag kann auch selbst ein Profil hosten.

Wenn ihr euch mit eurer WebID bei picserv einloggt, könnt ihr dort Bilder hochladen und kommentieren. Euer Name und eurer Bild wird aus eurem Profil ausgelesen und muss nicht nochmals bei picserv hinterlegt werden. Das ist das Schöne im dezentralen Social Web: Eure Identität und die Dienste, die ihr mit dieser Identität nutzt können auf völlig unterschiedlichen Servern liegen. Statt monolithischer Social-Network-Plattformen wird das Web zum Social Network. picserv leistet mit dem WebID-Login einen Beitrag zu dieser Entwicklung.

[notice]Bitte beachtet aber, dass sich picserv noch stark in Entwicklung befindet. Verlasst euch nicht darauf, dass der Dienst oder eure Bilder dauerhaft verfügbar sind![/notice]

[important]Ihr habt Fragen zu WebID oder Probleme beim Einrichten eines Profils? Ich helfe gerne weiter. Auch Anregungen zu picserv nehme ich gerne entgegen.[/important]

groovyrdf 0.2 veröffentlicht

Es ist mittlerweile schon über 1 Jahr her, dass ich mit groovyrdf eine Bibliothek zur einfachen Erzeugung von RDF-Daten mit Groovy veröffentlicht habe. Nun ist endlich das 2. Release da, und es bringt interessante Neuerungen mit sich.

Neben dem Erzeugen von RDF ist mit Version 0.2 auch das elegante Auslesen und Verarbeiten von Daten möglich. Mittels RdfLoader unterstützt groovyrdf das Laden von Linked Data Ressourcen inklusive Content-Negotiation. Die Daten können anschließend ausgelesen und weiter verarbeitet werden:

  // Namespace-Deklaration
  def foaf = new RdfNamespace ('http://xmlns.com/foaf/0.1/')

  // Laden einer Ressource mittels RdfLoader
  RdfLoader rdfLoader = new JenaRdfLoader()
  RdfResource person = rdfLoader.loadResource(
    'http://me.desone.org/person/aveltens#me'
  )

  println person(foaf.name) // Gibt 'Angelo Veltens' aus

Der Loader kümmert sich selbstständig um Content-Negotation und das Parsen des zurückgelieferten Formats. Solange RDF geliefert wird, kann es uns egal sein, ob dies vom Server in TURTLE, RDF/XML oder N3 ausgedrückt wird. Alle gängigen RDF-Syntaxen werden unterstützt. Der Zugriff auf die Eigenschaften der geladenen Resouce ist anschließend einfach über resource(predicateUri) möglich. Näheres erklärt der User Guide. Version 0.2 steht hier zum Download bereit und den Sourcecode gibt es nach wie vor bei GitHub.

[important]Wenn ihr groovyrdf nutzt, oder auch einfach nur kurz ausprobiert, freue ich mich über euer Feedback![/important]

Linked Data: Mehr als nur RDF

Das Beispiel offenerhaushalt.de zeigt, dass zur Partizipation am Web of Data mehr gehört, als die Veröffentlichung von RDF/XML-Daten. Es lohnt sich dennoch, den Schritt zu „Linked Data“ zu gehen.

Die Veröffentlichung von Daten im RDF-Format gehört zu den Linked Data Grundprinzipien, die Tim Berners-Lee aufgestellt hat. Daher freue ich mich, dass immer mehr Open-Data-Projekte neben JSON und XML, auch Daten in einer RDF-Syntax veröffentlichen.

Das allein reicht aber leider nicht aus, um von Linked Data sprechen zu können, wie ich am Beispiel der RDF/XML-Daten von offenerhaushalt.de zeigen möchte.

Rufen wir uns zunächst die Grundprinzipien noch einmal ins Gedächtnis:

  1. Use URIs as names for things
  2. Use HTTP URIs so that people can look up those names
  3. When someone looks up a URI, provide useful information, using the standards (RDF, SPARQL)
  4. Include links to other URIs. so that they can discover more things

Ich werde diese Prinzipien nun nacheinander mit den RDF-Daten des Haushaltspostens „Bundesministerium für Bildung und Forschung“ von offenerhaushalt.de abgleichen, welche sich im Dokument http://bund.offenerhaushalt.de/30.rdf befinden.

[important]Disclaimer: Auch wenn ich in Sachen Linked Data in diesem Artikel einiges an offenerhaushalt.de zu kritisieren habe, möchte ich dies nicht als generelle Kritik am Projekt verstehen. Im Gegenteil: Ich halte das Projekt für ein Vorzeigebeispiel der Open-Data-Bewegung und spreche allen Beteiligten großen Dank und Respekt aus! Meine Kritik ist im Vergleich zu dem, was bereits geleistet wurde, eine Kleinigkeit. Ich möchte sie eher als Anregung verstanden wissen. Auch bin ich gerne bereit zu helfen, wenn Interesse besteht, die offenen Haushaltsdaten ins Web of Data zu hieven.[/important]

Use URIs as names for things

Wesensmerkmal des Web of Data ist, dass dort nicht nur reine Dokumente („Informationsressourcen„), sondern auch Daten über reale und abstrakte „Dinge“ aufzufinden sind. Diese Dinge benötigen einen global eindeutigen Namen. Genau diese Anforderung erfüllen URIs.

Bei der Namensgebung ist zu beachten, dass das „Ding“ welches beschrieben wird und die Dokumente welche es beschreiben unterschiedlich sind und deshalb auch über unterschiedliche URIs identifiziert werden müssen. Getreu dem Merksatz: „Du bist nicht deine Website„!

Das Datendokument http://bund.offenerhaushalt.de/30.rdf beschreibt ein Subjekt namens http://bund.offenerhaushalt.de/30. Unklar bleibt dabei, um was für eine Art von „Ding“ es sich dabei handelt. Ein rdf:type ist nicht hinterlegt.

Nun liegt die Vermutung nahe, dass bei offenerhaushalt.de Haushaltsposten beschrieben werden. Ruft man jedoch die URI http://bund.offenerhaushalt.de/30 im Browser oder mit Hilfe eines Tools wie curl ab, so wird ein HTML-Dokument zurückgeliefert:

user@pc:~$ curl -I http://bund.offenerhaushalt.de/30
HTTP/1.1 200 OK
Date: Wed, 02 May 2012 18:38:32 GMT
Server: Apache/2.2.14 (Ubuntu)
Pragma: no-cache
Cache-Control: no-cache
Content-Length: 73434
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8

Auch wenn man den Accept-Header explizit auf application/rdf+xml oder text/turtle setzt, wird ausschließlich text/html zurück geliefert.

Bei http://bund.offenerhaushalt.de/30 handelt es sich also schlichtweg um ein herkömmliches HTML-Dokument und nicht um einen Haushaltsposten.

Interessant sind unter diesem Aspekt Aussagen wie zum Beispiel folgende¹:

<http://bund.offenerhaushalt.de/30> openhaushalt:is_department "true".

Das HTML-Dokument ist also eine Abteilung, soso 🙂

Wobei wir streng genommen gar nicht wissen können, was openhaushalt:is_department überhaupt bedeutet. Das Prädikat ist nämlich nicht auflösbar, womit wir beim nächsten Punkt angelangt sind:

Use HTTP URIs so that people can look up those names

Die URI des Prädikats erhält man, indem man das Namespace-Prefix durch die Namespace-URI ersetzt. Für openhaushalt:is_department ergibt sich somit http://offenerhaushalt.de/schema/0.3/is_department. Bei Abruf dieser URI erhält man leider nichts weiter als den HTTP-Fehlercode 404: Not Found. Zwar wurden HTTP-URIs verwendet, diese sind aber nicht abrufbar.

Provide useful information

Bei den abrufbaren URIs scheitert es an „nützlichen Informationen“. Wie schon im ersten Abschnitt bemerkt, liefert http://bund.offenerhaushalt.de/30 lediglich ein HTML-Dokument zurück, wohingegen die RDF-Daten eher auf ein abstraktes „Ding“, wie einen Haushaltsposten oder eine Abteilung, hindeuten.

Dieses „Ding“ müsste zunächst einmal einen eigenen Namen bekommen, z.B. http://bund.offenerhaushalt.de/30#item

Beim Abruf mittels Browser würde durch den Wegfall des Fragment-Identifiers weiterhin das HTML-Dokument http://bund.offenerhaushalt.de/30 ausgeliefert werden, wodurch die „nützlichen Informationen“ zumindest für den menschlichen Klienten weiterhin gewährleistet wären.

Fordert ein Client mittels HTTP-Accept-Header jedoch ausdrücklich RDF, dann muss dieses ebenfalls über die URI http://bund.offenerhaushalt.de/30#item respektive http://bund.offenerhaushalt.de/30 verfügbar sein, da der Client entscheidet, welches Datenformat für ihn nützlich ist. Derzeit wird aber immer HTML ausgeliefert.

Nützlich sind die Daten aber auch deshalb nicht, weil die URIs der Prädikate nicht abrufbar sind. Die verwendete Ontologie ist somit ohne API-Dokumentation nicht zu verstehen. Es bleibt unklar, was Prädikate wie openhaushalt:is_department tatsächlich bedeuten. Die RDF-Daten sind damit kein Zugewinn im Vergleich zu z.B. JSON. Die Semantik fehlt in beiden Varianten.

Include links to other URIs

Die Verlinkung beschränkt sich auf andere URIs innerhalb des Projekts offenerhaushalt.de. Eine Verlinkung ins offene Web of Data findet derzeit nicht statt. Problematisch ist auch hier wieder, dass die URIs lediglich HTML-Dokumente identifizieren und somit auch kein „internes Web of Data“ entsteht. Was bleibt sind RDF/XML-Dokumente mit Links zu HTML-Seiten.

Na und?

Nun stellt sich dem ein oder anderen sicher die Frage, wozu man diese manchmal recht akademisch anmutenden Ansätze überhaupt verfolgen sollte? Die offenen Haushaltsdaten, die derzeit vom Projekt angeboten werden, sind zweifelsohne bereits in der vorliegenden Form sehr wertvoll. Die vorliegenden RDF/XML-Daten bieten aber nach meiner Auffassung keinen Mehrwert gegenüber dem JSON-Format. Im Gegenteil: Sie sind für einen Programmierer eher noch schwerer zu verarbeiten.

In Form von Linked Data können die Daten aber ein Potential entfalten, das deutlich über den Status quo hinaus geht. Eindeutige URIs für Haushaltsposten (nicht die HTML-Seiten!) könnten z.B. auch von anderen Projekten genutzt werden um strukturierte Aussagen über diese Haushaltsposten zu treffen. Denkbar wären zum Beispiel Tools zum Bürgerhaushalt, welche ihre Nutzer die Budgets für die einzelnen Haushaltsposten neu verteilen lassen. Dadurch dass alle über die gleichen (durch URIs global benannten!) Haushaltsposten „sprechen“, ist es dabei völlig egal, auf welchem Server mit welchem Tool solch ein Bürgerhaushalt erstellt wurde. Man kann sich das ähnlich vorstellen wie heute Verlinkungen und Pingbacks in der Blogosphäre, nur dass eben nicht über Dokumente/Blogeinträge „gesprochen“ wird, sondern über Daten und Dinge, wie z.B. Haushaltsposten.

Die Verwendung von einheitlichen Ontologien macht diesen Austausch ebenfalls leichter. Zudem wird eine „API“-Dokumentation letztlich überflüssig, wenn die Prädikate der Ontologien im Web abrufbar sind uns sich auf diese Weise selbst erklären.

Fazit

Das Projekt offenerhaushalt.de stellt RDF/XML-Daten bereit, ist damit aber noch kein Teil des Web of Data. Die folgenden Kritikpunkte zeigten sich bei einem Abgleich mit den Linked Data Prinzipien von Tim Berners-Lee:

  1. URIs identifizieren lediglich Dokumente, aber keine „Dinge“ wie Haushaltsposten.
  2. Die „Ontologie“ besteht nur aus toten Links und ist damit genauso ausdruckslos wie JSON.
  3. Es findet keine Content-Negotiation statt, die Wünsche des Clients werden ignoriert.
  4. Aufgrund von 1. kann es auch keine Links auf „Dinge“ geben. Es entsteht somit kein Web of Data.
  5. Es gibt keine Verlinkungen ins Web of Data.

Werden diese Aspekte angepasst und die Linked Data Prinzipien beachtet, können die Daten von offenerhaushalt.de Teil des Web of Data werden und dadurch ihr volles Potential entfalten.


¹ Zur besseren Lesbarkeit verwende ich hier die TURTLE-Notation, obwohl die Daten im Original als RDF/XML vorliegen. Semantisch macht dies keinen Unterschied. 

RDF auf Groovy-Art

Wie bereits angekündigt arbeite ich derzeit an einer Domain-Specific-Language / Bibliothek um RDF mit Groovy zu erzeugen. Das erste Release ist nun verfügbar. Die Vorzüge erkennt man am besten an einem kleinen Code-Beispiel:

RdfData rdfData = rdfBuilder {
  "http://example.com/resource/alice" {
     a "http://example.com/vocab/Person"
    "http://example.com/vocab/name" "Alice"
  }
}

Dieser Ausdruck ist äquivalent zu folgenden RDF-Daten im TURTLE-Format:

<http://example.com/resource/alice>
  a <http://example.com/vocab/Person>;
  <http://example.com/vocab/name> "Alice".
Nett, oder? Interessant wird das ganze natürlich erst, mit ein wenig Dynamik:
def person = new Person (...)

RdfData rdfData = rdfBuilder {
  "http://example.com/resource/${person.nick}" {
     a "http://example.com/vocab/Person"
    "http://example.com/vocab/name" person.name
    "http://example.com/vocab/knows" {
      person.friends.each { friend ->
        "http://example.com/resource/${friend.nick}" {}
      }
    }
  }
}

Die ganze Sprachvielfalt von Groovy steht zur Verfügung. Die Daten lassen sich dann in beliebigen Repräsentation schreiben, z.B. RDF/XML oder TURTLE. Mehr Code-Beispiele und Erklärungen gibts im User Guide. Version 0.1 steht hier zum Download bereit und den Sourcecode gibt es bei GitHub.

Freue mich über Feedback und weitere Ideen. Wer zur weiteren Entwicklung beitragen möchte, forkt einfach das Projekt bei GitHub und sendet mir ein Pull-Request.

Linked Data Thesaurus

Linked Data Thesaurus ist ein kleines Projekt von mir, das die Daten von openthesaurus.de als Linked Data verfügbar macht. OpenThesaurus ist ein freies deutsches Synonymwörterbuch, welches seine Daten auch über eine offene API zur Verfügung stellt. Allerdings liefert diese API lediglich unverlinkte XML-Dokumente aus. Der Linked Data Thesaurus ergänzt den Dienst, indem die Daten zusätzlich in Form von RDF bereitgestellt werden. Ein Begriff bekommt beim Linked Data Thesaurus eine URI der folgenden Form:

http://thesaurus.datenwissen.de/Begriff#term

Synonyme zum Begriff „Daten“ sind somit unter folgender URI abrufbar:

http://thesaurus.datenwissen.de/Daten#term

Es handelt sich dabei um eine Nicht-Informationsressource. Der Fragmentbezeichner #term wird wie üblich beim Abruf per Browser abgetrennt und die Informationsressource http://thesaurus.datenwissen.de/Daten wird vom Server zurückgeliefert. Abhängig vom HTTP-Accept-Header liefert Linked Data Thesaurus entweder ein RDF/XML- (application/rdf+xml) oder Turtle-Dokument (text/turtle) aus. Im Firefox kann der Accept Header mit dem Plugin Modify Headers geändert werden. Andernfalls werden die originalen XML-Daten der OpenThesaurus-API zurückgeliefert! Im Folgenden erkläre ich den Aufbau der Daten anhand des Turtle-Formats und dem Begriff „Daten“. Der Begriff selbst ist vom Typ Label aus der SKOS-XL Ontologie. Das eigentliche Textliteral wird inklusive Sprachangabe über das Attribut skosxl:literalForm angefügt:

<Daten#term>
  a <http://www.w3.org/2008/05/skos-xl#Label>;
  <http://www.w3.org/2008/05/skos-xl#literalForm> "Daten"@de.

OpenThesaurus gruppiert Synonyme in sogenannten SynSets. Dabei handelt es sich um Gruppen von Begriffen mit der gleichen Bedeutung. Ein Begriff mit mehreren Bedeutungen kommt somit in unterschiedlichen SynSets vor, mit jeweils unterschiedlichen Synonymen die den jeweiligen Bedeutungen entsprechen. Zum Beispiel ist das Wort Schild zum einen in einem SynSet mit „Schutzwaffe“ und in einem anderen mit „Zeichen“.

Ein SynSet wird durch den Linked Data Thesaurus als skos:Concept abgebildet. Der abgefragte Begriff wird über das Attribut skosxl:prefLabel angefügt und alle Synonyme über skosxl:altLabel. Hier eines der SynSets in denen der Begriff „Daten“ vorkommt:

<#synset1>
  a <http://www.w3.org/2004/02/skos/core#Concept>;
  <http://www.w3.org/2008/05/skos-xl#altLabel>
    <Informationen#term>,
    <Angaben#term>,
    <Aussagen#term>,
    <Datensammlung#term>,
    <Unterlagen#term>;
  <http://www.w3.org/2008/05/skos-xl#prefLabel>
    <Daten#term>.

Ich freue mich über Feedback zum Linked Data Thesaurus und über die Art und Weise wie die Daten strukturiert sind. Es ist sicherlich noch nicht der Weisheit letzter Schluss, aber ein Anfang. Der OpenThesaurus stellt noch ein paar mehr Daten bereit, die ich gerne noch einbinden möchte und auch eine Verlinkung mit Lexvo.org habe ich bereits im Hinterkopf.

Wer mitarbeiten möchte kann sich gerne an mich wenden, oder einfach den Quellcode von GitHub beziehen und loslegen.