Makina Blog

Le blog Makina-corpus

Cas d'utilisation : développer des packages Django réutilisables pour l'UCLouvain


Les logiciels libres sont des logiciels qui sont distribués sous une licence libre, ils peuvent alors être utilisés et modifiés par toute personne compétente dans le domaine car leur code source est ouvert. Mais encore faut-il concevoir son projet et les développements associés pour que d'autres puissent effectivement et assez facilement les réutiliser !

Une bonne pratique est d'identifier au sein de son projet les fonctionnalités transverses qui ne sont pas liées directement au métier et qui pourraient être réutilisés dans d'autres projets.

Une fois identifiées, ces fonctionnalités peuvent alors être développés dans des packages isolés du reste du projet, et les partager avec la communauté. En suivant cette philosophie dans le cadre de son projet OSIS (Open Student Information System, sous licence GPL v3), l'Université Catholique de Louvain (UCLouvain) a confié à Makina Corpus le développement de modules réutilisables Django.

L'objectif de ces différents modules est de gérer de manière générique :

  • L'historique d'un objet métier
  • La gestion de templates d'e-mail
  • L'envoi de notifications aux utilisateurs
  • La gestion et le transfert de fichiers par les utilisateurs, incluant leur visualisation
  • La création de processus de signature
  • La gestion de tâches asynchrones
  • L'export de listes au format Excel

Dans cet article, nous vous présentons un à un les packages solutionnant ces demandes.

Tout d'abord, abordons l'architecture logicielle imposée par l'UCLouvain, car celle-ci a un impact important pour le design technique de ces modules. En effet, par souci de sécurité l'UCLouvain a mis en place une architecture basée sur deux serveurs :

  • OSIS est le backoffice réservé aux équipes internes de l'UCLouvain qui héberge et permet de gérer toutes les données : catalogue, programmes, étudiants, partenariats, admissions, etc.
  • OSIS-Portal est un portail accessible au public d'étudiants et d'enseignants.

Cette séparation permet une meilleure sécurité et une gestion des droits "dégrossie" ainsi qu'une séparation des interfaces graphiques. En revanche, elle impose une communication server-to-server au travers d'une API. Les profils des utilisateurs (modèle Person) sont donc tous présents en back office, mais leurs informations d'authentification (modèle User de django.auth) sont distribuées sur chaque serveur. Nous pouvons noter également qu'OSIS est traduit en deux langues : l'anglais et le français.

Ainsi, selon les fonctionnalités, un package pourra être utilisé sur OSIS (back office), sur le portail (front office), ou sur les deux. Un troisième serveur a même été imaginé pour ne stocker que les documents transférés par les utilisateurs, pour une meilleure gestion RGPD en se dirigeant vers un micro-service externalisé.

OSIS-History

L'objectif de ce module est de fournir une manière générique d'enregistrer des entrées d'historiques à propos d'un objet donné. Pour identifier cet objet, nous référençons son identifiant unique UUID. Une autre solution aurait pu être de stocker une clé étrangère générique, mais l'UUID est préférable. Il expose une fonction simple add_history_entry() permettant d'enregistrer une chaîne de caractères dans les deux langues, un auteur (facultatif) et des tags (facultatifs).

Ces entrées sont ensuite facilement visualisables à travers une mixin de vue, et un widget VueJS permettant un affichage sous forme de tableau ou de frise chronologique.

Interface d'historique en tableau
Interface d'historique en frise horizontale

 

OSIS-Mail-template

Ce module fournit une interface d'administration de templates d'e-mail. Ceux-ci sont définis par un identifiant unique et sont associés à une description, un tag et à des jetons de remplacement (tokens) pouvant être utilisés, et dont la valeur sera injectée dynamiquement lors de l'envoi de l'e-mail. C'est donc un package pour améliorer la "developer experience".

Chaque template d'e-mail est déclaré par le module amené à utiliser celui-ci - donc envoyer un e-mail à un certain moment - dans un fichier mail_templates.py, qui sera automatiquement chargé et viendra étoffer la bibliothèque de template d'e-mail. Le contenu texte du sujet et du corps de l'e-mail sera ensuite modifiable sans action dans le code via une interface d'administration. Le contenu est donc stocké dans un modèle MailTemplate, avec une instance pour chaque langue (anglais et français), ce qui nécessite une migration pour initialiser le contenu du mail afin de ne pas avoir d'erreur lors de la livraison du code en production.

L'interface d'administration présente tous les templates déclarés avec la possibilité de les prévisualiser (c'est-à-dire en remplaçant les tokens par des valeurs d'exemple). Le contenu du corps du template peut contenir du HTML et est donc modifiable via un profil CKEditor simplifié, qui sera automatiquement converti en texte brut via la bibliothèque html2text.

