pip und request auf Synology

  • Ab sofort steht euch hier im Forum die neue Add-on Verwaltung zur Verfügung – eine zentrale Plattform für alles rund um Erweiterungen und Add-ons für den DSM.

    Damit haben wir einen Ort, an dem Lösungen von Nutzern mit der Community geteilt werden können. Über die Team Funktion können Projekte auch gemeinsam gepflegt werden.

    Was die Add-on Verwaltung kann und wie es funktioniert findet Ihr hier

    Hier geht es zu den Add-ons

Status
Für weitere Antworten geschlossen.

Jerome

Benutzer
Registriert
20. Okt. 2022
Beiträge
19
Reaktionspunkte
3
Punkte
3
Hallo zusammen,

ich habe mein Synology (718+) DSM auf dem neusten Stand und möchte ein curl an eine API (kavita) mittels Python-Script absetzten. Wenn ich pip und request direkt via SSH installiere bekomme ich folgende Fehlermeldung:

WARNING: Running pip as root will break packages and permissions. Y
ou should install packages reliably by using venv:
https://pip.pypa.io/warnings/venv

Kann man das ignorieren?

Wenn ich mein script in einer venv mit installiertem pip und request benutzte funktioniert alles einwandfrei.

Ich bin gerade nicht sicher ob ich den Fehler ignorieren kann und falls nein, kann ich nicht herausfinden wie ich die venv vor Ausführung des Scripts automatisch aktiviere. Ich habe schon einige Befehle im Script selbst ausprobiert und auch source volume1/py/kavita/bin/activate in einer, vor dem Script ausgeführten, Bash funktioniert nicht. Auch mit dem Aufgabenplaner komme ich nicht weiter.

Kann mir hier jemand weiter helfen?
Vielleicht bin ich auch mit request falsch unterwegs, pycurl hatte ich auch schon ausprobiert, fand ich aber jetzt weniger charmant.

Beste Grüße
 
Ich nutze das in synOCR genau so und es funktioniert einwandfrei.

https://git.geimist.eu/geimist/synOCR/src/tag/v1.3.0/APP/ui/synOCR.sh#L881
https://git.geimist.eu/geimist/synOCR/src/tag/v1.3.0/APP/ui/synOCR.sh#L2244

Ich lasse auch noch zusätzliche Module installieren, was für dein vorhaben vielleicht nicht relevant ist.

Bash:
# https://git.geimist.eu/geimist/synOCR/src/tag/v1.3.0/APP/ui/synOCR.sh#L881
python3_env="/usr/syno/synoman/webman/3rdparty/synOCR/python3_env"

