Dynamische HTML-Seiten mit AWS Lambda und Python

Was du machen willst

Ich möchte eine Seite erstellen, die __dynamisches HTML mit Lambda aus AWS __ generiert. Mit Lambda können Sie Ihre bevorzugten Python-Skripte ausführen, ohne einen eigenen Server einrichten zu müssen. Daher werde ich versuchen, damit eine Seite zu erstellen, die dynamisches HTML generiert.

Es gibt bereits einige Gespräche über das Erstellen von Seiten mit Lambda, aber die zuvor angekündigte __API Gateway Lambda-Proxy-Integration __ Der Zweck dieser Zeit ist es, das Gefühl ein wenig besser zu machen, indem Lambdas Bereitstellungstool apex kombiniert wird. Außerdem ist template engine für das Ausspucken von HTML aus dem Skript unverzichtbar. Daher habe ich damit gespielt, um zu überprüfen, ob es tatsächlich in Kombination verwendet werden kann.

Was zu machen

Was die Art der Seite angeht, habe ich mich diesmal entschlossen, einen __ Schrein __ zu bauen. Eine der berühmten Template-Engines von Python ist "jinja2", und ich habe beschlossen, einen Schrein ohne Server zu erstellen. (Aber es ist nur eine Webseite, nur für den Fall)

Ich möchte es als Beispiel für eine dynamische Seite erstellen, daher werde ich einen Zugriffszähler einrichten, der die Anzahl der Anbeter anzeigt. Die Rückgabe der aktuellen Uhrzeit ist ein gutes Beispiel für Dynamik, aber es ist auch langweilig, das zu tun, was Sie mit Javascript auf dem Server tun können, und ich denke, dass die meisten Dinge, die eine dynamische Verarbeitung erfordern, dazu dienen, mit der Datenbank herumzuspielen. Ich habe den Zugangsschalter als praktisches Element gewählt. Achten Sie darauf, dass der Zugangsschalter selbst wie ein Fossil behandelt wird.

Diagramm

image https://cloudcraft.co/view/67eed248-a460-46dc-91dd-fdb5a70f529f?key=D4aRY_6kyWIfbEKtYk78TQ

Die Konfiguration des Servers, den ich dieses Mal vornehmen werde, ist wie folgt. Lambda kann nicht direkt vom Browser aus aufgerufen werden, daher habe ich das API-Gateway zuvor gebissen, um es zugänglich zu machen. Darüber hinaus wird DynamoDB dahinter installiert, um die Anzahl der Zugriffe zu speichern. DynamoDB ist auch eine Schlüsselwertdatenbank, die verwendet werden kann, ohne eine Instanz zu erstellen. Es ist einfach, aber es ist immer noch eine gute Architektur ohne Server.

Vorbereitung

Apex

Dieses Mal habe ich beschlossen, Lambda mit einem Tool namens Apex bereitzustellen. Wenn Sie externe Bibliotheken mit Lambda verwenden, müssen diese komprimiert und platziert werden. Dieses Tool namens Apex ist jedoch sehr praktisch, da es die Bereitstellung und Ausführung installierter Skripts über die Befehlszeile vereinfacht.

Ich werde hier nicht auf Details eingehen,

  1. Installieren Sie Apex
  2. Legen Sie den AWS-Schlüssel in der Umgebungsvariablen fest
  3. Initialisieren Sie das Projekt und erstellen Sie eine Vorlage mit `` `apex init```
  4. Implementieren Sie die Funktion mit Bezug auf die Vorlage
  5. apex deploy

Sie können so schnell bereitstellen.

DynamoDB Bereiten Sie zuerst eine Tabelle für die Zugriffsaggregation vor. Im Fall von DynamoDB müssen nicht alle zu verwendenden Spalten definiert werden, da es schemenlos ist. Es ist jedoch erforderlich, den Primärschlüssel für das Scannen im Voraus zu bestimmen.

Dieses Mal habe ich die folgende Tabelle gemacht. image

Wir haben einen primären Partitionsschlüssel namens "counter_id". Als Verwendung ist es so, als würde man 10 Zähler mit counter_id von 0 bis 9 vorbereiten und sie zufällig angeben, um sie zu erhöhen. Durch die Vorbereitung mehrerer Zähler wird das Schreiben nicht an einem Ort konzentriert und die Leistung kann konstant gehalten werden.

