web-dev-qa-db-fra.com

Cadres de workflow pour Django

Je cherchais un cadre pour simplifier le développement de flux de travail relativement complexes dans les applications Django. J'aimerais pouvoir utiliser le framework pour automatiser les transitions d'état, les permissions, et peut-être quelques extras tels que la journalisation d'audit et les notifications.

J'ai vu des informations plus anciennes sur le même sujet, mais pas trop au cours des 2-3 dernières années. Les principaux choix dont j'ai entendu parler sont GoFlow (non mis à jour depuis 2/2009) et Django-workflow (semble plus actif).

Est-ce que quelqu'un a utilisé ces paquets? Sont-ils matures et/ou compatibles avec Django moderne (1.3)? Existe-t-il d’autres options intéressantes à considérer qui pourraient être mieux ou mieux soutenues?

39
Michael C. O'Connor

Laissez-moi vous donner quelques notes ici car je suis l'auteur de Django-fsm et Django-viewflow, deux projets qui pourraient être appelés "bibliothèques de flux de travail".

Workflow Word lui-même est un peu surestimé. Différents types de bibliothèques et de logiciels peuvent s’appeler "flux de travail" mais avoir des fonctionnalités variables. Le point commun est qu’un flux de travail relie les étapes d’un processus à un tout.

Classification générale

Comme je le vois, les approches de mise en œuvre de workflow peuvent être classées comme suit:

  • Single/Multiple users - Indique si la bibliothèque de flux de travail automatise les tâches mono-utilisateur ou dispose d'options de vérification des autorisations/d'attribution de tâches.
  • Sequential/Parallel - Le flux de travail séquentiel est simplement une implémentation de modèle de machine à états et permet d'avoir un seul état actif à la fois. Les workflows parallèles permettent d’avoir plusieurs tâches actives à la fois, et probablement une sorte de fonctionnalité de synchronisation/jointure parallèle.
  • Explicit/Implicit - Que le flux de travail soit représenté en tant qu'entité externe distincte ou qu'il soit tissé dans une autre classe, cette responsabilité principale est différente.
  • Static/Dynamic - Les flux de travail statiques sont implémentés dans le code python une fois, puis exécutés. Les flux de travail dynamiques peuvent généralement être configurés en modifiant le contenu des tables de la base de données de flux de travail. Les flux de travail statiques sont généralement mieux intégrés au reste de l'infrastructure Django. Comme les vues, formulaires et modèles, ils prennent en charge une meilleure personnalisation par les constructions python habituelles, telles que l'héritage de classe. Les flux de travail dynamiques supposent que vous avez une interface générique pouvant s'adapter à toutes les modifications d'exécution du flux de travail.

Parmi celles-ci, les deux premières pourraient être considérées comme des différences graduelles, mais les deux autres sont fondamentales.

Forfaits spécifiques

Voici une brève description de ce que nous avons actuellement à Django, dans les paquetages et awesome-Django liste de projets dans la section flux de travail:

  • Django.contrib.WizardView - implicite, utilisateur unique, séquentiel, statique l’implémentation de flux de travail la plus simple possible. Il stocke l'état intermédiaire dans les données de publication sous forme masquée.
  • Django-flows - flux de travail explicite, utilisateur unique, séquentiel, statique, qui conserve l'état du flux dans la mémoire de stockage externe, afin de permettre à l'utilisateur de fermer ou d'ouvrir une page sur un autre onglet et de continuer à travailler.
  • Django-fsm - flux de travail implicite, multi-utilisateur, séquentiel, statique - la bibliothèque de machines d'état la plus compacte et légère. Les événements de changement d'état sont représentés comme des appels de méthodes python de la classe de modèle. Possède un support rudimentaire pour l'héritage et les dérogations de flux. Fournit des emplacements pour l'autorisation d'association avec des transitions d'état. Permet d'utiliser un verrouillage optimiste pour empêcher les mises à jour d'état simultanées.
  • Django-states - flux de travaux statique, multi-utilisateur, séquentiel, avec une classe distincte pour la machine à états et les transitions d'état. Transitions effectuées en transmettant le nom de chaîne de la transition à la méthode make_transition. Fournit un moyen pour une autorisation d'association avec des transitions d'état. Possède un point d'extrémité générique REST simple pour changer les états du modèle à l'aide d'appels AJAX. La prise en charge de l'héritage de l'ordinateur Machine n'est pas mentionnée dans la documentation, mais la définition d'état de classe le rend possible avec aucune ou peu de modifications de bibliothèque principale.
  • Django_xworkflows - flux de travaux explicite, séquentiel, statique sans prise en charge de la vérification des autorisations utilisateur, classe séparée pour la machine à états. Utilise des n-uplets pour les définitions d'état et de transition, complique la prise en charge de l'héritage des flux de travail.
  • Django-workflows - flux de travaux explicite, multi-utilisateur, séquentiel, dynamique, stockant l'état dans des modèles Django fournis par la bibliothèque. A un moyen d'attacher la permission à la transition de flux de travail, et c'est tout.

