ModuleNotFoundError while importing python files as modules in Azure App Services

Question:

I am getting started with Azure App Services.

I followed this tutorial and was able to get the example main.py app running.

The modules (fastapi, uvicorn, etc…) specified in the requirements.txt are all installed and imported correctly.

However, when trying to import Python files located in the same directory as the main.py, deployment is still successful, but I am getting an application error when trying to browse by webpage: enter image description here

For instance, I created a file called settings.py, containing:

MY_TITLE = "My FastAPI prototype"

In this main.py, I simply modified:

app = FastAPI()

With:

import settings
app = FastAPI(title=f"{settings.MY_TITLE}")

But this failed!
Please note that when I specify MY_TITLE in the main script, I am able to update the page’s title correctly.

How can I import Python files from my main.py script on Azure App Services?

Asked By: Sheldon

||

Answers:

Adding an answer from our comment discussion

I would suggest you enable diagnostic logging on your webapp and Try to look the application logs under (Diagnose and solve problems–> Availability and performance) to identify what is causing this issue.

As you have mentioned in your comments that you are seeing Module not found error. In general, ModuleNotFoundError: means that Python could not find one or more of your modules when the application started. This most often occurs if you deploy your virtual environment with your code. Virtual environments are not portable, so a virtual environment should not be deployed with your application code.

You can refer to this documentation for further troubleshooting on Module not found error

Answered By: VenkateshDodda-MSFT

A ModuleNotFoundError occurs when Python is unable to resolve the module‘s name. If the module’s name was found neither in sys.modules nor in the standard library, Python will try to resolve it in sys.path (see The Module Search Path). If the named module cannot be found, a ModuleNotFoundError is raised.

To ovecome this error, you will have to either add the parent directory of the module (Python file)—or the directory containing the entire project—to the system PATH variable, or use relative imports, as decribed in this answer and this answer. One advantage of relative imports is that they are quite succinct. To specify the location for relative imports, you use the dot notation. A single dot means that the module referenced is in the same directory as the current location. Two dots would mean that it is in the parent directory of the current location, and so on. Example:

from .settings import MY_TITLE

or, to import every function and property contained in the settings module, use the * wildcard:

from .settings import *

However, be careful when using *. The PEP 8 style guide also suggests that:

Wildcard imports (from <module> import *) should be avoided, as they
make it unclear which names are present in the namespace, confusing
both readers and many automated tools.

I should also mention that relative imports can be messy, particularly for shared projects where directory structure is likely to change, and are not as readable as absolute ones. Thus, the PEP 8 style guide recommends using absolute imports in general:

Absolute imports are recommended, as they are usually more readable
and tend to be better behaved (or at least give better error messages)
if the import system is incorrectly configured (such as when a
directory inside a package ends up on sys.path).

However:

explicit relative imports are an acceptable alternative to absolute imports, especially when dealing with complex package layouts where using absolute imports would be unnecessarily verbose.

Answered By: Chris