[PYTHON] Until hello world with zappa

Try hello world with zappa.

What is zappa

https://github.com/Miserlou/Zappa

It seems to be a flask-based framework that realizes serverless python web service with aws. It seems to make full use of api gateway + lamdba + cloudwatch events.

The demo gif image is exciting.


What is flask

http://flask.pocoo.org/

It is a microframework for python web application with wsgi + jinja2 as the back end. The first commit has a long history of 2010. As you can see on the official top page, you can do hello world with http with the following code.

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!\n"

if __name__ == "__main__":
    app.run()
$ pip install Flask
$ python hello.py &
 * Running on http://localhost:5000/
$ curl http://localhost:5000
Hello World!

Environment

This time I will try to run it with centos7 on vagrant. Since virtualenv is required for zappa, let's start from that area. In addition, we will proceed as a vagrant user.

Installation of required packages

Install with yum normally.

sudo yum install -y gcc libffi-devel python-devel openssl-devel zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel git

pip installation

Install pip system-wide.

curl -L https://bootstrap.pypa.io/get-pip.py | sudo python

pyenv + virtualenv

Install pyenv and virtualenv. I'm grateful to have a great script that can install both at once.

curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
cat << 'EOF' >> ~/.bash_profile

### virtualenv
export PATH="/home/vagrant/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
EOF

The following sites were easy to understand about pyenv and virtualenv. http://blog.ieknir.com/blog/pyenv-with-virtualenv/

virtualenvwrapper

It seems to be convenient, so I will introduce it with reference to the following qiita. http://qiita.com/drafts/505492193317819772c7/edit

sudo pip install virtualenvwrapper
export WORKON_HOME="~/python-venv"
mkdir -p $WORKON_HOME
virtualenvwrapper_sh=$(whereis virtualenvwrapper.sh | cut -d : -f2)
echo """
if [ -f ${virtualenvwrapper_sh} ]; then
    export WORKON_HOME=$HOME/.virtualenvs
    source ${virtualenvwrapper_sh}
fi
""" >> ~/.bash_profile
source ${virtualenvwrapper_sh}

So far I've put it on github.

Install python

### install python
pyenv install 2.7.12
pyenv local 2.7.12

It is 2.7.12.

$ pyenv versions
  system
* 2.7.12 (set by PYENV_VERSION environment variable)

zappa setup

mkvirtualenv

Let's create a dedicated environment with mkvirtualenv. The prompt changes and it's fashionable.

vagrant 07:42:55 ~$ mkvirtualenv zappa_2.7.12
(zappa_2.7.12) vagrant 07:42:55 ~$

I will set it up.

$ mkdir app
$ cd app
$ cat << EOF >> requirements.txt
zappa
flask
EOF
$ pip install -r requirements.txt
$ zappa init

███████╗ █████╗ ██████╗ ██████╗  █████╗
╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗
  ███╔╝ ███████║██████╔╝██████╔╝███████║
 ███╔╝  ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║
███████╗██║  ██║██║     ██║     ██║  ██║
╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝     ╚═╝  ╚═╝

Welcome to Zappa!

Zappa is a system for running server-less Python web applications on AWS Lambda and AWS API Gateway.
This `init` command will help you create and configure your new Zappa deployment.
Let's get started!

Your Zappa configuration can support multiple production environments, like 'dev', 'staging', and 'production'.
What do you want to call this environment (default 'dev'): 

Something came out. You are asked for the environment name, but leave it as dev.

Your Zappa deployments will need to be uploaded to a private S3 bucket.
If you don't have a bucket yet, we'll create one for you too.
What do you want call your bucket? (default 'zappa-*****'):

You'll be asked for an S3 bucket name to deploy to lambda, but leave this as the default.

It looks like this is a Flask application.
What's the modular path to your app's function?
This will likely be something like 'your_module.app'.
Where is your app's function?: 

Let's call it test.app.

Okay, here's your zappa_settings.js:

{
    "dev": {
        "app_function": "test.app",
        "s3_bucket": "zappa-******"
    }
}

Does this look okay? (default y) [y/n]: y

Done! Now you can deploy your Zappa application by executing:

	$ zappa deploy dev

After that, you can update your application code with:

	$ zappa update dev

To learn more, check out the Zappa project page on GitHub: https://github.com/Miserlou/Zappa
or stop by our Slack channel: http://bit.do/zappa

Enjoy!

Initialization is complete.

zappa_settings.json

By default the region was us-east-1, so edit it. Also, if the profile is separated by credentials, specify it by profile_name.

$  cat zappa_settings.json
{
    "dev": {
        "app_function": "test.app",
        "s3_bucket": "zappa-*****",
        "aws_region": "ap-northeast-1",
        "profile_name": "profile_name" //If necessary
    }
}

Sample placement

I would like to run the sample here.

$  cat test.py
import logging
from flask import Flask

app = Flask(__name__)
logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

@app.route('/', methods=['GET', 'POST'])
def hello(event=None, context=None):
    logger.info('Lambda function invoked index()')
    return 'hello from Flask!\n'


if __name__ == '__main__':
    app.run(debug=True)

The folder structure looks like this.

~/app$  tree
.
├── requirements.txt
├── test.py
└── zappa_settings.json

0 directories, 3 files

aws credential settings

Since you are accessing aws, set the credential in the following way.

deploy !

It's finally deploy.

(zappa_2.7.12-2) vagrant 08:05:26 ~/app$  zappa deploy dev
Packaging project as zip...
Uploading zip (2.7MiB)...
100%|█████████████████████████████████████████████████████████████████████████████████████████| 2.81M/2.81M [00:00<00:00, 2.97Mit/s]
Scheduling keep-warm..
Creating API Gateway routes (this only happens once)..
1008it [01:39, 10.17it/s]
Deploying API Gateway..
Deployed! https://*****.execute-api.ap-northeast-1.amazonaws.com/dev

I'll hit it.

(zappa_2.7.12-2) vagrant 08:07:45 ~/app$  curl -l https://*****.execute-api.ap-northeast-1.amazonaws.com/dev
hello from Flask!

It was!

Check the log

It is convenient to check cloudwatch logs with zappa tail dev. (I'm getting an error.)

[1470384650490] [DEBUG] 2016-08-05T08:10:50.490Z    1f3ccb88-5ae4-11e6-b4c6-c9ecf09594ff    Zappa Event: {u'body': u'e30=', u'headers': {u'Via': u'1.1 9736f79fa942ea72a1eee114f49093dd.cloudfront.net (CloudFront)', u'CloudFront-Is-Desktop-Viewer': u'true', u'CloudFront-Is-SmartTV-Viewer': u'false', u'CloudFront-Forwarded-Proto': u'https', u'X-Forwarded-For': u'1.1.1.1, 2.2.2.2', u'CloudFront-Viewer-Country': u'JP', u'Accept': u'*/*', u'User-Agent': u'curl/7.43.0', u'Host': u'q14421ik6h.execute-api.ap-northeast-1.amazonaws.com', u'X-Forwarded-Proto': u'https', u'X-Amz-Cf-Id': u'RdcP863CiLrem7LekuwSQrt2YvNw29a9m3Es55O2Db6E9YGjqWQdCg==', u'CloudFront-Is-Tablet-Viewer': u'false', u'X-Forwarded-Port': u'443', u'CloudFront-Is-Mobile-Viewer': u'false'}, u'params': {}, u'method': u'GET', u'query': {}}
[1470384650491] [INFO]  2016-08-05T08:10:50.491Z    1f3ccb88-5ae4-11e6-b4c6-c9ecf09594ff    Lambda function invoked index()
[1470384650491] [INFO]  2016-08-05T08:10:50.491Z    1f3ccb88-5ae4-11e6-b4c6-c9ecf09594ff    1.1.1.1 - - [05/Aug/2016:08:10:50 +0000] "GET / HTTP/1.1" 200 18 "" "curl/7.43.0" 0/0.798
[1470384659083] need more than 1 value to unpack: ValueError
Traceback (most recent call last):
  File "/var/task/handler.py", line 324, in lambda_handler
    return LambdaHandler.lambda_handler(event, context)
  File "/var/task/handler.py", line 121, in lambda_handler
    return cls().handler(event, context)
  File "/var/task/handler.py", line 146, in handler
    app_function = self.import_module_and_get_function(whole_function)
  File "/var/task/handler.py", line 114, in import_module_and_get_function
    module, function = whole_function.rsplit('.', 1)
ValueError: need more than 1 value to unpack

Application update

You can update your application with zappa update dev.

Application removal

You can delete everything deployed with zappa undeploy dev.

$ zappa undeploy dev
Are you sure you want to undeploy? [y/n] y
Deleting API Gateway..
Removing keep-warm..
Deleting Lambda function..
Done!

at the end

I was able to build a web application that hello world without knowing what it was. It's amazing.

Recommended Posts

Until hello world with zappa
hello world with ctypes
Hello, World with Docker
Hello world with flask
Draw hello world with mod_wsgi
Hello World with Flask + Hamlish
Python starting with Hello world!
Hello world
Hello, world! With virtual CAN communication
[Note] Hello world output with python
Hello World! By QPython with Braincrash
Until Hello World with Flask + uWSGI + Nginx @ Sakura's VPS (CentOS 6.6)
Hello World and face detection with opencv-python 4.2
Hello World with Raspberry Pi + Minecraft Pi Edition
Pymacs hello world
cython hello world
Hello World! By QPython with Brainfu * k
Hello World and face detection with OpenCV 4.3 + Python
Hello World with gRPC / go in Docker environment
Hello world with full features of Go language
Say hello to the world with Python with IntelliJ
Hello World with nginx + uwsgi + python on EC2
Create a one-file hello world application with django
First python ① Environment construction with pythonbrew & Hello World !!
Create a "Hello World" (HTTP) server with Tornado
RabbitMQ Tutorial 1 ("Hello World!")
Hello World on Django
Django's first Hello World
Predicting Kaggle's Hello World, Titanic Survivors with Logistic Regression-Modeling-
[Learning memo] How to make an application with Django ~ Until Hello World is displayed ~
Hello World with Google App Engine (Java 8) + Spring Boot + Gradle
Hello World with Google App Engine (Java 8) + Servlet API 3.1 + Gradle
Programming language in "Hello World"
Hello World in GO language
Predicting Kaggle's Hello World, Titanic Survivors with Logistic Regression-Prediction / Evaluation-
Hello World (beginners) on Django
Hello World with Google App Engine (Java 11) + Spring Boot + Gradle
Getting Started with Heroku-Viewing Hello World in Python Django with Raspberry PI 3
Start with Windows, not so scary Nim ① It's like hello world.
Let's do "Hello World" in 40 languages! !!
Until you start Jupyter with Docker
Hello world! (Minimum Viable Block Chain)
cout << "Hello, World! \ N" in python
Hello World in Flask [Appropriate memo]
Code: 2 "Hello World" in "Choregraphe-Python script"
Until you run python with apache
Until dealing with python in Atom
Python #Hello World for super beginners
Until you shake ruby with renpy
Introduction to Ansible Part 1'Hello World !!'
[AWS] Create a Python Lambda environment with CodeStar and do Hello World
Re: Heroku life begin with Flask from zero - Environment and Hello world -