Distribution meines Projekts

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
BennySamir

Hallo Zusammen,

zu beginn wollte ich mich erstmal vorstellen, da ich neu hier bin.
Mein Name ist Benny und ich beschäftige mich seit einiger Zeit mit Python.
Bisher hat auch alles gut geklappt und ich habe auch bereits 2-3 kleinere Projekte mit Python programmiert.

Nun hab ich mich hier angemeldet um bei bestimmten Themen etwas Unterstützung zu erhalten, bzw. auch andere die noch weniger Erfahrung haben zu unterstützen.

Ich habe vor ein paar Tagen ein kleines Projekt gestartet, Ziel ist es eine Art Alarmanlage zu implementieren.
Mein Projekt habe ich unter https://github.com/BennySamir/Pi-SecurityCam veröffentlicht.

In meinem Projekt verwende ich einige Abhängigkeiten. Nun möchte ich, dass jemand der mein Programm nutzen will diese Abhängigkeiten nicht selbst installieren muss.
Hier bin ich bereits auf das Thema Distribution über ein setup.py Script gestoßen. Doch bisher hab ich es immer nur so verstanden dass man es für Module benutzt.
Mein Programm ist aber kein Modul, sondern eine lauffähige Application welches aber gewisse abhängigkeiten zu anderen Modulen bzw. Linux-Programmen hat.

Ist es mit der setup.py Methode möglich diese Abhängigkeiten zu installieren?

Meine Abhängigkeiten sind die Anwendung MP4Box, welche über den Befehl
sudo apt-get update
sudo apt-get install -y gpac
installiert werden.
Die zweite Abhängigkeit ist das auf Github veröffentliche Modul PICam welche über
sudo pip install https://github.com/ashtons/picam/zipbal ... #egg=picam
installiert wird
Die dritte Abhängigkeit ist die Dropbox API für Python, welche ich mit
sudo pip install dropbox
installieren kann.
Und die letzte Abhängigkeit ist der Daemon für das verwendete Tinkerforge Modul:
# Use libudev1 instead of libudev0 in Ubuntu 13.04
sudo apt-get install libusb-1.0-0 libudev0
# On ARM (e.g. Raspberry Pi)
wget http://download.tinkerforge.com/tools/b ... _armhf.deb
sudo dpkg -i brickd_linux_latest_armhf.deb

und die benötigten Bindings:
easy_install tinkerforge.egg

Ist es möglich alle diese Abhängigkeiten über das Setup.py script zu installieren?

Vielen Dank schon einmal für die Hilfe.
BlackJack

@BennySamir: Ich würde mal spontan sagen da gibt es keinen normalen Weg. Über die ``setup.py`` und zum Beispiel ``pip`` lassen sich nur Python-Abhängigkeiten automatisiert installieren.¹ Wobei auch Anwendungen mit der ``setup.py`` kein Problem sind wenn man sie als Python-Paket mit einem Skript zum starten des Programms schreibt, denn das ist ein Szenario welches vorgesehen ist.

Ansonsten kann man sich damit beschäftigen Debianpakete zu erstellen. Da kann man Abhängigkeiten aber auch nur in Form von Debianpaketen angeben. Also muss es alles andere entweder irgendwo als Debian-Paket geben und möglichst in der Linux-Distribution vorhanden sein, oder man muss die externen Sachen selber paketieren und mit ausliefern.

Ich würde wahrscheinlich für's erste eine ``setup.py`` für ``pip`` schreiben welche die Python-Abhängigkeiten installiert und in der INSTALL oder README und auf der Projektseite angeben welche Debianpakete zusätzlich installiert werden müssen. Gleich mit der entsprechenden ``sudo apt-get-install …``-Zeile, damit Anfänger das einfach übernehmen können.

____
¹ Das stimmt nicht ganz weil die ``setup.py`` normaler Python-Code ist, in dem man im Grunde *alles* machen kann, aber es wäre zumindest ungewöhnlich da anzufangen Debianpakete herunterzuladen und zu installieren.
BennySamir

@BlackJack: Danke. Ja schau mir das mal mit PIP an. Kennst du eine gut verständliche Anleitung wie ich PIP nutzen kann?? Danke
BlackJack

@BennySamir: Naja, ``pip`` hat eine Dokumentation, und `setuptools` hat auch eine.
BennySamir

Ich hab es jetzt erst einmal über ein Shell-Script gelöst.
Ich hätte da aber noch eine andere Frage.
Und zwar verwende ich bei diesem Projekt einen Dropbox Upload. Hierfür habe ich einen Key und einen Secret. Diese kann ich nicht mit auf GitHub hosten (hab es ursprünglich gemacht und Ärgern bekommen :oops: ). Jetzt habe ich diese in ein Config-File ausgelagert, welches nicht auf GitHub publiziert wird. Jetzt möchte ich aber meine App nicht nur zum weiterentwickeln anderen anbieten, sondern auch damit Leute sie direkt nutzen. Hierfür muss ich ihnen ja die Möglichkeit bieten meine bei Dropbox erstellte App auch zu verwenden, ohne dabei die Keys ihnen mit zuteilen. Jetzt habe ich mir überlegt dass ich einfach die Anwendung zusätzlich als Bytecode zur Verfügung stelle und vor dem compilieren die Keys in den Code schreibe. Das sollte doch prinzipiel so möglich sein oder? Den Bytecode kann man ja nicht mehr lesen, bzw. die Keys lassen sich aus der Dateien nicht extrahieren.
Wenn dies möglich ist, gibt es Workflow Programm welche mir es ermöglichen automatisch vorher die Keys einzufügen und den Code kompilieren? Ich kenn nur Grunt, was aber leider kaum Python Funktionen bietet. Oder muss ich mir da selbst was Programmieren?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@BennySamir: was läßt Dich annehmen, dass man ByteCode nicht lesen kann, oder einfacher, importieren und sich die Variablen einfach ausgeben läßt? Außerdem sollte bei Python immer der SourceCode beim Bytecode liegen, um verschiedene Pythonversionen zu unterstützen und dann ergibt es natürlich keinen Sinn, wenn der ByteCode sich nicht aus dem SourceCode erstellen läßt.
BlackJack

