Passing arguments through Docker to argparse not working

Question:

The setup

I have a dockercontainer with the following Dockerfile:

FROM python:3.10

WORKDIR /usr/src/app

ENV ARGS=""

COPY requirements.txt ./
COPY main.py ./
COPY ...
COPY ...
COPY ...

RUN apt update
RUN apt install ffmpeg -y
RUN apt install wkhtmltopdf -y

RUN pip install --no-cache-dir -r requirements.txt
RUN mkdir output

VOLUME /usr/src/app/output

CMD python main.py $ARGS

The important part of main.py looks like this:


# ... Some more code

if __name__ == "__main__":
    # Setup argparse
    parser = argparse.ArgumentParser(description="Transcribe audio files to text")

    # Download data
    vo_data_links = parser.add_mutually_exclusive_group()
    vo_data_links.add_argument("--data-path", "-p", type=str, default=None, help="path to the file where the VO-data is stored, this path is not influenced by the -i/--input-folder argument")
    vo_data_links.add_argument("--data-link", "-k", type=str, default=None, help="link to the VO-Data of u:space")
    parser.add_argument("--vos", action="append", type=str, help="Titels of the VOs which shall be transcribed. If this argument is not set, no VOs will be transcribed.")

    # Some more setup....

The problem

When i run the script outside of the Dockercontainer it runs fine:

python main.py --vos="2. Aufzeichnung vom 20.12.2022"

But when i build and run the container it fails with the following error:

# Command
docker run -d --name container -e ARGS="--vos="2. Aufzeichnung vom 20.12.2022""  vo-transcriber:1.6.0

# Output
usage: main.py [-h] [--data-path DATA_PATH | --data-link DATA_LINK]
               [--vos VOS] [--model-name MODEL_NAME] [--language LANGUAGE]
               [--verbose] [--txt] [--vtt] [--srt] [--pdf] [--page-numbers]
               [-o OUTPUT_FOLDER]
main.py: error: unrecognized arguments: Aufzeichnung vom 20.12.2022"

What I have tried

I already tried (probably) every possible combination of ", ' and and i still can’t figure it out.

But what I noticed is that the error only appears when the inputed string (for –vos) has spaces. For example running the following command would result in no errors at all:

docker run -d --name container -e ARGS="--vos="2.-Aufzeichnung-vom-20.12.2022""  vo-transcriber:1.6.0

Unfortunatly I need this variable to accept spaces, so here I am wirting this question and hoping that somebody will know what to do…
Help me!!!

Asked By: bananensplit

||

Answers:

You can just set the current CMD as an ENTRYPOINT and everything you give in the command line after the container will be passed to it.

FROM python:3.10

WORKDIR /usr/src/app

COPY requirements.txt ./
COPY main.py ./
COPY ...
COPY ...
COPY ...

RUN apt update
RUN apt install ffmpeg -y
RUN apt install wkhtmltopdf -y

RUN pip install --no-cache-dir -r requirements.txt
RUN mkdir output

VOLUME /usr/src/app/output

ENTRYPOINT ["python", "main.py"]

Then running

docker run -d --name container vo-transcriber:1.6.0 --vos="2.-Aufzeichnung-vom-20.12.2022"  

will just pass --vos="2.-Aufzeichnung-vom-20.12.2022" to the python main.py entrypoint.

PS. You should also try to reduce your layers by grouping those COPY and RUN instructions (i.e. RUN apt update && apt install ...).

Answered By: ljmc