641 votes

Utilisation d'IPython / Jupyter Notebooks sous contrôle de version

Quelle est une bonne stratégie pour garder IPython des carnets de notes sous contrôle de version ?

Le format du carnet de notes se prête bien au contrôle de version : si l'on veut contrôler la version du carnet de notes et des résultats, cela fonctionne très bien. L'ennui vient lorsque l'on veut seulement contrôler la version de l'entrée, à l'exclusion des sorties de la cellule (alias "produits de construction") qui peuvent être de gros blobs binaires, en particulier pour les films et les intrigues. En particulier, j'essaie de trouver un bon flux de travail qui :

  • me permet de choisir entre inclure ou exclure la sortie,
  • m'empêche de commettre accidentellement des sorties si je ne le souhaite pas,
  • me permet de conserver la sortie dans ma version locale,
  • me permet de voir quand j'ai des changements dans les entrées en utilisant mon système de contrôle de version (i.e. si je ne contrôle que les entrées mais que mon fichier local a des sorties, alors j'aimerais pouvoir voir si les entrées ont changé (ce qui nécessite un commit). L'utilisation de la commande d'état du contrôle de version enregistrera toujours une différence puisque le fichier local a des sorties).
  • me permet de mettre à jour mon cahier de travail (qui contient la sortie) à partir d'un cahier propre mis à jour. (mise à jour)

Comme mentionné, si je choisis d'inclure les sorties (ce qui est souhaitable lorsque l'on utilise des nbviewer par exemple), alors tout va bien. Le problème est que lorsque je ne pas vous voulez contrôler la version de la sortie. Il existe quelques outils et scripts pour dépouiller la sortie du carnet de notes, mais je rencontre fréquemment les problèmes suivants :

  1. J'ai accidentellement commit une version avec la sortie, polluant ainsi mon référentiel.
  2. J'efface la sortie pour utiliser le contrôle de version, mais je préférerais vraiment garder la sortie dans ma copie locale (il faut parfois un certain temps pour reproduire par exemple).
  3. Certains des scripts qui dépouillent la sortie modifient légèrement le format par rapport à l'option Cell/All Output/Clear ce qui crée un bruit indésirable dans les diffs. Ce problème est résolu par certaines des réponses.
  4. Lorsque j'apporte des modifications à une version propre du fichier, je dois trouver un moyen d'incorporer ces modifications dans mon carnet de travail sans avoir à tout réexécuter. (mise à jour)

J'ai envisagé plusieurs options dont je parlerai ci-dessous, mais je n'ai pas encore trouvé de bonne solution globale. Une solution complète pourrait nécessiter quelques changements dans IPython, ou pourrait s'appuyer sur quelques simples scripts externes. J'utilise actuellement mercuriel mais j'aimerais une solution qui fonctionne aussi avec git Une solution idéale serait agnostique au contrôle de version.

Cette question a été discutée à de nombreuses reprises, mais il n'existe pas de solution définitive ou claire du point de vue de l'utilisateur. La réponse à cette question devrait fournir la stratégie définitive. Ce n'est pas grave si cela nécessite une version récente (même de développement) de IPython ou une extension facile à installer.