Da DynamoDB keine Transaktionen hat, dachte ich, dass das Schreiben in dieselbe Tabelle zur gleichen Zeit inkonsistent werden würde, aber es scheint, dass ein Atomzähler durch Inkrementieren als Ausdruck mit update_item realisiert werden kann. (Ich habe gerade gelernt)

Beim Lesen erhalten wir alle Zähler und geben die Summe zurück. Wenn Sie keine "starke Konsistenz" verwenden, wird das schriftliche Ergebnis anscheinend nicht sofort wiedergegeben, aber diesmal bitten wir nicht um Strenge, daher verwenden wir eine vernünftig schwache Konsistenz.

image Das Ergebnis des mehrmaligen Schreibens.

Implementierung

Ich werde es sofort schaffen.

Verwenden von Jinja2 mit Lambda

Durch das Einfügen des Jinja2-Pakets und der Vorlage, die ich verwenden möchte, in den Apex-Funktionsordner konnte ich die Vorlagen-Engine problemlos mit Lambda verwenden.

Ordnerstruktur.txt


├── functions
│   └── jinja
│       ├── jinja2/Eine solche
│       ├── main.py
│       ├── requirements.txt
│       └── templates
│           ├── index.html
│           └── layout.html
├── project.json

Die Ordnerstruktur aus dem Apex-Projektstamm befindet sich oben. In dem Ordner namens functions befindet sich ein Ordner namens jinja. Dies ist der Stammordner der diesmal definierten Lambda-Funktion. Durch das Erstellen mehrerer Ordner in dieser Hierarchie ist es möglich, verschiedene Lambda-Funktionen zusammen zu verarbeiten.

Um jinja2 zu verwenden, müssen Sie pip install -t .jinja2 im jinja-Ordner ausführen, um das gesamte jinja2-Paket zu installieren. Erstellen Sie außerdem einen Ordner für die Vorlagendateien, die Sie verwenden möchten.

main.py


# coding: utf-8

from jinja2 import Environment, FileSystemLoader

env = Environment(loader=FileSystemLoader(path.join(path.dirname(__file__), 'templates'), encoding='utf8'))

template = env.get_template('index.html')
html = template.render()

Beim Anrufen sieht es so aus. Jetzt können Sie die Vorlagen in templates / index.html ausgeben.

Greifen Sie auf DynamoDB zu

Es ist einfach, die offizielle Bibliothek "boto3" zu verwenden, um über die Lambda-Funktion auf DynamoDB zuzugreifen. Sie können es verwenden, ohne es in das Apex-Paket einfügen zu müssen (in einigen Fällen können Sie es explizit einfügen, weil Sie die Version korrigieren möchten). Wenn Sie die entsprechende Rolle für Lambda angeben, können Sie es verwenden, ohne sich in Ihrem Code authentifizieren zu müssen.

main.py


import boto3

dynamodb = boto3.resource('dynamodb')
count_table  = dynamodb.Table('lambda-jinja')
counts = count_table.scan(Limit=10)

Lambda-Proxy-Integration für API Gateway

Mit API Gateway können Sie Lambda über HTTP ausführen und die Ergebnisse erhalten. Beim herkömmlichen API-Gateway musste jedoch zugeordnet werden, welche Art von Anforderung in welcher Art von Pfad einging und welche Art von Antwort zurückgegeben wurde. Dies ist relativ problematisch. Ich konnte den Fall nicht behandeln, in dem ich nicht auf beliebige Anfragen antworten oder ein Skript gemäß dem Pfad wiederverwenden konnte, aber kürzlich wurde ein wunderbarer Mechanismus namens Proxy-Integration eingeführt. es war erledigt. Wenn Sie dies verwenden, werden Anforderungs- und Pfadinformationen an die Funktionsseite übergeben, sodass die Möglichkeiten von API Gateway + Lambda sofort erweitert werden. Diesmal habe ich es sofort versucht.

image

Erstellen Sie auf diese Weise eine Methode und eine Ressource für die Route mit API Gateway und ordnen Sie diese Lambda zu, die diesmal erstellt werden soll.

swagger.yaml


