pythonazureazure-functionsretrypolicytimer-trigger

Azure function app (python) Retry with timer_trigger is not working


I am facing an issue to run the below code. I directly ran the code from the Microsoft official documentation

from azure.functions import FunctionApp, TimerRequest, Context, AuthLevel
import logging

app = FunctionApp(http_auth_level=AuthLevel.ANONYMOUS)


@app.timer_trigger(schedule="*/1 * * * * *", arg_name="mytimer",
                   run_on_startup=False,
                   use_monitor=False)
@app.retry(strategy="fixed_delay", max_retry_count="3",
           delay_interval="00:00:01")
def mytimer(mytimer: TimerRequest, context: Context) -> None:
    logging.info(f'Current retry count: {context.retry_context.retry_count}')

    if context.retry_context.retry_count == \
            context.retry_context.max_retry_count:
        logging.info(
            f"Max retries of {context.retry_context.max_retry_count} for "
            f"function {context.function_name} has been reached")
    else:
        raise Exception("This is a retryable exception")

I am getting this error:

Received WorkerMetadataRequest, request ID b7bfaf90-17e3-4983-b4a5-1ce251db2312, directory: /src/components/test
[2024-06-05T03:09:22.466Z] Worker failed to index functions
[2024-06-05T03:09:22.466Z] Result: Failure
[2024-06-05T03:09:22.466Z] Exception: AttributeError: 'FunctionApp' object has no attribute 'retry'
[2024-06-05T03:09:22.466Z] Stack:   File "/usr/lib/azure-functions-core-tools-4/workers/python/3.10/LINUX/X64/azure_functions_worker/dispatcher.py", line 338, in handle_functions_metadata_request
[2024-06-05T03:09:22.466Z]     fx_metadata_results = self.index_functions(function_path)
[2024-06-05T03:09:22.466Z]   File "/usr/lib/azure-functions-core-tools-4/workers/python/3.10/LINUX/X64/azure_functions_worker/dispatcher.py", line 607, in index_functions
[2024-06-05T03:09:22.466Z]     indexed_functions = loader.index_function_app(function_path)
[2024-06-05T03:09:22.467Z]   File "/usr/lib/azure-functions-core-tools-4/workers/python/3.10/LINUX/X64/azure_functions_worker/utils/wrappers.py", line 44, in call
[2024-06-05T03:09:22.467Z]     return func(*args, **kwargs)
[2024-06-05T03:09:22.467Z]   File "/usr/lib/azure-functions-core-tools-4/workers/python/3.10/LINUX/X64/azure_functions_worker/loader.py", line 151, in index_function_app
[2024-06-05T03:09:22.467Z]     imported_module = importlib.import_module(module_name)
[2024-06-05T03:09:22.467Z]   File "/usr/local/lib/python3.10/importlib/_init_.py", line 126, in import_module
[2024-06-05T03:09:22.467Z]     return _bootstrap._gcd_import(name[level:], package, level)
[2024-06-05T03:09:22.467Z]   File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
[2024-06-05T03:09:22.468Z]   File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
[2024-06-05T03:09:22.468Z]   File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
[2024-06-05T03:09:22.468Z]   File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
[2024-06-05T03:09:22.468Z]   File "<frozen importlib._bootstrap_external>", line 883, in exec_module
[2024-06-05T03:09:22.468Z]   File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
[2024-06-05T03:09:22.468Z]   File "/src/components/test/function_app.py", line 10, in <module>
[2024-06-05T03:09:22.468Z]     @app.retry(strategy="fixed_delay", max_retry_count="3",
[2024-06-05T03:09:22.468Z] .
[2024-06-05T03:09:22.473Z] 0 functions found
[2024-06-05T03:09:22.491Z] 0 functions loaded
[2024-06-05T03:09:22.493Z] Looking for extension bundle Microsoft.Azure.Functions.ExtensionBundle at /home/vscode/.azure-functions-core-tools/Functions/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle

I am using poetry, azure function apps and docker container with the following package versions:

  1. python 3.10
  2. azure-functions 1.19.0
  3. azure-core 1.30.1
  4. azure-identity 1.16.0
  5. Python model v2 in Azure
  6. run time version on azure: 4.34.1.1

I did try with azure function 1.19.0; the retry policy is there for timertrigger but I am still getting this annoying issue.

https://github.com/Azure/azure-functions-python-library/blob/bdeb2c2e29dd491129784ccb5cf5b5371b1ce286/azure/functions/decorators/function_app.py#L3190

EDIT: Folder Structure

enter image description here

Steps to run

  1. Docker image FROM mcr.microsoft.com/azure-functions/python:4-python3.10-core-tools
  2. Docker build and docker exec -it bash
  3. cd to folder structure
  4. poetry config virtual env true
  5. poetry shell
  6. poetry install
  7. func host start --python --verbose

Solution

  • enter image description here

    function_app.py-

    import logging
    from azure.functions import FunctionApp, TimerRequest, Context, AuthLevel
    
    app = FunctionApp(http_auth_level=AuthLevel.ANONYMOUS)
    
    @app.timer_trigger(schedule="*/1 * * * * *", arg_name="mytimer", run_on_startup=False,
                  use_monitor=False) 
    @app.retry(strategy="fixed_delay", max_retry_count="3",
               delay_interval="00:00:01")
    def mytimer(mytimer: TimerRequest, context: Context) -> None:
        logging.info(f'Current retry count: {context.retry_context.retry_count}')
    
        if context.retry_context.retry_count == \
                context.retry_context.max_retry_count:
            logging.info(
                f"Max retries of {context.retry_context.max_retry_count} for "
                f"function {context.function_name} has been reached")
        else:
            raise Exception("This is a retryable exception")
    

    host.json-

    {
      "version": "2.0",
      "logging": {
        "applicationInsights": {
          "samplingSettings": {
            "isEnabled": true,
            "excludedTypes": "Request"
          }
        }
      },
      "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[4.*, 5.0.0)"
      }
    }
    

    local.settings.json-

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "python",
        "AzureWebJobsFeatureFlags": "EnableWorkerIndexing"
      }
    }
    

    requirements.txt-

    azure-functions
    

    If you have all these codes in your folder structure then you will be able to get the expected response alike me.

    Enable Azurite (fn + f5) before executing the function.

    Azure Functions Core Tools
    Core Tools Version:       4.0.5700 Commit hash: N/A +71cc8*****7bdd (64-bit)
    Function Runtime Version: 4.33.2.22572
    
    
    Functions:
    
            mytimer: timerTrigger
    
    For detailed output, run func with --verbose flag.
    [2024-06-05T07:18:08.035Z] Executing 'Functions.mytimer' (Reason='Timer fired at 2024-06-05T12:48:08.0148226+05:30', Id=c5512c8b-4abd-41e3-9871-f7b5d574e060)
    [2024-06-05T07:18:08.095Z] Current retry count: 0
    [2024-06-05T07:18:08.134Z] Executed 'Functions.mytimer' (Failed, Id=c5512c8b-4abd-41e3-9871-f7b5d574e060, Duration=108ms)
    [2024-06-05T07:18:08.136Z] System.Private.CoreLib: Exception while executing function: Functions.mytimer. System.Private.CoreLib: Result: Failure
    Exception: Exception: This is a retryable exception
    Stack:   File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.11/WINDOWS/X64\azure_functions_worker\dispatcher.py", line 545, in _handle__invocation_request
        call_result = await self._loop.run_in_executor(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\***\AppData\Local\Programs\Python\Python311\Lib\concurrent\futures\thread.py", line 58, in run
        result = self.fn(*self.args, **self.kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.11/WINDOWS/X64\azure_functions_worker\dispatcher.py", line 826, in _run_sync_func
        return ExtensionManager.get_sync_invocation_wrapper(context,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.11/WINDOWS/X64\azure_functions_worker\extension.py", line 215, in _raw_invocation_wrapper
        result = function(**args)
                 ^^^^^^^^^^^^^^^^
      File "C:\Users\***\OneDrive - Microsoft\Documents\functionApp\78578594\function_app.py", line 19, in mytimer
        raise Exception("This is a retryable exception")
    .
    [2024-06-05T07:18:09.167Z] Executing 'Functions.mytimer' (Reason='Timer fired at 2024-06-05T12:48:09.1667627+05:30', Id=fc680c7a-cd73-4d7c-9976-ed3facc8c591)
    [2024-06-05T07:18:09.176Z] Current retry count: 1
    [2024-06-05T07:18:09.178Z] Executed 'Functions.mytimer' (Failed, Id=fc680c7a-cd73-4d7c-9976-ed3facc8c591, Duration=11ms)
    [2024-06-05T07:18:09.179Z] System.Private.CoreLib: Exception while executing function: Functions.mytimer. System.Private.CoreLib: Result: Failure
    Exception: Exception: This is a retryable exception
    Stack:   File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.11/WINDOWS/X64\azure_functions_worker\dispatcher.py", line 545, in _handle__invocation_request
        call_result = await self._loop.run_in_executor(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\****\AppData\Local\Programs\Python\Python311\Lib\concurrent\futures\thread.py", line 58, in run
        result = self.fn(*self.args, **self.kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.11/WINDOWS/X64\azure_functions_worker\dispatcher.py", line 826, in _run_sync_func
        return ExtensionManager.get_sync_invocation_wrapper(context,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.11/WINDOWS/X64\azure_functions_worker\extension.py", line 215, in _raw_invocation_wrapper
        result = function(**args)
                 ^^^^^^^^^^^^^^^^
      File "C:\Users\v-iafrin\OneDrive - Microsoft\Documents\functionApp\78578594\function_app.py", line 19, in mytimer
        raise Exception("This is a retryable exception")
    .
    [2024-06-05T07:18:10.179Z] Executing 'Functions.mytimer' (Reason='Timer fired at 2024-06-05T12:48:10.1797346+05:30', Id=032731bb-1b08-40f9-a9c9-71c6c759c478)
    [2024-06-05T07:18:10.185Z] Current retry count: 2
    [2024-06-05T07:18:10.187Z] Executed 'Functions.mytimer' (Failed, Id=032731bb-1b08-40f9-a9c9-71c6c759c478, Duration=7ms)
    [2024-06-05T07:18:10.188Z] System.Private.CoreLib: Exception while executing function: Functions.mytimer. System.Private.CoreLib: Result: Failure
    Exception: Exception: This is a retryable exception
    Stack:   File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.11/WINDOWS/X64\azure_functions_worker\dispatcher.py", line 545, in _handle__invocation_request
        call_result = await self._loop.run_in_executor(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\****\AppData\Local\Programs\Python\Python311\Lib\concurrent\futures\thread.py", line 58, in run
        result = self.fn(*self.args, **self.kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.11/WINDOWS/X64\azure_functions_worker\dispatcher.py", line 826, in _run_sync_func
        return ExtensionManager.get_sync_invocation_wrapper(context,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.11/WINDOWS/X64\azure_functions_worker\extension.py", line 215, in _raw_invocation_wrapper
        result = function(**args)
                 ^^^^^^^^^^^^^^^^
      File "C:\Users\*****\OneDrive - Microsoft\Documents\functionApp\78578594\function_app.py", line 19, in mytimer
        raise Exception("This is a retryable exception")
    .
    [2024-06-05T07:18:11.195Z] Executing 'Functions.mytimer' (Reason='Timer fired at 2024-06-05T12:48:11.1950786+05:30', Id=c365ae71-280b-4fc8-9954-0c6eecd917ce)
    [2024-06-05T07:18:11.203Z] Current retry count: 3
    [2024-06-05T07:18:11.204Z] Max retries of 3 for function mytimer has been reached
    [2024-06-05T07:18:11.214Z] Executed 'Functions.mytimer' (Succeeded, Id=c365ae71-280b-4fc8-9954-0c6eecd917ce, Duration=18ms)