diff --git a/aws_lambda/aws_lambda.py b/aws_lambda/aws_lambda.py index 7a4eeec..23362b5 100755 --- a/aws_lambda/aws_lambda.py +++ b/aws_lambda/aws_lambda.py @@ -3,7 +3,6 @@ import json import logging import os -import sys import time from imp import load_source from shutil import copy, copyfile @@ -63,7 +62,7 @@ def cleanup_old_versions(src, keep_last_versions): .format(version_number, e.message)) -def deploy(src, requirements=False, local_package=None): +def deploy(src, requirements=False, local_package=None, raw_copy=None): """Deploys a new function to AWS Lambda. :param str src: @@ -81,7 +80,7 @@ def deploy(src, requirements=False, local_package=None): # folder then add the handler file in the root of this directory. # Zip the contents of this folder into a single file and output to the dist # directory. - path_to_zip_file = build(src, requirements, local_package) + path_to_zip_file = build(src, requirements, local_package, raw_copy) if function_exists(cfg, cfg.get('function_name')): update_function(cfg, path_to_zip_file) @@ -111,12 +110,6 @@ def invoke(src, alt_event=None, verbose=False): path_to_event_file = os.path.join(src, 'event.json') event = read(path_to_event_file, loader=json.loads) - #Tweak to allow module to import local modules - try: - sys.path.index(src) - except: - sys.path.append(src) - handler = cfg.get('handler') # Inspect the handler string (.) and translate it # into a function we can execute. @@ -149,13 +142,11 @@ def init(src, minimal=False): for filename in os.listdir(templates_path): if (minimal and filename == 'event.json') or filename.endswith('.pyc'): continue - dest_path = os.path.join(templates_path, filename) + destination = os.path.join(templates_path, filename) + copy(destination, src) - if not os.path.isdir(dest_path): - copy(dest_path, src) - -def build(src, requirements=False, local_package=None): +def build(src, requirements=False, local_package=None, raw_copy=None): """Builds the file bundle. :param str src: @@ -175,22 +166,22 @@ def build(src, requirements=False, local_package=None): path_to_dist = os.path.join(src, dist_directory) mkdir(path_to_dist) + path_to_temp = mkdtemp(prefix='aws-lambda') + + if raw_copy: + bin_dir = os.path.join(path_to_temp, "lambda_bin") + import shutil + shutil.copytree(raw_copy, bin_dir) + # Combine the name of the Lambda function with the current timestamp to use # for the output filename. function_name = cfg.get('function_name') output_filename = "{0}-{1}.zip".format(timestamp(), function_name) - path_to_temp = mkdtemp(prefix='aws-lambda') pip_install_to_target(path_to_temp, requirements=requirements, local_package=local_package) - # Hack for Zope. - if "zope" in os.listdir(path_to_temp): - print("Zope packages detected; fixing Zope package paths to make them importable.") - # Touch. - with open(os.path.join(path_to_temp, "zope/__init__.py"), "wb"): - pass # Gracefully handle whether ".zip" was included in the filename or not. output_filename = ('{0}.zip'.format(output_filename) @@ -204,7 +195,6 @@ def build(src, requirements=False, local_package=None): continue if filename == 'config.yaml': continue - print("Bundling: %r" % filename) files.append(os.path.join(src, filename)) # "cd" into `temp_path` directory. @@ -300,15 +290,17 @@ def pip_install_to_target(path, requirements=False, local_package=None): print('Gathering requirement packages') data = read("requirements.txt") packages.extend(data.splitlines()) + elif os.path.exists(requirements): + print('Gathering requirement from %s' % requirements) + data = read(requirements) + packages.extend(data.splitlines()) if not packages: print('No dependency packages installed!') if local_package is not None: - if not isinstance(local_package, (list, tuple) ): - local_package = [local_package] - for l_package in local_package: - packages.append(l_package) + # TODO: actually sdist is probably bettter here... + packages.append(local_package) _install_packages(path, packages) @@ -413,8 +405,8 @@ def function_exists(cfg, function_name): aws_secret_access_key = cfg.get('aws_secret_access_key') client = get_client('lambda', aws_access_key_id, aws_secret_access_key, cfg.get('region')) - functions = client.list_functions().get('Functions', []) - for fn in functions: - if fn.get('FunctionName') == function_name: - return True - return False + try: + client.get_function(FunctionName=function_name) + except: + return False + return True diff --git a/scripts/lambda b/scripts/lambda index ad50d5e..6af2401 100755 --- a/scripts/lambda +++ b/scripts/lambda @@ -29,8 +29,9 @@ def init(folder): @click.command(help="Bundles package for deployment.") @click.option('--use-requirements', default=False, is_flag=True, help='Install all packages defined in requirements.txt') @click.option('--local-package', default=None, help='Install local package as well.', type=click.Path(), multiple=True) -def build(use_requirements, local_package): - aws_lambda.build(CURRENT_DIR, use_requirements, local_package) +@click.option('--raw-copy', default=None, help='directory of stuff to raw copy to the lambda dir', type=click.Path(), multiple=True) +def build(use_requirements, local_package, raw_copy): + aws_lambda.build(CURRENT_DIR, use_requirements, local_package, raw_copy) @click.command(help="Run a local test of your function.") @@ -41,7 +42,7 @@ def invoke(event_file, verbose): @click.command(help="Register and deploy your code to lambda.") -@click.option('--use-requirements', default=False, is_flag=True, help='Install all packages defined in requirements.txt') +@click.option('--use-requirements', default=None, help='Install all packages defined in requirements.txt', type=click.Path()) @click.option('--local-package', default=None, help='Install local package as well.', type=click.Path(), multiple=True) def deploy(use_requirements, local_package): aws_lambda.deploy(CURRENT_DIR, use_requirements, local_package)