---
swagger: "2.0"
basePath: "/jinja"
schemes:
- "https"
paths:
paths:
  /:
    x-amazon-apigateway-any-method:
      produces:
      - "application/json"
      responses:
        200:
          description: "200 response"
          schema:
            $ref: "#/definitions/Empty"
  /{proxy+}:
    x-amazon-apigateway-any-method:
      produces:
      - "application/json"
      parameters:
      - name: "proxy"
        in: "path"
        required: true
        type: "string"
      responses: {}
definitions:
  Empty:
    type: "object"
    title: "Empty Schema"

Das Schreiben in Swagger sieht so aus.

Durch Auflisten der Ressource als "/ {proxy +}" ist es möglich, Anforderungen eines beliebigen Pfads mit demselben Lambda zu verarbeiten. Ich konnte den Zugriff des Stamms nicht nur mit / {proxy +} abrufen, daher habe ich auch eine separate Methode für den Stamm definiert.

Antwort für API Gateway

Das Setup auf der API-Gateway-Seite war einfach, aber auf der Lambda-Seite gab es ein Problem. Ich habe mich gefragt, ob ich ein Lambda erstellen könnte, das HTML zurückgibt und es mit API Gateway verbindet, und es würde die Seite zurückgeben, aber es war etwas anders. Wenn Sie nur HTML zurückgeben, wird 502 auf der API-Gateway-Seite zurückgegeben. Zuerst habe ich mit den Einstellungen für ContentType und API Gateway herumgespielt und gedacht, dass das Format nicht JSON ist, aber die Ursache liegt woanders.

Bei Verwendung der Proxy-Integration scheint das Skript __ eine Antwort in einem bestimmten Format __ zurückgeben zu müssen. Es war eine Pointe, dass 502 ohne Fragen zurückgegeben würde, wenn Sie dieses Format nicht befolgen würden.

Klicken Sie hier für das feste Format.

main.py


def handle(event, context):
    html = ...
    return {
        "statusCode": 200,
        "headers": {"Content-Type": "text/html"},
        "body": html
    }

Es ist erforderlich, das Wörterbuch, das drei von "statusCode", "headers" und "body" definiert, aus der von Lambda aufgerufenen Funktion zurückzugeben. API Gateway betrachtet diese und erstellt eine HTTP-Antwort.

Außerdem werden alle Informationen beim Anfordern einer Anforderung an das API-Gateway an das Ereignis (erstes Argument) der Funktion "handle" übergeben. In diesem Beispiel wird von pprint angezeigt, welche Art von Wert übergeben wird. Wenn Sie möchten, beziehen Sie sich bitte darauf.

Komplett

https://teu24wc5u9.execute-api.ap-northeast-1.amazonaws.com/jinja/ Der Schrein wurde erfolgreich abgeschlossen. Ich wollte die Seite ein bisschen mehr wie einen Schrein machen, aber ich war erschöpft, weil ich keine Zeit hatte. Ich bin froh, dass ich Ihnen gesagt habe, was ich technisch vermitteln möchte.

Können Sie sehen, dass die Anzahl der angezeigten Anbeter mit jedem Zugriff zunimmt? Ich konnte eine dynamische Webseite erstellen, ohne eine einzelne Instanz zu erstellen.

Der Pfad zum Zugriff ist

/jinja/
/jinja/hoge
/jinja/fuga
/jinja/piyopiyo

Alles wird akzeptiert. Die Anforderungsinformationen "Pfad" am Ende der Seite sollten ebenfalls ordnungsgemäß verwendet werden. Auf diese Weise können Sie ganz einfach Ihren eigenen Routing-Prozess hinzufügen und verschiedene Seiten anzeigen.

Aufgrund von API-Gateway-Einschränkungen ist der Teil / jinja / eine Versionszeichenfolge und kann nicht entfernt werden.

Für den Zugriff über root scheint es gut, CloudFront usw. vor API Gateway zu stellen. Sie können statische Dateien nicht nur mit API Gateway hosten.

Am Ende

Ich habe versucht, mit Lambda eine dynamische Seite mit einer ziemlich engen Abweichung zu erstellen, aber es war gut, sie sicher erstellen zu können. Ich hatte wegen des Namens API Gateway Bedenken, etwas für API als Webseite zu verwenden, aber am Ende ist es mächtig, dass sogar ein vollwertiger Webdienst mit Lambda + API Gateway verwendet werden kann. Ich habe es gefühlt. Der einzige Schmerz in Lambda ist, dass Sie nur Python2 verwenden können ... Bitte unterstütze 3 so schnell wie möglich: bete:

