Deploy a Python API on AWS
By: Jeremy Zhang
Tags: Flask, Python, AWS, API

Deploy a Python API on AWS

Flask + Lambda + API Gateway

The very first idea of creating my own app and deploying it on the cloud so that everyone could use it is super exciting to me, and this is what inspired me to write this post. If this idea also intrigues you, please follow through and from this post, you will learn how to deploy a python app step by step.

Firstly, you need an app

You will need to wrap your idea in an app, or say an API, which can process calls from the internet. An example is here. This is a flask app,

where the key lies in the app.py file, and this app receives your resume and help refer you internally. Notice that we don’t even need a docker file, the AWS Lambda is so light-weighted that you don’t even need to wrap your code in a container!

Secondly, download Zappa

Zappa, a quote from the official docs, it

makes it super easy to build and deploy server-less, event-driven Python applications (including, but not limited to, WSGI web apps) on AWS Lambda + API Gateway. Think of it as “serverless” web hosting for your Python apps. That means infinite scaling, zero downtime, zero maintenance — and at a fraction of the cost of your current deployments!

If you’ve been using AWS service for a while, you would know that to deploy a service on the cloud with the usage of multiple different services and configurations is no easy task, but Zappa comes to the rescue, that with simple commands(trust me, it’s really just a few lines!), all the heavy lifting configurations would be done!

pip install zappa

BTW, I assume you have all the packages installed in the project virtual environment, if not, do

virtualenv -p `which python3` env

(you need to have virtualenv pre-installed)

Now do

zappa init

Go through the settings one by one, if you don’t understand just use the default, and you will still be able to change it afterwards. After this, you would have a zappa_setting.json in your root folder, mine looks like this

{

"production": {

"app_function": "app.app",

"aws_region": "ap-southeast-1",

"profile_name": "default",

"project_name": "referral-api",

"runtime": "python3.7",

"s3_bucket": "zappa-referral-api-eu2hzy8sf"

}

}

Thirdly, give Zappa access to your AWS

Now you need to go to your AWS console, but wait, you said Zappa would do all the AWS work for us? Yes, but think it this way, before Zappa could make any changes on your behalf, it needs access to you AWS resources, and this step is to give Zappa the credential to do such thing.

You can follow the steps here deploy-serverless-app (trust me, this one is really an illustrative guide through with all the images you need).

For the policy attached to the group, use this one! (The one in the link above does not enable you to update your app)

{

"Version": "2012-10-17",

"Statement": [

{

"Effect": "Allow",

"Action": [

"iam:AttachRolePolicy",

"iam:GetRole",

"iam:CreateRole",

"iam:PassRole",

"iam:PutRolePolicy"

],

"Resource": [

"arn:aws:iam::XXXXXXXXXXXXXXXX:role/*-ZappaLambdaExecutionRole"

]

},

{

"Effect": "Allow",

"Action": [

"lambda:CreateFunction",

"lambda:ListVersionsByFunction",

"logs:DescribeLogStreams",

"events:PutRule",

"lambda:GetFunctionConfiguration",

"cloudformation:DescribeStackResource",

"apigateway:DELETE",

"apigateway:UpdateRestApiPolicy",

"events:ListRuleNamesByTarget",

"apigateway:PATCH",

"events:ListRules",

"cloudformation:UpdateStack",

"lambda:DeleteFunction",

"events:RemoveTargets",

"logs:FilterLogEvents",

"apigateway:GET",

"lambda:GetAlias",

"events:ListTargetsByRule",

"cloudformation:ListStackResources",

"events:DescribeRule",

"logs:DeleteLogGroup",

"apigateway:PUT",

"lambda:InvokeFunction",

"lambda:GetFunction",

"lambda:UpdateFunctionConfiguration",

"cloudformation:DescribeStacks",

"lambda:UpdateFunctionCode",

"lambda:DeleteFunctionConcurrency",

"events:DeleteRule",

"events:PutTargets",

"lambda:AddPermission",

"cloudformation:CreateStack",

"cloudformation:DeleteStack",

"apigateway:POST",

"lambda:RemovePermission",

"lambda:GetPolicy"

],

"Resource": "*"

},

{

"Effect": "Allow",

"Action": [

"s3:ListBucketMultipartUploads",

"s3:CreateBucket",

"s3:ListBucket"

],

"Resource": "arn:aws:s3:::zappa-*"

},

{

"Effect": "Allow",

"Action": [

"s3:PutObject",

"s3:GetObject",

"s3:AbortMultipartUpload",

"s3:DeleteObject",

"s3:ListMultipartUploadParts"

],

"Resource": "arn:aws:s3:::zappa-*/*"

}

]

}

Now you add the credentials you created for Zappa to your local file (credentials and configs), mine looks like this

[default]

aws_access_key_id = ****

aws_secret_access_key = **** [zappa]

aws_access_key_id = ****

aws_secret_access_key = ****

and config like this

[default]

region = ap-southeast-1

output = json [zappa]

region = ap-southeast-1

output = json

I created one especially for Zappa, because I believe most of us would have a default credential for ourself, this setting would allow you to switch between different profiles.

Now it is ready to deploy!

export AWS_DEFAULT_PROFILE=zappa

zappa deploy production

You would see your API url right after the command line. Now go to your AWS Lambda you should see our API deployed:

And in API Gateway you can see:

Now that I can test the public endpoint on postman and get a response:

Congrats! Now you have your app fully deployed to AWS with Lambda and API Gateway!

You can stop here if this already satisfies your need, but if you would like to distribute your API and add restrictions for it, you can continue to the next part.

Extra1: Add Key to API

You might have noticed that so far our API is publicly accessible, which means anyone can access our API and it is susceptible to malicious attack. To avoid such undesired visits, we need to add extra limitations on our API usage (Usage Plan) and credentials (x-api-key) to restrict visits.

To add a key to your API, follow the steps here.

Extra2: Distribute your API through RapidAPI

RapidAPI is where for everyone to freely open and sell their API to the world as long as someone is willing to pay for it.

Go to RapidAPI and click Add New API Fill in the basic info of your API For the URL of your API, paste the AWS url we previous got after deploying though Zappa In the access control add your api key as follow

5. Add a pricing plan and you are ready to launch it to the public!

Lastly, if you are interested, you can check out my referral API. If you are looking for a new career, so far it helps you to refer you to the company of Bytedance and Grab through the internal portal.

This is post is initially inspired by this, a great post helped me to start the plan, feel free to check that out!