Une fois le contenu du template configuré, pour l'utiliser et générer le message avant envoi, il suffit de fournir l'identifiant unique du template, l'émetteur et les destinataires, la langue désirée et le contenu de chaque token pour générer le sujet et le corps de l'e-mail prêt à envoyer. Le rôle de ce module s'arrête ici, pour l'envoi effectif, il faudra utiliser OSIS-Notification, décrit dans la section suivante.

Interface d'OSIS-Mail-template

 

OSIS-Notification

Ce package est destiné à stocker et traiter les messages de notification web ou e-mail de l'application que ce soit côté back-office ou front-office.

Deux modèles sont offerts : WebNotification et MailNotification avec leur contenu respectif, leur destinataire et leur statut d'envoi. Des tâches - commandes d'administration - pouvant être exécutées via cron permettent de gérer finement la queue de notifications.

Pour l'affichage des notifications web, un widget VueJS et des vues permettent de récupérer les notifications web côté back-office ou front office, de les rafraîchir à chaque chargement de page (en Ajax) et les marquer comme lues.

Widget d'OSIS-Notification

 

OSIS-Document

Ce module permet de centraliser la gestion des fichiers, grâce à un widget VueJS de transfert et de visualisation. Installé dans le back office et le front office, celui-ci peut également être totalement découplé pour une architecture tri-serveur proche du micro-service.

Côté développement, ce module expose un nouveau champ de modèle permettant de référencer un ou plusieurs UUID de fichier. Les instances de fichiers sont centralisées dans une table avec leur chemin, leurs métadonnées - nom, type, taille, date de transfert - qu'il est possible d'étendre. Un fichier a le statut "temporaire" lorsqu'il a été déposé dans le widget VueJS, puis il est ensuite passé dans l'état "confirmé" par l'application, lorsque le formulaire ou l'instance qui l'utilise est enregistrée. Les fichiers temporaires peuvent être supprimés au bout d'un certain temps via un réglage et une tâche cron.

Ensuite, lorsqu'on veut accéder à un fichier, nous évitons d'exposer publiquement l'UUID du fichier. Nous préférerons créer un token d'accès en lecture ou écriture, révocable, pour permettre l'affichage ou la modification de celui-ci. Un widget de visualisation, toujours en VueJS, permet de visualiser le fichier à travers une fenêtre modale lorsque c'est une image ou un PDF.

Interface d'upload de documents
Modale de modification d'OSIS-document

 

OSIS-Signature

Ce package offre une base de travail pour tracer les états d'un processus de signature, de l'envoi des demandes à l'apposition de celles-ci. Il expose deux modèles : Process auquel sont liés des Actor, chacun ayant un statut. Le but premier de ce module est de stocker les données de base, elles peuvent donc être étendues via des modèles liés et affichées au travers de vues, mais ce sera la responsabilité du module implémentant le processus de signature.

OSIS-Async

L'objectif de ce module est de tracer l'état de tâches asynchrones et de les exposer au travers d'un widget VueJS, que ce soit dans le back office ou le front office. Il fournit un modèle AsyncTask et des commandes pour dépiler celles-ci, que les autres packages peuvent utiliser pour rendre compte de leurs traitements en arrière-plan. Les propriétés de ces tâches comprennent un nom, une description, un statut, un pourcentage de progression, un temps avant arrêt en cas de tâche trop longue et sont rattachées à un profil pour pouvoir apparaître dans le menu de l'utilisateur.

OSIS-Export

Une des principales implémentations d'OSIS-Async est le package OSIS-Export. Il permet d'exporter une liste d'objets sous format Excel ou générer un PDF à partir d'un template et d'un contexte.

Conclusion

Tous ces modules, toujours en cours de développement, sont librement accessibles sur le Github de l'UCLouvain : 

Dans chaque projet, prenez du recul sur les fonctionnalités qui vous sont demandées, tentez d'identifier celles qui seront utiles pour vos autres projets, pour d'autres personnes, pour la communauté, et initiez vos projets open source !

 

Formations associées

Django

Django avancé

A distance (foad) Du 7 au 9 novembre 2022

Voir la formation

Django

Django intégration

A distance (foad) Le jeudi 3 novembre 2022

Voir la formation

Django

Django Rest Framework

A distance (foad) Du 1er au 6 décembre 2022

Voir la formation

Actualités en lien

Image
logging
08/07/2020 - 16:27

Présentation de django-admin-watchdog

Comment garder une trace des erreurs Django en toute simplicité.

Voir l'article
Image
Django logo
08/07/2020 - 13:25

Présentation de django-tracking-fields

Suivi de modification d'objets Django

Voir l'article
Image
Django logo
09/07/2013 - 15:50

Présentation de Django-Safedelete

Masquage d'objets en base de données une alternative à la suppression définitive.

Voir l'article

Inscription à la newsletter

Nous vous avons convaincus