aws / aws-lambda-python-runtime-interface-client

Apache License 2.0
263 stars 75 forks source link

Runtime.ExitError AttributeError: 'NoneType' object has no attribute 'next' #22

Open synic opened 3 years ago

synic commented 3 years ago

This is happening to me with the python:3.9-alpine3.12 base image. Here is the Dockerfile:

ARG build_info="head@now"
ARG build_env="development"

FROM python:3.9-alpine3.12 AS base

ARG build_info
ARG build_env

ENV PYTHONPATH=/function
ENV BUILD_INFO=${build_info}

WORKDIR /function
COPY . /function

RUN apk add --no-cache --virtual .build-deps \
    autoconf \
    automake \
    build-base \
    cmake \
    libcurl \
    libexecinfo-dev \
    libstdc++ \
    libtool \
    make \
    postgresql-dev \
    python3-dev \
    && pip install --no-cache-dir -e . \
    && apk del --no-cache .build-deps

FROM base AS build-production
RUN echo " -> Building production image"

FROM base AS build-development
RUN echo " -> Building development image" \
    && apk add --no-cache \
    bash \
    vim \
    iputils \
    && pip3 install --no-cache-dir -e .[debug,testing]

ENV PS1="someapp> "
ENV PYTHONBREAKPOINT=ipdb.set_trace

FROM build-${build_env} AS final

ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie
COPY entry.sh /
RUN chmod 755 /usr/bin/aws-lambda-rie /entry.sh
ENTRYPOINT [ "/entry.sh" ]
CMD [ "fieldeye.handler" ]

Here's the entry.sh:

#!/bin/sh

if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
    exec /usr/bin/aws-lambda-rie /usr/local/bin/python -m awslambdaric $1
else
    exec /usr/local/bin/python -m awslambdaric $1
fi

and here's the error:

time="2021-02-19T00:09:20.268" level=info msg="exec '/usr/local/bin/python' (cwd=/function, handler=someapp.handler)"
time="2021-02-19T00:09:26.44" level=info msg="extensionsDisabledByLayer(/opt/disable-extensions-jwigqn8j) -> stat /opt/disable-extensions-jwigqn8j: no such file or directory"
START RequestId: 724c1d85-78fc-4424-800e-c745e8bd51a1 Version: $LATEST
time="2021-02-19T00:09:26.441" level=warning msg="Cannot list external agents" error="open /opt/extensions: no such file or directory"
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/local/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/usr/local/lib/python3.9/site-packages/awslambdaric/__main__.py", line 21, in <module>
    main(sys.argv)
  File "/usr/local/lib/python3.9/site-packages/awslambdaric/__main__.py", line 17, in main
    bootstrap.run(app_root, handler, lambda_runtime_api_addr)
  File "/usr/local/lib/python3.9/site-packages/awslambdaric/bootstrap.py", line 416, in run
    event_request = lambda_runtime_client.wait_next_invocation()
  File "/usr/local/lib/python3.9/site-packages/awslambdaric/lambda_runtime_client.py", line 76, in wait_next_invocation
    response_body, headers = runtime_client.next()
AttributeError: 'NoneType' object has no attribute 'next'
Executing 'someapp.handler' in function directory '/function'
time="2021-02-19T00:09:26.604" level=warning msg="First fatal error stored in appctx: Runtime.ExitError"
time="2021-02-19T00:09:26.604" level=warning msg="Process 13(python) exited: Runtime exited with error: exit status 1"
time="2021-02-19T00:09:26.604" level=error msg="Init failed" InvokeID= error="Runtime exited with error: exit status 1"
time="2021-02-19T00:09:26.604" level=warning msg="Failed to send default error response: ErrInvalidInvokeID"
time="2021-02-19T00:09:26.604" level=error msg="INIT DONE failed: Runtime.ExitError"
time="2021-02-19T00:09:26.604" level=warning msg="Reset initiated: ReserveFail"

Just to make sure, I ran docker exec -it mycontainer /bin/bash and typed /usr/local/bin/python --version, the response was Python 3.9.1

synic commented 3 years ago

Figured it out, it's because I'm installing libstdc++ as a build library and then uninstalling it after the build completes. It needs to stay installed, so changing the first apk-add bit to this works:

RUN apk add --no-cache \
    libstdc++ \
    libpq \
    && apk add --no-cache --virtual .build-deps \
    autoconf \
    automake \
    build-base \
    cmake \
    libcurl \
    libexecinfo-dev \
    libtool \
    make \
    musl-dev \
    postgresql-dev \
    python3-dev \
    && pip install --no-cache-dir -e . \
    && apk del --no-cache .build-deps
synic commented 3 years ago

By the way, I was able to find out why it wasn't working by looking at the code, specifically this line: https://github.com/aws/aws-lambda-python-runtime-interface-client/blob/main/awslambdaric/lambda_runtime_client.py#L31

try:
    import runtime_client

    runtime_client.initialize_client(_user_agent())
except ImportError:
    runtime_client = None   # THIS LINE HERE

Then, I just opened a python shell and typed import runtime_client

I don't know that it's good that it just silently fails on the import there. Is there a reason to believe the library can work when runtime_client is None?

jantman commented 3 years ago

I've had the same issue, but with python:3.8-alpine. It seems like there are a LOT of assumptions (see also the documentation issue I opened, #24 ) about the container being perfectly set up... when there's little documentation on how to actually do that.

benoit-laplante commented 3 years ago

I had the same issue and had to do the same step as @synic to figure out the cause. In my case, the missing dependency was resolved by installing curl. I would remove except ImportError clause or at least document which dependencies are required by awslambdaric to be installed.

juls858 commented 3 years ago

I had the same issue and had to do the same step as @synic to figure out the cause. In my case, the missing dependency was resolved by installing curl. I would remove except ImportError clause or at least document which dependencies are required by awslambdaric to be installed.

This worked for me.

unacceptable commented 10 months ago

For me it was libzstd.so missing (FROM python:3.12-alpine3.19). I just added to my the following to the final stage of my docker multi-stage build.

RUN apk add --no-cache zstd-dev

This was a really annoying issue, and there was no way to identify the cause without additional logging. I have opened a PR and am waiting for guidance about the proper way to log this.

Here's the full Dockerfile if interested:

FROM python:3.12-alpine3.19 as base
ARG FUNCTION_DIR="/app"
WORKDIR ${FUNCTION_DIR}

FROM base as builder
RUN apk update && \
      apk add --no-cache \
        cmake \
        autoconf \
        automake \
        libtool \
        binutils \
        gcc \
        libc-dev \
        make \
        elfutils-dev \
        g++

COPY requirements.txt .
RUN pip install \
      --target ${FUNCTION_DIR} --no-cache-dir -r requirements.txt
COPY app.py .
COPY --chmod=755 entrypoint.sh .
RUN rm requirements.txt

FROM base as final
RUN apk add --no-cache zstd-dev
COPY --from=builder ${FUNCTION_DIR} ${FUNCTION_DIR}
EXPOSE 3000

ENTRYPOINT ["/app/entrypoint.sh"]