Data Fair

Version 4.25.2

Interopérer

19 novembre 2024

1 - API Data Fair

Data Fair expose une API Rest complète. Une partie de cette API est essentiellement destinée à des applications et autres réutilisations des jeux de données. Une autre partie concerne principalement les producteurs de contenu qui souhaitent automatiser leur processus. Dans cette page, nous proposons un aperçu de quelques méthodes de publication de contenu. Les exemples ci-dessous ne montrent qu'un échantillon des capacités de l'API Data Fair et ne remplacent pas la documentation interactive, bien plus complète, embarquée dans le service.

Pré-requis

  • Une installation opérationnelle de Data Fair, soit locale, soit publique, comme sur koumoul.com ;
  • Un compte et une clé d'API avec la portée gestion des jeux de données (voir vos paramètres personnels ou d'organisation dans le menu en haut à droite) ;
  • curl ou autre client HTTP, à condition d'adapter les exemples.

Définissez une variable contenant votre clé d'API :

export API_KEY="XXXX"

Définissez une variable contenant l'URL de base de votre instance Data Fair :

export Data Fair_URL="https://koumoul.com/data-fair"
export Data Fair_URL="http://localhost/data-fair"

Jeu de données simple basé fichier

Téléchargez un fichier CSV d'exemple :

curl https://raw.githubusercontent.com/data-fair/data-fair/master/test/resources/dataset1.csv -o dataset1.csv

Créez un jeu de données simple à partir de ce fichier avec une requête HTTP multipart :

curl -v --header "x-apiKey: $API_KEY" --form file=@dataset1.csv $Data Fair_URL/api/v1/datasets

Notez dans le retour que le jeu de données créé s'est vu attribuer un identifiant « id » que vous pouvez conserver pour effectuer des opérations ultérieures sur ce jeu de données.

export DATASET_ID=identifiant que vous venez de recevoir

L'attribut « status » est à « loaded ». Notez que les traitements sur le jeu de données sont exécutés de manière asynchrone, quelques secondes plus tard le statut devrait devenir « finalized » en passant par des étapes intermédiaires. Pour vérifier cela, vous pouvez faire un GET sur le jeu de données :

curl -v --header "x-apiKey: $API_KEY" $Data Fair_URL/api/v1/datasets/$DATASET_ID

L'attribut page est lui aussi intéressant, il vous permet de naviguer dans un navigateur directement sur la page de description du jeu de données. Pour connaître l'étendue des capacités de requêtage sur ce jeu de données, vous pouvez vous rendre sur l'onglet API depuis cette page. Voici un exemple basique :

curl -v --header "x-apiKey: $API_KEY" $Data Fair_URL/api/v1/datasets/$DATASET_ID/lines

Jeu de données basé fichier avec pièces jointes

Téléchargez un fichier CSV d'exemple qui contient une colonne de chemins vers des pièces jointes :

curl https://raw.githubusercontent.com/data-fair/data-fair/master/test/resources/dataset-attachments.csv -o dataset-attachments.csv

Téléchargez l'archive contenant les pièces jointes correspondantes :

curl https://raw.githubusercontent.com/data-fair/data-fair/master/test/resources/files.zip -o files.zip

Créez un jeu de données basé sur le CSV et enrichi avec les pièces jointes de l'archive, grâce à cette requête HTTP multipart :

curl -v --header "x-apiKey: $API_KEY" --form file=@dataset-attachments.csv --form attachments=@files.zip $Data Fair_URL/api/v1/datasets
export DATASET_ID=identifiant que vous venez de recevoir

Si vous visitez la page de ce jeu de données, vous verrez un onglet fichiers supplémentaire qui permet de lister les pièces jointes et d'effectuer des recherches dans leur contenu. En effectuant une requête basique sur le jeu de données, vous pouvez constater l'ajout de champs _file.* qui sont issus de l'analyse du contenu des pièces jointes.

Jeu de données éditable

Créez un jeu de données éditable vide avec un schéma minimaliste. Notez l'attribut « isRest », qui est la condition pour créer ce type de jeu de données :

curl -v --header "x-apiKey: $API_KEY" --header "Content-Type: application/json" $Data Fair_URL/api/v1/datasets --data '{
  "isRest": true,
  "title": "rest1",
  "schema": [{ "key": "attr1", "type": "string" }, { "key": "attr2", "type": "string" }]
}'
export DATASET_ID=identifiant que vous venez de recevoir

Ajoutez une ligne de donnée :

curl -v --header "x-apiKey: $API_KEY" --header "Content-Type: application/json" $Data Fair_URL/api/v1/datasets/$DATASET_ID/lines --data '{
  "_id": "ligne1",
  "attr1": "attr1 ligne1",
  "attr2": "attr2 ligne1"
}'

Ajoutez/modifiez plusieurs lignes de donnée :

curl -v --header "x-apiKey: $API_KEY" --header "Content-Type: application/json" $Data Fair_URL/api/v1/datasets/$DATASET_ID/_bulk_lines --data '[
  { "_id": "ligne1", "_action": "patch", "attr1": "attr1 ligne1 autre valeur"},
  { "_id": "ligne2", "attr1": "attr1 ligne2", "attr2": "attr2 ligne2"}
]'

