简体   繁体   中英

Python Modules in Docker: ModuleNotFoundError: No module named 'src'

I know this is a common problem, but after having search the web for about an hour, no solution has worked yet. The code works locally but in Docker I get this error:

ModuleNotFoundError: No module named 'src'

It's driving me insane b/c no matter how I structure the code, I get either this one or a path not found error, but either way, something I do is just off the charts/

In a nutshell, I am building a dockerized monitor for a shaky gateway that tests every couple of minutes if the gateway host is still reachable and the gateway itself still working. That gateway.

The folder structure is simple:

 monitor
    - src 
       - api
       - __init__
       EmailManager.py
       GatewayManager.py
   CONTACT.py # contains email addresses
   main.py  

The module init looks like so:

from src.api.EmailManager import EmailManager
from src.api.GatewayManager import GatewayManager 

Each of those two classes follows a fairly standard pattern. taking the EmailManager as an example:


class EmailManager(object):
    def __init__(self, default_address):
    
    def send_email()...

Nothing special here, as far as I'm concerned. The main.py contains both, a MainClass and a simple main function to run.

from src.api.EmailManager import EmailManager
from src.api.GatewayManager import GatewayManager
from src.CONTACT import ADMIN_EMAIL

class MainClass:

    def __init__(self):
        self.em = EmailManager(default_address=ADMIN_EMAIL)
        .... 
    
if __name__ == '__main__':
    mc = MainClass()

    def signal_handler(sig, frame):
        print('Handle signal {signal}'.format(signal=sig))
        mc.shutdown()

    print("Register SIGTERM event handler")
    signal.signal(signal.SIGTERM, signal_handler)

    print("Start gateway monitor")
    mc.run(minutes=1)

This works well on my workstation and roughly does what it is supposed to do. The matching Dockerfile is also very simple:

FROM python:3.8-slim-buster

COPY config/requirements.txt .
COPY src /src

CMD 'python -m pip install --upgrade pip'

RUN pip install -r requirements.txt

CMD [ "python", "./src/main.py" ]

That one throws the ModuleNotFound error.

When changing the last line to

CMD [ "python", "-m", "./src/main.py" ]

I get the following error:

/usr/local/bin/python: Relative module names not supported

Any idea how to structure the classes so that they run well in Docker?

Any help is appreciated.

The tree structure is a little confusing, but going off the imports, your folder structure should be looking like so:

├── main.py
└── src
    ├── CONTACT.py
    ├── __init__.py
    └── api
        ├── EmailManager.py
        ├── GatewayManager.py
        └── __init__.py

From there, your main.py would look like so (as you have it):

from src.api.EmailManager import EmailManager
from src.api.GatewayManager import GatewayManager
from src.CONTACT import ADMIN_EMAIL

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM