[PYTHON] J'ai touché AWS Chalice

Qu'est-ce qu'AWS Chalice?

Amazon API Gateway et AWS Lambda sont cliqués semi-automatiquement à partir de la CLI. Il semble que cela puisse être fait. J'aime AWS Lambda (et Amazon API Gateway), alors je l'ai touché.

Préparation

Créer un environnement virtuel pour Python

Il est recommandé de créer un environnement virtuel avec AWS Chalice Hands-on, donc créez-le si nécessaire. Je vais.

Installation de Virtualenv pour créer un environnement virtuel

$ pip install virtualenv

Créer un environnement virtuel

# 『~/.virtualenvs/chalice-"handson" est le nom de l'environnement
#Tout nom d'environnement convient car il ne correspond qu'à AWS pratique.
virtualenv ~/.virtualenvs/chalice-handson

Activer l'environnement virtuel

$ source ~/.virtualenvs/chalice-handson/bin/activate
#"Source" est ".] Peut être substitué, donc la commande suivante a la même signification que ci-dessus.
$ . ~/.virtualenvs/chalice-handson/bin/activate

Fin de l'environnement virtuel

Si vous souhaitez mettre fin à l'environnement virtuel, utilisez la commande suivante. Même si vous quittez l'environnement virtuel, les fichiers d'environnement virtuel créés resteront, vous pouvez donc entrer dans l'environnement virtuel en tapant à nouveau la commande enable.

$ deactivate

Installation du calice

$ pip install chalice
#Vérifiez s'il a été installé
$ chalice --version
chalice 1.12.0, python 3.7.3, darwin 19.6.0

Informations d'identification AWS

Si ~ / .aws / credentials et ~ / .aws / config n'existent pas, définissez-les avec la commande suivante. Sinon, vous vous fâcherez lors du déploiement sur AWS.

$ aws configure

Créer un nouveau projet

Maintenant que nous sommes prêts, examinons rapidement le flux de la création du projet au déploiement vers AWS. Commencez par créer un projet avec la commande suivante.

#«Helloworld» est le nom de projet utilisé dans AWS pratique, et n'importe quel nom de projet peut être spécifié.
$ chalice new-project helloworld

Les fichiers suivants sont créés en créant un projet.

.
├── .chalice
│   └── config.json
├── .gitignore
├── app.py
└── requirements.txt

Le contenu de l''app.py 'créé automatiquement est le suivant. Le contenu est simple et lorsque vous accédez à l'index du point de terminaison API Gateway, il renvoie {'hello': 'world'} comme corps de réponse. Le corps de la réponse {'hello': 'world'} est défini avec {'hello': 'world'} même si le nom du projet est autre que helloworld.

from chalice import Chalice

app = Chalice(app_name = 'helloworld')

@app.route('/')
def index():
    return {'hello': 'world'}    #Même si le nom du projet est autre que helloworld, ici{'hello': 'world'}est

Test local

Essayez-le dans votre environnement local pour voir s'il se comporte réellement comme décrit ci-dessus (renvoie-t-il {'hello': 'world'} lors de l'accès)? Vous pouvez démarrer le serveur local avec la commande suivante. : + 1: Facile et sympa!

$ chalice local
Serving on http://127.0.0.1:8000

Si vous essayez d'y accéder avec un navigateur, vous devriez voir {" hello ":" world "}.

Déployer sur AWS

Cela semble correct, alors déployons-le sur AWS afin qu'il soit accessible de l'extérieur. Le déploiement est facile, exécutez simplement la commande suivante:

$ chalice deploy

Ensuite, les éléments suivants seront créés automatiquement sur AWS.

Après le déploiement, la configuration sera la suivante.

.
├── .chalice
│   ├── config.json
│   ├── deployed
│   │   └── dev.json
│   └── deployments
│       └── xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-python3.8.zip
├── .gitignore
├── app.py
└── requirements.txt

Enfin, le point de terminaison API Gateway est affiché en tant que Rest API URL, nous allons donc y accéder avec un navigateur. Si vous ne connaissez pas l'URL de l'API Rest, vous pouvez l'afficher avec la commande suivante.

$ chalice url

Demande de traitement

Maintenant que vous avez vu les bases de l'utilisation d'AWS Chalice, examinons d'autres fonctionnalités de contrôle.

Paramètres d'URL

Vous pouvez écrire des paramètres dans le modèle de chemin de @ app.route ('/') dans ʻapp.py` comme indiqué ci-dessous, et vous pouvez utiliser la valeur reçue comme paramètre comme argument dans la méthode.

from chalice import Chalice

app = Chalice(app_name = 'helloworld')

@app.route('/')
def index():
    return {'hello': 'world'} 

#Ajoutez ce qui suit
@app.route('/hello/{name}')
def greet(name):
    return {'hello': name}

Après avoir édité ʻapp.py, refaites ʻalice deploy. Une fois le déploiement terminé, ajoutez / hello /" valeur arbitraire " au point de terminaison API Gateway et accédez-y avec un navigateur. Vous devriez voir {" bonjour ":" "valeur arbitraire" "}. Veuillez noter que la valeur passée en tant que «valeur arbitraire» est une chaîne de caractères même s'il s'agit d'une valeur numérique.

Méthode HTTP

La méthode HTTP peut être spécifiée en écrivant une méthode dans @ app.route ('/') de ʻapp.py` comme indiqué ci-dessous.

from chalice import Chalice

app = Chalice(app_name = 'helloworld')

@app.route('/')
def index():
    return {'hello': 'world'}

@app.route('/hello/{name}')
def greet(name):
    return {'hello': name}

#Ajoutez ce qui suit
@app.route('/hello', methods = ['POST'])
def hello():
    return {'hello': 'POST world'}

Après avoir édité ʻapp.py, refaites ʻalice deploy. Le POST ajouté cette fois ne peut pas être confirmé depuis le navigateur, donc vérifions-le rapidement en mode interactif de Python.

$ python
>>> import requests    #Si les demandes ne sont pas incluses, les demandes d'installation pip
>>> response = requests.post('"API Gateway Endpoint"/hello', data = {})
>>> print(response.text)
{"hello":"POST world"}

Accéder aux métadonnées

Le code d'ici ne décrira que le bloc de modification et la réponse. L'acquisition des métadonnées est spécifiée sous la forme ʻapp.current_request. "Honyara" `. HTTP Method

@app.route('/hello')
def hello():
    return {'metadata': app.current_request.method}

#réponse
{"metadata":"GET"}

Query Parameters

@app.route('/hello')
def hello():
    return {'metadata': app.current_request.query_params}

#Réponse (la demande est/hello?test1=abc&test2=123&test2=456)
#Si un paramètre du même nom est spécifié dans la requête, le calice l'emportera plus tard (test2)=123&test2=456 est test2=Devenir 456)
{"metadata":{"test1":"abc","test2":"456"}}

Request Body - Raw Récupère le corps de la requête en octet. Si Content-Type: application / json, vous pouvez utiliser ʻapp.current_request.json_body au lieu de ʻapp.current_request.raw_body. Il s'agit d'un type de chaîne de caractères.

@app.route('/hello')
def hello():
    return {'metadata': app.current_request.raw_body}

#demande
$ python
>>> import requests, json
>>> response = requests.post('"API Gateway Endpoint"/hello', data = json.dumps({'hello': 'world'}), headers = {'Content-Type': 'application/json' })
>>> print(response.text)
#réponse
{"metadata":{"hello":"world"}}

Traitement des réponses

Ensuite, regardons la réponse.

Réponse HTTP personnalisée

Si vous souhaitez renvoyer un code d'état ou un en-tête arbitraire, renvoyez-le avec des informations arbitraires incluses dans l'objet de classe de réponse. N'oubliez pas «Importer la réponse». (Cela n'a pas d'importance, mais j'ai écrit json.dumps sans json.dump et s, et` {"Code": "InternalServerError", "Message": "Une erreur interne du serveur s'est produite."} J'ai eu une réponse de ʻet j'y ai été accro pendant un moment sans remarquer l'erreur ...: persévérez :)

