Skip to content

Commit cdc63c9

Browse files
committed
Merge branch 'master' of github.com:nficano/python-lambda
* 'master' of github.com:nficano/python-lambda: Update boto3 and botocore to Latest Versions Use STS to fetch the account ID instead of IAM Updated API Endpoint documentation Update README.rst Add option to delete old versions of a lambda function Remove self requirement Excluded compiled python files Update folder name in package data Simplify init action Renamed directory and removed __init__ file
2 parents 9e879c8 + 5d452e4 commit cdc63c9

File tree

10 files changed

+80
-22
lines changed

10 files changed

+80
-22
lines changed

README.rst

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ python-λ
66
:alt: Pypi
77
:target: https://pypi.python.org/pypi/python-lambda/
88

9-
.. image:: https://img.shields.io/pypi/dm/python-lambda.svg
10-
:alt: Pypi downloads per month
11-
:target: https://pypi.python.org/pypi/python-lambda/
12-
139
.. image:: https://img.shields.io/pypi/pyversions/python-lambda.svg
1410
:alt: Python Versions
1511
:target: https://pypi.python.org/pypi/python-lambda/
@@ -125,6 +121,20 @@ Under API endpoint type select "API Gateway".
125121

126122
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).
127123

124+
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:
125+
126+
.. code:: python
127+
128+
def handler(event, context):
129+
# Your code goes here!
130+
e = event.get('e')
131+
pi = event.get('pi')
132+
return {
133+
"statusCode": 200,
134+
"headers": { "Content-Type": "application/json"},
135+
"body": e + pi
136+
}
137+
128138
Now try and run:
129139

130140
.. code:: bash

aws_lambda/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
__email__ = 'nficano@gmail.com'
55
__version__ = '0.4.0'
66

7-
from .aws_lambda import deploy, invoke, init, build
7+
from .aws_lambda import deploy, invoke, init, build, cleanup_old_versions
88

99
# Set default logging handler to avoid "No handler found" warnings.
1010
import logging

aws_lambda/aws_lambda.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,60 @@
88
from shutil import copy, copyfile
99
from tempfile import mkdtemp
1010

11+
import botocore
1112
import boto3
1213
import pip
1314
import yaml
14-
from . import project_template
15+
1516
from .helpers import mkdir, read, archive, timestamp
1617

1718

1819
log = logging.getLogger(__name__)
1920

2021

22+
def cleanup_old_versions(src, keep_last_versions):
23+
"""Deletes old deployed versions of the function in AWS Lambda.
24+
25+
Won't delete $Latest and any aliased version
26+
27+
:param str src:
28+
The path to your Lambda ready project (folder must contain a valid
29+
config.yaml and handler module (e.g.: service.py).
30+
:param int keep_last_versions:
31+
The number of recent versions to keep and not delete
32+
"""
33+
if keep_last_versions <= 0:
34+
print("Won't delete all versions. Please do this manually")
35+
else:
36+
path_to_config_file = os.path.join(src, 'config.yaml')
37+
cfg = read(path_to_config_file, loader=yaml.load)
38+
39+
aws_access_key_id = cfg.get('aws_access_key_id')
40+
aws_secret_access_key = cfg.get('aws_secret_access_key')
41+
42+
client = get_client('lambda', aws_access_key_id, aws_secret_access_key,
43+
cfg.get('region'))
44+
45+
response = client.list_versions_by_function(
46+
FunctionName=cfg.get("function_name")
47+
)
48+
versions = response.get("Versions")
49+
if len(response.get("Versions")) < keep_last_versions:
50+
print("Nothing to delete. (Too few versions published)")
51+
else:
52+
version_numbers = [elem.get("Version") for elem in
53+
versions[1:-keep_last_versions]]
54+
for version_number in version_numbers:
55+
try:
56+
client.delete_function(
57+
FunctionName=cfg.get("function_name"),
58+
Qualifier=version_number
59+
)
60+
except botocore.exceptions.ClientError as e:
61+
print("Skipping Version {}: {}".format(version_number,
62+
e.message))
63+
64+
2165
def deploy(src, local_package=None):
2266
"""Deploys a new function to AWS Lambda.
2367
@@ -93,15 +137,13 @@ def init(src, minimal=False):
93137
Minimal possible template files (excludes event.json).
94138
"""
95139

96-
path_to_project_template = project_template.__path__[0]
97-
for f in os.listdir(path_to_project_template):
98-
path_to_file = os.path.join(path_to_project_template, f)
99-
if minimal and f == 'event.json':
100-
continue
101-
if f.endswith('.pyc'):
102-
# We don't need the compiled files.
140+
templates_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
141+
"project_templates")
142+
for filename in os.listdir(templates_path):
143+
if (minimal and filename == 'event.json') or filename.endswith('.pyc'):
103144
continue
104-
copy(path_to_file, src)
145+
destination = os.path.join(templates_path, filename)
146+
copy(destination, src)
105147

106148

107149
def build(src, local_package=None):
@@ -222,9 +264,9 @@ def get_role_name(account_id, role):
222264

223265

224266
def get_account_id(aws_access_key_id, aws_secret_access_key):
225-
"""Query IAM for a users' account_id"""
226-
client = get_client('iam', aws_access_key_id, aws_secret_access_key)
227-
return client.get_user()['User']['Arn'].split(':')[4]
267+
"""Query STS for a users' account_id"""
268+
client = get_client('sts', aws_access_key_id, aws_secret_access_key)
269+
return client.get_caller_identity().get('Account')
228270

229271

230272
def get_client(client, aws_access_key_id, aws_secret_access_key, region=None):

aws_lambda/project_template/__init__.py

Whitespace-only changes.

requirements.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
boto3==1.3.1
2-
botocore==1.4.32
1+
boto3==1.4.1
2+
botocore==1.4.61
33
click==6.6
44
docutils==0.12
55
futures==3.0.5
66
jmespath==0.9.0
77
pyaml==15.8.2
88
python-dateutil==2.5.3
9-
python-lambda==0.2.0
109
PyYAML==3.11
11-
six==1.10.0
10+
six==1.10.0

scripts/lambda

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,16 @@ def invoke(event_file, verbose):
3838
def deploy(local_package):
3939
aws_lambda.deploy(CURRENT_DIR, local_package)
4040

41+
42+
@click.command(help="Delete old versions of your functions")
43+
@click.option("--keep-last", type=int, prompt="Please enter the number of recent versions to keep")
44+
def cleanup(keep_last):
45+
aws_lambda.cleanup_old_versions(CURRENT_DIR, keep_last)
46+
4147
if __name__ == '__main__':
4248
cli.add_command(init)
4349
cli.add_command(invoke)
4450
cli.add_command(deploy)
4551
cli.add_command(build)
52+
cli.add_command(cleanup)
4653
cli()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
url='https://github.com/nficano/python-lambda',
3030
packages=find_packages(),
3131
package_data={
32-
'aws_lambda': ['templates/*'],
32+
'aws_lambda': ['project_templates/*'],
3333
'': ['*.json'],
3434
},
3535
include_package_data=True,

0 commit comments

Comments
 (0)