Dropbox-Upload mit Python, API v2

Dieser Beitrag zeigt, wie Sie mit einem kleinen Python-Script Dateien vom Raspberry Pi in Ihr Dropbox-Konto hochladen. Die in der zweiten und dritten Auflage unseres Buchs beschriebene Vorgehensweise wird ab 28.6.2017 nicht mehr funktionieren, weil Dropbox voraussichtlich mit diesem Datum die alte API v1 deaktivieren wird. Ab dann muss die neue API v2 verwendet werden, die dieser Beitrag behandelt.

Update 19.8.2017: Das Paket requests muss aktualisiert werden, damit das Dropbox-Modul funktioniert (Quelle).

Dropbox-App einrichten

Die Grundvoraussetzung besteht natürlich einmal darin, dass Sie über ein eigenes Dropbox-Konto verfügen. Auf den Dropbox-Developer-Seiten richten Sie dann in der sogenannten »App Console« eine neue Dropbox-App ein:

https://www.dropbox.com/developers/apps

Für dieses Beispiel haben ich der App den Namen pi-buch-uploader gegeben. Sie müssen als App-Namen einen im Dropbox-Universum eindeutigen Namen verwenden! Wenn Ihnen nichts besseres einfällt, versuchen Sie es mit einer Kombination aus Ihrem Namen vorname-nachname-test123.

Beim Einrichten den App haben Sie die Wahl zwischen zwei Zugriffsvarianten (access type):

  • App folder: die App hat nur den Zugriff auf ein Verzeichnis, das gleichlautend wie der App-Name ist
  • Full dropbox: die App hat Zugriff auf alle ihre Dropbox-Daten

Für dieses Beispiel ist die App-Folder-Variante ausreichend. In der Einstellungsseite dieser App finden Sie nun den Button Generate, um einen App-spezifischen Code (ein Token) zu generieren.

Eine neue Dropbox-App einrichten

Dropbox-Funktionen installieren

Für Python-Funktionen zur Kommunikation mit Dropbox befinden sich in einem Erweiterungspaket, das sich am einfachsten mit pip installieren lässt. Der Kommandoname pip steht für Pip Installs Python und ist eine eigenes Paketverwaltungssystem für Python. Das Paket requests ist zwar standardmäßig unter Raspbian schon installiert, seine Version ist aber zu alt für Dropbox. pip3 install requests ersetzt das Paket durch eine neuere Version.

sudo apt-get install python3-pip
sudo pip3 install dropbox
sudo pip3 install requests

Erste Tests

Mit dem zuvor generierten Token können wir nun testen, ob der Verbindungsaufbau zu Dropbox gelingt. Das folgende Mini-Script sollte Informationen über Ihren Dropbox-Account liefern. Entscheidend ist, dass Sie zur Kommunikation mit Dropbox ein Dropbox-Objekt verwenden (API v2), nicht mehr DropboxClient (API v1).

#!/usr/bin/python3
import dropbox
db = dropbox.Dropbox('ihr-token')
print('Account infos: ', db.users_get_current_account())

Die Ausgabe sollte so ähnlich wie im folgenden Listing aussehen:

./dropbox-info.py
  Account infos:  
    FullAccount(account_id='dbid:xxx', 
                name=Name(given_name='Michael', ...), 
                email='xxx', 
                email_verified=True, 
                disabled=False, 
                locale='de', ...)

Klappt soweit alles, ist es Zeit für den ersten Upload. Die folgenden Zeilen laden die Datei test.jpg aus dem lokalen Verzeichnis in das Root-Verzeichnis der Dropbox-App hoch. Die hochgeladene Datei hat dort den Namen upload.jpg. Beachten Sie, dass der Pfad im zweiten Parameter der files_upload-Methode mit einem Schrägstrich beginnen muss!

#!/usr/bin/python3
import dropbox
db = dropbox.Dropbox('ihr-token')
fname = 'test.jpg'     # Name einer lokalen Datei
dname = '/upload.jpg'  # Name der Datei in Dropbox
f = open(fname, 'rb')
response = db.files_upload(f.read(), dname)
print('uploaded:', response)
f.close()

Foto mit Datum- und Zeitinfos hochladen

Ein wenig praxisnäher ist das zweite Beispiel: Es erstellt zuerst ein Foto und lädt dieses dann in das Dropbox-Verzeichnis hoch. Der Dateiname des Fotos unter Dropbox setzt sich aus rapi- und dem Datum zusammen, z.B. rapi-2017-06-30.jpg.

#!/usr/bin/python3
import datetime, dropbox, picamera
db = dropbox.Dropbox('your-token')

# Foto erstellen und lokal speichern
localname = 'tmp.jpg'
camera = picamera.PiCamera()
camera.resolution=(1280, 960)
camera.capture(localname)
camera.close()

# Foto hochladen
f = open(localname, 'rb')
today = datetime.date.today()
upname = today.strftime('/rapi-%Y-%m-%d.jpg')
db.files_upload(f.read(), upname)
f.close()

Migrationsprobleme

Bei unseren Tests hatten wir mehrfach das Problem, dass bei alten Dropbox-Apps die Fehlermeldung Your app is not currently allowed to use API v2. auftrat. Die Lösung bestand darin, eine neue Dropbox-App einzurichten — eigentlich etwas unbefriedigend. Wenn Dropbox erreichen will, dass möglichst viele Apps bis Ende Juli 2017 auf v2 umgestellt werden, sollten derartige Probleme jetzt eigentlich nicht mehr auftreten.

Allgemeingültige Dropbox-Authentifizierung

Wir sind hier davon ausgegangen, dass Ihr Script nur mit Ihrem eigenen Dropbox-Konto kommunizieren möchte. Ganz anders ist die Ausgangslage, wenn Sie ein Script zur Weitergabe an andere Benutzer entwickeln, die jeweils ihre eigenen Dropbox-Konten verwenden möchten.

In diesem Fall müssen Sie im Script Code vorsehen, der dem Benutzer die Möglichkeit gibt, den jeweiligen Dropbox-Zugriff zu authentifizieren. Der Benutzer wird dabei auf eine Seite von Dropbox geleitet, muss dort sein Dropbox-Passwort angeben und erhält dann einen speziellen Code für das Script. Ihr Script bittet um die Eingabe dieses Codes und speichert ihn so, dass es später wieder darauf zugreifen kann. Mehr Details können Sie auf den unter Quellen aufgezählten Seiten nachlesen:

Quellen