from chalice import Chalice, Response
import json

app = Chalice(app_name='helloworld')

@app.route('/')
def index():
    return Response(
        body = json.dumps({'hello':'world'}),
        headers = {'Content-Type': 'application/json'},
        status_code = 200
    )

@app.route('/text')
def text():
    return Response(
        body = 'Hello, World',
        headers = {'Content-Type': 'text/plain'},
        status_code = 200
    )

Erreur de réponse HTTP

Puisqu'il existe une classe pour renvoyer une réponse d'erreur, nous l'utiliserons. Dans l'exemple ci-dessous, il s'agit d'une erreur interdite 403. N'oubliez pas d'importer également la classe d'erreur ici.

from chalice import Chalice, ForbiddenError

app = Chalice(app_name='helloworld')

@app.route('/forbidden')
def forbidden():
    raise ForbiddenError(
        '403!'
    )

Il existe d'autres classes d'erreur comme suit. ([[Learn AWS with Easy Hands-on] Créez une API RESTful sans serveur! Développement d'applications Python avec Chalice | Blog de démarrage AWS](https://aws.amazon.com/jp/blogs/startup/event] Voir -report-calice-handson /)) Il est également possible de renvoyer une réponse avec un code d'erreur qui n'est pas préparé à l'aide de la réponse HTTP personnalisée présentée ci-dessus. (Bien sûr, il est également possible de renvoyer une erreur avec un code d'erreur dans une réponse HTTP personnalisée.)

Activer CORS

Vous pouvez simplement écrire ce qui suit.

@app.route('/', methods = ['POST'], cors = True)

Décorateur

Je l'ai toujours écrit sous la forme de @ app.route ('/'), mais c'est sous la forme d'API Gateway + AWS Lambda. L'intégration AWS Lambda autre que API Gateway est possible en utilisant d'autres décorateurs. Les éléments suivants sont actuellement pris en charge.

--AWS Lambda indépendante: @ app.lambda_function

Pour une utilisation détaillée et un exemple de code, j'ai essayé de gérer Lambda (Python) et API Gateway avec Chalice est très utile.

Effacer

Les rôles IAM, Lambda et API Gateway (pour @ app.route) déployés sur AWS avec chalice deploy peuvent être supprimés en bloc avec la commande suivante.

$ chalice delete

Résumé

Il semble que vous puissiez créer un environnement sans serveur assez facilement à l'aide d'AWS Chalice. Il est facile à supprimer, il est donc agréable de pouvoir le créer et le supprimer facilement. Je pensais écrire un exemple plus concret, mais comme c'est déjà devenu un long article, je vais le résumer dans un autre article.

We're hiring! Nous développons un chatbot IA. Si vous êtes intéressé, n'hésitez pas à nous contacter depuis la page Wantedly!

Article de référence

Recommended Posts

J'ai touché AWS Chalice
J'ai essayé d'utiliser AWS Chalice
J'ai touché HaikuFinder
J'ai touché Flask
J'ai essayé AWS Iot
J'ai essayé de toucher l'API Qiita
J'ai touché Bergeronnette (2). Introduction des extensions django.
J'ai touché Tensorflow et keras
J'ai touché PyAuto pendant un moment
Déterminer si AWS Chalice est un calice local
J'ai touché quelque chose qui s'appelle Touch Designer
J'ai créé un nouveau compartiment AWS S3
J'ai touché "Orator" alors j'ai fait une note
Je crée mon propre cli aws
Je veux jouer avec aws avec python
3 petites histoires que j'ai vérifiées en utilisant Chalice
J'ai touché à l'outil de préparation de données Paxata
Je viens de faire FizzBuzz avec AWS Lambda