prepare_python()
{
#########################################################################################
# This function check the python3 & pip installation and the necessary modules          #
#                                                                                       #
#########################################################################################


# check python3:
# ---------------------------------------------------------------------
    [ "$loglevel" = "2" ] && printf "\n${log_indent}  Check Python:\n"
    if [ ! $(which python3) ]; then
        echo "${log_indent}  (Python3 is not installed / use fallback search with regex"
        echo "${log_indent}  for more precise search results Python3 is required)"
        python_check=failed
        return 1
    else
        [ ! -d "$python3_env" ] && python3 -m venv "$python3_env"
        source "${python3_env}/bin/activate"

        if [ "$(cat "${python3_env}/synOCR_python_env_version" 2>/dev/null | head -n1)" != "$python_env_version" ]; then
            [ "$loglevel" = "2" ] && printf "${log_indent}  python3 already installed ($(which python3))\n"

        # check / install pip:
        # ---------------------------------------------------------------------
            [ "$loglevel" = "2" ] && printf "\n${log_indent}  Check pip:\n"
            if ! python3 -m pip --version > /dev/null  2>&1 ; then
                printf "${log_indent}  Python3 pip was not found and will be now installed ➜ "
                # install pip:
                tmp_log1=$(python3 -m ensurepip --default-pip)
                # upgrade pip:
                tmp_log2=$(python3 -m pip install --upgrade pip)
                # check install:
                if python3 -m pip --version > /dev/null  2>&1 ; then
                    echo "ok"
                else
                    echo "failed ! ! ! (please install Python3 pip manually)"
                    echo "${log_indent}  install log:"
                    echo "$tmp_log1" | sed -e "s/^/${log_indent}  /g"
                    echo "$tmp_log2" | sed -e "s/^/${log_indent}  /g"
                    python_check=failed
                    return 1
                fi
            else
                if python3 -m pip list 2>&1 | grep -q "version.*is available" ; then
                    printf "${log_indent}  pip already installed ($(python3 -m pip --version)) / upgrade available ...\n"
                    python3 -m pip install --upgrade pip | sed -e "s/^/${log_indent}  /g"
                else
                    [ "$loglevel" = "2" ] && printf "${log_indent}  pip already installed ($(python3 -m pip --version))\n"
                fi
            fi

            [ "$loglevel" = "2" ] && printf "\n${log_indent}  read installed python modules:\n"

            moduleList=$(python3 -m pip list 2>/dev/null)

            [ "$loglevel" = "2" ] && echo "$moduleList" | sed -e "s/^/${log_indent}  /g"

            # check / install python modules:
            # ---------------------------------------------------------------------
            echo -e
            for module in ${synOCR_python_module_list[@]}; do
                moduleName=$(echo "$module" | awk -F'=' '{print $1}' )

                unset tmp_log1
                printf "${log_indent}  ➜ check python module \"$module\": ➜ "
                if !  grep -qi "$moduleName" <<<"$moduleList"; then
                    printf "$module was not found and will be installed ➜ "

                    # install module:
                    tmp_log1=$(python3 -m pip install "$module")

                    # check install:
                    if grep -qi "$moduleName" <<<"$(python3 -m pip list 2>/dev/null)" ; then
                        echo "ok"
                    else
                        echo "failed ! ! ! (please install $module manually)"
                        echo "${log_indent}  install log:" && echo "$tmp_log1" | sed -e "s/^/${log_indent}  /g"
                        python_check=failed
                        return 1
                    fi
                else
                    printf "ok\n"
                fi
            done

            echo "$python_env_version" > "${python3_env}/synOCR_python_env_version"

            printf "\n"
        fi
    fi

    [ "$loglevel" = "2" ] && printf "\n${log_indent}  module list:\n" && python3 -m pip list | sed -e "s/^/${log_indent}  /g" && printf "\n"

    return 0
}


# https://git.geimist.eu/geimist/synOCR/src/tag/v1.3.0/APP/ui/synOCR.sh#L2244
prepare_python_log=$(prepare_python)
if [ "$?" -eq 0 ]; then
    [ -n "$prepare_python_log" ] && echo "$prepare_python_log"
    printf "${log_indent}prepare_python: OK\n"
    source "${python3_env}/bin/activate"
else
    [ -n "$prepare_python_log" ] && echo "$prepare_python_log"
    printf "${log_indent}prepare_python: ! ! ! ERROR ! ! ! \n"
fi

# dein Pythonscript aufrufen:
which python3
 
  • Like
Reaktionen: Jerome
Hi Stefan,

vielen Dank für deine ausführliche Antwort!
Wenn ich das richtig sehe benötige ich doch nur 2 Zeilen die ich via des Synology-Aufgabenplaners aufrufe:

Bash:
source "$/volume1/py/kavita/bin/activate"
which python3 /volume1/dl/script/update_cover.py

Zusammen gefasst möchte ich ja in meinem venv "kavita" mit installierten "pip" und "request" das script update_cover.py aufrufen, welches wiederum "import request" enthält um in python konvertierte curls auszuführen ... 😅

Aber ich checke nicht wie ich einer *.sh oder alternativ dem Aufgabenplaner sage, dass er mein Script im venv "kavita" ausführen soll...

Grüße

Jérôme
 
Zuletzt bearbeitet:
Die entscheidende Zeile ist: [ ! -d "$python3_env" ] && python3 -m venv "$python3_env". Den Pfad für $python3_env hatte ich ja zuvor definiert, den kannst du natürlich auch hard verdrahten.

Bash:
#!/bin/bash
python3_env="/volume1/py/kavita"

# prüfen, ob Enviroment vorhanden:
[ ! -d "$python3_env" ] && python3 -m venv "$python3_env"

# Enviroment aktivieren:
source "${python3_env}/bin/activate"