Aucune de ces bibliothèques de machines d'état Django ne prend en charge les flux de travail parallèles, ce qui limite beaucoup leur champ d'application. Mais il y en a deux qui font:

  • Django-viewflow - flux de travaux explicite, multi-utilisateur, parallèle, statique, avec prise en charge de l'exécution de tâches parallèles, de la scission complexe et de la sémantique de jointures. Fournit des aides pour intégrer les vues fonctionnelles et basées sur les classes de Django, différentes requêtes d’exécution de tâches en arrière-plan, ainsi que diverses stratégies de verrouillage pessimistes et optimistes afin d’empêcher les mises à jour simultanées.

  • GoFlow, mentionné dans la question, tend à être le flux de travaux explicite, multi-utilisateur, parallèle, dynamique, mais il a été abandonné par l'auteur pendant un an. 

Je vois le moyen d'implémenter la fonctionnalité de construction de workflow dynamique en plus de Django-viewflow . Dès qu'il sera terminé, if fermera le dernier cas, le plus sophistiqué, d'implémentation de workflow dans le monde Django.

Hope, si quelqu'un était capable de lire jusqu'à présent, comprend maintenant mieux le terme de flux de travaux et peut faire le choix conscient de la bibliothèque de flux de travaux de son projet.

74
kmmbvnr

Existe-t-il d’autres options intéressantes à considérer qui pourraient être mieux ou mieux soutenues?

Oui.

Python.

Vous n'avez pas besoin d'un produit de flux de travail pour automatiser les transitions d'état, les autorisations et peut-être certains extras tels que la journalisation d'audit et les notifications.

Il y a une raison pour laquelle peu de projets le font.

  • Le modèle de conception State est assez facile à mettre en œuvre.

  • Les règles d'autorisation ("permissioning") sont déjà une partie De première classe de Django.

  • La journalisation est déjà une partie intégrante de Python (et a été ajoutée à Django). Son utilisation pour la journalisation d'audit est soit une table d'audit , Soit un autre journal (ou les deux).

  • Le cadre de messagerie ("notifications") fait déjà partie de Django.

Qu'as-tu besoin de plus? Vous avez déjà tout.

L'utilisation de définitions de classe pour le modèle de conception State et de décorateurs pour l'autorisation et la journalisation fonctionne si bien que vous n'avez besoin de rien au-delà de ce que vous avez déjà.

Lisez cette question connexe: Implémentation d'un "moteur de règles" en Python

6
S.Lott

Un paquetage écrit par un de mes collaborateurs, Django-fsm , semble fonctionner - il est à la fois assez léger et suffisamment fonctionnel pour être utile.

6
Michael C. O'Connor

C'est drôle parce que j'aurais convenu avec S.Lott de simplement utiliser Python tel quel pour un moteur de règles. J'ai une perspective COMPLÈTEMENT différente maintenant que je l'ai fait. 

