[PYTHON] Holen Sie sich während der Pip-Installation Datendateien von einer anderen Stelle

Überblick

Ich weiß nicht, ob das in Ordnung ist, aber ich möchte die für das Paket benötigten Daten von etwas anderem als dem PyPI-Server abrufen und installieren. Datendateibezogene Argumente, die in setup.py, package_data und data_files beschrieben werden können, werden beide mit dem Quellcode verteilt. Es scheint, dass nur Dateien unterstützt werden. Daher habe ich den Befehl install_data, der während der Pip-Installation aufgerufen wurde, eingehakt, um die erforderlichen Dateien separat herunterzuladen.

Befehlshaken

Verwenden Sie zum Verknüpfen oder Ersetzen des Befehls das Schlüsselwortargument cmdclass in der Funktion setuptools.setup. Dies kann durch Übergeben eines Wörterbuchs mit der Implementierung als Wert erfolgen, wobei der zu ersetzende Befehlsname als Schlüssel verwendet wird. (Referenz: Integration neuer Befehle)

Die ursprüngliche Quelle des Befehls install_data, der dieses Mal ersetzt werden soll, ist hier. Ich habe einen benutzerdefinierten Befehl install_data als Referenz erstellt.

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_Die Setup-Funktionsdaten in Dateien_Enthält den an das Argument files übergebenen Wert.
        #das ist,(Liste der Speicherziele für Datendateien und Pfade für Datendateien)Da es für die Liste der Tapples verantwortlich ist, wird es einzeln verarbeitet.
        for f in self.data_files:
            if not isinstance(f, tuple):
                continue
            
            for i, u in enumerate(f[1]):
                #Wenn der Datendateipfad keine URL ist, wird nichts unternommen.
                if not u.startswith("http"):
                    continue

                #Wenn die Zieldatendatei bereits lokal ist, verwenden Sie sie erneut.
                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]):
                    #Wenn nicht lokal gefunden, herunterladen.
                    f[1][i] = urllib.urlretrieve(u, base)[0]

        #Die andere Verarbeitung wird auf den ursprünglichen Befehl übertragen.
        return distutils.command.install_data.install_data.run(self)

Da die grundlegende Verarbeitung mit dem ursprünglichen Befehl install_data identisch ist, Erstellen Sie eine Klasse, die distutils.command.install_data.install_data erbt. Beachten Sie, dass die übergeordnete Klasse "distutils.command.install_data.install_data" anstelle von "distutils.command.install_data" lautet.

Überschreiben Sie diese Methode, da die Ausführungsmethode der Hauptteil des Befehls ist. self.data_files enthält eine Liste von (Verzeichnis, Dateien)Paaren, die an das Argument data_files der Setup-Funktion übergeben wurden # Installation von zusätzlichen Dateien). Verzeichnis ist das Speicherziel für Datendateien, und Dateien ist eine Liste der zu installierenden Datendateipfade.

Extrahieren Sie einzelne Elemente aus "self.data_files" und extrahieren Sie einzelne Datendateipfade zur Verarbeitung daraus. Wenn der Datendateipfad keine URL ist, ist die normale Verarbeitung ausreichend, sodass nichts für sie getan wird.

Wenn die Zieldatendatei bereits installiert ist, möchte ich sie als Nächstes wiederverwenden, um unnötige Downloads zu vermeiden. Gemäß dem Handbuch wird die Datendatei in gespeichert.

Wenn das Verzeichnis ein relativer Pfad ist, wird es als relativer Pfad aus dem Installationspräfix interpretiert (sys.prefix für reine Python-Pakete, sys.exec_prefix für Pakete mit Erweiterungen).

Wenn der Dateiname, den Sie installieren möchten, "Dateiname" ist,

Du kannst nachschauen. In meinem Ubuntu wurde es jedoch an der Stelle gespeichert, an der ich einen Schritt als "os.path.join (sys.prefix," local ", Verzeichnis, Dateiname)" anstelle eines der oben genannten Schritte ausgegraben habe. Daher wird im obigen Code auch der Pfad mit local überprüft.

Es ist auch möglich, dass das Paket mit pip install --user im Benutzerverzeichnis installiert wird. In diesem Fall wird das Paket unter site.USER_BASE gespeichert Im obigen Code wird "site.getuserbase ()" verwendet, um den Wert von "site.USER_BASE" abzurufen, und das Vorhandensein dieser Datei wird ebenfalls überprüft.

Wenn die Zieldatendatei nicht lokal gefunden wird, wird sie schließlich mit "urllib.urlretrieve" erfasst.

Der Rest der Verarbeitung entspricht dem ursprünglichen Befehl install_data, daher wird die Methode der übergeordneten Klasse aufgerufen. Da distutils.command.install_data.install_data eine alte Klasse ist, wird die Methode der übergeordneten Klasse von distutils.command.install_data.install_data.run (self) aufgerufen.

Setup-Funktion

Der Aufruf der Setup-Funktion mit dem obigen benutzerdefinierten Befehl lautet wie folgt (nicht verwandte Elemente werden weggelassen).

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

CustomInstallData wird als Implementierungsklasse des Befehls install_data im Argument cmdclass übergeben. Jetzt können Sie die URL an data_files übergeben.

Zusammenfassung

Um zu vermeiden, dass eine große Datei auf dem PyPI-Server registriert wird, haben wir die Methode zum Herunterladen der erforderlichen Datei von einem anderen Server zum Zeitpunkt der Pip-Installation zusammengefasst. Es ist jedoch nicht sehr gut für die Sicherheit, da es den Hash der erfassten Datei nicht überprüft. Erstens habe ich das Gefühl, dass es eine andere Methode gibt, ohne so etwas zu tun. Lassen Sie es mich bitte wissen, wenn Sie es wissen.

Recommended Posts

Holen Sie sich während der Pip-Installation Datendateien von einer anderen Stelle
Strukturdaten von CHEMBLID abrufen
pip install mysql-Handling Fehler während Python
Die Installation von pip verhindert, dass der Proxy installiert wird
Installieren Sie die Datendatei mit setup.py
Holen Sie sich Daten von Twitter mit Tweepy
[Hinweis] Mit Python Daten von PostgreSQL abrufen
Holen Sie sich Daten von Cloudant mit Bluemix-Kolben
Holen Sie sich mit pyVISA Daten von einem Oszilloskop
Installieren Sie den Openstack-Client von Pip, damit unter CentOS7 kein Fehler angezeigt wird
Holen Sie sich mit Python Zeitreihendaten von k-db.com
Holen Sie sich mehr als 10 Daten aus dem SSM-Parameterspeicher
sudo pip installieren
Von conda-forge installieren
Holen Sie sich mit Python Daten vom GPS-Modul mit 10 Hz
Wenn Sie süchtig nach Pip sind, installieren Sie dlib unter OSX
Holen Sie sich Dateien von Linux mit paramiko und scp [Python]
Abrufen von Daten aus der Datenbank über ODBC mit Python (Access)