web-dev-qa-db-fra.com

Utilisation des ordinateurs portables IPython sous contrôle de version

Quelle est la bonne stratégie pour conserver les carnets IPython sous contrôle de version?

Le format de cahier est assez pratique pour le contrôle de version: si on veut contrôler le cahier et les sorties, cela fonctionne assez bien. Le désagrément survient lorsque l’on veut seulement contrôler la version de l’entrée, à l’exclusion des sorties de cellules (alias "build products") qui peuvent être de grandes blobs binaires, en particulier pour les films et les tracés. En particulier, j'essaie de trouver un bon flux de travail qui:

  • me permet de choisir entre inclure ou non la sortie,
  • m'empêche de commettre accidentellement des sorties si je ne les veux pas,
  • me permet de garder la sortie dans ma version locale,
  • me permet de voir les modifications apportées aux entrées à l’aide de mon système de contrôle de version (c’est-à-dire que si je ne contrôle que les versions mais que mon fichier local contient des sorties, je voudrais pouvoir voir si les entrées ont été modifiées L’utilisation de la commande version control status 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 vierge mis à jour. (mise à jour)

Comme mentionné, si j'ai choisi d'inclure les sorties (ce qui est souhaitable lors de l'utilisation de nbviewer par exemple), alors tout va bien. Le problème est quand je ne veux pas contrôler la version de la sortie. Il existe des outils et des scripts pour supprimer la sortie du bloc-notes, mais je rencontre fréquemment les problèmes suivants:

  1. Je commets accidentellement 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ère vraiment conserver la sortie dans ma copie locale (il faut parfois un certain temps pour la reproduire, par exemple).
  3. Certains des scripts qui séparent la sortie modifient légèrement le format par rapport à l'option de menu Cell/All Output/Clear, créant ainsi un bruit indésirable dans les diffs. Ceci est résolu par certaines des réponses.
  4. Lors de l'extraction des modifications dans une version vierge du fichier, je dois trouver un moyen d'incorporer ces modifications dans mon cahier de travail sans avoir à tout réexécuter. (mise à jour)

J'ai examiné plusieurs options dont je vais discuter ci-dessous, mais je n'ai pas encore trouvé de bonne solution complète. Une solution complète peut nécessiter certaines modifications d'IPython ou peut s'appuyer sur de simples scripts externes. J'utilise actuellement Mercurial , mais j'aimerais une solution qui fonctionne également avec git : une solution idéale serait agnostique avec contrôle de version.

Cette question a été discutée à plusieurs 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. C'est bien si cela nécessite une version récente (même de développement) de IPython ou une extension facile à installer.

Mise à jour: Je joue avec mon cahier modifié version qui enregistre éventuellement une version .clean à chaque enregistrement en utilisant suggestions de Gregory Crosswhite . Ceci satisfait la plupart de mes contraintes mais laisse les problèmes suivants non résolus:

  1. Ce n'est pas encore une solution standard (nécessite une modification de la source ipython. Existe-t-il un moyen de résoudre ce problème avec une simple extension? Besoin d'une sorte de hook lors de la sauvegarde.
  2. Un problème que j'ai avec le flux de travail actuel est de tirer les changements. Ceux-ci entreront dans le fichier .clean, et devront 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 cahier, mais cela peut être pénible, surtout si certains résultats dépendent de longs calculs, de calculs parallèles, etc.). Je ne sais pas encore comment résoudre ce problème. . Peut-être qu'un flux de travail impliquant une extension comme ipycache pourrait fonctionner, mais cela semble un peu trop compliqué.

Remarques

Retrait (stripping) de la sortie

  • Lorsque le cahier est en cours d'exécution, vous pouvez utiliser l'option de menu Cell/All Output/Clear pour supprimer la sortie.
  • Il existe certains scripts pour supprimer la sortie, tels que le script nbstripout.py qui supprime la sortie, mais ne produit pas le même résultat que l’utilisation de l’interface du cahier. Cela a finalement été inclus dans le repot ipython/nbconvert , mais il a été fermé en indiquant que les modifications sont maintenant incluses dans ipython/ipython , mais la fonctionnalité correspondante ne semble pas avoir été encore inclus. (update) Cela étant dit, la solution de Gregory Crosswhite montre que c'est assez facile à faire, même sans invoquer ipython/nbconvert , cette approche est donc probablement réalisable si elle peut être correctement connectée. (La relier à chaque système de contrôle de version ne semble toutefois pas être une bonne idée. Cela devrait en quelque sorte être connecté au mécanisme de l'ordinateur portable. .)

Groupes de discussion

Problèmes

Demandes de traction

537
mforbes

Voici ma solution avec git. Cela vous permet simplement d'ajouter et de commettre (et de diff) comme d'habitude: ces opérations ne modifieront pas votre arbre de travail, et en même temps, le fait de (ré) exécuter un bloc-notes ne modifiera pas l'historique de votre git.

Bien que cela puisse probablement être adapté à d’autres VCS, je sais que cela ne répond pas à vos exigences (au moins l’agnosticité de VSC). Pourtant, il est parfait pour moi, et bien que ce ne soit rien de particulièrement brillant, et que beaucoup de gens l'utilisent probablement déjà, je n'ai pas trouvé d'instructions claires sur la façon de le mettre en œuvre en cherchant sur Google. Cela peut donc être utile à d’autres personnes.

  1. Enregistrez un fichier avec ce conten quelque part (supposons que ~/bin/ipynb_output_filter.py)
  2. Le rendre exécutable (chmod +x ~/bin/ipynb_output_filter.py)
  3. Créez le fichier ~/.gitattributes avec le contenu suivant

    *.ipynb    filter=dropoutput_ipynb
    
  4. Exécutez les commandes suivantes:

    git config --global core.attributesfile ~/.gitattributes
    git config --global filter.dropoutput_ipynb.clean ~/bin/ipynb_output_filter.py
    git config --global filter.dropoutput_ipynb.smudge cat
    

Terminé!

Limitations:

  • ça marche seulement avec git
  • dans git, si vous êtes dans la branche somebranch et que vous faites git checkout otherbranch; git checkout somebranch, vous vous attendez généralement à ce que l’arbre de travail ne soit pas modifié. Ici, vous aurez perdu la sortie et la numérotation des cellules des cahiers dont la source diffère entre les deux branches.
  • plus généralement, la sortie n'est pas du tout versée, comme dans la solution de Gregory. Afin de ne pas simplement le jeter à chaque fois que vous faites quelque chose impliquant une commande, l'approche peut être modifiée en la stockant dans des fichiers séparés (notez qu'au moment où le code ci-dessus est exécuté, l'identifiant de validation n'est pas connu!), et éventuellement en les versionnant (mais notez que cela nécessiterait plus qu'un git commit notebook_file.ipynb, bien que cela garderait au moins git diff notebook_file.ipynb libre de tout déchet base64).
  • cela dit, incidemment, si vous extrayez du code (c'est-à-dire commis par quelqu'un d'autre qui n'utilise pas cette approche) qui contient une sortie, celle-ci est extraite normalement. Seule la sortie produite localement est perdue.

Ma solution reflète le fait que, personnellement, je n'aime pas garder les éléments générés versionnés. Notez que les fusions impliquant la sortie invalident presque toujours la sortie ou votre productivité ou les deux.

EDIT:

  • si vous adoptez la solution telle que je l'ai suggérée (c'est-à-dire globalement), vous aurez des problèmes en cas de repositionnement de git que vous souhaitez pour la sortie de la version. Donc, si vous voulez désactiver le filtrage de sortie pour un référentiel git spécifique, créez simplement un fichier . Git/info/attributes , avec

    **. filtre ipynb =