Si vous voulez un moteur de règles complet, il faut quelques pièces mobiles. Nous avons construit un moteur de règles Python/Django complet et vous seriez surpris de voir ce qui doit être intégré pour obtenir un excellent moteur de règles opérationnel. Je vais expliquer plus en détail, mais d’abord le site Web est http://nebrios.com

Un moteur de règles devrait au moins avoir:

  • Listes de contrôle d'accès - Voulez-vous que tout le monde voie tout?
  • Paire de clés/valeur API - KVP stocke l'état et toutes les règles réagissent aux états modifiés.
  • Mode Debug - Être capable de voir chaque état modifié, ce qui l'a changé et pourquoi. Primordial. 
  • Interaction via formulaires Web et e-mail - Etre capable de scripter rapidement un formulaire Web est un atout considérable, tout en analysant systématiquement les e-mails entrants. 
  • ID de processus - Ils suivent un "fil" de valeur commerciale. Sinon, les processus se chevaucheraient continuellement. 
  • Sooo beaucoup plus!

Essayez donc Nebri ou les autres que je énumère ci-dessous pour voir s’ils répondent à vos besoins. 

Voici le mode débogage

enter image description here

Un formulaire généré automatiquement

enter image description here

Un exemple de règle de workflow:

class task_sender(NebriOS):
# send a task to the person it got assigned to
listens_to = ['created_date']

def check(self):
    return (self.created_date is not None) and (self.creator_status != "complete") and (self.assigned is not None)

def action(self):
    send_email (self.assigned,"""
        The ""{{task_title}}"" task was just sent your way!

        Once you finish, send this email back to log the following in the system:

        i_am_finished := true

        It will get assigned back to the task creator to look over.

        Thank you!! - The Nebbs
        """, subject="""{{task_title}}""")

Donc, non, il n'est pas simple de créer un moteur de flux de travaux basé sur des règles et des événements en Python uniquement. Nous y sommes depuis plus d'un an! Je recommanderais d'utiliser des outils comme 

4
Adam

Je peux ajouter une bibliothèque supplémentaire qui prend en charge à la volée les modifications apportées aux composants de flux de travail, à la différence de ses équivalents. 

Regarde Django-river

3
Ahmet DAL

ActivFlow : un moteur de flux de travaux générique, léger et extensible pour le développement agile et l'automatisation d'opérations de processus métier complexes.

Vous pouvez avoir un flux de travail complet modélisé en un rien de temps!

Étape 1: Enregistrement de l'application de flux de travail

WORKFLOW_APPS = ['leave_request']

Étape 2: Configuration de l'activité

from activflow.core.models import AbstractActivity, AbstractInitialActivity
from activflow.leave_request.validators import validate_initial_cap

class RequestInitiation(AbstractInitialActivity):
    """Leave request details"""
    employee_name = CharField(
        "Employee", max_length=200, validators=[validate_initial_cap])
    from = DateField("From Date")
    to = DateField("To Date")
    reason = TextField("Purpose of Leave", blank=True)

    def clean(self):
        """Custom validation logic should go here"""
        pass

class ManagementApproval(AbstractActivity):
    """Management approval"""
    approval_status = CharField(verbose_name="Status", max_length=3, choices=(
        ('APP', 'Approved'), ('REJ', 'Rejected')))
    remarks = TextField("Remarks")

    def clean(self):
        """Custom validation logic should go here"""
        pass

Étape 3: Définition du flux

FLOW = {
'initiate_request': {
    'name': 'Leave Request Initiation',
    'model': RequestInitiation,
    'role': 'Submitter',
    'transitions': {
        'management_approval': validate_request,
    }
},
'management_approval': {
    'name': 'Management Approval',
    'model': ManagementApproval,
    'role': 'Approver',
    'transitions': None
    }
}

Étape 4: règles de gestion

def validate_request(self):
    return self.reason == 'Emergency'
1
faxad

Je migre le Django-goflow de Django 1.X - python 2.X pour tenir compte de Django 2.X - python 3.x, le projet est à Django2-goflow

0
mikewolfli