https://github.com/pistatium/lambda_jinja_sample Die Quelle für diese Zeit ist hier.

Bonus

Unsere Qiita-Organisation Wurde letztes Mal gemacht. Ich würde gerne mein Bestes geben, um etwas anderes als AdventCalender zu schreiben.

Recommended Posts

Dynamische HTML-Seiten mit AWS Lambda und Python
Machen Sie mit AWS Lambda und Python gewöhnliche Tweets flottenartig
Benachrichtigen Sie HipChat mit AWS Lambda (Python)
Site-Überwachung und Alarmbenachrichtigung mit AWS Lambda + Python + Slack
[AWS] Verwenden von INI-Dateien mit Lambda [Python]
[AWS] Verknüpfen Sie Lambda und S3 mit boto3
Stellen Sie mit AWS Lambda Python eine Verbindung zu s3 her
Berühren Sie AWS mit Serverless Framework und Python
[AWS] Erstellen Sie mit CodeStar eine Python Lambda-Umgebung und führen Sie Hello World aus
Einfache Serverüberwachung mit AWS Lambda (Python) und Ergebnisbenachrichtigung mit Slack
LINE BOT mit Python + AWS Lambda + API Gateway
Serverlose Anwendung mit AWS SAM! (APIGATEWAY + Lambda (Python))
Amazon API Gateway und AWS Lambda Python-Version
Ich habe versucht, LINE BOT mit Python und Heroku zu machen
Stellen Sie die Python 3-Funktion mit Serverless Framework unter AWS Lambda bereit
Erstellen Sie in Docker eine Ebene für AWS Lambda Python
Ich möchte Lambda mit Python auf Mac AWS!
So veröffentlichen Sie GitHub-Seiten mit Pelican, einem statischen HTML-Generator von Python
Programmieren mit Python und Tkinter
Ver- und Entschlüsselung mit Python
Betreiben Sie TwitterBot mit Lambda, Python
Python und Hardware-Verwenden von RS232C mit Python-
[Python] Scraping in AWS Lambda
Ich habe einen Blackjack mit Python gemacht!
PyTorch mit AWS Lambda [Lambda-Import]
Python mit Pyenv und Venv
Ich habe mit Python einen Blackjack gemacht.
Othello gemacht mit Python (wie GUI)
Ich habe Wordcloud mit Python gemacht.
Funktioniert mit Python und R.
Lösen mit Ruby und Python AtCoder ABC178 D Dynamische Planungsmethode
[AWS] Versuchen Sie, die Python-Bibliothek mit SAM + Lambda (Python) zur Ebene hinzuzufügen.
Lösen mit Ruby und Python AtCoder ABC011 C Dynamische Planungsmethode
Lösen mit Ruby und Python AtCoder ABC153 E Dynamische Planungsmethode
Erstellen Sie mit AWS SAM schnell eine API mit Python, Lambda und API Gateway
Erstellen Sie mit AWS CDK Python ganz einfach Netzwerkinfrastruktur und EC2
Kommunizieren Sie mit FX-5204PS mit Python und PyUSB
Leuchtendes Leben mit Python und OpenCV
Ich habe eine einfache Schaltung mit Python gemacht (AND, OR, NOR, etc.)
Roboter läuft mit Arduino und Python
Installieren Sie Python 2.7.9 und Python 3.4.x mit pip.
Mit Flask erstellte SNS Python-Grundlagen
Neuronales Netzwerk mit OpenCV 3 und Python 3
Zusammenfassung bei Verwendung von AWS Lambda (Python)
AM-Modulation und Demodulation mit Python
Scraping mit Node, Ruby und Python
Zeigen Sie Fotos in Python und HTML an
[AWS] API mit API Gateway + Lambda erstellen
Dynamischer Proxy mit Python, Ruby, PHP
Scraping mit Python, Selen und Chromedriver
Textextraktion mit AWS Textract (Python3.6)
Gesichtserkennung mit Lambda (Python) + Erkennung
Kratzen mit Python und schöner Suppe
Schreiben Sie die AWS Lambda-Funktion in Python
Numer0n mit Elementen, die mit Python erstellt wurden
Ich habe mit Python eine Lotterie gemacht.