oschlueter
oschlueter

Reputation: 2698

python module not properly installed without apparent reason

I want to create a Docker image for a package that provides a CLI tool. My image works if I install the package from our pypi server but it doesn't work if I install it from source. Installing from source is required to enable the developer to test his code in a container before publishing a new release.

# Building is done using
# docker build . --build-arg PIPCONTENT="`cat ~/.pip/pip.conf | base64 `" -t tmw:latest
#
FROM python:3.6-slim as base

RUN mkdir /app
WORKDIR /app

# this is our first build stage, it will not persist in the final image
FROM base as intermediate

RUN apt-get update && apt-get install -y \
    build-essential \
 && rm -rf /var/lib/apt/lists/*

## contains credentials
ARG PIPCONTENT
RUN mkdir -p /root/.pip/ && echo ${PIPCONTENT}  | base64 -d > /root/.pip/pip.conf

COPY requirements.txt /app/
RUN pip install -r requirements.txt

COPY setup.py MANIFEST.in tagger_model_workbench /app/

# doesn't create /usr/local/lib/python3.6/site-packages/tagger_model_workbench
#RUN python setup.py sdist
#RUN pip install dist/*.tar.gz

# TeamCity: python setup.py sdist && twine upload --verbose -r pypicloud dist/*
# does create /usr/local/lib/python3.6/site-packages/tagger_model_workbench
RUN pip install tagger-model-workbench

# build final image
#FROM base

#COPY --from=intermediate /usr/local /usr/local

EXPOSE 8050
ENTRYPOINT ["tagger-model-workbench", "0.0.0.0", "8050"]

Here is the setup.py:

import os

from setuptools import setup, find_packages


def get_install_requires():
    with open(os.path.join(os.path.dirname(__file__), "requirements.txt")) as f:
        return [line for line in map(str.strip, f) if line and not line.startswith('-') and not line.startswith("git+")]


setup(
    name='tagger_model_workbench',
    version='0.2.4',
    packages=find_packages(include=("tagger_model_workbench", "tagger_model_workbench.*",)),
    url='',
    license='',
    author='',
    author_email='',
    description='',
    install_requires=get_install_requires(),
    entry_points={
        'console_scripts': ['tagger-model-workbench=tagger_model_workbench.app.main:main'],
    }
)

Running the container with the python setup.py sdist && pip install dist/*.tar.gz option causes this error message:

tmw_1  | Traceback (most recent call last):
tmw_1  |   File "/usr/local/bin/tagger-model-workbench", line 6, in <module>
tmw_1  |     from tagger_model_workbench.app.main import main
tmw_1  | ModuleNotFoundError: No module named 'tagger_model_workbench'

Installation using pip install properly installs the package from our internal pypi whereas building and installing using built artifact doesn't. Build commands are identical. Can anyone explain what's happening?

Upvotes: 0

Views: 332

Answers (1)

Bierbarbar
Bierbarbar

Reputation: 1479

It seems like tagger_model_workbench is the folder with the source code of the module. If you copy it in the way you described above it will only copy the content of your folder, but not the folder. Depending on your setup.py this can lead to an module without any python files if you referencing the folder in your packages list in the setup.py instead of listing the content of the folder. If the module have no python files in it you will get the described error message.

If my assumption that tagger_model_workbench is a folder is right you can simple fix it. Just make sure you are adding the complete folder to the docker image. Simply adapt the line where you copy the setup.py in the following way:

COPY setup.py MANIFEST.in /app/
COPY tagger_model_workbench /app/tagger_model_workbench

Upvotes: 1

Related Questions