![]() |
Wie Embedded-Python und PIP?
Ich würde den PackageManager gern benutzen, aber er hasst mich. :cry:
Gegeben: Python 3.8.10 Embedded 32-bit + Python4Delphi Das P4D damals aus GitHub, bzw. hier aus'm Forum (nicht das Neue vom GetIt, k.A. ob es da Unterschiede gibt). Also im Prinzip das ![]() (Unser Python4Delphi ist zwar bissl angepasst, damit es mit dem Embedded besser geht, weil der Entwickler vorrangig auf ein installiertes Python bedacht war, aber egal ... wir wollten einfach keine externen Abhängigkeiten, wenn z.B. der Kunde bei sich eine andere Python-Version installiert) Und nun versuchte ich dort via PIP etwas zu "installieren". z.B.
Delphi-Quellcode:
des
python.exe -m pip install requests
![]() So geht das erstmal natürlich nicht, denn es fehlt ja das Modul "pip". Für das Nachfolgende ist das Embedded (EXE oder DLL im Delphi) egal irrelevant. (unnötig aufwändig, extra noch eine Test-Anwendung in Delphi) Die python.exe wird also erstmal als "Portable" benutzt. (macht für die Funktion keinen Unterschied) Einige Standardsachen (Python-Scripts und Modules) liegen als *.pyc in der python38.zip, sowie als *.pyd im Verzeichnis) PS: Ja, im Python wird ein Modul "request" mitgeliefert (python38.zip), aber benötigt wird "requests". :stupid: Versuch 1: ![]() Die ![]() und
Delphi-Quellcode:
macht etwas, lädt es runter und es sieht so aus, als würde es installiert.
python.exe get-pip.py
Code:
es sind in .\Scripts\ ein paar *.exe aufgetaucht
Collecting pip
Downloading pip-23.1.2-py3-none-any.whl (2.1 MB) ------------------------------------------------- 2.1/2.1 MB 11.9 MB/s eta 0:00:00 Collecting setuptools Downloading setuptools-68.0.0-py3-none-any.whl (804 kB) ------------------------------------------------- 804.0/804.0 kB 24.8 MB/s eta 0:00:00 Collecting wheel Downloading wheel-0.40.0-py3-none-any.whl (64 kB) ------------------------------------------------- 64.5/64.5 kB ? eta 0:00:00 Installing collected packages: wheel, setuptools, pip WARNING: The script wheel.exe is installed in 'C:\*****\Python3\Scripts' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. WARNING: The scripts pip.exe, pip3.8.exe and pip3.exe are installed in 'C:\*****\Python3\Scripts' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. Successfully installed pip-23.1.2 setuptools-68.0.0 wheel-0.40.0 und unter .\Lib\site-packages\ Unterverzeichnisse mit den 3 runtergeladenen Modulen und weitere Dateien/Verzeichnisse von der Packageverwaltung. aber
Delphi-Quellcode:
sagt immernoch, dass es kein PIP gäbe.
python.exe -m pip install requests
Zitat:
Delphi-Quellcode:
sagt das Gleiche.
.\Scripts\pip.exe
Zitat:
So, also nun Versuch 2: ebenfalls ![]() Die ![]() und
Delphi-Quellcode:
python.exe pip.pyz install requests
Code:
Hier wird "scheinbar" auch das Gewünschte runtergeladen,
Collecting requests
Downloading requests-2.31.0-py3-none-any.whl (62 kB) ------------------------------------------------- 62.6/62.6 kB 1.6 MB/s eta 0:00:00 Collecting charset-normalizer<4,>=2 (from requests) Downloading charset_normalizer-3.2.0-cp38-cp38-win32.whl (89 kB) ------------------------------------------------- 89.4/89.4 kB 2.6 MB/s eta 0:00:00 Collecting idna<4,>=2.5 (from requests) Downloading idna-3.4-py3-none-any.whl (61 kB) ------------------------------------------------- 61.5/61.5 kB 814.3 kB/s eta 0:00:00 Collecting urllib3<3,>=1.21.1 (from requests) Downloading urllib3-2.0.3-py3-none-any.whl (123 kB) ------------------------------------------------- 123.6/123.6 kB 3.7 MB/s eta 0:00:00 Collecting certifi>=2017.4.17 (from requests) Downloading certifi-2023.5.7-py3-none-any.whl (156 kB) ------------------------------------------------- 157.0/157.0 kB 2.3 MB/s eta 0:00:00 Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests WARNING: The script normalizer.exe is installed in 'C:\*****\Scripts' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. Successfully installed certifi-2023.5.7 charset-normalizer-3.2.0 idna-3.4 requests-2.31.0 urllib3-2.0.3 also in .\Scripts\ eine *.exe und unter .\Lib\site-packages\ das "requests" und dessen Requires (certifi, charset_normalizer, idna und urllib3). Aber es geht dann dennoch nicht, also wird nicht gefunden. Dann jetzt mal Testen. (Anhand dem 2. Versuch) Per Parameter, aber ginge auch als PY-Script.
Delphi-Quellcode:
python -c "print('example')"
oder
Delphi-Quellcode:
als test.py und
print('example')
Delphi-Quellcode:
python test.py
perfekt und es gibt auch schön das
Delphi-Quellcode:
aus.
example
Mit einem Modul (aus der python38.zip) geht's auch.
Delphi-Quellcode:
=>
python -c "import uuid; print(uuid.uuid4())"
Delphi-Quellcode:
5d6615d3-b65e-467c-b6ca-dfbf6fe7f874
Ebenfalls mit einem Modul von außerhalb. ( _hashlib.pyd im Verzeichnis, nicht hashlib.pyc aus der python38.zip )
Delphi-Quellcode:
=>
python -c "import _hashlib; print(_hashlib.openssl_md5('aaa'.encode('utf-8')).hexdigest())"
Delphi-Quellcode:
47bce5c74f589f4867dbd57e9ca9f808
Nun aber unser neues Modul.
Delphi-Quellcode:
ergibt das bekannte Bild
python -c "import requests"
Zitat:
Die Hilfe war auch keine Hilfe. ![]()
Delphi-Quellcode:
will dennoch nicht, denn es mag keine - und ' oder " in sonstwelchen Varianten ändert sowieso nichts.
python -c "import Lib.site-packages.requests"
Außerdem wäre es eh blöd, was IMPORTs in Fremd-Komponenten anginge. Die Modul-Verzeichnisse von
Delphi-Quellcode:
direkt ins Python-Verzeichnis
.\Lib\site-packages\
Delphi-Quellcode:
verschoben/kopiert geht zwar,
.
Delphi-Quellcode:
python -c "import requests; r=requests.get('https://github.com/timeline.json'); print(r.status_code,' ',r.text)"
aber da könnte ich mir das PIP doch auch sparen und diese Module/Verzeichnisse manuell runterladen. :freak: |
AW: Wie Embedded-Python und PIP?
Schau Dir mal das Konzept von virtuellen Environments bei Python an.
Solange Du nicht explizit in einem virtuellen Environment bist, weiss PIP das nicht und installiert grundsätzlich alles global (Womit Du eine bereits bestehende Installation ggf. zerschiessen könntest, weil Du ggf. packages in anderen Versionen installierst als die, die ein existierendes Stück Software braucht). Und wenn Du selber ein so umgebogenes Python hast, das eben nicht die "normalen" globalen Packages verwendet, findet es die dann eben auch nicht. |
AW: Wie Embedded-Python und PIP?
Gut, ich hab hier grade kein "installiertes" Python drauf, aber zumindestens sieht es erstmal so aus, als wenn PIP "hier nur" in Unterverzeichnisse was reinpappt. (könnte vielleicht mal noch ein Python installieren und dann processmonitoren)
Im Moment sieht es so aus, als wenn ich die pip.pyz zumindestens nutzen könnte, zum Runterladen inkl. der Abhängigkeiten. Und das dann manuell ins Hauptverzeichnis verschieben müsste, damit es genutzt werden kann. Kollege hatte es (vor)gestern alles manuell gemacht. * das gewünschte Python-Script besorgt * ausprobiert und geschaut was fehlt * das dann gesucht und z.B. von GitHub runtergeladen * wieder ausprobiert, was jetzt noch fehlt usw. Aktuell war mein Plan, sein Runtergeladenes bei uns ins GitRepo einzufügen, damit das Setup es auch in den Installationen verteilt und die pip.pyz zu belassen, damit man zumindestens den automatischen Download nutzen könnte (und dann halt verschieben). [ADD] Boar eh, gleich das erste gesponsorte Suchergebnis im G "Wissenschaftliche Artikel zu python virtuellen Environments" ... da bekommt man doch Angst? Bezüglich PIP nichts im Python4Delphi gefunden, aber zum VENV bzw. VirtualEnv, welches am Ende auf eine pyvenv.cfg hinaus läuft. ![]() ![]() Ich glaub innerhalb dieser/unseren "portablen Installation" brauchen wir aktuell wohl noch kein VirtualEnvironment. -> mehrere getrennte Umgebungen für unsere python.exe/dll Außer vielleicht, wenn es eine virtuelle Umgebung wird, welche auch dieses Verzeichnis benutzt. :angle2: Gefühlt brauchen wir doch "bloß" irgendwo einen Suchpfad, damit Python auch in diesem PIP-Verzeichnis sucht? Also das "import requests" nicht nur in .\requests.* oder .\python38.zip\requests.*, sondern auch im .\Lib\site-packages\requests.* |
AW: Wie Embedded-Python und PIP?
Ja, Python verwendet viel an Umgebungsvariablen, die u.a. eben auch durch die virtual environments gesteuert / belegt werden.
Python muss wissen wo es nach modulen suchen muss, sonst sucht es nur global an seinen default-Orten. Durch andere variablen wird allerdings für PIP definiert, wo es drauf arbeitet, sonst nimmt es seine default-Orte. Die Python- und die PIP-Defaults sind aber nicht zwangsläufig identisch (bzw. vermutlich nur mehr oder weniger zufällig, wenn Du in einer globalen Installation arbeitest). Das virtual env macht im Prinzip nix anderes, als die für diese Dinge verwendeten Umgebungsvariablen zu setzen, inkl. auch den PATH so anzupassen dass die jeweiligen python- und pip executables des aktuellen Envs genommen werden (weil Du pro virtuellem environment ja auch unterschiedliche Python-Versionen haben kannst). Du musst keine virtuellen envs verwenden, aber in dem Kontext in dem Python dann ausgeführt wird müssen halt zumindest alle notwendigen Umgebungsvariablen auf die richtigen Verzeichnisse zeigen und Du musst sicherstellen, dass die PATH-Angabe deine lokalen Verzeichnisse vor den globalen listet, damit nicht versehentlich ein globales pip mit lokalem python oder umgekehrt verwendet wird. |
AW: Wie Embedded-Python und PIP?
Danke nochmal, für's Stupsen in die passende Richtung. :thumb:
Ahhh, es gibt die python38._pth da stehen die Suchpfade drin, also "python38.zip" und "." und NEU nun von mir auch "Lib\site-packages" sowie ein "Addons", wo ich grade die zusätzlichen Scripte reinschiebe (damit liegt in "." nur noch der Inhalt der python-3.8.10-embed-win32.zip ) Außerdem kann man dort auch automatische Imports und ein InitialScript hinterlegen. (muß man nur drauf achten beim nächsten Upgrade das nicht zu überschreiben, bzw. nicht zu vergessen es in die neue ._pth zu übernehmen :freak:) Zitat:
Wo ich langsam immer mehr Suchbegriffe zusammen hatte, fand sich nun auch endlich etwas ..... (ur)alter Weg:
Code:
Quelle:
import sys
py_ext_path = r"C:\Users\bob\AppData\Local\Programs\Python\Python38\Lib\site-packages" if py_ext_path not in sys.path: sys.path.append(py_ext_path) ![]() oder die Umgebungsvariable PYTHONPATH oder
Code:
oder neu eben die python38._pth :firejump:
import sys
sys.path.append('.\Lib\site-packages') import mod ![]() ![]() ![]() ![]() ![]() ![]() |
AW: Wie Embedded-Python und PIP?
Liste der Anhänge anzeigen (Anzahl: 1)
:hi:
Zitat:
Im Grunde ist das der Unterschied zwischen manuellem Download und dem Installieren via PIP, wo zusätzliche Dateien aufgetaucht sind. Weiß jemand, was Diese darstellen sollen? Anhang 56146 Ja, die dist-infos sind klar, aber diese markierten PYD :?: Sie sind im Download nicht da und hier auch ausschließlich innerhalb dieses einen Packages. Gelöscht und neu installiert, da sind sie auch schon drin. (hätte sein können, dass es noch Reste meiner Tests waren) Klar, einfach löschen und weg ist das Problem, aber ich wüsste gern warum, vorallem wenn sie beim nächsten Update wieder da sein sollten. Die genaue Fehlermeldung kann ich noch nicht liefern. Kollege will dann nochmal bei sich das Verzeichnis zurücksetzen und wenn er den Fehler wieder sieht ........ |
AW: Wie Embedded-Python und PIP?
Wie ist denn nun der bevorzugte Weg, die PIP Abhängigkeiten automatisch mit zu installieren?
Hast du da was in der ._pth Datei ergänzt und wenn ja, was :wink: Und wie wird das getriggered? Automatisch beim Erzeugen der PythonEngine? Viele Grüße Bastian |
AW: Wie Embedded-Python und PIP?
Ich fürchte viele sind Linux-Entwickler oder nutzen ein großes installiertes Python,
wo bereits einige Module vorinstalliert sind und welche dann fast alle vergessen in ihre Requires eintzutragen. Steht dann aber meistens irgendwo in der Mitte der Logausgabe, wo Fehlermeldung+Stacktrace gern 1-2 Bildschime lang ist. das Python von dort ![]() z.B. ![]() dann das ![]() also die ttps://bootstrap.pypa.io/pip/pip.pyz ins Verzeichnis (das ist eine ZIP, wo alles drin ist ... ABER nicht auspacken) oder die ![]()
Delphi-Quellcode:
python get-pip.py
leider lädt Letzteres das PIP-Modul auch nur runter, aber vergißt ebenfalls den Suchpfad (python*._pth) z.B. python38._pth
Code:
Addons ist von mir (manuell runtergeladene *.py, damit die nicht im RootVerzeichnis rumkullern und ein Upgrade einfacher ist)
python38.zip
. Addons Lib\site-packages # Uncomment to run site.main() automatically #import site Lib\site-packages ist für das Runtergeladene vom PIP und Nachfolgendes könnte man für automatische Initialisierungen benutzen
Code:
und die
@prompt @@$G$S
@cd /d "%~dp0" @echo. @echo Aktuelle pip.pyz downloaden. @echo. @echo Info: PIP ist nicht als Python-Modul via PIP installiert, @echo sonden liegt als gepackte Python-Application vor. @echo. @pause @echo. del pip.pyz curl https://bootstrap.pypa.io/pip/pip.pyz --output "pip.pyz" @echo. @pause ![]() (aber aufpassen, denn da ist python*._pth drin und würde somit überschrieben)
Delphi-Quellcode:
python pip.pyz <command> <params>
bzw.
Delphi-Quellcode:
python -m pip <command> <params>
Code:
Elso einfach im Explorer in die Adresszeile "CMD" schreiben, [Enter] und dann schön Rumbefehlen.
python pip.pyz help Hilfe
python pip.pyz list Liste des Installierten python pip.pyz search Suchen : geht nicht mehr, aber siehe https://pypi.org/search bzw. https://pypi.org/classifiers/ python pip.pyz install <modulname> Installieren python pip.pyz uninstall <modulname> Deinstallieren python pip.pyz show <modulname> Infos: Abhängigkeiten, Version, Beschreibung, Quelle usw. python pip.pyz check Abhängigkeiten prüfen PIP läd auch ein paar Hilfs-EXEn runter, welche über die Suchpfade gesucht werden, anstatt mit einem relativem Pfad zu arbeiten, daher dann noch in Console/Batch:
Code:
durch das PYCACHE= wird der Download-Cache des PIP deaktiviert :oops:
@set PATH=%~dp0Scripts;%PATH%
@set PYCACHE= ::@set PYTHONPATH=irgendwas....... python.exe pip.pyz install sowie beim Laden des Python im Delphi:
Delphi-Quellcode:
P := EnviromentVar('PATH', False);
S := ExtractFilePath(FPythonDLL) + 'Scripts'; if DirectoryExists(S) and not ContainsText(P, S) then SetEnvironmentVariable('PATH', PChar(S + ';' + P)); |
AW: Wie Embedded-Python und PIP?
Danke für die ausführliche Antwort. Das heißt du installierst die Requirements / Pakete immer über die Kommandozeile direkt in diesem embedded Python Verzeichnis.
Ich hab gedacht / befürchtet, dass das über ein TPythonEngine.ExecuteIrgendwas direkt ausgeführt werden kann / muss. Aber über die Shell sollte das klappen. Ich teste und berichte :) |
AW: Wie Embedded-Python und PIP?
Man könnte es auch über ein Python-Script im Python machen. (ob über die Console oder die DLL wäre egal .... ich weiß nur nicht wie man dort die Parameter übergibt)
TPythonEngine selbst kennt ja das PIP nicht direkt, drum ist dort auch nichts eingebaut. Bezüglich der EnvironmentVariablen ... die kann man auch ans ShellExecute/CreateProcess übergeben (komisch, ich dachte es gab auch einen Parameter an ShellExecute/ShellExecuteEx) mit SET & den CALL als "Script" an die CMD.exe oder SetEnvironmentVariable (im eigenen Process) und dann ShellExecute/ShellExecuteEx oder SetEnvironmentVariable und dann mit GetEnvironmentStrings an CreateProcess:lpEnvironment oder GetEnvironmentStrings + die Variablen und dann an CreateProcess:lpEnvironment oder ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz