AWS Lambda tips / gotchas for Python
I use Pipenv to bundle Python libraries but you cannot run pipenv install
on Lambda environment.
There was also a gotcha when I tried to use psycopg2, so in this post, I’m going to clearify how I successfully connected to RDS.
(Note: We decided not to go with Serverless because we were in the middle of migrating from AWS to GCP and things around deployment would be totally different in case you use it.)
To simplify things, let’s say we have just one file called main.py
. If you have other files, of course you need to copy them into the deployed directory.
Python Pipenv package
When you need libraries from PyPI, you want to make a zip file and that zip file needs to include those PyPI libraries. As I mentioned, I use Pipenv and this is how you can do it.
And now you have libraries from Pipfile into deploy
directory.
Gotcha regarding directory structure when you deploy in zip format
So AWS Lambda requires your main python file be at the root level when you unzip the deployed zip file. This is what I did first.
But I kept seeing the error when I deployed the file, that says my main
package is missing.
The issue is when you unzip this file, actually main.py belongs to the second top level like this.
So the right way to zip the package is,
Maybe it was clear to you already, but I don’t zip files so often and figuring out the issue took me a while.
psycopg2
So psycopg2 needs to be compiled on Amazon Linux OS on which lambda functions run. You cannot compile it on the fly on Lambda environment, so you have to deploy the compiled one.
The solution is to use this library awslambda-psycopg2. You can simply download the library and put the whole necessary directory into the deploy directory as README suggests, UNLESS you need SSL/TLS option on Postgres connection.
When you need SSL/TLS connection, you have to compile pyscopg2 yourself on Amazon Linux Image.
I will update step by step command when I have a change later but this is the procedures you need to take.
- Run docker container from this image on your local
- Install the “build essentials” for the OS
- Install the version of Python you want and on the container. (I had to compile from source).
- Download regular psycopg2
- Install postgres you need, FOLLOWING THIS SSL INSTRUCTION
- Build psycopg2 by following this README
- Do
docker cp
and put the generated directory into ourdeploy
directory. The name needs to bepsycopg2
.
So they are the gotchas I have seen when I deployed Python functions to AWS Lambda.
Upload script sample
This is not limited to this particular case but when I work on the lambda functions, I found the work flow becomes repetitive. I think it’s useful to have a simple script that does the zip/deployment. My script looks something like this:
You can run it in the directory right above the deploy directory.