# Wenn ich mich recht erinnere, dann ist default kein pip installiert. Das kannst du noch prüfen und ggf. nachinstallieren, bzw. updaten:
# check / install pip:
# ---------------------------------------------------------------------
if ! python3 -m pip --version > /dev/null  2>&1 ; then
    printf "Python3 pip was not found and will be now installed ➜ "
    # install pip:
    tmp_log1=$(python3 -m ensurepip --default-pip)
    # upgrade pip:
    tmp_log2=$(python3 -m pip install --upgrade pip)

    # check install:
    if python3 -m pip --version > /dev/null  2>&1 ; then
        echo "ok"
    else
        echo "failed ! ! ! (please install Python3 pip manually)"
        echo "install log:"
        echo "$tmp_log1"
        echo "$tmp_log2"
        python_check=failed
        return 1
    fi
else
    if python3 -m pip list 2>&1 | grep -q "version.*is available" ; then
        printf "pip already installed ($(python3 -m pip --version)) / upgrade available ...\n"
        python3 -m pip install --upgrade pip
    else
        printf "pip already installed ($(python3 -m pip --version))\n"
    fi
fi

# Optional: testen, ob Python3 aus der env genommen wird (sollte wohl /volume1/py/kavita/bin/python3 ausgeben):
which python3

# dein Programm aufrufen:
python3 /volume1/dl/script/update_cover.py

exit 0

Die Routine zum testen, installieren und upgraden von PIP kannst du natürlich auch in deinem Pythonskript machen.
 
  • Like
Reaktionen: Motorum und Jerome
Vielen Dank, dass du dir die Mühe gemacht hast mir das Script zu schreiben!
Das Script ist ja sogar so programmiert, dass ich wirklich Garnichts mehr machen muss, du hast ja sogar meine Variablen eingefügt! :D

Es funktionierte zuerst nicht, aber ich glaube das lag daran, dass ich die *.sh-Datei unter Windows erzeugt habe ...

Folgender Befehl hat einmal geholfen:
Bash:
sed -i -e 's/^M$//' scriptname.sh

Jedes mal wenn ich die Datei unter Windows bearbeite muss ich diesen Befehl ausführen:
Bash:
cat scriptname.sh | sed -e 's/\r$//' > fixedscriptname.sh

Wenn ich das richtig verstanden habe ist sed ein Linux/Unix-Editor, durch dessen Bearbeitung die Datei ausführbar wird (Die Parameter kann ich nicht zuordnen, ich glaube -e bezeichnet ein Script und -s ersetzt Zeichen).

Lange Rede, kurzer Sinn: Es funktioniert!

Vielen Dank auch für die Ausführungen!
Dass im Standard kein pip installiert ist, kann ich bestätigen.

Wenn ich die Routine zum testen, installieren und upgraden von pip im Python-Script verwenden will muss ich den Code zuerst von Bash in Python umwandeln richtig?

Es ist zwar Schmuck am Nachhemd, aber dieses Script zeigt mir dann im Script selbst in welcher venv ich mich befinde:

Python:
import sys

def is_venv():
    return (hasattr(sys, 'real_prefix') or
            (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))

if is_venv():
    print('inside virtualenv or venv')
    print(sys.prefix)
else:
    print('outside virtualenv or venv')

Beste Grüße und schönen Abend noch!
 
  • Like
Reaktionen: geimist
Jedes mal wenn ich die Datei unter Windows bearbeite muss ich diesen Befehl ausführen:
Verwende am besten einen Editor, in dem du Unixzeilenenden definieren kannst oder nimm den Texteditor im DSM.

Wenn ich das richtig verstanden habe ist sed ein Linux/Unix-Editor durch dessen Bearbeitung die Datei ausführbar wird (Die Parameter kann ich nicht zuordnen, ich glaube -e bezeichnet ein Script und -s ersetzt Zeichen).
Die Ausführbarkeit ist ein Dateiattribut, welches man über die Eigenschaften in der Filestation oder auf der Kommandozeile z.b. mit chmod +x /Pfad/zum/skrip.sh setzen kann. Meines Wissens ändert sed von sich aus nichts an diesem Attribut.

Freut mich, dass es funktioniert (y)
 
  • Like
Reaktionen: Jerome
Status
Für weitere Antworten geschlossen.
 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat