Skip to content

Commit 7c80aa9

Browse files
Merge pull request #5 from 4dn-dcic/overhaul
Overhaul
2 parents e3f2a86 + f039884 commit 7c80aa9

20 files changed

Lines changed: 428 additions & 177 deletions

.travis.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
language: python
2+
sudo: false
3+
python:
4+
- '3.6'
5+
install:
6+
- pip install -r requirements.txt
7+
- pip install -r dev-requirements.txt
8+
- pip install coveralls
9+
script:
10+
- pytest --cov aws_lambda -v tests
11+
after_success:
12+
- coveralls
13+
- echo 'Success!'

README.rst

Lines changed: 41 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ python-λ
77
:alt: Pypi
88
:target: https://pypi.python.org/pypi/python-lambda/
99

10-
.. image:: https://img.shields.io/pypi/pyversions/python-lambda.svg
11-
:alt: Python Versions
12-
:target: https://pypi.python.org/pypi/python-lambda/
10+
.. image:: https://travis-ci.org/4dn-dcic/python-lambda.svg?branch=master
11+
:alt: Build Status
12+
:target: https://travis-ci.org/4dn-dcic/python-lambda
13+
14+
.. image:: https://coveralls.io/repos/github/4dn-dcic/python-lambda/badge.svg?branch=master
15+
:alt: Coverage
16+
:target: https://coveralls.io/github/4dn-dcic/python-lambda?branch=master
1317

1418
Python-lambda is a toolset for developing and deploying *serverless* Python code in AWS Lambda.
1519

@@ -18,10 +22,6 @@ Important
1822
This is a FORK of the original Python-lambda package by Nick Ficano.
1923
It will NOT be updated regularly and is frozen per our projects needs.
2024

21-
A call for contributors
22-
=======================
23-
With python-lambda and `pytube <https://github.com/nficano/pytube/>`_ both continuing to gain momentum, I'm calling for contributors to help build out new features, review pull requests, fix bugs, and maintain overall code quality. If you're interested, please email me at nficano[at]gmail.com.
24-
2525
Description
2626
===========
2727

@@ -34,125 +34,55 @@ The *Python-Lambda* library takes away the guess work of developing your Python-
3434
Requirements
3535
============
3636

37-
* Python 2.7 & 3.6 (At the time of writing this, AWS Lambda only supports Python 2.7/3.6).
38-
* Pip (~8.1.1)
39-
* Virtualenv (~15.0.0)
40-
* Virtualenvwrapper (~4.7.1)
37+
* Python 3.6
38+
* Pip (Any should work)
39+
* Virtualenv (>=15.0.0)
40+
* Virtualenvwrapper (>=4.7.1)
4141

4242
Getting Started
4343
===============
4444

45-
First, you must create an IAM Role on your AWS account called `lambda_basic_execution` with the `LambdaBasicExecution` policy attached.
46-
47-
On your computer, create a new virtualenv and project folder.
48-
49-
.. code:: bash
50-
51-
$ mkvirtualenv pylambda
52-
(pylambda) $ mkdir pylambda
53-
54-
Next, download *Python-Lambda* using pip via pypi.
55-
56-
.. code:: bash
57-
58-
(pylambda) $ pip install python-lambda
59-
60-
From your ``pylambda`` directory, run the following to bootstrap your project.
61-
62-
.. code:: bash
63-
64-
(pylambda) $ lambda init
65-
66-
This will create the following files: ``event.json``, ``__init__.py``, ``service.py``, and ``config.yaml``.
67-
68-
Let's begin by opening ``config.yaml`` in the text editor of your choice. For the purpose of this tutorial, the only required information is ``aws_access_key_id`` and ``aws_secret_access_key``. You can find these by logging into the AWS management console.
69-
70-
Next let's open ``service.py``, in here you'll find the following function:
45+
Using this library is intended to be as straightforward as possible. Code for a very simple lambda used in the tests is reproduced below.
7146

7247
.. code:: python
7348
74-
def handler(event, context):
75-
# Your code goes here!
76-
e = event.get('e')
77-
pi = event.get('pi')
78-
return e + pi
79-
80-
81-
This is the handler function; this is the function AWS Lambda will invoke in response to an event. You will notice that in the sample code ``e`` and ``pi`` are values in a ``dict``. AWS Lambda uses the ``event`` parameter to pass in event data to the handler.
82-
83-
So if, for example, your function is responding to an http request, ``event`` will be the ``POST`` JSON data and if your function returns something, the contents will be in your http response payload.
49+
config = {
50+
'function_name': 'my_test_function',
51+
'function_module': 'service',
52+
'function_handler': 'handler',
53+
'handler': 'service.handler',
54+
'region': 'us-east-1',
55+
'runtime': 'python3.6',
56+
'role': 'helloworld',
57+
'description': 'Test lambda'
58+
}
8459
85-
Next let's open the ``event.json`` file:
8660
87-
.. code:: json
61+
def handler(event, context):
62+
return 'Hello! My input event is %s' % event
8863
89-
{
90-
"pi": 3.14,
91-
"e": 2.718
92-
}
64+
This code illustrates the two things required to create a lambda. The first is ``config``, which specifies metadata for AWS. One important thing to note in here is the ``role`` field. This must be a IAM role with Lambda permissions - the one in this example is ours. The second is the ``handler`` function. This is the actual code that is executed.
9365

94-
Here you'll find the values of ``e`` and ``pi`` that are being referenced in the sample code.
66+
Given this code in ``example_function.py`` you would deploy this function like so:
9567

96-
If you now try and run:
97-
98-
.. code:: bash
99-
100-
(pylambda) $ lambda invoke -v
101-
102-
You will get:
103-
104-
.. code:: bash
105-
106-
# 5.858
107-
108-
# execution time: 0.00000310s
109-
# function execution timeout: 15s
110-
111-
As you probably put together, the ``lambda invoke`` command grabs the values stored in the ``event.json`` file and passes them to your function.
112-
113-
The ``event.json`` file should help you develop your Lambda service locally. You can specify an alternate ``event.json`` file by passing the ``--event-file=<filename>.json`` argument to ``lambda invoke``.
114-
115-
When you're ready to deploy your code to Lambda simply run:
116-
117-
.. code:: bash
118-
119-
(pylambda) $ lambda deploy
120-
121-
The deploy script will evaluate your virtualenv and identify your project dependencies. It will package these up along with your handler function to a zip file that it then uploads to AWS Lambda.
122-
123-
You can now log into the `AWS Lambda management console <https://console.aws.amazon.com/lambda/>`_ to verify the code deployed successfully.
124-
125-
Wiring to an API endpoint
126-
=========================
127-
128-
If you're looking to develop a simple microservice you can easily wire your function up to an http endpoint.
68+
.. code:: python
12969
130-
Begin by navigating to your `AWS Lambda management console <https://console.aws.amazon.com/lambda/>`_ and clicking on your function. Click the API Endpoints tab and click "Add API endpoint".
70+
from aws_lambda import deploy_function
71+
import example_function
72+
deploy_function(example_function,
73+
function_name_suffix='<suffix>',
74+
package_objects=['list', 'of', 'local', 'modules'],
75+
requirements_fpath='path/to/requirements',
76+
extra_config={'optional_arguments_for': 'boto3'})
13177
132-
Under API endpoint type select "API Gateway".
78+
And that's it! You've deployed a simple lambda function. You can navigate to the AWS console to create a test event to trigger it or you can invoke it directly using Boto3.
13379

134-
Next change Method to ``POST`` and Security to "Open" and click submit (NOTE: you should secure this for use in production, open security is used for demo purposes).
80+
Advanced Usage
81+
==============
13582

136-
At last you need to change the return value of the function to comply with the standard defined for the API Gateway endpoint, the function should now look like this:
83+
Many of the options specified in the above code block when it came to actually deploying the function are not used. These become more useful as you want to make more complicated lambda functions. The ideal way to incorporate dependencies into lambda functions is by providing a ``requirements.txt`` file. We rely on ``pip`` to install these packages and have found it to be very reliable. While it is also possible to specify local modules as well through ``package_objects``, doing so is not recommended because those modules must be specified at the top level of the repository in order to work out of the box. There is a comment on this topic in ``example_function_package.py`` with code on how to handle it.
13784

138-
.. code:: python
85+
Tests
86+
========
13987

140-
def handler(event, context):
141-
# Your code goes here!
142-
e = event.get('e')
143-
pi = event.get('pi')
144-
return {
145-
"statusCode": 200,
146-
"headers": { "Content-Type": "application/json"},
147-
"body": e + pi
148-
}
149-
150-
Now try and run:
151-
152-
.. code:: bash
153-
154-
$ curl --header "Content-Type:application/json" \
155-
--request POST \
156-
--data '{"pi": 3.14, "e": 2.718}' \
157-
https://<API endpoint URL>
158-
# 5.8580000000000005
88+
Tests can be found in the ``test_aws_lambda.py``. Using the tests as a guide to develop your lambdas is probably a good idea. You can also see how to invoke the lambdas directly from Python (and interpret the response).

aws_lambda/__init__.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
# -*- coding: utf-8 -*-
2-
# flake8: noqa
3-
__author__ = 'Nick Ficano'
4-
__email__ = 'nficano@gmail.com'
5-
__version__ = '0.7.1'
6-
72
from .aws_lambda import deploy_function
8-
9-
# Set default logging handler to avoid "No handler found" warnings.
103
import logging
11-
try: # Python 2.7+
12-
from logging import NullHandler
13-
except ImportError:
14-
class NullHandler(logging.Handler):
15-
def emit(self, record):
16-
pass
174

18-
logging.getLogger(__name__).addHandler(NullHandler())
5+
logging.getLogger(__name__).addHandler(logging.NullHandler())

aws_lambda/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Version information."""
22

33
# The following line *must* be the last in the module, exactly as formatted:
4-
__version__ = "0.12.3"
4+
__version__ = "1.0.0"

0 commit comments

Comments
 (0)