0

I am trying to use AWS Chalice to upload my Python application to a Lambda function. I need to use a number of dependencies that will exceed the 50MB limit for a Lambda app. I think I can overcome this limit by using Lambda layers for each dependency, provided each layer is below the 50MB limit. For my final app, the total unzipped deployment size is about 225 MB so it is below the 250 MB unzipped limit imposed for Lambda deployments. When I has issues with the full deployment, I decided to try increasing the size by adding dependencies. I have been successful in using Chalice to deploy an app using Lambda layers that has scipy and numpy as dependencies. The deployment size with scipy and numpy dependencies is 48.6 MB zipped and 157 MB unzipped. When I also add matplotlib the size is 66 MB zipped and 210 MB unzipped and causes an error as described below.

My requirements.txt file contains:

scipy>=1.7.0
numpy>=1.19.2
matplotlib>=3.5.0

My chalice config file contains:

{
  "automatic_layer": true,
  "stages": {
    "dev": {
      "api_gateway_stage": "api"
    }
  },
  "version": "2.0",
  "app_name": "demoapp"
}

My chalice app code looks like this:

from chalice import Chalice

app = Chalice(app_name='demoapp')
app.debug = True

@app.lambda_function()
def numpy_import(event, context):
    import numpy
    return {'numpy': numpy.__file__}

@app.lambda_function()
def scipy_import(event, context):
    import scipy
    return {'scipy': scipy.__file__}

@app.lambda_function()
def matplotlib_import(event, context):
    import matplotlib
    return {'matplotlib': matplotlib.__file__}

@app.route('/myapp', methods=['POST'])
def mufunction():
    jsonbody = app.current_request.json_body

    # extract data from json
    data_array = jsonbody['data_array']

    # do stuff. As a test case it is just returning what it was given.
    result = data_array

    # package output in json
    output = {'result': result}
    return output

The stack trace of the error I get is:

Creating shared layer deployment package.
  Reusing existing shared layer deployment package.
Creating app deployment package.
Creating lambda layer: demoapp-dev-managed-layer
Traceback (most recent call last):
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 394, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py", line 234, in request
    super(HTTPConnection, self).request(method, url, body=body, headers=headers)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1255, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\awsrequest.py", line 94, in _send_request
    rval = super()._send_request(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1301, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1250, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\awsrequest.py", line 123, in _send_output
    self.send(msg)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\awsrequest.py", line 218, in send
    return super().send(str)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 971, in send
    self.sock.sendall(data)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1204, in sendall
    v = self.send(byte_view[count:])
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1173, in send
    return self._sslobj.write(data)
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\httpsession.py", line 455, in send
    urllib_response = conn.urlopen(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\util\retry.py", line 507, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\packages\six.py", line 734, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 394, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py", line 234, in request
    super(HTTPConnection, self).request(method, url, body=body, headers=headers)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1255, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\awsrequest.py", line 94, in _send_request
    rval = super()._send_request(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1301, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1250, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\awsrequest.py", line 123, in _send_output
    self.send(msg)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\awsrequest.py", line 218, in send
    return super().send(str)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 971, in send
    self.sock.sendall(data)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1204, in sendall
    v = self.send(byte_view[count:])
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1173, in send
    return self._sslobj.write(data)
urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionAbortedError(10053, 'An established connection was aborted by the software in your host machine', None, 10053, None))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\chalice\cli\__init__.py", line 636, in main
    return cli(obj={})
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\click\core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\click\core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\click\core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\click\core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\click\core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\click\decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\chalice\cli\__init__.py", line 189, in deploy
    deployed_values = d.deploy(config, chalice_stage_name=stage)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\chalice\deploy\deployer.py", line 376, in deploy
    return self._deploy(config, chalice_stage_name)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\chalice\deploy\deployer.py", line 392, in _deploy
    self._executor.execute(plan)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\chalice\deploy\executor.py", line 42, in execute
    getattr(self, '_do_%s' % instruction.__class__.__name__.lower(),
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\chalice\deploy\executor.py", line 55, in _do_apicall
    result = method(**final_kwargs)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\chalice\awsclient.py", line 334, in publish_layer
    return self._client('lambda').publish_layer_version(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\client.py", line 514, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\client.py", line 921, in _make_api_call
    http, parsed_response = self._make_request(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\client.py", line 944, in _make_request
    return self._endpoint.make_request(operation_model, request_dict)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\endpoint.py", line 119, in make_request
    return self._send_request(request_dict, operation_model)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\endpoint.py", line 202, in _send_request
    while self._needs_retry(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\endpoint.py", line 354, in _needs_retry
    responses = self._event_emitter.emit(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\hooks.py", line 412, in emit
    return self._emitter.emit(aliased_event_name, **kwargs)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\hooks.py", line 256, in emit
    return self._emit(event_name, kwargs)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\hooks.py", line 239, in _emit
    response = handler(**kwargs)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\retryhandler.py", line 207, in __call__
    if self._checker(**checker_kwargs):
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\retryhandler.py", line 284, in __call__
    should_retry = self._should_retry(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\retryhandler.py", line 320, in _should_retry
    return self._checker(attempt_number, response, caught_exception)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\retryhandler.py", line 363, in __call__
    checker_response = checker(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\retryhandler.py", line 247, in __call__
    return self._check_caught_exception(
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\retryhandler.py", line 416, in _check_caught_exception
    raise caught_exception
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\endpoint.py", line 281, in _do_get_response
    http_response = self._send(request)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\endpoint.py", line 377, in _send
    return self.http_session.send(request)
  File "C:\Users\Matthew Reid\AppData\Local\Programs\Python\Python39\lib\site-packages\botocore\httpsession.py", line 494, in send
    raise ConnectionClosedError(
botocore.exceptions.ConnectionClosedError: Connection was closed before we received a valid response from endpoint URL: "https://lambda.ap-southeast-2.amazonaws.com/2018-10-31/layers/demoapp-dev-managed-layer/versions".

I think this error is a connection timeout issue caused by my computer. I have tried to fix this by adjusting the DEFAULT_TIMEOUT variable in botocore from 60 to 600. I also deploy with the command “chalice deploy --connection-timeout 600”.

My internet upload speed is approximately 5 MB/s so for a 66 MB file it should manage that in about 15 seconds.

If you have any suggestions about how to deploy an app that has multiple python dependancies that exceed 50MB when zipped, then I’d love to know your solution.

For reference, I have looked at these similar questions:

How to deploy projects with larger dependencies and exceeding deployment limits on AWS Lambda function?

boto3 ConnectionClosedError python

Matthew Reid
  • 332
  • 2
  • 9
  • lambda is not designed for big code base (aka large libraries ) , for example i tried with simple pandas dataframe and ended up with 2GB ram usage . So for your case, i recommend using something like ec2 or ecs/fargate – Bao Tran Oct 31 '22 at 09:42

0 Answers0