1

[UPDATED] We are currently working on creating a Multi-Arm Bandit model for sign up optimization using the Build Your Own workflow that can be found here (basically substituting the model for our own):

https://github.com/aws/amazon-sagemaker-examples/tree/master/advanced_functionality/scikit_bring_your_own

Our project directory is set up as: Project Directory

The issue is that I added some code including the dataclasses library that is only available since Python 3.7, and our project seems to keep using 3.6, causing a failure when running the Cloud Formation set up. The error in our Cloudwatch Logs is:

2021-03-31T11:04:11.077-05:00 Copy
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/arbiter.py", line 589, in spawn_worker
    worker.init_process()
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/base.py", line 134, in init_process
    self.load_wsgi()
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/base.py", line 146, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/app/wsgiapp.py", line 58, in load
    return self.load_wsgiapp()
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/util.py", line 359, in import_app
    mod = importlib.import_module(module)
  File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/opt/program/wsgi.py", line 1, in <module>
    import predictor as myapp
  File "/opt/program/predictor.py", line 9, in <module>
    from model_contents.model import MultiArmBandit, BanditParameters
  File "/opt/program/model_contents/model.py", line 7, in <module>
    from dataclasses import dataclass, field, asdict
Traceback (most recent call last): File "/usr/local/lib/python3.6/dist-packages/gunicorn/arbiter.py", line 589, in spawn_worker worker.init_process() File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/base.py", line 134, in init_process self.load_wsgi() File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/base.py", line 146, in load_wsgi self.wsgi = self.app.wsgi() File "/usr/local/lib/python3.6/dist-packages/gunicorn/app/base.py", line 67, in wsgi self.callable = self.load() File "/usr/local/lib/python3.6/dist-packages/gunicorn/app/wsgiapp.py", line 58, in load return self.load_wsgiapp() File "/usr/local/lib/python3.6/dist-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp return util.import_app(self.app_uri) File "/usr/local/lib/python3.6/dist-packages/gunicorn/util.py", line 359, in import_app mod = importlib.import_module(module) File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 994, in _gcd_import File "<frozen importlib._bootstrap>", line 971, in _find_and_load File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 665, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 678, in exec_module File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed File "/opt/program/wsgi.py", line 1, in <module> import predictor as myapp File "/opt/program/predictor.py", line 9, in <module> from model_contents.model import MultiArmBandit, BanditParameters File "/opt/program/model_contents/model.py", line 7, in <module> from dataclasses import dataclass, field, asdict

    2021-03-31T11:04:11.077-05:00

Copy
ModuleNotFoundError: No module named 'dataclasses'
ModuleNotFoundError: No module named 'dataclasses'

Our updated Dockerfile is:

# This is a Python 3 image that uses the nginx, gunicorn, flask stack
# for serving inferences in a stable way.

FROM ubuntu:18.04

# Retrieves information about what packages can be installed
RUN apt-get -y update && apt-get install -y --no-install-recommends \
         wget \
         python3-pip \
         python3.8 \
         python3-setuptools \
         nginx \
         ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# Set python 3.8 as default
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1

# Here we get all python packages.
RUN pip --no-cache-dir install numpy boto3 flask gunicorn

# Set some environment variables. PYTHONUNBUFFERED keeps Python from buffering our standard
# model_output stream, which means that logs can be delivered to the user quickly. PYTHONDONTWRITEBYTECODE
# keeps Python from writing the .pyc files which are unnecessary in this case. We also update
# PATH so that the train and serve programs are found when the container is invoked.

ENV PYTHONUNBUFFERED=TRUE
ENV PYTHONDONTWRITEBYTECODE=TRUE
ENV PATH="/opt/program:${PATH}"
ENV PYTHONPATH /model_contents

# Set up the program in the image
COPY bandit/ /opt/program/
WORKDIR /opt/program/

RUN chmod +x /opt/program/serve && chmod +x /opt/program/train
LABEL git_tag=$GIT_TAG

I'm not sure if the nginx.conf file defaults to Py 3.6 so I want to make sure that it's not a big hassle to upgrade to Py 3.7 or 3.8 without many changes.

1
  • Found a question that might be similar but not exactly sure how to update this Dockerfile for that use case: stackoverflow.com/questions/61371949/… Commented Apr 1, 2021 at 20:55

1 Answer 1

1

You can update the Dockerfile after it install Python3.8 using apt-get with the following RUN commands

RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1

The first RUN command will link /usr/bin/python to /usr/bin/python3.8 and the second one will link /usr/bin/python3 to /usr/bin/python3.8

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! So are you meaning that I should add that after the RUN apt-get or replace them? I modified Dockerfile above:
Yeah you should try adding that after the RUN apt-get command

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.