Vérifiez la donnée :

curl -v --header "x-apiKey: $API_KEY" $Data Fair_URL/api/v1/datasets/$DATASET_ID/lines

Jeu de données éditable avec pièces jointes

Créez un jeu de données éditable vide avec un schéma qui contient un champ type pièces jointes :

curl -v --header "x-apiKey: $API_KEY" --header "Content-Type: application/json" $Data Fair_URL/api/v1/datasets --data '{
  "isRest": true,
  "title": "rest1",
  "schema": [
    { "key": "attr1", "type": "string" },
    { "key": "attachmentPath", "type": "string", "x-refersTo": "http://schema.org/DigitalDocument" }
  ]
}'
export DATASET_ID=identifiant que vous venez de recevoir

Ajoutez plusieurs lignes de données avec pièces jointes dans une archive :

echo '[
  { "_id": "line1", "attr1": "test1", "attachmentPath": "test.odt" },
  { "_id": "line2", "attr1": "test1", "attachmentPath": "dir1/test.pdf" }
]' > actions.json
curl -v --header "x-apiKey: $API_KEY" $Data Fair_URL/api/v1/datasets/$DATASET_ID/_bulk_lines --form attachments=@files.zip --form actions=@actions.json

Vérifiez la donnée :

curl -v --header "x-apiKey: $API_KEY" $Data Fair_URL/api/v1/datasets/$DATASET_ID/lines

2 - Applications de visualisation

N'importe qui peut développer une nouvelle application de visualisation de données compatible avec Data Fair. Ces applications sont mises à disposition sous forme de services : ce sont des applications web disponibles en ligne. Une instance de Data Fair fait office de proxy vers les applications configurées et les réexpose en leur communiquant les informations de contexte dont elles ont besoin. Pour pouvoir être intégrée dans une instance Data Fair, une application doit exposer certaines informations.

Exemples

  • Un plugin pour vue-cli qui permet de générer une application : vue-cli-plugin-app ;
  • Une application statique minimaliste en HTML/JS/CSS pur avec juste un petit peu de jQuery : app-minimal ;
  • Une application complète développée avec des frameworks modernes : app-charts.

Métadonnées essentielles

Une application expose un fichier HTML, typiquement un fichier index.html à sa racine. Ce fichier doit contenir certaines informations, renseignées dans des balises de la section HEAD :

  • title : titre de l'application, dans une balise title ;
  • description : description de l'application, dans une balise meta.

Gestion des configurations

Une application doit donner à Data Fair le moyen de créer et éditer des configurations cohérentes avec ses besoins. Les configurations sont décrites à l'aide de JSON schéma, en servant à la racine de l'application un fichier config-schema.json. Ce fichier peut avoir des annotations particulières permettant d'avoir du contrôle sur le formulaire de configuration qui sera généré.

Ce formulaire est généré à l'aide de la librairie vuetify-jsonschema-form (VJSF), la documentation des différentes annotations JSON schéma utilisées est disponible ici.

Informations de contexte

Côté client

Par simplicité, nous privilégions des applications statiques déployables sur un simple serveur web, comme nos applications exemples. Pour ces applications, nous avons prévu un mécanisme simple de transmission des informations contextuelles.

Le proxy Data Fair cherche, dans le contenu HTML qui transite, la chaîne de caractère %APPLICATION% et la remplace par la configuration d'application complète au format JSON. Le code JavaScript peut donc récupérer cet objet et l'utiliser pour effectuer un rendu adapté et consommer l'API de Data Fair en conséquence. L'objet JSON transmis contient les champs suivants :

  • title : titre de la visualisation configurée ;
  • url : URL où est exposée l'application utilisée pour la configuration ;
  • id : identifiant de la visualisation ;
  • status : état de la configuration (brouillon, publié...) ;
  • configuration : la structure de cet objet dépend du schéma de configuration de l'application utilisée ;
  • href : point d'accès de l'API Data Fair permettant de lire / modifier la configuration d'application ;
  • page : page qui présente la visualisation ;
  • exposedUrl : URL d'exposition de la visualisation, peut être utilisée dans une iframe ou en accès direct ;
  • apiUrl : URL de l'API Data Fair ;
  • captureUrl : URL vers le service de capture, permet de réaliser des exports image ou impressions PDF ;
  • wsUrl : URL de la web socket Data Fair, utile pour les applications qui manipulent des données mises à jour en temps réel.

Côté serveur

Il est aussi possible de développer une application avec rendu côté serveur. Dans ce cas, le mode de transmission des informations contextuelles est différent.