Mise à jour : J'ai joué avec mon carnet de notes modifié qui enregistre éventuellement une .clean avec chaque sauvegarde utilisant Les suggestions de Gregory Crosswhite . Cela satisfait la plupart de mes contraintes mais laisse les suivantes non résolues :

  1. Cette solution n'est pas encore standard (elle nécessite une modification du code source d'ipython). Existe-t-il un moyen d'obtenir ce comportement avec une simple extension ? Il faut une sorte de crochet on-save.
  2. Un problème que je rencontre avec le flux de travail actuel est de tirer les modifications. Ceux-ci arrivent dans le .clean et doivent ensuite être intégrés d'une manière ou d'une autre dans ma version de travail. (Bien sûr, je peux toujours réexécuter le notebook, mais cela peut être pénible, surtout si certains des résultats dépendent de longs calculs, de calculs en parallèle, etc. Peut-être qu'un flux de travail impliquant une extension comme ipycache pourrait fonctionner, mais cela semble un peu trop compliqué.

Notes

Retrait (stripping) Sortie

  • Lorsque le notebook est en cours d'exécution, on peut utiliser la fonction Cell/All Output/Clear pour supprimer la sortie.
  • Il existe quelques scripts pour supprimer la sortie, comme le scripts. nbstripout.py qui supprime la sortie, mais ne produit pas la même sortie qu'en utilisant l'interface du notebook. Ceci a finalement été inclus dans la version ipython/nbconvert mais il a été clôturé en indiquant que les modifications sont maintenant incluses dans le répertoire de l'entreprise. ipython/ipython mais la fonctionnalité correspondante ne semble pas encore avoir été incluse. (mise à jour) Ceci étant dit, La solution de Gregory Crosswhite montre que cela est assez facile à faire, même sans invoquer ipython/nbconvert Cette approche est donc probablement réalisable si elle peut être connectée correctement. (L'attacher à chaque système de contrôle de version, cependant, ne semble pas être une bonne idée - cela devrait d'une manière ou d'une autre s'accrocher au mécanisme du carnet de notes).

Groupes de discussion

Questions

Pull Requests

0 votes

Cela semble être une bonne chose à ajouter en tant que problème sur le site Web de la Commission européenne. github.com/ipython/ipython ou soumettez une demande de retrait qui vous aide à atteindre cet objectif.

0 votes

Comme vous pouvez le constater, il existe déjà une pléthore de relations publiques et de questions relatives à cet objectif. Une fois ceux-ci résolus (à savoir PR 4175 ), alors une réponse définitive devrait être disponible, mais elle impliquera probablement des scripts supplémentaires en dehors d'IPython (des hooks git ou hg par exemple). Par conséquent, je ne pense pas qu'il y aura quoi que ce soit à gagner en ajoutant un nouveau PR ou problème.

0 votes

Oui, leur développement progresse rapidement et régulièrement chaque jour. Mais les développeurs sont de bonnes personnes (et ont probablement lu ce message). Je sais que je veux un flux de travail facile pour travailler avec git.

22voto

Marc Wouts Points 169

Après quelques années de suppression des sorties dans les carnets, j'ai essayé de trouver une meilleure solution. J'utilise maintenant Jupytext une extension pour Jupyter Notebook et Jupyter Lab que j'ai conçue.

Jupytext peut convertir les carnets Jupyter en divers formats de texte (scripts, Markdown et R Markdown). Et inversement. Il offre également la possibilité de paire un carnet de notes à l'un de ces formats, et de synchroniser automatiquement les deux représentations du carnet de notes (une .ipynb et un .md/.py/.R ).

Laissez-moi vous expliquer comment Jupytext répond aux questions ci-dessus :

me permet de choisir entre inclure ou exclure la sortie,

En .md/.py/.R ne contient que les cellules d'entrée. Vous devez toujours suivre ce fichier. La version .ipynb seulement si vous voulez suivre les sorties.

m'empêche de commettre accidentellement des sorties si je ne le souhaite pas,

Ajouter *.ipynb a .gitignore

me permet de conserver la sortie dans ma version locale,

Les sorties sont conservées dans le fichier (local) .ipynb fichier

me permet de voir quand j'ai des changements dans les entrées en utilisant mon système de contrôle de version (c'est-à-dire que si je ne contrôle que les entrées mais que mon fichier local a des sorties, alors j'aimerais pouvoir voir si les entrées ont changé (ce qui nécessite un commit). L'utilisation de la commande d'état du contrôle de version enregistrera toujours une différence puisque le fichier local a des sorties).

La différence sur le .py/.R o .md est ce que vous recherchez

me permet de mettre à jour mon cahier de travail (qui contient la sortie) à partir d'un cahier propre mis à jour. (mise à jour)

Tirer la dernière révision de la .py/.R o .md et rafraîchissez votre notebook dans Jupyter (Ctrl+R). Vous obtiendrez les dernières cellules d'entrée du fichier texte, avec les sorties correspondantes de l'application .ipynb fichier. Le noyau n'est pas affecté, ce qui signifie que vos variables locales sont préservées - vous pouvez continuer votre travail là où vous l'avez laissé.

Ce que j'aime avec Jupytext, c'est que le carnet de notes (sous forme de .py/.R o .md ) peut être modifié dans votre IDE préféré. Avec cette approche, le refactoring d'un notebook devient facile. Une fois que vous avez terminé, il vous suffit de rafraîchir le notebook dans Jupyter.

Si vous voulez essayer : installez Jupytext avec pip install jupytext et redémarrez votre éditeur Jupyter Notebook ou Lab. Ouvrez le carnet de notes que vous voulez contrôler la version, et le jumeler vers un fichier Markdown (ou un script) à l'aide de la commande Menu Jupytext dans le carnet de notes Jupyter (ou le fichier Commandes Jupytext dans Jupyter Lab). Sauvegardez votre notebook, et vous obtiendrez les deux fichiers : l'original .ipynb plus la représentation textuelle promise du carnet de notes, qui convient parfaitement au contrôle de version !

Pour ceux qui seraient intéressés : Jupytext est également disponible sur le site ligne de commande .

18voto

neves Points 3075

Mise à jour : Maintenant vous pouvez éditer le carnet de notes Jupyter directement dans Visual Studio Code. Vous pouvez choisir de modifier la notebook ou le fichier python converti.

J'ai finalement trouvé un moyen simple et productif de faire jouer ensemble Jupyter et Git. J'en suis encore aux premiers pas, mais je pense déjà que c'est beaucoup mieux que toutes les autres solutions alambiquées.

Code Visual Studio est un éditeur de code cool et open source de Microsoft. Il possède une excellente extension Python qui vous permet désormais de Importer un carnet de notes Jupyter en tant que code python. Maintenant, vous pouvez aussi directement éditer les Jupyter Notebooks .

Après avoir importé votre carnet de notes dans un fichier python, tout le code et le markdown seront réunis dans un fichier python ordinaire, avec des marqueurs spéciaux dans les commentaires. Vous pouvez le voir dans l'image ci-dessous :

VSCode editor with a notebook converted to python

Votre fichier python contient juste le contenu des cellules d'entrée du cahier. La sortie sera générée dans une fenêtre divisée. Vous avez du code pur dans le notebook, il ne change pas pendant que vous l'exécutez. Pas de sortie mélangée avec votre code. Pas de format JSON incompréhensible pour analyser vos différences.

Juste du pur code python où vous pouvez facilement identifier chaque différence.

Je n'ai même pas besoin de version de mon .ipynb plus de fichiers. Je peux mettre un *.ipynb ligne dans .gitignore .

Vous avez besoin de générer un carnet de notes pour le publier ou le partager avec quelqu'un ? Aucun problème, il suffit de cliquez sur le bouton d'exportation dans la fenêtre python interactive

Exporting a python file to Notebook format

Si vous éditez directement le carnet de notes, il y a maintenant une icône Convert and save to a python script . Jupyter icons in Visual Studio Code

Voici une capture d'écran d'un carnet de notes dans Visual Studio Code :

Editing Notebook inside VSCode

Je ne l'utilise que depuis un jour, mais je peux enfin utiliser Jupyter avec Git.

P.S. : La complétion de code VSCode est bien meilleure que Jupyter.

14voto

Wes Turner Points 91

(2017-02)

stratégies

  • on_commit() :
    • dépouiller la sortie > name.ipynb ( nbstripout , )
    • dépouiller la sortie > name.clean.ipynb ( nbstripout ,)
    • toujours nbconvert en python : nom.ipynb.py ( nbconvert )
    • toujours convertir en markdown : nom.ipynb.md ( nbconvert , ipymd )
  • vcs.configure() :
    • git difftool, mergetool : nbdiff et nbmerge depuis nbdime

outils

13voto

Spencer Boucher Points 832

Voici une nouvelle solution de Cyrille Rossant pour IPython 3.0, qui persiste dans les fichiers markdown plutôt que dans les fichiers ipymd basés sur json :

https://github.com/rossant/ipymd

9voto

simon Points 984

Je viens de tomber sur "jupytext" qui semble être une solution parfaite. Il génère un fichier .py à partir du carnet de notes et les deux restent synchronisés. Vous pouvez contrôler la version, différencier et fusionner les entrées via le fichier .py sans perdre les sorties. Lorsque vous ouvrez le carnet de notes, il utilise le fichier .py pour les cellules d'entrée et le fichier .ipynb pour les sorties. Et si vous voulez inclure la sortie dans git, il vous suffit d'ajouter l'ipynb.

https://github.com/mwouts/jupytext

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X