Skip to content

Commit 3c3269e

Browse files
author
Marcel Radischat
committed
Install only required packages if option is set
The current solution installs all packages found by pip freeze to the distribution folder and deploys this to AWS Lambda. This includes some unnecessary packages to run the code, e.g. testing modules which increase the distribution size. The option to install only required packages helps reducing the build size. For now, the file must be named `requirements.txt` and be in the same directory of the project which shall be uploaded.
1 parent cf536e4 commit 3c3269e

File tree

1 file changed

+49
-15
lines changed

1 file changed

+49
-15
lines changed

aws_lambda/aws_lambda.py

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
log = logging.getLogger(__name__)
1919

2020

21-
def deploy(src, local_package=None):
21+
def deploy(src, requirements=False, local_package=None):
2222
"""Deploys a new function to AWS Lambda.
2323
2424
:param str src:
@@ -36,7 +36,7 @@ def deploy(src, local_package=None):
3636
# folder then add the handler file in the root of this directory.
3737
# Zip the contents of this folder into a single file and output to the dist
3838
# directory.
39-
path_to_zip_file = build(src, local_package)
39+
path_to_zip_file = build(src, requirements, local_package)
4040

4141
if function_exists(cfg, cfg.get('function_name')):
4242
update_function(cfg, path_to_zip_file)
@@ -104,7 +104,7 @@ def init(src, minimal=False):
104104
copy(path_to_file, src)
105105

106106

107-
def build(src, local_package=None):
107+
def build(src, requirements=False, local_package=None):
108108
"""Builds the file bundle.
109109
110110
:param str src:
@@ -130,7 +130,9 @@ def build(src, local_package=None):
130130
output_filename = "{0}-{1}.zip".format(timestamp(), function_name)
131131

132132
path_to_temp = mkdtemp(prefix='aws-lambda')
133-
pip_install_to_target(path_to_temp, local_package)
133+
pip_install_to_target(path_to_temp,
134+
requirements=requirements,
135+
local_package=local_package)
134136

135137
# Gracefully handle whether ".zip" was included in the filename or not.
136138
output_filename = ('{0}.zip'.format(output_filename)
@@ -191,29 +193,61 @@ def get_handler_filename(handler):
191193
return '{0}.py'.format(module_name)
192194

193195

194-
def pip_install_to_target(path, local_package=None):
196+
def _install_packages(path, packages):
197+
"""Install all packages listed to the target directory.
198+
199+
Ignores any package that includes Python itself and python-lambda as well
200+
since its only needed for deploying and not running the code
201+
202+
:param str path:
203+
Path to copy installed pip packages to.
204+
:param list packages:
205+
A list of packages to be installed via pip.
206+
"""
207+
def _filter_blacklist(package):
208+
blacklist = ["-i", "#", "Python==", "python-lambda=="]
209+
return all(package.startswith(entry) is False for entry in blacklist)
210+
filtered_packages = filter(_filter_blacklist, packages)
211+
for package in filtered_packages:
212+
if package.startswith('-e '):
213+
package = package.replace('-e ', '')
214+
215+
print('Installing {package}'.format(package=package))
216+
pip.main(['install', package, '-t', path, '--ignore-installed'])
217+
218+
219+
def pip_install_to_target(path, requirements=False, local_package=None):
195220
"""For a given active virtualenv, gather all installed pip packages then
196221
copy (re-install) them to the path provided.
197222
198223
:param str path:
199224
Path to copy installed pip packages to.
225+
:param bool requirements:
226+
If set, only the packages in the requirements.txt file are installed.
227+
The requirements.txt file needs to be in the same directory as the
228+
project which shall be deployed.
229+
Defaults to false and installs all pacakges found via pip freeze if
230+
not set.
200231
:param str local_package:
201232
The path to a local package with should be included in the deploy as
202233
well (and/or is not available on PyPi)
203234
"""
204-
print('Gathering pip packages')
205-
for r in pip.operations.freeze.freeze():
206-
if r.startswith('Python=='):
207-
# For some reason Python is coming up in pip freeze.
208-
continue
209-
elif r.startswith('-e '):
210-
r = r.replace('-e ','')
235+
packages = []
236+
if not requirements:
237+
print('Gathering pip packages')
238+
packages.extend(pip.operations.freeze.freeze())
239+
else:
240+
if os.path.exists("requirements.txt"):
241+
print('Gathering requirement packages')
242+
data = read("requirements.txt")
243+
packages.extend(data.splitlines())
211244

212-
print('Installing {package}'.format(package=r))
213-
pip.main(['install', r, '-t', path, '--ignore-installed'])
245+
if not packages:
246+
print('No dependency packages installed!')
214247

215248
if local_package is not None:
216-
pip.main(['install', local_package, '-t', path])
249+
packages.append(local_package)
250+
_install_packages(path, packages)
217251

218252

219253
def get_role_name(account_id, role):

0 commit comments

Comments
 (0)