en tant que contenu. Clairement, de la même manière, il est possible de faire le contraire: activer le filtrage uniquement pour un référentiel spécifique.

  • le code est maintenant maintenu dans son propre git repo

  • si les instructions ci-dessus aboutissent à ImportErrors, essayez d'ajouter "ipython" avant le chemin du script:

    git config --global filter.dropoutput_ipynb.clean ipython ~/bin/ipynb_output_filter.py
    

EDIT: Mai 2016 (mise à jour en février 2017): il existe plusieurs alternatives à mon script - pour être complet, voici une liste de celles que je connais: nbstripout ( autrevariantes ), nbstrip , jq .

115
Pietro Battiston

Nous avons un projet collaboratif dans lequel le produit est Jupyter Notebooks, et nous utilisons une approche qui fonctionne très bien: nous activons l'enregistrement automatique des fichiers .py et suivons les fichiers .ipynb et les fichiers .py.

De cette façon, si quelqu'un veut voir/télécharger le dernier cahier, il peut le faire via github ou nbviewer, et si quelqu'un veut voir comment le code du cahier a changé, il peut simplement regarder les modifications apportées aux fichiers .py. .

Pour Jupyter serveurs de bloc-notes , vous pouvez le faire en ajoutant les lignes.

import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['jupyter', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

dans le fichier jupyter_notebook_config.py et redémarrez le serveur de notebook.

Si vous ne savez pas dans quel répertoire trouver votre fichier jupyter_notebook_config.py, vous pouvez taper jupyter --config-dir, et si vous n'y trouvez pas le fichier, vous pouvez le créer en tapant jupyter notebook --generate-config. .

Pour Ipython 3 serveurs de bloc-notes , vous pouvez le faire en ajoutant les lignes.

import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['ipython', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

dans le fichier ipython_notebook_config.py et redémarrez le serveur de notebook. Ces lignes proviennent d'un problème de github qui donne une réponse @ minrk fourni et @dror les inclut également dans sa SO réponse.

Pour Ipython 2 serveurs de bloc-notes , vous pouvez le faire en démarrant le serveur à l'aide de:

ipython notebook --script

ou en ajoutant la ligne

c.FileNotebookManager.save_script = True

dans le fichier ipython_notebook_config.py et redémarrez le serveur de notebook.

Si vous ne savez pas dans quel répertoire trouver votre fichier ipython_notebook_config.py, vous pouvez taper ipython locate profile default, et si vous n'y trouvez pas le fichier, vous pouvez le créer en tapant ipython profile create. .

Voici notre projet sur github qui utilise cette approche : et voici un exemple de github explorant les modifications récentes apportées à un bloc-notes .

Nous avons été très heureux avec cela.

58
Rich Signell

J'ai créé nbstripout , basé sur MinRKs Gist , qui prend en charge Git et Mercurial (grâce à mforbes). Il est conçu pour être utilisé de manière autonome sur la ligne de commande ou en tant que filtre, qui est facilement installé dans le référentiel actuel via nbstripout install/nbstripout uninstall.

Obtenez-le de PyPI ou simplement

pip install nbstripout
36
kynan

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

https://github.com/rossant/ipymd

13
Spencer Boucher

(2017-02)

stratégies

  • on_commit ():
    • effacez la sortie> name.ipynb (nbstripout,)
    • effacez la sortie> name.clean.ipynb (nbstripout,)
    • toujours nbconvert to python: name.ipynb.py (nbconvert)
    • toujours convertir en markdown: name.ipynb.md (nbconvert, ipymd)
  • vcs.configure ():
    • git difftool, mergetool: nbdiff et nbmerge à partir de nbdime

outils

11
Wes Turner

J'ai finalement trouvé un moyen simple et productif de faire en sorte que Jupyter et Jit jouent bien ensemble. Je suis toujours dans les premiers pas, mais je pense déjà que c'est déjà le cas. beaucoup mieux que toutes les autres solutions compliquées.

Visual Studio Code est un éditeur de code source cool et open source de Microsoft. Il possède une excellente extension Python qui vous permet maintenant de importer un bloc-notes Jupyter en tant que code python.

Une fois que vous avez importé votre bloc-notes dans un fichier python, tout le code et toutes les annotations sont regroupés dans un fichier python ordinaire, avec des marqueurs spéciaux dans les commentaires. Vous pouvez voir dans l'image ci-dessous:

VSCode editor with a notebook converted to python

Votre fichier python contient uniquement le contenu des cellules d'entrée du bloc-notes. La sortie sera générée dans une fenêtre fractionnée. Vous avez du code pur dans le cahier, il ne change pas pendant que vous l'exécutez. Aucune sortie mélangée avec votre code. Pas d'étrange format Json incompréhensible pour analyser vos diffs.

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

Je n'ai même plus besoin de versionner mes fichiers .ipynb. Je peux mettre une ligne *.ipynb dans .gitignore.

Besoin de générer un cahier à publier ou à partager avec quelqu'un? Pas de problème, juste cliquez sur le bouton d'exportation dans la fenêtre interactive python

Exporting a python file to Notebook format

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.

9
neves

Comme indiqué par, le --script est obsolète dans 3.x. Cette approche peut être utilisée en appliquant un post-save-hook. Ajoutez en particulier ce qui suit à ipython_notebook_config.py:

import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['ipython', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

Le code provient de # 8009 .

8
Dror

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

Jupytext peut convertir les blocs-notes Jupyter en divers formats de texte (Scripts, Markdown et R Markdown). Et inversement. Il offre également la possibilité de coupler un bloc-notes à l'un de ces formats et de synchroniser automatiquement les deux représentations du bloc-notes (un .ipynb et un fichier .md/.py/.R).

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

me permet de choisir entre inclure ou non la sortie,

Le fichier .md/.py/.R contient uniquement les cellules en entrée. Vous devez toujours suivre ce fichier. Versionnez le fichier .ipynb uniquement si vous souhaitez suivre les résultats.

m'empêche de commettre accidentellement des sorties si je ne les veux pas,

Ajouter *.ipynb à .gitignore

me permet de garder la sortie dans ma version locale,

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

me permet de voir les modifications apportées aux entrées à l’aide de mon système de contrôle de version (c’est-à-dire que si je ne contrôle que les versions mais que mon fichier local contient des sorties, je voudrais pouvoir voir si les entrées ont été modifiées L’utilisation de la commande version control status enregistrera toujours une différence puisque le fichier local a des sorties.)

Le diff sur le fichier .py/.R ou .md est ce que vous recherchez

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

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

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

Si vous voulez essayer: installez Jupytext avec pip install jupytext et redémarrez votre éditeur Jupyter Notebook ou Lab. Ouvrez le bloc-notes que vous souhaitez contrôler par la version et associez-le à un fichier Markdown (ou à un script) à l'aide du Jupytext Men dans le bloc-notes Jupyter (ou les commandes Jupytext dans Jupyter Lab). Enregistrez votre bloc-notes et vous obtiendrez les deux fichiers: l'original .ipynb, ainsi que la représentation textuelle promise du bloc-notes, qui convient parfaitement au contrôle de version!

Pour ceux qui pourraient être intéressés: Jupytext est également disponible sur le ligne de commande .

8
Marc Wouts

Vient de tomber sur "jupytext" qui ressemble à une solution parfaite. Il génère un fichier .py à partir du bloc-notes, puis les synchronise. Vous pouvez contrôler les versions, falsifier et fusionner les entrées via le fichier .py sans perdre les sorties. Lorsque vous ouvrez le bloc-notes, il utilise le fichier .py pour les cellules d'entrée et le fichier .ipynb pour la sortie. Et si vous voulez inclure la sortie dans git, vous pouvez simplement ajouter ipynb.

https://github.com/mwouts/jupytext

7
simon

Les réponses très populaires de 2016 ci-dessus sont des hacks incohérents par rapport à la meilleure façon de le faire en 2019.

Plusieurs options existent, le meilleur qui réponde à la question est Jupytext.

Jupytext

Capturez le article de Towards Data Science sur Jupytext

La façon dont cela fonctionne avec le contrôle de version consiste à placer les fichiers .py et .ipynb dans le contrôle de version. Regardez le .py si vous voulez le diff d'entrée, regardez le .ipynb si vous voulez la dernière sortie rendue.

Mentions remarquables: VS studio, nbconvert, nbdime, hydrogène

Je pense qu'avec un peu plus de travail, VS studio et/ou hydrogène (ou similaire) deviendront les principaux acteurs de la solution à ce flux de travail.

7
SwimBikeRun

Malheureusement, je ne connais pas grand chose à Mercurial, mais je peux vous donner une solution qui fonctionne avec Git, dans l’espoir de pouvoir traduire mes commandes Git en leurs équivalents Mercurial.

Pour l’arrière-plan, dans Git, la commande add enregistre les modifications apportées à un fichier dans une zone de stockage intermédiaire. Une fois que vous avez fait cela, toutes les modifications ultérieures apportées au fichier sont ignorées par Git, à moins que vous ne lui demandiez de les mettre également en scène. Par conséquent, le script suivant, qui, pour chacun des fichiers donnés, supprime tous les outputs et Prompt_number sections, met en forme le fichier extrait, puis restaure l'original:

NOTE: Si cela vous génère un message d'erreur comme ImportError: No module named IPython.nbformat, utilisez ipython pour exécuter le script à la place de python.

from IPython.nbformat import current
import io
from os import remove, rename
from shutil import copyfile
from subprocess import Popen
from sys import argv

for filename in argv[1:]:
    # Backup the current file
    backup_filename = filename + ".backup"
    copyfile(filename,backup_filename)

    try:
        # Read in the notebook
        with io.open(filename,'r',encoding='utf-8') as f:
            notebook = current.reads(f.read(),format="ipynb")

        # Strip out all of the output and Prompt_number sections
        for worksheet in notebook["worksheets"]:
            for cell in worksheet["cells"]:
               cell.outputs = []
               if "Prompt_number" in cell:
                    del cell["Prompt_number"]

        # Write the stripped file
        with io.open(filename, 'w', encoding='utf-8') as f:
            current.write(notebook,f,format='ipynb')

        # Run git add to stage the non-output changes
        print("git add",filename)
        Popen(["git","add",filename]).wait()

    finally:
        # Restore the original file;  remove is needed in case
        # we are running in windows.
        remove(filename)
        rename(backup_filename,filename)

Une fois que le script a été exécuté sur les fichiers dont vous voulez valider les modifications, exécutez simplement git commit.

7

J'utilise une approche très pragmatique; qui fonctionnent bien pour plusieurs cahiers, à plusieurs côtés. Et cela me permet même de "transférer" des cahiers. Cela fonctionne aussi bien pour Windows que pour Unix/MacOS.
Al a pensé que c’était simple, c’est résoudre les problèmes ci-dessus ...

Concept

Fondamentalement, ne pas suivre les fichiers .ipnyb-, uniquement les fichiers .py- correspondants.
En démarrant le notebook-server avec l'option --script, ce fichier est automatiquement créé/enregistré lors de l'enregistrement du notebook. .

Ces fichiers .py- contiennent toutes les entrées; les non-codes sont enregistrés dans les commentaires, de même que les limites de cellules. Ce fichier peut être lu/importé (et glissé) dans le serveur de cahiers pour (re) créer un cahier. Seule la sortie est parti; jusqu'à ce qu'il soit relancé.

Personnellement, j'utilise Mercurial pour suivre les versions de fichiers .py; et utilisez les commandes normales (ligne de commande) pour ajouter, check-in (ect) pour cela. La plupart des autres (D) VCS le permettront.

Il est simple de suivre l’histoire maintenant; les .py sont petits, textuels et simples à différencier. De temps en temps, nous avons besoin d'un clone (branchez-le simplement; démarrez un deuxième cahier-serveur), ou d'une version plus ancienne (extraction et importation dans un serveur de cahier), etc.

Conseils & Astuces

  • Ajoutez *. Ipynb à '. Hgignore', afin que Mercurial sache qu'il peut ignorer ces fichiers.
  • Créez un script (bash) pour démarrer le serveur (avec l'option --script) et faites le suivi des versions
  • L'enregistrement d'un bloc-notes enregistre le fichier .py-, mais ne l'enregistre pas .
    • Ceci est un inconvénient: On peut oublier que
    • C'est un fonctionnalité aussi: Il est possible de sauvegarder un cahier (et de continuer plus tard) sans mettre en cluster l'historique du référentiel.

Vœux

  • Il serait bien d’avoir un bouton pour l’enregistrement/ajouter/etc dans le cahier
  • Une commande à (par exemple) file@date+rev.py) devrait être utile. Il serait trop compliqué d’ajouter cela; et peut-être que je le ferai une fois. Jusqu'à présent, je le fais simplement à la main.
6
Albert

J'ai construit le package python qui résout ce problème

https://github.com/brookisme/gitnb

Il fournit une interface de ligne de commande avec une syntaxe inspirée de git pour suivre/mettre à jour/des cahiers de notes dans votre référentiel git.

Heres 'un exemple

# add a notebook to be tracked
gitnb add SomeNotebook.ipynb

# check the changes before commiting
gitnb diff SomeNotebook.ipynb

# commit your changes (to your git repo)
gitnb commit -am "I fixed a bug"

Notez que la dernière étape, dans laquelle j'utilise "gitnb commit", consiste à valider votre dépôt Git. C'est essentiellement une enveloppe pour

# get the latest changes from your python notebooks
gitnb update

# commit your changes ** this time with the native git commit **
git commit -am "I fixed a bug"

Il existe plusieurs méthodes supplémentaires, et peut être configuré de manière à nécessiter plus ou moins la participation de l'utilisateur à chaque étape, mais c'est l'idée générale.

3
brook

Puisqu'il existe tant de stratégies et d'outils pour gérer le contrôle de version pour les ordinateurs portables, j'ai essayé de créer un diagramme de flux pour choisir une stratégie appropriée (créée en avril 2019).

Decision flow to pick version control strategy

3
nik

Pour faire suite à l’excellent script de Pietro Battiston, si vous obtenez une erreur d’analyse Unicode comme celle-ci:

Traceback (most recent call last):
  File "/Users/kwisatz/bin/ipynb_output_filter.py", line 33, in <module>
write(json_in, sys.stdout, NO_CONVERT)
  File "/Users/kwisatz/anaconda/lib/python2.7/site-packages/IPython/nbformat/__init__.py", line 161, in write
fp.write(s)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2014' in position 11549: ordinal not in range(128)

Vous pouvez ajouter au début du script:

reload(sys)
sys.setdefaultencoding('utf8')
3
Guillaume Dumas

Après avoir fouillé, j’ai finalement trouvé ce crochet de pré-sauvegarde relativement simple sur la documentation Jupyter . Il supprime les données de sortie de la cellule. Vous devez le coller dans le fichier jupyter_notebook_config.py (voir les instructions ci-dessous).

def scrub_output_pre_save(model, **kwargs):
    """scrub output before saving notebooks"""
    # only run on notebooks
    if model['type'] != 'notebook':
        return
    # only run on nbformat v4
    if model['content']['nbformat'] != 4:
        return

    for cell in model['content']['cells']:
        if cell['cell_type'] != 'code':
            continue
        cell['outputs'] = []
        cell['execution_count'] = None
        # Added by binaryfunt:
        if 'collapsed' in cell['metadata']:
            cell['metadata'].pop('collapsed', 0)

c.FileContentsManager.pre_save_hook = scrub_output_pre_save

De réponse de Rich Signell :

Si vous ne savez pas dans quel répertoire trouver votre fichier jupyter_notebook_config.py, vous pouvez taper jupyter --config-dir [dans la commande Invite/terminal], et si vous n'y trouvez pas le fichier, vous pouvez le créer. en tapant jupyter notebook --generate-config.

3
binaryfunt

J'ai fait ce qu'Albert et Rich ont fait: ne pas utiliser la version .ipynb (car ceux-ci peuvent contenir des images, ce qui devient désordonné). Au lieu de cela, exécutez toujours ipython notebook --script ou insérez c.FileNotebookManager.save_script = True dans votre fichier de configuration afin qu'un fichier (versionable) .py soit toujours créé lorsque vous enregistrez votre cahier.

Pour régénérer les cahiers (après avoir extrait un dépôt ou changé de branche), je mets le script py_file_to_notebooks.py dans le répertoire où je stocke mes cahiers.

Maintenant, après avoir extrait un dépôt, lancez simplement python py_file_to_notebooks.py pour générer les fichiers ipynb. Après avoir changé de branche, vous devrez peut-être exécuter python py_file_to_notebooks.py -ov pour écraser les fichiers ipynb existants.

Juste pour être sûr, il est bon d’ajouter également *.ipynb à votre fichier .gitignore.

Edit: je ne le fais plus parce que (A) vous devez régénérer vos cahiers à partir de fichiers py chaque fois que vous extrayez une branche et (B) il y a d’autres choses comme le démarquage dans les cahiers que vous perdez. Au lieu de cela, je supprime la sortie des ordinateurs portables en utilisant un filtre git. La discussion sur la façon de procéder est ici .

2
Peter

Ok, il semble donc que la meilleure solution actuelle, selon une discussion ici , consiste à créer un filtre git pour supprimer automatiquement la sortie des fichiers ipynb lors de la validation. .

Voici ce que j'ai fait pour que cela fonctionne (copié de cette discussion):

J'ai légèrement modifié le fichier nbstripout de cfriedline pour donner une erreur informative lorsque vous ne pouvez pas importer le dernier IPython: https://github.com/petered/plato/blob/fb2f4e252f50c79768920d0e7b870a8d799e92b/booksf/bookf/config/ strip_notebook_output Et l'a ajouté à mon référentiel, disons dans ./relative/path/to/strip_notebook_output

Également ajouté le fichier .gitattributes à la racine du référentiel, contenant:

*.ipynb filter=stripoutput

Et créé un setup_git_filters.sh contenant

git config filter.stripoutput.clean "$(git rev-parse --show-toplevel)/relative/path/to/strip_notebook_output" 
git config filter.stripoutput.smudge cat
git config filter.stripoutput.required true

Et a lancé source setup_git_filters.sh. La bonne chose $ (git rev-parse ...) est de trouver le chemin local de votre repo sur n'importe quelle machine (Unix).

2
Peter

Cette extension jupyter permet aux utilisateurs de pousser des blocs-notes jupyter directement dans github.

S'il vous plaît regardez ici

https://github.com/sat28/githubcommit

1
sat

Que diriez-vous de l’idée évoquée dans l’article ci-dessous, où le résultat du cahier devrait être conservé, avec l’argument selon lequel sa génération risque d’être longue, et c’est pratique puisque GitHub peut désormais rendre les cahiers. Des crochets de sauvegarde automatique ont été ajoutés pour exporter le fichier .py, utilisés pour les diffs et .html pour le partage avec les membres de l'équipe qui n'utilisent pas de portables ou de git.

https://towardsdatascience.com/version-control-for-jupyter-notebook-3e6cef13392d

0