[PYTHON] Obtenez des fichiers de données ailleurs pendant l'installation de pip

Aperçu

Je ne sais pas si c'est correct de le faire, mais je veux obtenir les données nécessaires pour le paquet à partir d'autre chose que le serveur PyPI et l'installer. Les arguments liés aux fichiers de données qui peuvent être décrits dans setup.py, package_data et data_files, sont tous deux distribués avec le code source. Il semble que seuls les fichiers soient pris en charge. Par conséquent, j'ai accroché la commande install_data appelée pendant pip install pour télécharger les fichiers nécessaires séparément.

Crochet de commande

Pour raccorder ou remplacer la commande, utilisez le mot-clé argument cmdclass dans la fonction setuptools.setup. Cela peut être fait en passant un dictionnaire avec l'implémentation comme valeur, en utilisant le nom de commande à remplacer comme clé. (Référence: Intégration de nouvelles commandes)

La source d'origine de la commande install_data à remplacer cette fois est ici. J'ai créé une commande install_data personnalisée pour référence.

import distutils.command.install_data
from os import path
import site
import sys
import urllib


class CustomInstallData(distutils.command.install_data.install_data):

    def run(self):
        # self.data_Les données de la fonction de configuration dans les fichiers_Contient la valeur passée à l'argument files.
        #c'est,(Liste des destinations de sauvegarde des fichiers de données et des chemins des fichiers de données)Puisqu'il est responsable de la liste des tapples, il est traité individuellement.
        for f in self.data_files:
            if not isinstance(f, tuple):
                continue
            
            for i, u in enumerate(f[1]):
                #Si le chemin du fichier de données n'est pas une URL, rien n'est fait.
                if not u.startswith("http"):
                    continue

                #Si le fichier de données cible est déjà local, réutilisez-le.
                base = path.basename(u)
                f[1][i] = path.join(sys.prefix, f[0], base)
                if not path.exists(f[1][i]):
                    f[1][i] = path.join(sys.prefix, "local", f[0], base)
                if not path.exists(f[1][i]):
                    f[1][i] = path.join(site.getuserbase(), f[0], base)
                if not path.exists(f[1][i]):
                    #S'il n'est pas trouvé localement, téléchargez.
                    f[1][i] = urllib.urlretrieve(u, base)[0]

        #Les autres traitements sont transférés vers la commande d'origine.
        return distutils.command.install_data.install_data.run(self)

Le traitement de base étant le même que la commande d'origine install_data, Créez une classe qui hérite de distutils.command.install_data.install_data. Notez que la classe parente est distutils.command.install_data.install_data au lieu de distutils.command.install_data.

Étant donné que la méthode d'exécution est le corps de la commande, remplacez cette méthode. self.data_files contient une liste de paires (directory, files)passées à l'argument data_files de la fonction setup # installation-fichiers-supplémentaires). directory est la destination de sauvegarde des fichiers de données et files est une liste de chemins de fichiers de données à installer.

Extrayez des éléments individuels de self.data_files et extrayez-en les chemins de fichiers de données individuels pour le traitement. Si le chemin du fichier de données n'est pas une URL, le traitement normal est suffisant, donc rien n'est fait pour eux.

Ensuite, si le fichier de données cible est déjà installé, je voudrais le réutiliser pour éviter les téléchargements inutiles. Selon le Manual, le fichier de données est enregistré dans.

Si le répertoire est un chemin relatif, il est interprété comme un chemin relatif à partir du préfixe d'installation (sys.prefix pour les packages Python purs, sys.exec_prefix pour les packages avec extensions).

Donc, si le nom du fichier que vous essayez d'installer est filename,

Tu peux vérifier. Cependant, dans mon Ubuntu, il a été enregistré en une seule étape en creusant ʻos.path.join (sys.prefix, "local", directory, filename) ʻ dans l'un des éléments ci-dessus. Par conséquent, dans le code ci-dessus, le chemin avec local est également vérifié.

Il est également possible que le paquet soit installé dans le répertoire utilisateur avec pip install --user. Dans ce cas, le package est enregistré sous site.USER_BASE, donc Dans le code ci-dessus, site.getuserbase () est utilisé pour obtenir la valeur de site.USER_BASE, et l'existence de ce fichier est également vérifiée.

Enfin, si le fichier de données cible n'est pas trouvé localement, il est obtenu en utilisant ʻurllib.urlretrieve`.

Le reste du traitement est identique à la commande install_data d'origine, la méthode de la classe parente est donc appelée. Puisque distutils.command.install_data.install_data est une ancienne classe, la méthode de la classe parente est appelée par distutils.command.install_data.install_data.run (self).

fonction de configuration

L'appel de la fonction de configuration à l'aide de la commande personnalisée ci-dessus est le suivant (les éléments non liés sont omis).

setup(
    data_files=[(
        "rgmining/data",
        ["http://times.cs.uiuc.edu/~wang296/Data/LARA/TripAdvisor/TripAdvisorJson.tar.bz2"]
    )],
    cmdclass={
        "install_data": CustomInstallData
    },
    ... #Autres éléments omis
)

CustomInstallData est passé en tant que classe d'implémentation de la commande install_data dans l'argument cmdclass. Vous pouvez maintenant transmettre l'URL à data_files.

Résumé

Afin d'éviter d'enregistrer un fichier énorme sur le serveur PyPI, nous avons résumé la méthode de téléchargement du fichier nécessaire à partir d'un autre serveur au moment de l'installation de pip. Cependant, ce n'est pas très bon pour la sécurité car il ne vérifie pas le hachage du fichier acquis. En premier lieu, je pense qu'il existe une autre méthode sans faire une chose aussi gênante, alors faites-le moi savoir si vous la connaissez.

Recommended Posts

Obtenez des fichiers de données ailleurs pendant l'installation de pip
Obtenir les données structurelles de CHEMBLID
Obtenir des données de Quandl en Python
pip installer les erreurs de gestion de mysql pendant python
pip install empêche l'installation du proxy
Installez le fichier de données avec setup.py
Obtenez des données de Twitter avec Tweepy
[Note] Obtenir des données de PostgreSQL avec Python
Obtenez des données de Cloudant avec le flacon Bluemix
Obtenez des données d'un oscilloscope avec pyVISA
Installez le client openstack à partir de pip pour ne pas obtenir d'erreur sur CentOS7
Obtenez des données de séries chronologiques de k-db.com avec Python
Obtenez plus de 10 données du magasin de paramètres SSM
installation sudo pip
Installer depuis conda-forge
Obtenez des données du module GPS à 10 Hz avec Python
Si vous êtes accro à pip, installez dlib sur OSX
Récupérer des fichiers depuis Linux en utilisant paramiko et scp [Python]
Obtenir des données de la base de données via ODBC avec Python (Access)