@BennySamir: Egal was Du mit den Zugangsdaten im Programm machst, *irgendwann* muss das Programm die ja an den Dropbox-Server schicken, und an *der* Stelle kann man die abgreifen wenn man das Programm unter Kontrolle hat. Der Ansatz ist also schon grundlegend falsch.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@BennySamir: ich habe mal einen kurzen Blick auf Deinen Code auf GitHub geworfen und mir sind dabei ein paar Dinge aufgefallen: Die »__del__«-Methoden in Deinen Klassen sind nicht der richtige Ort, um Konfigurationsparameter zu speichern. Wann und ob diese Methode aufgerufen wird, ist nämlich nicht festgelegt. Klassenattribute sind kein Weg um Defaultattribute einer Instanz zu setzen. Der Leser wird dadurch nur verwirrt, wenn Klassenattribute plötzlich durch Instanzattribute ersetzt werden. Der richtige Weg ist es, alle Attribute in »__init__« zu setzen. Doppelte Unterstriche bei Deinen Attributen haben nur Sinn, wenn Du sie vor Namenskonflikten bei Vererbung schützen willst. Da Du das aber nicht tust, ist maximal ein Unterstrich zum Kennzeichnen eines nicht-öffentlichen Attributs sinnvoll. Das prüfen auf »is True« und »is False« ist umständlich. Bei True kann »is True« einfach weggelassen werden »a is False« wird zu »not a«.
Die beiden for-Schleifen in »write_config« sind sinnlos, da Du nur den Namen »u« wieder aus dem lokalen Namensraum löschst, den Du aber erst eine Zeile zuvor erzeugt hast. Programme mit »os.system« zu starten, wenn der Befehl aus Strings zusammengesetzt wird, ist nicht nur fehleranfällig sondern auch ein großes Sicherheitsrisiko. Nimm »subprocess.Popen« aber ohne »shell=True«. Du hast in einigen »print« und »if«-Zeilen noch zu viele Klammern. In »setup_tinkerforge« gibt es zu viele Codewiederholungen, die ganze Funktion läßt sich wahrscheinlich auf 10 Zeilen reduzieren.
BennySamir

@Sirius3: Vielen vielen Dank für die Tipps. Ich habe gerade alle umgesetzt

@BlackJack: Ich weiß dass man mit gut genug Energie und Einsatz an alles ran kommt :-) Aber ich ich glaub in dem Fall würde es sich nicht lohnen, da diese Keys nur dafür benötigt werden einen Access_token bei Dropbox anzufordern. Anschließend werden Sie nicht mehr gebraucht und ermöglichen auch keinerlei zugriff auf irgendwelche Dateien. Außerdem dem kann jeder selbst bei Dropbox solche Keys anfordern. Hättest du denn einen anderen Ansatz für mich? Ich soll einfach nur dafür sorgen, dass die Keys nicht im Klartext bei GitHub liegen.

Der Dropbox Dev Support hat mir folgendes geschrieben:
If you want to release your code (e.g., on GitHub), you can certainly do so, but we do ask that you omit your keys from the publicly available source code. That way, if someone wants to fork your code and make their own version of the app, they will need to register for their own keys.

If you want to release your app to end users, we do recommend including but encrypting/obfuscating the keys. While of course it's impossible to truly protect a secret in a client-side app, you should at least make it a bit difficult to make it clear that users/developers should not be extracting the keys from your app.
@Sirius3: ich habe wohl ByteCode mit BinärCode gleichgesetzt :-D Dass es da einen unterschied gibt weiß ich. Bin davon ausgegangen dass es sehr aufwendig ist Informationen aus einem ByteCode zu extrahieren. Und das der Aufwand sich dafür nicht lohnt.
BlackJack

@BennySamir: Also Bytecode ist in diesem Fall durch die CPython-Implementierung ziemlich genau definiert. Aber was ist Binärcode? So ganz allgemein doch alles was nicht als Textdatei angesehen werden, also auch die Bytecode-Dateien, die vom CPython-Compiler erzeugt werden. Oder meinst Du damit Maschinencode der direkt auf dem Prozessor ausgeführt werden kann? Wenn dort der Entwickler-Schlüssel unkodiert drin steht, dann kann man ihn relativ einfach finden. Und wie gesagt: Irgendwann muss der ja mal an den Webdienst geschickt werden, und an der Stelle kann man ihn abgreifen, und der Aufwand dafür ist unabhängig davon wie aufwändig die Daten im Programm selbst verschleiert sind.

Der Mail vom Support nach zu urteilen würde ich a) den Schlüssel in eine eigene Datei (Konfigurationsdatei oder Python-Modul) auslagern und die Datei aus der Versionsverwaltung ausnehmen, und b) den Schlüssel dort zum Beispiel Base64-kodiert speichern. Zusätzlich ein Kommentar in die Datei für Leute die den Schlüssel suchen sich doch bitte einen Eigenen zu besorgen.
BennySamir

BlackJack hat geschrieben:Aber was ist Binärcode? [...] Oder meinst Du damit Maschinencode [...]
Sorry :oops: Ja ich meine Maschinencode.
Oh man, dass Thema scheint ja echt nicht leicht zu sein :?
Antworten