Zal
Zal

Reputation: 975

Azure function "ModuleNotFoundError" for local script

I have the following folderstructure:

Monday
|-- __init__.py
|-- api.py
|-- db.py
|-- exceptions.py
|-- function.json
|-- main.py
`-- process_data.py

In my main.py I import methods from process_data.py. When I run func start to start my Azure Function, I get:

(venv) ➜  monday git:(main) ✗ func start
Found Python version 3.8.5 (python3).
Azure Functions Core Tools (3.0.2931 Commit hash: d552c6741a37422684f0efab41d541ebad2b2bd2)
Function Runtime Version: 3.0.14492.0

Functions:

        monday: timerTrigger

For detailed output, run func with --verbose flag.
[2020-11-02T00:56:08.423] Worker process started and initialized.
[2020-11-02T00:56:08.975] Worker failed to function id f73b3d07-44a3-4f64-be74-617bc6fede70.
[2020-11-02T00:56:08.976] Result: Failure
[2020-11-02T00:56:08.976] Exception: ModuleNotFoundError: No module named 'monday'. Troubleshooting Guide: https://aka.ms/functions-modulenotfound
[2020-11-02T00:56:08.976] Stack:   File "/usr/local/Cellar/azure-functions-core-tools@3/3.0.2931/workers/python/3.8/OSX/X64/azure_functions_worker/dispatcher.py", line 262, in _handle__function_load_request
[2020-11-02T00:56:08.976]     func = loader.load_function(
[2020-11-02T00:56:08.976]   File "/usr/local/Cellar/azure-functions-core-tools@3/3.0.2931/workers/python/3.8/OSX/X64/azure_functions_worker/utils/wrappers.py", line 34, in call
[2020-11-02T00:56:08.976]     raise extend_exception_message(e, message)
[2020-11-02T00:56:08.976]   File "/usr/local/Cellar/azure-functions-core-tools@3/3.0.2931/workers/python/3.8/OSX/X64/azure_functions_worker/utils/wrappers.py", line 32, in call
[2020-11-02T00:56:08.976]     return func(*args, **kwargs)
[2020-11-02T00:56:08.976]   File "/usr/local/Cellar/azure-functions-core-tools@3/3.0.2931/workers/python/3.8/OSX/X64/azure_functions_worker/loader.py", line 76, in load_function
[2020-11-02T00:56:08.976]     mod = importlib.import_module(fullmodname)
[2020-11-02T00:56:08.976]   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/importlib/__init__.py", line 127, in import_module
[2020-11-02T00:56:08.976]     return _bootstrap._gcd_import(name[level:], package, level)
[2020-11-02T00:56:08.976]   File "/Users/en/Workspace/zypp/monday/monday/process_data.py", line 3, in <module>
[2020-11-02T00:56:08.976]     from monday.api import request_data
[2020-11-02T00:56:08.976] .

I read this thread, but it is about external and installed packages. These are just my local scripts in the same directory.

This how my main.py looks like:

import datetime
import logging
import azure.functions as func
from monday.process_data import export_to_azure, create_dataframe


def main(timer: func.TimerRequest) -> None:
    utc_timestamp = datetime.datetime.utcnow().replace(
        tzinfo=datetime.timezone.utc).isoformat()

    # on timer run export data
    df = create_dataframe()
    export_to_azure(table_name="tasks", schema="monday", df=df)

    logging.info('Python timer trigger function ran at %s', utc_timestamp)

Content of my function.json:

{
  "scriptFile": "main.py",
  "bindings": [
    {
      "name": "timer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 */5 * * * *"
    }
  ]
}

Note: the code runs fine on it's own.

Upvotes: 1

Views: 1946

Answers (1)

suziki
suziki

Reputation: 14113

Below is the code on my side, it works fine:

main.py

import logging

import azure.functions as func
from .process_data import funcname1, funcname2

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    funcname1()
    funcname2()
    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
    else:
        return func.HttpResponse(
             "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

process_data.py

def funcname1():
    """
    docstring
    """
    print('This is funcname1')
    pass

def funcname2():
    """
    docstring
    """
    print('This is funcname2')
    pass

function.json

{
  "scriptFile": "main.py",
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

This is the structure on my side:

enter image description here

It works fine:

enter image description here

Upvotes: 2

Related Questions