text: import boto3
  import botocore
  import os
  import shutil
  import zipfile
  from boto3.s3.transfer import S3Transfer
  from vulcan.aws.services._session import AWSSession
  from vulcan.aws._common import ls, which
  from vulcan.aws._common import execute, execute_in_docker
  from subprocess import check_call, CalledProcessError
  from datetime import datetime
  
  try:
      from urlparse import urlparse
  except ImportError:
      from urllib.parse import urlparse
  
  
  class AWSLambda(AWSSession):
  
      def __init__(self, **kwargs):
          super(
              self.__class__,
              self
          ).__init__(kwargs['profile_name'], kwargs.get('region_name', None))
  
          self.profile_name = kwargs['profile_name']
          self.function_name = kwargs['function_name']
  
          if 'pip_requirements' in kwargs:
              self.pip_requirements = kwargs['pip_requirements']
          else:
              self.pip_requirements = list()
  
          self.s3_filename = kwargs['s3_filename']
  
          url = urlparse(kwargs['s3_uri'])
          self.s3_bucket = url.netloc
          self.s3_key = url.path
  
          if self.s3_key.endswith('/'):
              self.s3_key = "%s%s" % (
                  self.s3_key, os.path.basename(self.s3_filename))
  
          if self.s3_key.startswith('/'):
              self.s3_key = self.s3_key[1:]
  
      def validate(self):
          self.install_deps(['--user'])
          errors = list()
          files = ls('./src/main/python', '*.py')
  
          if not which('pylint'):
              print('pylint command not found,'
                    ' skipping code validation via PyLint')
              return True
  
          if len(files) == 0:
              print("No python files for validation")
              return True
          else:
              print("Validating files via pylint: %s" % files)
  
          for filename in files:
              try:
                  execute('pylint', '--extension-pkg-whitelist=pymssql',
                          '--errors-only', filename)
              except Exception as e:
                  errors.append(filename)
  
          if len(errors) > 0:
              print("There are errors in python files: %s" % errors)
              raise Exception(
                  "Lambda validation error. Check output for details.")
  
          return True
  
      def package(self, **kwargs):
          print('[ Packaging lambda deployment package ]')
          shutil.rmtree('target/distrib/', ignore_errors=True)
  
          files = ls('src/main/python/', '*.py')
          cwd = os.getcwd()
          print('[ Files ]')
          for name in files:
              print(name[len(cwd) + 1:])
  
          shutil.copytree('src/main/python/', 'target/distrib/',
                          ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
  
          self.install_deps(
              ['--target', 'target/distrib/'],
              docker_image=kwargs.get('docker_image', None)
          )
  
          zipf = zipfile.ZipFile(
              'target/{}'.format(self.s3_filename), 'w', zipfile.ZIP_DEFLATED)
          # with safe_cd('target/distrib/')
          basedir_len = len(os.path.abspath(
              os.path.join(os.getcwd(), 'target/distrib')))
          for name in ls('target/distrib/'):
              zipf.write(name, name[basedir_len:])
          zipf.close()
  
          return True
  
      def install_deps(self, pip_args=None, **kwargs):
          print('[ Installing lambda dependencies ]')
          print('[ Dependencies ]')
  
          args = ['install', '--upgrade']
  
          if pip_args:
              if type(pip_args) != list:
                  raise "pip_args argument should be of a list() type"
  
              for pip_arg in pip_args:
                  if pip_arg == '--user' and os.getenv('VIRTUAL_ENV', False):
                      # skip --user when inside virtualenv
                      pass
                  else:
                      args.append(pip_arg)
  
          for req in self.pip_requirements:
              if kwargs['docker_image']:
                  print('Installing {req} via docker image {docker}'.format(
                      req=req,
                      docker=kwargs['docker_image'])
                  )
                  execute_in_docker(kwargs['docker_image'], 'pip', args, req)
              else:
                  print('Installing {}'.format(req))
                  execute('pip', args, req)
  
          if not self.pip_requirements or len(self.pip_requirements) == 0:
              print("Your lambda doesn't have any pip dependencies")
  
      def upload(self):
          s3 = self.client('s3')
          lambda_package = os.path.normpath(os.path.join(
              os.getcwd(), 'target/', self.s3_filename))
          print("Uploading %s to temporary location s3://%s/%s" %
                (lambda_package, self.s3_bucket, self.s3_key))
          S3Transfer(s3).upload_file(
              lambda_package,
              self.s3_bucket,
              self.s3_key,
              extra_args={'ACL': 'bucket-owner-full-control'}
          )
  
      def update_code(self, **kwargs):
          lambdas = self.client('lambda')
          if kwargs and 'function_name' in kwargs:
              function_name = kwargs['function_name']
          else:
              function_name = self.function_name
          print("Updating function {name} "
                "code from s3://{bucket}/{key}".format(
                    name=function_name,
                    bucket=self.s3_bucket,
                    key=self.s3_key))
          resp = lambdas.update_function_code(
              FunctionName=function_name,
              S3Bucket=self.s3_bucket,
              S3Key=self.s3_key,
              Publish=False
          )
  
      def update_dev_alias(self):
          lambdas = self.client('lambda')
          print('Updating function {} DEV alias to version $LATEST'.format(
              self.function_name))
          lambdas.update_alias(
              FunctionName=self.function_name,
              FunctionVersion='$LATEST',
              Name='DEV',
              Description='Updated by pynt at {} UTC'.format(
                  datetime.utcnow().strftime("%Y-%b-%d %H:%M:%S"))
          )
  
          pass
  
      def update_prod_alias(self):
          lambdas = self.client('lambda')
          resp = lambdas.publish_version(
              FunctionName=self.function_name,
          )
  
          print('Updating function {} PROD alias to version {}'.format(
              self.function_name, resp['Version']))
          lambdas.update_alias(
              FunctionName=self.function_name,
              FunctionVersion=resp['Version'],
              Name='PROD',
              Description='Updated by pynt at {} UTC'.format(
                  datetime.utcnow().strftime("%Y-%b-%d %H:%M:%S"))
          )
  
      def test_local(self, event={}, **kwargs):
          lambdas = self.client('lambda')
          if kwargs and 'function_name' in kwargs:
              function_name = kwargs['function_name']
          else:
              function_name = self.function_name
          resp = lambdas.get_function(
              FunctionName=function_name
          )
  
          sep = resp['Configuration']['Handler'].rfind('.')
          py_file_name = resp['Configuration']['Handler'][:sep]
          py_method_name = resp['Configuration']['Handler'][sep + 1:]
  
          import logging
          logging.basicConfig()
          logger = logging.getLogger('lambda')
          logger.setLevel('DEBUG')
  
          import sys
          import platform
          if platform.system() == 'Windows':
              sys.path.append('src\\main\\python')
          else:
              sys.path.append('src/main/python')
  
          import importlib
          mod = importlib.import_module(py_file_name)
          result = getattr(mod, py_method_name)(event, {})
  