Relativer Pfad für Windows / Linux / Mac

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
fischer-klaus3
User
Beiträge: 27
Registriert: Donnerstag 17. September 2020, 08:07

Hallo,

Ich versuche, einen Kaggle-Datensatz herunterzuladen. Hier ist die Dokumentation zu https://www.kaggle.com/docs/api und https://github.com/Kaggle/kaggle-api. Eine Json-Datei muss heruntergeladen und in einem bestimmten Ordner abgelegt werden. Es ist wie folgt geschrieben:
This will trigger the download of kaggle.json, a file containing your API credentials. Place this file in the location ~/.kaggle/kaggle.json (on Windows in the location C:\Users<Windows-username>.kaggle\kaggle.json

Ich zeige meine Implementierung weiter unten. Der Code funktionierte zuvor in Colab / Jupyter Notebooks für Windows und Mac. Ich möchte weiterhin in PyCharm arbeiten und verwende derzeit Windows. Leider wird eine Fehlermeldung angezeigt:

Code: Alles auswählen

with open('/root/.kaggle/kaggle.json', 'w') as file:
FileNotFoundError: [Errno 2] No such file or directory: '/root/.kaggle/kaggle.json'

Wie kann ich den Ordner mit Hilfe von Pathlib universell angeben? Damit es später unter Windows, Mac und Linux funktioniert?

Code: Alles auswählen

 username_kaggle = "dummy"
    token_kaggle = "dummy"
    savepath = "/retailrocket"
    if not os.path.exists(savepath):
        os.makedirs(savepath)
    os.chdir(savepath)

    # Download the dataset from kaggle
    os.system("mkdir ~ /.kaggle")
    os.system("touch ~ /.kaggle / kaggle.json")

    api_token = {"username": username_kaggle, "key": token_kaggle}
    with open('/root/.kaggle/kaggle.json', 'w') as file:
        json.dump(api_token, file)
    os.system("kaggle datasets download - d retailrocket / ecommerce - dataset")
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@fischer-klaus3: `Path.home()` liefert das Heimatverzeichnis des Benutzers.

Der gezeigte Code enthält einige Fehler. Und `os.system()` an sich sollte man schon nicht benutzen. Zum ausführen von externen Programmen ist das `subprocess`-Modul da.

Die ersten beiden `os.sysem()`-Aufrufe sind auch unsinnig. Verzeichnisse anlegen kann man auch ohne externe Prozess — wird ja sogar kurz vorher in dem Code-Schnipsel *gemacht*, und das ``touch`` ist überflüssig weil die Datei kurz danach sowieso mit Python-Code erstellt und mit Inhalt beschrieben wird.

Bei den externen Kommandos sind überall komische Leerzeichen drin, die da nicht hingehören.

`os.chdir()` sollte da auch nicht verwendet werden. Baue die Pfade ordentlich zusammen statt diesen prozessweiten Zustand zu ändern.

Sowohl Code als auch Daten wiederholt man nicht im Quelltext. Das ist fehleranfällig und unnötig schwer zu warten/ändern. Für Daten definiert man am Anfang entsprechende Konstanten.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
fischer-klaus3
User
Beiträge: 27
Registriert: Donnerstag 17. September 2020, 08:07

@__blackjack__ danke für deine Hilfe und die Tipps! Bin noch ein Pythonnoobie.
Also ich lege quasi mit Path.home()\.kaggle\kaggle.json die Datei ab und rufe die dann von dort aus?
Und wie stoße ich denn Download an, wenn os.system("kaggle datasets download - d retailrocket / ecommerce - dataset") eine schlechte Idee ist? Gibt es etwas anderes dazu? :)
Vielen Dank im Voraus!
fischer-klaus3
User
Beiträge: 27
Registriert: Donnerstag 17. September 2020, 08:07

@__blackjack__ danke für deine Hilfe und die Tipps! Bin noch ein Pythonnoobie.
Also ich lege quasi mit Path.home()\.kaggle\kaggle.json die Datei ab und rufe die dann von dort aus?
Und wie stoße ich denn Download an, wenn os.system("kaggle datasets download - d retailrocket / ecommerce - dataset") eine schlechte Idee ist? Gibt es etwas anderes dazu? :)
Vielen Dank im Voraus!
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Naja, __blackjack__ war mal wieder schneller.

Das ganze könnte so aussehen:

Code: Alles auswählen

from pathlib import Path
import subprocess
KAGGLE_USERNAME = "dummy"
KAGGLE_TOKEN = "dummy"
SAVEPATH = Path.home() / "retailrocket"


config_path = Path.home() / ".kaggle" / "kaggle.json"
config_path.parent.mkdir(exists_ok=True)
api_token = {"username": KAGGLE_USERNAME, "key": KAGGLE_TOKEN}
config_path.write_text(json.dumps(apitoken))

SAVEPATH.mkdir(exists_ok=True)
subprocess.run(["kaggle", "datasets", "download", "-d", "retailrocket / ecommerce - dataset"], cwd=SAVEPATH)
Wobei ich bei dem externen Aufruf keine Ahnung habe, wie die Parameter richtig wären.
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Sirius3: Na mit dem Code warst Du jetzt schneller. 🙂

Code: Alles auswählen

#!/usr/bin/env python3
import json
import subprocess
from pathlib import Path

KAGGLE_USERNAME = "dummy"
KAGGLE_TOKEN = "dummy"
KAGGLE_CONFIG_FILE_PATH = Path.home() / ".kaggle" / "kaggle.json"

SAVE_PATH = Path("retailrocket")


def main():
    KAGGLE_CONFIG_FILE_PATH.parent.mkdir(parents=True, exist_ok=True)
    with KAGGLE_CONFIG_FILE_PATH.open("w", encoding="ascii") as file:
        json.dump({"username": KAGGLE_USERNAME, "key": KAGGLE_TOKEN}, file)

    SAVE_PATH.mkdir(parents=True, exist_ok=True)
    subprocess.run(
        [
            "kaggle",
            "datasets",
            "download",
            "-d",
            str(SAVE_PATH / "ecommerce-dataset"),
        ],
        check=True,
    )


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
fischer-klaus3
User
Beiträge: 27
Registriert: Donnerstag 17. September 2020, 08:07

@Sirius3 und @__blackjack__ vielen Dank für die schnelle Hilfe! :) Nehme mir viel mit aus eurem Codesnippet! Wünsche euch einen tollen Tag.
Antworten