Ces informations sont transmises à l'aide de headers HTTP que le serveur de l'application interprète. Les headers suivants sont transmis par le service :

  • X-Exposed-Url : URL d'exposition de la visualisation, peut être utilisée dans une iframe ou en accès direct ;
  • X-Application-Url : URL à utiliser pour connaître le propriétaire de l'application, les droits de l'utilisateur courant (pour par exemple masquer / afficher un bouton de configuration) ;
  • X-API-Url : URL de l'API de Data Fair, ce qui permet ensuite d'accéder aux services distants et aux datasets ;
  • X-Directory-Url : URL vers le service de gestion des utilisateurs.

Outils de développement

Serveur de développement Data Fair

Le projet df-dev-server permet de simplifier le développement des applications Data Fair.

  • Il est plus léger que Data Fair, car il n'a pas besoin des différents services en local (bases de données, gestion utilisateurs...) ;
  • Il permet d'avoir déjà des données disponibles en se connectant à des sources distantes ;
  • Il est plus facile a faire fonctionner sous Windows, car ne nécessite pas Docker ;
  • Il nécessite par contre une connexion internet pour pouvoir accéder aux données.

3 - Services externes

Une API peut être utilisée par ce service si elle respecte certains critères. Elle doit être décrite avec un certain formalisme : spécification OpenAPI 3.0, annotations sémantiques particulières et mécanisme d'identification de l'API.

Spécification OpenAPI 3.0

Le schéma utilisé pour décrire une API est celui de la spécification OpenAPI 3.0. Le format à utiliser est JSON (YAML sera supporté prochainement). Les autres formats ne sont pas supportés, en particulier le format Swagger 2.0. Si votre API est décrite dans un autre format, certains outils permettent de la convertir dans le format OpenAPI 3.0.

Néanmoins, une description en pur OpenAPI 3.0 est insuffisante et il faut renseigner des informations complémentaires, notamment pour identifier l'API plus facilement et la sémantiser. Ces informations sont ajoutées en utilisant le format d'extensions autorisé par la spécification est les attributs supplémentaires sont de la forme x-PropertyName.

Identification de l'API

La spécification OpenAPI 3.0 n'offre pas de mécanisme permettant d'identifier de manière unique un API. Cela pose différents problèmes :

  • Il est difficile de suivre l'évolution de l'API, on ne sait pas si deux descriptions similaires correspondent à deux API différentes ou à deux versions différentes d'une même API.
  • Certaines applications nécessitent des fonctionnalités particulières d'API qu'il est difficile de décrire sémantiquement. Une identification unique de l'API permet au moins de dire que les applications ont besoin de cette API (et plus précisément d'une version minimale) en particulier.

Pour identifier de manière unique une API, nous avons choisi d'adopter ces recommandations : il faut renseigner un attribut x-api-id dans le bloc info. Plus précisément, il doit avoir cette forme :

/info/x-api-id:
  type: string
  format: urn
  pattern: ^[a-z0-9][a-z0-9-:.]{6,62}[a-z0-9]$
  description: |
    Globally unique and immutable ID required to identify the API. The API
    identifier allows to reveal the history and evolution of an API as a
    sequence of API specifications. It enables validation tools to detect
    incompatible changes and incorrect semantic versions.

Annotations sémantiques

Les annotations sémantiques permettent de préciser ce que font les différentes opérations d'une API. On peut, d'une part, typer plus précisément les données en entrée et en sortie en utilisant des ontologies (par exemple, un code postal est plus précis qu'un entier) et, d'autre part, déterminer une plus grande diversité d'actions que les verbes HTTP qui sont très restreints.

Le format d'annotations sémantiques que nous avons choisi est décrit dans cet article. x-operationType permet de spécifier plus précisément l'action réalisée par l'opération. Nous conseillons d'utiliser le vocabulaire défini ici dans les types spécifiques. Pour pouvoir être utilisé pour de l'enrichissement, un endpoint doit utiliser l'action Search. x-refersTo permet de typer les entrées et sorties avec des ontologies. Le vocabulaire à utiliser est décrit dans ce projet, dans le fichier contract/vocabulary.json.

3 - Collecteurs de données

Les collecteurs de données périodiques permettent de mettre à jour certains jeux de données spécifiques de manière automatisée. Il y a principalement deux cas d'usage, mais on peut en imaginer d'autres :

  • Mise à jour de jeux de données alimentées par des fichiers produits par d'autres traitement automatisés. Typiquement, des traitements réalisés par des ETL avec en sortie des fichiers tabulaires ou cartographiques mis à disposition sur un espace d'échange (serveur HTTP ou FTP).
  • Mise à jour de données temps réel alimentées par des flux de données ayant des formats spécifiques. Cela concerne principalement des données IOT.

La collecte de données est assurée par le service open source Data Fair Processings. Lorsque l'on souhaite collecter des données dans un nouveau format ou protocole d'échange, il faut développer un nouveau plugin. On peut distinguer deux cas de figure. Soit la mise à disposition des données correspond à un standard qui n'est pas encore supporté, dans ce cas le plugin peut être intégré directement dans Data Fair Processings via une merge request. Soit le plugin reste propriétaire ou correspond à un format/protocole trop spécifique pour être intégré directement dans le projet, et il est rajouté par configuration, lors de l'installation du service.