pythonimport-module

Dynamically import Python module with Windows and Linux


I'm trying to dynamically import a Python module using importlib.

My project is an Azure function app and has the following file structure:

Shared_Code/
├── __init__.py
├── model.py
└── rule_engine.py

In the file rule_engine.py I'm trying to import model.py:

logging.info(__name__)
importlib.import_module(
    'Shared_Code.model', package=None
)

The above code prints

__app__.Shared_Code.rule_engine.py

and imports the module correctly on Linux and Azure Cloud.

However, when executing the exact same code on Windows I get an error that the module Shared_Code could not be found.

I've then used the following

importlib.import_module(
    '__app__.Shared_Code.model', package=None
)

which works on both, but breaks when running it on Azure Cloud.

Is there a generic solution for this without having to perform manual checks and if-clauses depending on the OS?


Solution

  • You can try to import model using a relative path:

    importlib.import_module('.model', package='Shared_Code')
    

    Edit: After some research, I'm concluding that this is an Azure issue, not a Python one.

    There isn't a single coincidence of the string __app__ in the full CPython code.

    There is, however, this azure-functions-python-worker PR where the __app__ top-level module is implemented for absolute imports.

    I guess this is a bug in azure-functions-python-worker, or whatever Azure platform you're working on, where they have different behavior between Linux and Azure Cloud VS Windows.

    The only things I can think you can do are:

    try:
        importlib.import_module(
            'Shared_Code.model', package=None
        )
    except ModuleNotFoundError:
        # In Windows, __app__ is mandatory
        importlib.import_module(
            '__app__.Shared_Code.model', package=None
        )
    

    I know this last one is exactly what you're asking for not to do, but if it's a platform problem (and I'm pretty sure it is) there is nothing more you can do except to deal with it.