One place for hosting & domains

      So verwenden Sie ps, kill und schön zum Verwalten von Prozessen unter Linux


      Einführung


      Auf einem Linux-Server werden wie auf jedem anderen Computer, mit dem Sie möglicherweise vertraut sind, Anwendungen ausgeführt. Auf dem Computer werden diese als „Prozesse“ bezeichnet.

      Während Linux die Verwaltung auf niedriger Ebene hinter den Kulissen im Lebenszyklus eines Prozesses übernimmt, benötigen Sie eine Möglichkeit zur Interaktion mit dem Betriebssystem, um es von einer höheren Ebene aus zu verwalten.

      In diesem Leitfaden werden wir einige einfache Aspekte der Prozessverwaltung erörtern. Linux bietet eine reichliche Sammlung von Tools für diesen Zweck.

      Wir werden diese Ideen auf einem Ubuntu 12.04 VPS untersuchen, aber jede moderne Linux-Distribution funktioniert auf ähnliche Weise.

      So zeigen Sie laufende Prozesse unter Linux an


      top


      Der einfachste Weg, um herauszufinden, welche Prozesse auf Ihrem Server ausgeführt werden, besteht darin, den Befehl top auszuführen:

      top***
      
      top - 15:14:40 bis 46 min, 1 Benutzer, Lastdurchschnitt: 0,00, 0,01, 0,05 Aufgaben: 56 insgesamt, 1 laufend, 55 inaktiv, 0 gestoppt, 0 Zombie Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st Mem: 1019600k gesamt, 316576k gebraucht, 703024k frei, 7652k Puffer Swap: 0k insgesamt, 0k verwendet, 0k frei, 258976k zwischengespeichert   PID USER PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND               1 root      20   0 24188 2120 1300 S  0.0  0.2   0:00.56 init                   2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd               3 root      20   0     0    0    0 S  0.0  0.0   0:00.07 ksoftirqd/0            6 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0            7 root      RT   0     0    0    0 S  0.0  0.0   0:00.03 watchdog/0             8 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 cpuset                 9 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 khelper               10 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kdevtmpfs
      

      Der oberste Informationsblock enthält Systemstatistiken wie die Systemlast und die Gesamtzahl der Aufgaben.

      Sie können leicht erkennen, dass 1 Prozess ausgeführt wird und 55 Prozesse inaktiv sind (auch bekannt als inaktiv/ohne CPU-Ressourcen).

      Der untere Teil enthält die laufenden Prozesse und ihre Nutzungsstatistiken.

      htop


      Eine verbesserte Version von top namens htop ist in den Repositorys verfügbar. Installieren Sie sie mit diesem Befehl:

      sudo apt-get install htop
      

      Wenn wir den Befehl htop ausführen, sehen wir, dass es eine benutzerfreundlichere Anzeige gibt:

      htop***
      
        Mem[|||||||||||           49/995MB]     Durchschnittslast: 0.00 0.03 0.05   CPU[                          0.0%]     Aufgaben: 21, 3 thr; 1 laufend   Swp[                         0/0MB]     Betriebszeit: 00:58:11   PID USER PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command  1259 root       20   0 25660  1880  1368 R  0.0  0.2  0:00.06 htop     1 root       20   0 24188  2120  1300 S  0.0  0.2  0:00.56 /sbin/init   311 root       20   0 17224   636   440 S  0.0  0.1  0:00.07 upstart-udev-brid   314 root       20   0 21592  1280   760 S  0.0  0.1  0:00.06 /sbin/udevd --dae   389 messagebu  20   0 23808   688   444 S  0.0  0.1  0:00.01 dbus-daemon --sys   407 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.02 rsyslogd -c5   408 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.00 rsyslogd -c5   409 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.00 rsyslogd -c5   406 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.04 rsyslogd -c5   553 root       20   0 15180   400   204 S  0.0  0.0  0:00.01 upstart-socket-br
      

      Sie können hier mehr über die Verwendung von top und htop erfahren.

      Verwendung von ps zum Auflisten von Prozessen


      Sowohl top als auch htop bieten eine schöne Benutzeroberfläche, um laufende Prozesse zu sehen, die einem grafischen Aufgabenmanager ähneln.

      Diese Tools sind jedoch nicht immer flexibel genug, um alle Szenarien angemessen zu behandeln. Ein leistungsfähiger Befehl namens ps ist oft die Antwort auf diese Probleme.

      Wenn er ohne Argumente aufgerufen wird, kann die Ausgabe etwas fehlerhafter sein:

      ps***
      
        PID TTY          TIME CMD  1017 pts/0    00:00:00 bash  1262 pts/0    00:00:00 ps
      

      Diese Ausgabe zeigt alle mit dem aktuellen Benutzer und der Terminalsitzung verknüpften Prozesse an. Dies ist sinnvoll, da wir derzeit nur bash und ps mit diesem Terminal ausführen.

      Um ein vollständigeres Bild der Prozesse auf diesem System zu erhalten, können wir Folgendes ausführen:

      ps aux***
      
      USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND root         1  0.0  0.2  24188  2120 ?        Ss   14:28   0:00 /sbin/initroot         2  0.0  0.0      0     0 ?        S    14:28   0:00 [kthreadd] root         3  0.0  0.0      0     0 ?        S    14:28   0:00 [ksoftirqd/0] root         6  0.0  0.0      0     0 ?        S    14:28   0:00 [migration/0] root         7  0.0  0.0      0     0 ?        S    14:28   0:00 [watchdog/0] root         8  0.0  0.0      0     0 ?        S<   14:28   0:00 [cpuset] root         9  0.0  0.0      0     0 ?        S<   14:28   0:00 [khelper] . . .
      

      Diese Optionen weisen ps an, Prozesse, die allen Benutzern gehören (unabhängig von ihrer Terminalzuordnung), in einem benutzerfreundlichen Format anzuzeigen.

      Um eine Baumansicht zu sehen, in der hierarchische Beziehungen illustriert werden, können wir den Befehl mit diesen Optionen ausführen:

      ps axjf***
      
       PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND     0     2     0     0 ?           -1 S        0   0:00 [kthreadd]     2     3     0     0 ?           -1 S        0   0:00  _ [ksoftirqd/0]     2     6     0     0 ?           -1 S        0   0:00  _ [migration/0]     2     7     0     0 ?           -1 S        0   0:00  _ [watchdog/0]     2     8     0     0 ?           -1 S<       0   0:00  _ [cpuset]     2     9     0     0 ?           -1 S<       0   0:00  _ [khelper]     2    10     0     0 ?           -1 S        0   0:00  _ [kdevtmpfs]     2    11     0     0 ?           -1 S<       0   0:00  _ [netns] . . .
      

      Wie Sie sehen können, wird der Prozess kthreadd als übergeordnetes Element des Prozesses ksoftirqd/0 und der anderen Prozesse angezeigt.

      Eine Anmerkung zu Prozess-IDs


      In Linux- und Unix-ähnlichen Systemen wird jedem Prozess einer Prozess-ID oder PID zugewiesen. So identifiziert und verfolgt das Betriebssystem Prozesse.

      Eine schnelle Möglichkeit zum Abrufen der PID eines Prozesses ist mit dem Befehl pgrep:

      pgrep bash***
      
      1017
      

      Dadurch wird die Prozess-ID einfach abfragt und zurückgegeben.

      Der erste beim Booten erzeugte Prozess namens init erhält die PID „1“.

      pgrep init***
      
      1
      

      Dieser Prozess ist dann dafür verantwortlich, jeden anderen Prozess auf dem System zu erzeugen. Die späteren Prozesse erhalten größere PID-Nummern.

      Das übergeordnete Element eines Prozesses ist der Prozess, der für das Ablegen verantwortlich war. Übergeordnete Prozesse verfügen über eine PPID, die Sie in den Spaltenüberschriften vieler Prozessverwaltungsanwendungen sehen können, einschließlich top, htop und ps.

      Jede Kommunikation zwischen dem Benutzer und dem Betriebssystem über Prozesse umfasst die Übersetzung zwischen Prozessnamen und PIDs zu einem bestimmten Zeitpunkt während des Vorgangs. Aus diesem Grund teilen Dienstprogramme Ihnen die PID mit.

      Übergeordnete-untergeordnete Beziehungen


      Das Erstellen eines untergeordneten Prozesses erfolgt in zwei Schritten: fork(), das einen neuen Adressraum erstellt und die Ressourcen des übergeordneten Elements per Copy-on-Write kopiert, um dem untergeordneten Prozess zur Verfügung zu stehen; und exec(), das eine ausführbare Datei in den Adressraum lädt und ausführt.

      Für den Fall, dass ein untergeordneter Prozess vor seinem übergeordneten Prozess beendet wird, wird der untergeordnete Prozess zu einem Zombie, bis der übergeordnete Prozess Informationen darüber gesammelt oder dem Kernel angezeigt hat, dass er diese Informationen nicht benötigt. Die Ressourcen aus dem untergeordneten Prozess werden dann freigegeben. Wenn der übergeordnete Prozess jedoch vor dem untergeordneten Prozess beendet wird, wird der untergeordnete Prozess von init übernommen, obwohl er auch einem anderen Prozess neu zugewiesen werden kann.

      So senden Sie Prozesssignale in Linux


      Alle Prozesse in Linux reagieren auf Signale. Signale sind eine Methode auf Betriebssystemebene, mit der Programme angewiesen werden, ihr Verhalten zu beenden oder zu ändern.

      So senden Sie Prozesssignale nach PID


      Die häufigste Art, Signale an ein Programm weiterzuleiten, ist mit dem Befehl kill.

      Wie Sie möglicherweise erwarten, besteht die Standardfunktion dieses Dienstprogramms darin, zu versuchen, einen Prozess zu beenden:

      kill PID_of_target_process

      Dadurch wird das TERM-Signal an den Prozess gesendet. Das TERM-Signal weist den Prozess an, zu beenden. Dadurch kann das Programm Reinigungsvorgänge durchführen und reibungslos beenden.

      Wenn sich das Programm schlecht verhält und bei Erhalt des TERM-Signals nicht beendet wird, können wir das Signal durch Weiterleiten des KILL-Signals eskalieren:

      kill -KILL PID_of_target_process

      Dies ist ein spezielles Signal, das nicht an das Programm gesendet wird.

      Stattdessen wird es dem Betriebssystem-Kernel übergeben, der den Prozess herunterschaltet. Dies wird verwendet, um Programme zu umgehen, die die an sie gesendeten Signale ignorieren.

      Jedem Signal ist eine Nummer zugeordnet, die anstelle des Namens übergeben werden kann. Beispielsweise können Sie „-15“ anstelle von „-TERM“ und „-9“ anstelle von „-KILL“ übergeben.

      So verwenden Sie Signale für andere Zwecke


      Signale werden nicht nur zum Herunterfahren von Programmen verwendet. Sie können auch verwendet werden, um andere Aktionen auszuführen.

      Beispielsweise werden viele Daemons neu gestartet, wenn sie das HUP– oder Auflegesignal erhalten. Apache ist ein Programm, das so funktioniert.

      sudo kill -HUP pid_of_apache

      Der obige Befehl führt dazu, dass Apache seine Konfigurationsdatei neu lädt und Inhalte wiederbelebt.

      Sie können alle Signale auflisten, die mit kill gesendet werden können, indem Sie Folgendes eingeben:

      kill -l***
      
      1) SIGHUP    2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP  6) SIGABRT  7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM . . .
      

      So senden Sie Prozesssignale nach Name


      Obwohl die konventionelle Art des Sendens von Signalen durch die Verwendung von PIDs ist, gibt es auch Methoden, dies mit regulären Prozessnamen zu tun.

      Der Befehl pkill funktioniert fast genau so wie kill, operiert jedoch stattdessen auf einem Prozessnamen:

      pkill -9 ping
      

      Der obige Befehl ist das Äquivalent von:

      kill -9 `pgrep ping`
      

      Wenn Sie ein Signal an jede Instanz eines bestimmten Prozesses senden möchten, können Sie den Befehl killall verwenden:

      killall firefox
      

      Der obige Befehl sendet das TERM-Signal an jede Instanz von Firefox, das auf dem Computer ausgeführt wird.

      So passen Sie Prozessprioritäten an


      Oft möchten Sie anpassen, welchen Prozessen in einer Serverumgebung Priorität eingeräumt wird.

      Einige Prozesse können als geschäftskritisch für Ihre Situation angesehen werden, während andere ausgeführt werden können, wenn Ressourcen übrig bleiben.

      Linux kontrolliert die Priorität durch einen Wert namens niceness.

      Hohe Prioritätsaufgaben werden als weniger nett angesehen, da sie auch keine Ressourcen teilen. Prozesse mit niedriger Priorität sind dagegen nett, weil sie darauf bestehen, nur minimale Ressourcen zu verbrauchen.

      Als wir am Anfang des Artikels top ausgeführt haben, gab es eine Spalte mit der Bezeichnung „NI“. Dies ist der nette Wert des Prozesses:

      top***
      
      Aufgaben: 56 insgesamt, 1 laufend, 55 inaktiv, 0 gestoppt, 0 Zombie Cpu(s):  0.0%us,  0.3%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st Mem:   1019600k insgesamt,   324496k verwendet,   695104k frei,     8512k Puffer Swap:   0k insgesamt,   0k verwendet,   0k frei,    264812k zwischengespeichert   PID-BENUTZER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            1635 root      20   0 17300 1200  920 R  0.3  0.1   0:00.01 top                    1 root      20   0 24188 2120 1300 S  0,0  0,2   0:00,56 init                   2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd               3 root      20   0     0    0    0 S  0.0  0.0   0:00.11 ksoftirqd/0
      

      Nette Werte können je nach System zwischen „-19/-20“ (höchste Priorität) und „19/20“ (niedrigste Priorität) liegen.

      Um ein Programm mit einem bestimmten netten Wert auszuführen, können wir den Befehl nice verwenden:

      nice -n 15 command_to_execute

      Dies funktioniert nur, wenn ein neues Programm gestartet wird.

      Um den netten Wert eines Programms zu ändern, das bereits ausgeführt wird, verwenden wir ein Tool namens renice:

      renice 0 PID_to_prioritize

      Hinweis: Während nice zwangsläufig mit einem Befehlsnamen funktioniert, ruft renice die Prozess-PID auf

      Zusammenfassung


      Die Prozessverwaltung ist ein Thema, das für neue Benutzer manchmal schwer zu verstehen ist, da sich die verwendeten Tools von ihren grafischen Gegenstücken unterscheiden.

      Die Ideen sind jedoch vertraut und intuitiv und werden mit ein wenig Übung zur Gewohnheit. Da Prozesse an allem beteiligt sind, was Sie mit einem Computersystem tun, ist es eine wesentliche Fähigkeit, zu lernen, wie man sie effektiv steuert.

      Von Justin Ellingwood



      Source link

      So bearbeiten Sie eingehende Anfragedaten in Flask


      Einführung

      Webanwendungen erfordern häufig die Verarbeitung eingehender Anforderungsdaten von Benutzern. Diese Nutzdaten können in Form von Abfragezeichenfolgen, Formulardaten und JSON-Objekten vorliegen. Mit Flask können Sie wie mit jedem anderen Webframework auf die Anforderungsdaten zugreifen.

      In diesem Tutorial erstellen Sie eine Flask-Anwendung mit drei Routen, die entweder Abfragezeichenfolgen, Formulardaten oder JSON-Objekte akzeptieren.

      Voraussetzungen

      Um diesem Tutorial zu folgen, benötigen Sie:

      • Dieses Projekt erfordert die Installation von Python in einer lokalen Umgebung.
      • In diesem Projekt wird Pipenv verwendet, ein produktionsfähiges Tool, mit dem das Beste aus allen Verpackungswelten in die Python-Welt gebracht werden soll. Es nutzt Pipfile, pip und virtualenv in einem einzigen Befehl.
      • Das Herunterladen und Installieren eines Tools wie Postman wird benötigt, um API-Endpunkte zu testen.

      Dieses Tutorial wurde mit Pipenv v2020.11.15, Python v3.9.0 und Flask v1.1.2 verifiziert.

      Einrichten des Projekts

      Um die verschiedenen Verwendungsmöglichkeiten von Anforderungen zu demonstrieren, müssen Sie eine Flask-App erstellen. Obwohl die Beispiel-App eine vereinfachte Struktur für die Ansichtsfunktionen und -routen verwendet, kann das, was Sie in diesem Tutorial lernen, auf jede Methode zum Organisieren Ihrer Ansichten angewendet werden, z. B. auf klassenbasierte Ansichten, Blaupausen oder eine Erweiterung wie Flask-Via.

      Zuerst müssen Sie ein Projektverzeichnis erstellen. Öffnen Sie Ihren Terminal und führen Sie folgenden Befehl aus:

      • mkdir flask_request_example

      Navigieren Sie dann zum neuen Verzeichnis:

      Installieren Sie als nächstes Flask. Öffnen Sie Ihren Terminal und führen Sie folgenden Befehl aus:

      Der Befehl pipenv erstellt eine virtuelle Umgebung für dieses Projekt, eine Pipfile, eine Installations-flask und eine Pipfile.lock.

      Führen Sie den folgenden Befehl aus, um virtualenv des Projekts zu aktivieren:

      Um auf die eingehenden Daten in Flask zuzugreifen, müssen Sie das Anforderungsobjekt verwenden. Das Anforderungsobjekt enthält alle eingehenden Daten aus der Anforderung, einschließlich Mimetyp, Referrer, IP-Adresse, Rohdaten, HTTP-Methode und Überschriften.

      Obwohl alle Informationen, die das Anforderungsobjekt enthält, nützlich sein können, konzentrieren Sie sich für die Zwecke dieses Artikels auf die Daten, die normalerweise direkt vom Aufrufer des Endpunkts bereitgestellt werden.

      Um Zugriff auf das Anforderungsobjekt in Flask zu erhalten, müssen Sie es aus der Flask-Bibliothek importieren:

      from flask import request
      

      Sie können es dann in jeder Ihrer Ansichtsfunktionen verwenden.

      Verwenden Sie Ihren Code-Editor, um eine Datei app.py zu erstellen. Importieren Sie Flask und das Anforderungsobjekt. Und erstellen Sie auch Routen für query-example, form-example und json-example:

      app.py

      # import main Flask class and request object
      from flask import Flask, request
      
      # create the Flask app
      app = Flask(__name__)
      
      @app.route('/query-example')
      def query_example():
          return 'Query String Example'
      
      @app.route('/form-example')
      def form_example():
          return 'Form Data Example'
      
      @app.route('/json-example')
      def json_example():
          return 'JSON Object Example'
      
      if __name__ == '__main__':
          # run app in debug mode on port 5000
          app.run(debug=True, port=5000)
      

      Öffnen Sie als nächstes Ihr Terminal und starten Sie die App mit dem folgenden Befehl:

      Die App wird auf Port 5000 gestartet, sodass Sie jede Route in Ihrem Browser über die folgenden Links anzeigen können:

      http://127.0.0.1:5000/query-example (or localhost:5000/query-example)
      http://127.0.0.1:5000/form-example (or localhost:5000/form-example)
      http://127.0.0.1:5000/json-example (or localhost:5000/json-example)
      

      Der Code erstellt drei Routen und zeigt die Nachrichten „Beispiel für Abfragezeichenfolge“,„Beispiel für Formulardaten“ bzw. „Beispiel für JSON-Objekt“ an.

      Verwenden von Abfrageargumenten

      URL-Argumente, die Sie einer Abfragezeichenfolge hinzufügen, sind eine übliche Methode, um Daten an eine Webanwendung zu übergeben. Beim Surfen im Internet sind Sie wahrscheinlich schon einmal auf eine Abfragezeichenfolge gestoßen.

      Eine Abfragezeichenfolge ähnelt der folgenden:

      example.com?arg1=value1&arg2=value2
      

      Die Abfragezeichenfolge beginnt nach dem Fragezeichen (?) Zeichen:

      example.com?arg1=value1&arg2=value2
      

      Und hat Schlüssel-Wert-Paare, die durch ein kaufmännisches Und (&) getrennt sind:

      example.com?arg1=value1&arg2=value2
      

      Für jedes Paar folgt auf den Schlüssel ein Gleichheitszeichen (=) und dann der Wert.

      arg1 : value1
      arg2 : value2
      

      Abfragezeichenfolgen sind nützlich, um Daten zu übergeben, für die der Benutzer keine Maßnahmen ergreifen muss. Sie können irgendwo in Ihrer App eine Abfragezeichenfolge generieren und an eine URL anhängen. Wenn ein Benutzer eine Anfrage stellt, werden die Daten automatisch für ihn übergeben. Eine Abfragezeichenfolge kann auch von Formularen generiert werden, deren Methode GET ist.

      Fügen wir der Abfragebeispielroute eine Abfragezeichenfolge hinzu. In diesem hypothetischen Beispiel geben Sie den Namen einer Programmiersprache an, die auf dem Bildschirm angezeigt wird. Erstellen Sie einen Schlüssel für „Sprache“ und einen Wert für „Python“:

      http://127.0.0.1:5000/query-example?language=Python
      

      Wenn Sie die App ausführen und zu dieser URL navigieren, wird weiterhin die Meldung „Beispiel für eine Abfragezeichenfolge“ angezeigt.

      Sie müssen den Teil programmieren, der die Abfrageargumente verarbeitet. Dieser Code liest den Schlüssel Sprache durch Verwendung von request.args.get('language') oder request.args.get('language').

      Durch den Aufruf von request.args.get('language') wird die Anwendung weiterhin ausgeführt, wenn der Schlüssel Sprache nicht in der URL vorhanden ist. In diesem Fall ist das Ergebnis der Methode Keine.

      Durch den Aufruf von request.args['language'] gibt die App einen 400-Fehler zurück, wenn der Schlüssel Sprache nicht in der URL vorhanden ist.

      Beim Umgang mit Abfragezeichenfolgen wird empfohlen, request.args.get () zu verwenden, um zu verhindern, dass die App fehlschlägt.

      Lesen wir den Schlüssel Sprache und zeigen ihn als Ausgabe an.

      Ändern Sie die Route query-example in app.py mit dem folgenden Code:

      app.py

      @app.route('/query-example')
      def query_example():
          # if key doesn't exist, returns None
          language = request.args.get('language')
      
          return '''<h1>The language value is: {}</h1>'''.format(language)
      

      Führen Sie dann die App aus und navigieren Sie zur URL:

      http://127.0.0.1:5000/query-example?language=Python
      

      Der Browser sollte die folgende Nachricht anzeigen:

      Output

      The language value is: Python

      Das Argument aus der URL wird der Variable Sprache zugewiesen und dann an den Browser zurückgegeben.

      Um weitere Parameter für Abfragezeichenfolgen hinzuzufügen, können Sie ein kaufmännisches Und und die neuen Schlüssel-Wert-Paare an das Ende der URL anhängen. Erstellen Sie einen Schlüssel für „Framework“ und einen Wert für „Flask“:

      http://127.0.0.1:5000/query-example?language=Python&framework=Flask
      

      Wenn Sie mehr möchten, fügen Sie weiterhin ein kaufmännisches Und und Schlüssel-Wert-Paare hinzu. Erstellen Sie einen Schlüssel für „Framework“ und einen Wert für „Flask“:

      http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean
      

      Um Zugriff auf diese Werte zu erhalten, verwenden Sie weiterhin entweder request.args.get() oder request.args[]. Verwenden wir beide, um zu demonstrieren, was passiert, wenn ein Schlüssel fehlt. Ändern Sie die Route query_example, um den Wert der Ergebnisse in Variablen zu zuweisen und sie dann anzuzeigen:

      @app.route('/query-example')
      def query_example():
          # if key doesn't exist, returns None
          language = request.args.get('language')
      
          # if key doesn't exist, returns a 400, bad request error
          framework = request.args['framework']
      
          # if key doesn't exist, returns None
          website = request.args.get('website')
      
          return '''
                    <h1>The language value is: {}</h1>
                    <h1>The framework value is: {}</h1>
                    <h1>The website value is: {}'''.format(language, framework, website)
      

      Führen Sie dann die App aus und navigieren Sie zur URL:

      http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean
      

      Der Browser sollte die folgende Nachricht anzeigen:

      Output

      The language value is: Python The framework value is: Flask The website value is: DigitalOcean

      Entfernen Sie den Schlüssel Sprache aus der URL:

      http://127.0.0.1:5000/query-example?framework=Flask&website=DigitalOcean
      

      Der Browser sollte die folgende Nachricht mit Keine anzeigen, wenn ein Wert nicht für Sprache bereitgestellt wird:

      Output

      The language value is: None The framework value is: Flask The website value is: DigitalOcean

      Entfernen Sie den Schlüssel Framework aus der URL:

      http://127.0.0.1:5000/query-example?language=Python&website=DigitalOcean
      

      Der Browser sollte auf einen Fehler stoßen, da er einen Wert für Framework erwartet:

      Output

      werkzeug.exceptions.BadRequestKeyError werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'framework'

      Jetzt verstehen Sie den Umgang mit Abfragezeichenfolgen. Fahren wir mit dem nächsten Typ eingehender Daten fort.

      Verwenden von Formulardaten

      Formulardaten stammen aus einem Formular, das als POST-Abfrage an eine Route gesendet wurde. Anstatt die Daten in der URL anzuzeigen (außer in Fällen, in denen das Formular mit einer GET-Abfrage gesendet wird), werden die Formulardaten hinter den Kulissen an die App übergeben. Obwohl Sie die Formulardaten nicht einfach sehen können, die übergeben werden, kann Ihre App sie weiterhin lesen.

      Um dies zu demonstrieren, ändern Sie die Formularbeispielroute in app.py, um sowohl GET- als auch POST-Abfragen zu akzeptieren, und geben Sie ein Formular zurück:

      app.py

      # allow both GET and POST requests
      @app.route('/form-example', methods=['GET', 'POST'])
      def form_example():
          return '''
                    <form method="POST">
                        <div><label>Language: <input type="text" name="language"></label></div>
                        <div><label>Framework: <input type="text" name="framework"></label></div>
                        <input type="submit" value="Submit">
                    </form>'''
      

      Führen Sie dann die App aus und navigieren Sie zur URL:

      http://127.0.0.1:5000/form-example
      

      Der Browser sollte ein Formular mit zwei Eingabefeldern - einem für Sprache und einem für Framework - und eine Senden-Taste übergeben.

      Das Wichtigste, was Sie über dieses Formular wissen müssen, ist, dass es eine POST-Abfrage an dieselbe Route ausführt, die das Formular generiert hat. Die Schlüssel, die in der App gelesen werden, stammen alle aus den Namensattributen in unseren Formulareingaben. In diesem Fall sind Sprache und Framework die Namen der Eingaben, sodass Sie Zugriff auf die in der App haben.

      Innerhalb der Ansichtsfunktion müssen Sie überprüfen, ob die Abfragemethode GET oder POST ist. Wenn es sich um eine GET-Abfrage handelt, können Sie das Formular anzeigen. Wenn es sich um eine POST-Abfrage handelt, möchten Sie die eingehenden Daten verarbeiten.

      Ändern Sie die Route form-example in app.py mit dem folgenden Code:

      app.py

      # allow both GET and POST requests
      @app.route('/form-example', methods=['GET', 'POST'])
      def form_example():
          # handle the POST request
          if request.method == 'POST':
              language = request.form.get('language')
              framework = request.form.get('framework')
              return '''
                        <h1>The language value is: {}</h1>
                        <h1>The framework value is: {}</h1>'''.format(language, framework)
      
          # otherwise handle the GET request
          return '''
                 <form method="POST">
                     <div><label>Language: <input type="text" name="language"></label></div>
                     <div><label>Framework: <input type="text" name="framework"></label></div>
                     <input type="submit" value="Submit">
                 </form>'''
      

      Führen Sie dann die App aus und navigieren Sie zur URL:

      http://127.0.0.1:5000/form-example
      

      Füllen Sie das Feld Sprache mit dem Wert von Python und das Feld Framework mit dem Wert von Flask aus. Drücken Sie dann Senden.

      Der Browser sollte die folgende Nachricht anzeigen:

      Output

      The language value is: Python The framework value is: Flask

      Jetzt verstehen Sie den Umgang mit Formulardaten. Fahren wir mit dem nächsten Typ eingehender Daten fort.

      Verwenden von JSON-Daten

      JSON-Daten werden normalerweise von einem Prozess erstellt, der die Route aufruft.

      Ein Beispiel-JSON-Objekt sieht folgendermaßen aus:

      {
        "language": "Python",
        "framework": "Flask",
        "website": "Scotch",
        "version_info": {
          "python": "3.9.0",
          "flask": "1.1.2"
        },
        "examples": ["query", "form", "json"],
        "boolean_test": true
      }
      

      Diese Struktur kann die Übergabe von viel komplizierteren Daten im Gegensatz zu Abfragezeichenfolgen und Formulardaten ermöglichen. Im Beispiel sehen Sie verschachtelte JSON-Objekte und eine Anordnung von Elementen. Flask kann dieses Format von Daten verarbeiten.

      Ändern Sie die Route form-example in app.py, um POST-Abfragen zu akzeptieren und andere Abfragen wie GET zu ignorieren:

      app.py

      @app.route('/json-example', methods=['POST'])
      def json_example():
          return 'JSON Object Example'
      

      Im Gegensatz zu dem Webbrowser, der für Abfragezeichenfolgen und Formulardaten zum Senden eines JSON-Objekts in diesem Artikel verwendet wird, verwenden Sie Postman, um benutzerdefinierte Anforderungen an URLs zu senden.

      Hinweis: Wenn Sie Hilfe benötigen, um Postman für Abfragen zu navigieren, konsultieren Sie die offizielle Dokumentation.

      Fügen Sie in Postman die URL hinzu und ändern Sie den Typ in POST. Wechseln Sie auf der Registerkarte Body zu raw und wählen Sie JSON aus der Dropdown-Liste aus.

      Diese Einstellungen sind erforderlich, sodass Postman JSON-Daten richtig senden kann und Ihre Flask-App versteht, dass sie JSON empfängt:

      POST http://127.0.0.1:5000/json-example
      Body
      raw JSON
      

      Kopieren Sie als Nächstes das frühere JSON-Beispiel in die Texteingabe.

      Senden Sie die Abfrage und Sie sollten „Beispiel eines JSON-Objekts“ als Antwort erhalten. Das ist ziemlich antiklimatisch, aber zu erwarten, da der Code für die Verarbeitung der JSON-Datenantwort noch nicht geschrieben wurde.

      Um die Daten zu lesen, müssen Sie verstehen, wie Flask JSON-Daten in Python-Datenstrukturen übersetzt:

      • Alles, was ein Objekt ist, wird in ein Python-Diktat konvertiert. {"key": value "} in JSON entspricht somedict['key'], das in Python einen Wert zurückgibt.
      • Eine Anordnung in JSON wird in Python in eine Liste konvertiert. Da die Syntax die gleiche ist, ist hier eine Beispielliste: [1,2,3,4,5]
      • Die Werte in Anführungszeichen im JSON-Objekt werden Zeichenfolgen in Python.
      • Boolean wahr und falsch werden in Python zu Wahr und Falsch.
      • Abschließend werden Zahlen ohne Anführungszeichen in Python zu Zahlen.

      Arbeiten wir nun an dem Code, um die eingehenden JSON-Daten zu lesen.

      Zuerst weisen wir alles aus dem JSON-Objekt mit request.get_json() einer Variable zu.

      request.get_json() konvertiert das JSON-Objekt in Python-Daten. Weisen wir die eingehenden Abfragedaten den Variablen zu, und geben sie zurück, indem wir die folgenden Änderungen an der Route json-example vornehmen:

      app.py

      # GET requests will be blocked
      @app.route('/json-example', methods=['POST'])
      def json_example():
          request_data = request.get_json()
      
          language = request_data['language']
          framework = request_data['framework']
      
          # two keys are needed because of the nested object
          python_version = request_data['version_info']['python']
      
          # an index is needed because of the array
          example = request_data['examples'][0]
      
          boolean_test = request_data['boolean_test']
      
          return '''
                 The language value is: {}
                 The framework value is: {}
                 The Python version is: {}
                 The item at index 0 in the example list is: {}
                 The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
      

      Beachten Sie, wie Sie auf Elemente zugreifen, die nicht auf der oberen Ebene sind. ['version']['python'] wird verwendet, da Sie ein verschachteltes Objekt eingeben. Und ['examples'][0] wird verwendet, um auf den 0. Index in der Anordnung der Beispiele zuzugreifen.

      Wenn das mit der Abfrage gesendete JSON-Objekt keinen Schlüssel hat, auf den in Ihrer Ansichtsfunktion zugegriffen wird, wird die Abfrage fehlschlagen. Wenn Sie nicht möchten, dass es fehlschlägt, wenn ein Schlüssel nicht vorhanden ist, müssen Sie überprüfen, ob der Schlüssel vorhanden ist, bevor Sie versuchen, darauf zuzugreifen.

      app.py

      # GET requests will be blocked
      @app.route('/json-example', methods=['POST'])
      def json_example():
          request_data = request.get_json()
      
          language = None
          framework = None
          python_version = None
          example = None
          boolean_test = None
      
          if request_data:
              if 'language' in request_data:
                  language = request_data['language']
      
              if 'framework' in request_data:
                  framework = request_data['framework']
      
              if 'version_info' in request_data:
                  if 'python' in request_data['version_info']:
                      python_version = request_data['version_info']['python']
      
              if 'examples' in request_data:
                  if (type(request_data['examples']) == list) and (len(request_data['examples']) > 0):
                      example = request_data['examples'][0]
      
              if 'boolean_test' in request_data:
                  boolean_test = request_data['boolean_test']
      
          return '''
                 The language value is: {}
                 The framework value is: {}
                 The Python version is: {}
                 The item at index 0 in the example list is: {}
                 The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
      

      Führen Sie die App aus und senden Sie die Beispiel-JSON-Abfrage mit Postman. In der Antwort erhalten Sie die folgende Ausgabe:

      Output

      The language value is: Python The framework value is: Flask The Python version is: 3.9 The item at index 0 in the example list is: query The boolean value is: false

      Jetzt verstehen Sie die Verarbeitung von JSON-Objekten.

      Zusammenfassung

      In diesem Artikel haben Sie eine Flask-Anwendung mit drei Routen erstellt, die entweder Abfragezeichenfolgen, Formulardaten oder JSON-Objekte akzeptieren.

      Denken Sie auch daran, dass alle Ansätze die wiederkehrende Überlegung berücksichtigen mussten, ob ein Schlüssel ordnungsgemäß fehlschlägt, wenn ein Schlüssel fehlt.

      Warnung: ein Thema, das in diesem Artikel nicht behandelt wurde, war die Bereinigung von Benutzereingaben. Durch die Bereinigung von Benutzereingaben wird sichergestellt, dass von der Anwendung gelesene Daten nicht unerwartet fehlschlagen oder Sicherheitsmaßnahmen umgehen.

      Wenn Sie mehr über Flask erfahren möchten, lesen Sie unsere Themenseite zu Flask für Übungen und Programmierprojekte.



      Source link

      So starten Sie Ihre Node.js-Apps automatisch mit nodemon neu


      Einführung

      In Node.js müssen Sie den Prozess neu starten, um Änderungen zu übernehmen. Dadurch wird Ihrem Workflow ein zusätzlicher Schritt hinzugefügt, um die Änderungen durchzuführen. Sie können diesen zusätzlichen Schritt durch Verwendung von nodemon eliminieren, um den Prozess automatisch neu zu starten.

      nodemon ist ein von @rem entwickeltes CLI-Dienstprogramm (Command Line Interface), das Ihre Node-App umschließt, das Dateisystem überwacht und den Prozess automatisch neu startet.

      In diesem Artikel erfahren Sie mehr über die Installation, Einrichtung und Konfiguration von nodemon.

      Voraussetzungen

      Wenn Sie diesem Artikel folgen möchten, benötigen Sie Folgendes:

      Schritt 1 — Installieren von nodemon

      Zuerst müssen Sie nodemon auf Ihrem Rechner installieren. Installieren Sie das Dienstprogramm entweder global oder lokal mit npm oder Yarn:

      Globale Installation

      Sie können nodemon global mit npm installieren:

      Oder mit Yarn:

      Lokale Installation

      Sie können nodemon auch lokal mit npm installieren. Bei der Ausführung einer lokalen Installation können wir nodemon als dev-Abhängigkeiten mit --save-dev (oder --dev) installieren:

      • npm install nodemon --save-dev

      Oder mit Yarn:

      Eine Sache, die Sie bei einer lokalen Installation wissen sollten, ist, dass Sie den Befehl nodemon nicht direkt aus der Befehlszeile verwenden können:

      Output

      • command not found: nodemon

      Sie können es jedoch als Teil von einigen npm Scripts oder mit npx verwenden.

      Dadurch wird der Prozess der Installation von nodemon abgeschlossen. Als Nächstes verwenden wir nodemon mit unseren Projekten.

      Schritt 2 — Einrichten eines Beispiel-Express-Projekts mit nodemon

      Wir können nodemon verwenden, um ein Node Script zu starten. Wenn wir beispielsweise ein Express-Server-Setup in einer server.js-Datei haben, können wir es starten und für Änderungen wie folgt ansehen:

      Sie können Argumente so übergeben, als ob Sie das Script mit Node ausführen:

      Jedesmal, wenn Sie eine Änderung in einer Datei mit einer der Standarderweiterung (.js, .mjs, .json, .coffee oder .litcoffee) im aktuellen Verzeichnis oder einem Unterverzeichnis vornehmen, wird der Prozess neu starten.

      Nehmen wir an, wir schreiben eine Beispieldatei server.js, die die Nachricht ausgibt: Dolphin-App hört auf Port ${port} zu.

      Wir können das Beispiel mit nodemon ausführen:

      Wir sehen die Terminalausgabe:

      Output

      [nodemon] 1.17.3 [nodemon] to restart at any time, enter `rs` [nodemon] watching: *.* [nodemon] starting `node server.js` Dolphin app listening on port 3000!

      Zwar wird nodemon noch immer ausgeführt, doch lassen Sie uns eine Änderung in der Datei server.js vornehmen, um die Nachricht auszugeben: Shark-App hört auf Port ${port} zu!

      Wir sehen die folgende zusätzliche Terminalausgabe:

      Output

      [nodemon] restarting due to changes... [nodemon] starting `node server.js` Shark app listening on port 3000!

      Die Terminalausgabe aus unserer Node.js-App wird wie erwartet angezeigt. Sie können den Prozess jederzeit neu starten, indem Sie rs eingeben und die ENTER drücken.

      Alternativ sucht nodemon auch nach einer Hauptdatei, die in der Datei package.json Ihres Projekts angegeben ist:

      package.json

      {
        // ...
        "main": "server.js",
        // ...
      }
      

      Oder ein Startskript:

      package.json

      {
        // ...
        "scripts": {
          "start": "node server.js"
        },
        // ...
      }
      

      Sobald Sie die Änderungen an package.json vornehmen, können Sie nodemon aufrufen, um die Beispiel-App im Beobachtungsmodus zu starten, ohne dass Sie server.js übergeben müssen.

      Schritt 3 — Verwenden von Optionen

      Sie können die Konfigurationseinstellungen für nodemon ändern.

      Gehen wir über einige der wichtigsten Optionen:

      • --exec: Verwenden Sie den Schalter --exec, um ein Binärsystem anzugeben, mit dem die Datei ausgeführt werden soll. In Kombination mit der Binärdatei ts-node kann --exec beispielsweise nützlich werden, um Änderungen zu beobachten und TypeScript-Dateien auszuführen.
      • --ext: Geben Sie verschiedene Dateierweiterungen an, um zu beobachten. Stellen Sie für diesen Schalter eine mit Komma getrennte Liste der Dateierweiterungen (z. B. -ext js,ts) bereit.
      • --delay: Standardmäßig wartet nodemon eine Sekunde, um den Prozess neu zu starten, wenn sich eine Datei ändert, aber mit dem Schalter --delay können Sie eine andere Verzögerung angeben. Beispielsweise nodemon --delay 3.2 für eine 3,2-Sekunden-Verzögerung.
      • --watch: Verwenden Sie den Schalter --watch, um mehrere Verzeichnisse oder Dateien anzugeben, die Sie beobachten können. Fügen Sie für jedes Verzeichnis, das Sie beobachten möchten, einen --watch-Schalter hinzu. Standardmäßig werden das aktuelle Verzeichnis und seine Unterverzeichnisse beobachtet, sodass Sie mit --watch die Beobachtung auf nur bestimmte Unterverzeichnisse oder Dateien beschränken können.
      • --ignore: Verwenden Sie den Schalter --ignore, um bestimmte Dateien, Dateimuster oder Verzeichnisse zu ignorieren.
      • --verbose: Eine ausführlichere Ausgabe mit Informationen darüber, welche Datei(en) geändert wurde(n), um einen Neustart auszulösen.

      Sie können mit dem folgenden Befehl alle verfügbaren Optionen anzeigen:

      Durch Verwendung dieser Optionen erstellen wir den Befehl, um das folgende Szenario zu erfüllen:

      • Beobachten des Server-Verzeichnisses
      • Spezifizieren von Dateien mit einer .ts-Erweiterung
      • Ignorieren von Dateien mit einer .test.ts-Endung
      • Ausführung der Datei (server/server.ts) mit ts-node
      • warten für drei Sekunden bis zum Neustart nach einer Dateiänderung
      • nodemon --watch server --ext ts --exec ts-node --ignore '*.test.ts' --delay 3 server/server.ts

      Dieser Befehl kombiniert --watch, --ext, --exec, --ignore und --delay-Optionen, um die Bedingungen für unser Szenario zu erfüllen.

      Schritt 4 — Verwenden von Konfigurationen

      Im vorherigen Beispiel kann das Hinzufügen von Konfigurationsschaltern bei der Ausführung von nodemon ziemlich mühsam werden. Eine bessere Lösung für Projekte, die spezifische Konfigurationen benötigen, ist die Angabe dieser Konfigurationen in einer Datei nodemon.json.

      Beispielsweise sind hier die gleichen Konfigurationen wie bei der vorherigen Befehlszeile, aber in einer Datei nodemon.json platziert:

      nodemon.json

      {
        "watch": ["server"],
        "ext": "ts",
        "ignore": ["*.test.ts"],
        "delay": "3",
        "execMap": {
          "ts": "ts-node"
        }
      }
      

      Beachten Sie die Verwendung von execMap anstelle des Schalters --exec. execMap ermöglicht es Ihnen, Binärdateien anzugeben, die bei bestimmten Dateierweiterungen verwendet werden sollten.

      Wenn Sie Ihrem Projekt lieber keine Konfigurationsdatei nodemon.json hinzufügen möchten, können Sie alternativ diese Konfigurationen unter einem Schlüssel nodemonConfig der Datei package.json hinzufügen:

      package.json

      {
        "name": "test-nodemon",
        "version": "1.0.0",
        "description": "",
        "nodemonConfig": {
          "watch": [
            "server"
          ],
          "ext": "ts",
          "ignore": [
            "*.test.ts"
          ],
          "delay": "3",
          "execMap": {
            "ts": "ts-node"
          }
        },
        // ...
      

      Sobald Sie die Änderungen an entweder nodemon.json oder package.json vornehmen, können Sie nodemon mit dem gewünschten Script starten:

      nodemon nimmt die Konfigurationen auf und verwendet sie. Auf diese Weise können Ihre Konfigurationen gespeichert, geteilt und wiederholt werden, um Fehler beim Kopieren und Einfügen oder Tippfehler in der Befehlszeile zu vermeiden.

      Zusammenfassung

      In diesem Artikel haben Sie erkundet, wie Sie nodemon mit Ihren Node.js-Anwendungen verwenden. Dieses Tool hilft dabei, den Prozess des Anhaltens und Startens eines Node-Servers zu automatisieren, um die Änderungen anzuzeigen.

      Weitere Informationen zu den verfügbaren Funktionen und Fehlerbehebungen finden Sie in der offiziellen Dokumentation.

      Wenn Sie mehr über Node.js erfahren möchten, lesen Sie unsere Themenseite zu Node.js für Übungen und Programmierprojekte.





      Source link