@@ -58,11 +58,11 @@ def cleanup_old_versions(src, keep_last_versions):
5858 Qualifier = version_number
5959 )
6060 except botocore .exceptions .ClientError as e :
61- print ("Skipping Version {}: {}" . format ( version_number ,
62- e .message ))
61+ print ("Skipping Version {}: {}"
62+ . format ( version_number , e .message ))
6363
6464
65- def deploy (src , local_package = None ):
65+ def deploy (src , requirements = False , local_package = None ):
6666 """Deploys a new function to AWS Lambda.
6767
6868 :param str src:
@@ -80,7 +80,7 @@ def deploy(src, local_package=None):
8080 # folder then add the handler file in the root of this directory.
8181 # Zip the contents of this folder into a single file and output to the dist
8282 # directory.
83- path_to_zip_file = build (src , local_package )
83+ path_to_zip_file = build (src , requirements , local_package )
8484
8585 if function_exists (cfg , cfg .get ('function_name' )):
8686 update_function (cfg , path_to_zip_file )
@@ -137,16 +137,16 @@ def init(src, minimal=False):
137137 Minimal possible template files (excludes event.json).
138138 """
139139
140- templates_path = os .path .join (os . path . dirname ( os . path . abspath ( __file__ )),
141- "project_templates" )
140+ templates_path = os .path .join (
141+ os . path . dirname ( os . path . abspath ( __file__ )), "project_templates" )
142142 for filename in os .listdir (templates_path ):
143143 if (minimal and filename == 'event.json' ) or filename .endswith ('.pyc' ):
144144 continue
145145 destination = os .path .join (templates_path , filename )
146146 copy (destination , src )
147147
148148
149- def build (src , local_package = None ):
149+ def build (src , requirements = False , local_package = None ):
150150 """Builds the file bundle.
151151
152152 :param str src:
@@ -172,7 +172,9 @@ def build(src, local_package=None):
172172 output_filename = "{0}-{1}.zip" .format (timestamp (), function_name )
173173
174174 path_to_temp = mkdtemp (prefix = 'aws-lambda' )
175- pip_install_to_target (path_to_temp , local_package )
175+ pip_install_to_target (path_to_temp ,
176+ requirements = requirements ,
177+ local_package = local_package )
176178
177179 # Gracefully handle whether ".zip" was included in the filename or not.
178180 output_filename = ('{0}.zip' .format (output_filename )
@@ -233,29 +235,61 @@ def get_handler_filename(handler):
233235 return '{0}.py' .format (module_name )
234236
235237
236- def pip_install_to_target (path , local_package = None ):
238+ def _install_packages (path , packages ):
239+ """Install all packages listed to the target directory.
240+
241+ Ignores any package that includes Python itself and python-lambda as well
242+ since its only needed for deploying and not running the code
243+
244+ :param str path:
245+ Path to copy installed pip packages to.
246+ :param list packages:
247+ A list of packages to be installed via pip.
248+ """
249+ def _filter_blacklist (package ):
250+ blacklist = ["-i" , "#" , "Python==" , "python-lambda==" ]
251+ return all (package .startswith (entry ) is False for entry in blacklist )
252+ filtered_packages = filter (_filter_blacklist , packages )
253+ for package in filtered_packages :
254+ if package .startswith ('-e ' ):
255+ package = package .replace ('-e ' , '' )
256+
257+ print ('Installing {package}' .format (package = package ))
258+ pip .main (['install' , package , '-t' , path , '--ignore-installed' ])
259+
260+
261+ def pip_install_to_target (path , requirements = False , local_package = None ):
237262 """For a given active virtualenv, gather all installed pip packages then
238263 copy (re-install) them to the path provided.
239264
240265 :param str path:
241266 Path to copy installed pip packages to.
267+ :param bool requirements:
268+ If set, only the packages in the requirements.txt file are installed.
269+ The requirements.txt file needs to be in the same directory as the
270+ project which shall be deployed.
271+ Defaults to false and installs all pacakges found via pip freeze if
272+ not set.
242273 :param str local_package:
243274 The path to a local package with should be included in the deploy as
244275 well (and/or is not available on PyPi)
245276 """
246- print ('Gathering pip packages' )
247- for r in pip .operations .freeze .freeze ():
248- if r .startswith ('Python==' ):
249- # For some reason Python is coming up in pip freeze.
250- continue
251- elif r .startswith ('-e ' ):
252- r = r .replace ('-e ' ,'' )
277+ packages = []
278+ if not requirements :
279+ print ('Gathering pip packages' )
280+ packages .extend (pip .operations .freeze .freeze ())
281+ else :
282+ if os .path .exists ("requirements.txt" ):
283+ print ('Gathering requirement packages' )
284+ data = read ("requirements.txt" )
285+ packages .extend (data .splitlines ())
253286
254- print ( 'Installing {package}' . format ( package = r ))
255- pip . main ([ 'install' , r , '-t' , path , '--ignore- installed' ] )
287+ if not packages :
288+ print ( 'No dependency packages installed!' )
256289
257290 if local_package is not None :
258- pip .main (['install' , local_package , '-t' , path ])
291+ packages .append (local_package )
292+ _install_packages (path , packages )
259293
260294
261295def get_role_name (account_id , role ):
@@ -294,10 +328,12 @@ def create_function(cfg, path_to_zip_file):
294328 client = get_client ('lambda' , aws_access_key_id , aws_secret_access_key ,
295329 cfg .get ('region' ))
296330
297- function_name = os .environ .get ('LAMBDA_FUNCTION_NAME' ) or cfg .get ('function_name' )
298- print ('Creating lambda function with name: {}' .format (function_name ))
331+ func_name = (
332+ os .environ .get ('LAMBDA_FUNCTION_NAME' ) or cfg .get ('function_name' )
333+ )
334+ print ('Creating lambda function with name: {}' .format (func_name ))
299335 client .create_function (
300- FunctionName = function_name ,
336+ FunctionName = func_name ,
301337 Runtime = cfg .get ('runtime' , 'python2.7' ),
302338 Role = role ,
303339 Handler = cfg .get ('handler' ),
0 commit comments