Ce workshop a pour but de créer une instance invenio de zéro, de charger des données et d'adapter l'interface utilisateur. Il utilise les notions vues précédemment, mais ne nécessite pas une connaissance importante du langage python.
prérequis:
- pouvoir créer un environnement virtuel python (testé avec 3.5.2)
- pouvoir exécuter les outils docker:
docker-compose - avoir
nodejsinstallé: la commandenpmdoit exister - avoir
gitinstallé
Créer une nouvelle instance invenio simple basée sur sqlite et qui répond à l’adresse: http://localhost:5000. Cette instance devra être installée dans un environnement virtuel python et utilisera docker pour les services externes (par ex. Elasticsearch). Nous utiliserons l'outil fournit par invenio: inveniomanage compris dans le paquet invenio-base.
Une instance invenio est un paquet python comprenant le fichier de configuration config.py, ainsi que les outils soit pour lancer un site web de développement python soit pour le déployer via apache ou nginx.
Nous voulons utiliser les outils invenio pour créer une nouvelle instance. Pour faire les choses proprement, nous allons créer un environnement virtuel pour notre nouvelle instance.
mkvirtualenv workshop1 # création d'un environnement virtuel
cdvirtualenv # aller dans le répertoire de travail
deactivate # sortir de l'environnement virtuelpip install Flask # installer un paquet par ex. Flask
pip install . # installer un paquet depuis le répertoire contenant `setup.py`
pip install -e xxx # installer en conservant les sources
# installer un paquet depuis github
pip install git+https://github.com/inveniosoftware/invenio-xx.git#egg=invenio-xx- créer un environnement virtuel python nommé
workshop1 - créer un répertoire
srcdans le virtualenv - installer
invenio-base(version github) dans le répertoiresrc
Si tout s'est bien passé vous avez une nouvelle commande disponible: inveniomanage et les sources de ce paquet installé dans src. Vous pouvez dès à présent explorer la commande pour créer la nouvelle instance.
C'est une bonne pratique d'installer les paquets python et les sources du projet dans le répertoire de l'environnement virtuel. Ceci permet de lier naturellement les sources et l'environnement de développement. Attention toutefois à bien sauvegarder vos modifications (git push) avant de détruire l'environnement virtuel.
Créer et installer la nouvelle instance.
pip install -r list.txt # installer une liste de paquets depuis un fichier
pip install -e . # installer en dev un paquet depuis un répertoire contenant setup.pynote: l'option -e crée des liens symboliques au lieu d'une copie lors de l'installation du paquet. Ceci évite la réinstallation du paquet lors de la modification des sources.
Pour lancer le serveur web avec un rechargement automatique lors des modifications des fichiers:
# debug mode (chargement automatique lors de la modification des sources)
export FLASK_DEBUG=1
my_instance rundocker-compose build # création des images docker
docker-compose up # exécution des containers
docker-compose down # arrêt des containers avec perte des donnéesnote: il existe un équivalent à pyenv dans le monde de nodejs: nvm (https://github.com/creationix/nvm#install-script).
# installation des outils nodejs utilisé par Invenio
npm install -g --prefix ${VIRTUAL_ENV} node-sass@3.8.0 clean-css requirejs uglify-js
npm install # installation des paquets nodejs décrits dans packages.jsonnote: nodejs est utilisé pour le code javascript de l'interface utilisateur. Les paquets js d'invenio suivent la dénomination invenio-xxx-js.
inveniomanage instance create xxx # création d'une nouvelle instance
my_instance npm # création de la liste des dépendences js
my_instance collect # collecte des fichiers statiques
my_instance assets build # compilation des fichiers js et cssnote: my_instance est à remplacer par le nom de l'instance ici workshop1. Ceci permet l'interaction avec différentes instances sur la même machine.
- créer la nouvelle instance avec l'outil fournit avec
invenio-basedans le répertoiresrcnouvellement créé - explorer les fichiers créés et identifier les fichiers utiles pour la suite de l'installation
- installer les paquets python utilisé pour le développement
- installer l'instance elle-même
- installer les dépendances
nodejs, les fichiers statiques et les assets (cssetjs) - installer et exécuter les services
dockers - lancer le serveur de développement et visualiser l'application
http://localhost:5000
A cette étape le serveur répond à http://localhost:5000.
Initialiser les services: base de donnée et indexation.
my_instance db --help # utilitaire de base de données
my_instance index --help # utilitaire pour l'indexation
my_instance index queue --help # utilitaires de queue d'indexation- initialiser la base de donnée
- initialiser le moteur d'indexation
- obtenir "no results" pour http://localhost:5000/search
A présent l'instance est installée. Elle ne contient aucune donnée. C'est le début de sa personnalisation.
Se familiariser avec les données au format JSON et leur chargement dans le système soit une par une soit par lots. Il faudra les valider avec jsonschema et configurer le moteur de recherche.
Créer une nouvelle donnée, la stocker dans la base de donnée et l'indexer. Nous voulons aussi avoir des identifiants pérennes: pid's (rappelez-vous la notion de minter). Nous utiliserons un scénario de création d'un catalogue d'albums de musique.
my_instance records --help # utilitaire de données
my_instance index --help # utilitaire d'indexation- charger un nouveau document dans la base une donnée avec un champ
album=mon album préféré. Note: ne pas oublier les identifiants (minter)! - indexer le document
- visualiser la donnée dans la page des résultats, la vue détaillée et l'API REST
La commande workshop1 index reindex ne lance pas l'indexation! Elle ne fait que la mettre dans la queue.
Créer et installer un schema correspondant à nos données. Cela nous permettra de nous familiariser avec la validation de données.
dojson --help # utilitaire de donnéesIl faut installer un nouveau schéma dans l'instance et copier le fichier JSON comprenant les données:
mkdir -p workshop1/schemas/records
touch workshop1/schemas/records/__init__.py
touch workshop1/schemas/__init__.py
wget "https://gitlab.rero.ch/rero-projects/invenio-survival-guide/raw/master/workshop/data/schemas/record-v1.0.0.json" -O workshop1/schemas/records/record-v1.0.0.json
# ajouter les lignes suivantes au entrypoints de `setup.py`
# 'invenio_jsonschemas.schemas': [
# 'records = workshop1.schemas'
# ]
pip install -e . # déclaration du schéma local à invenio-jsonschemas
echo "
# invenio-jsonschemas
JSONSCHEMAS_HOST = 'workshop.rero.ch'
" >> workshop1/config.py
mkdir data
wget "https://gitlab.rero.ch/rero-projects/invenio-survival-guide/raw/master/workshop/data/data.json" -O data/data.jsonVérification: le schema doit exister via http://localhost:5000/schemas/records/record-v1.0.0.json.
Note: à chaque fois que le fichier setup.py est modifié il faut réinstaller l'instance.
- examiner et charger les données
data/data.jsonen rajoutant le schema avec l'aide dedojson - corriger le schema au besoin
Configuration de la navigation par facettes.
Nous allons récupérer une configuration de base pour les facettes (fichier: workshop1/config.py) et installer un mapping elasticsearch.
wget "https://gitlab.rero.ch/rero-projects/invenio-survival-guide/raw/master/workshop/data/config_facets.py" -O workshop1/config.py
mkdir -p workshop1/mappings/records/
touch workshop1/mappings/records/__init__.py
touch workshop1/mappings/__init__.py
wget "https://gitlab.rero.ch/rero-projects/invenio-survival-guide/raw/master/workshop/data/mapping/record-v1.0.0.json" -O workshop1/mappings/records/record-v1.0.0.json
# ajouter les lignes suivantes aux entrypoints de `setup.py`
# 'invenio_search.mappings' : [
# 'records = workshop1.mappings'
# ]
pip install -e .Note: il arrive fréquemment d'oublier la création des fichiers __init__.py: ils sont nécessaires à python pour que celui-ci considère un répertoire comme un paquet. Ils ne sont par exemple pas nécessaire dans les répertoires static car ceux-ci ne sont utilisés que pour la partie interface utilisateur (javascript, css).
- ré-indexer les données avec le nouveau
mapping - visualiser les facettes
- rajouter la facette
artistet modifier le mappingElasticsearchau besoin
Lorsque le mapping est touché, il est nécessaire de ré-indexer. Ceci peut paraître lourd, mais c'est inévitable. Par chance, Elasticsearch permet de créer et remplir un nouvel index tout en utilisant l'ancien; il sera part contre nécessaire de rattraper les notices touchées durant le processus. Le mécanisme d'alias permet la commutation d'indexes à chaud.
Adapter et personnaliser l'interface utilisateur au schema de nos données.
Remplacer le logo invenio contenu dans l'entête du site.
my_instance collect # récolte les fichiers statiques- Créer les répertoires
static/imagesdans l'instance - Copier le logo https://github.com/rero/invenio-survival-guide/raw/master/workshop/data/logo.png dans le répertoire crée
- Ajouter le logo au site (variable
THEME_LOGO)
A chaque fois que des fichiers sont rajoutés dans le répertoire static il est nécessaire d'exécuter la commande collect. Ils seront installé dans le répertoire de l'instance (variable instance_path d'une application Flask). Dans notre cas: '../../var/workshop1-instance'.
La liste des résultats n'affichent pas correctement les champs de la notice. Il faut donc modifier les templates d'angularjs pour l'adapter à nos données. Nous allons afficher le titre de l'album, le nom de l'artiste et la liste des musiciens.
L'API REST permet de voir des exemples de notices:
- http://localhost:5000/api/records: affiche une liste résultats
- http://localhost:5000/api/records/1: affiche la première notice
- la syntaxe dans un template
angularjspour afficher le contenu d'une variable est{{ variable_name }}
note: lorsque l'on change une variable, il faut cocher Disable cache dans les outils de développement du navigateur.
# copier un exemple de template
mkdir -p workshop1/static/templates/workshop1
wget "https://gitlab.rero.ch/rero-projects/invenio-survival-guide/raw/master/workshop/data/record_brief.html" -O workshop1/static/templates/workshop1/record_brief.html
# collecte le nouveau fichier statique
workshop1 collect -v
# change le template des résultats
echo "SEARCH_UI_JSTEMPLATE_RESULTS = \
'templates/workshop1/record_brief.html'" >> workshop1/config.py- Modifier le fichier de
templatepour afficher les différents champs de la notice
Lorsque l'interface utilisateur demande une grande interaction avec l'utilisateur angularjs est utilisé, sinon c'est le couple Flask - Jinja qui s'en charge. Il peut-être déroutant d'avoir deux langages de template et il est souvent nécessaire de visiter les paquets pour savoir quelle technologie est utilisée. Lorsque les templates sont dans le répertoire static alors c'est certainement une application angularjs.
Un bug est présent dans le template des facettes; en effet la facette année est présente deux fois. Une fois sous forme de graphique et une fois sous forme textuelle. Il faut supprimer cette dernière.
S’inspirer du point précédent pour installer le template des facettes contenu dans le module nodejs: invenio-search-js.
- installer un fichier de template pour les facettes, par ex. en reprenant celui d'
invenio-search-js - ajouter la configuration
- modifier le fichier de template pour ne pas afficher la facette
years
Nous voici au terme de ce workshop. Vous avez créé une instance de zéro et chargé vos propres données. Gardez ce tutoriel sous la main cela vous sera certainement utile dans le futur!