Azure / azure-functions-durable-python

Python library for using the Durable Functions bindings.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

starter string in V2 model

crypto-ralph opened this issue · comments

Is your question related to a specific version? If so, please specify:
V2 Model

What binding does your question apply to, if any? (e.g. Blob Trigger, Event Hub Binding, etc)
Azure Durable Functions Orchestration Triggers

Question
In the V1 model there is following syntax for the Activity function:

async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
instance_id = await client.start_new(req.params.functionName, None, None)

is there any way in V2 model to extract this starter string? to be able to create df.DurableOrchestrationClient later during app runtime?

I'm wondering the same as I would like to have client = df.DurableOrchestrationClient(starter) as Global Dependency in FastAPI. So that we can use durable functions Orchestrator but called from regular FastAPI endpoints.

Here is an example with a custom orchestration status, but again needs the starter: str
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-custom-orchestration-status?tabs=python#e1_sayhello-activity-function

For the sake of it starter in v1 is:

{
    "taskHubName": "TestHubName",
    "connectionName": null,
    "creationUrls": {
        "createNewInstancePostUri": "http://localhost:7071/runtime/webhooks/durabletask/orchestrators/{functionName}[/{instanceId}]?code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ==",
        "createAndWaitOnNewInstancePostUri": "http://localhost:7071/runtime/webhooks/durabletask/orchestrators/{functionName}[/{instanceId}]?timeout={timeoutInSeconds}&pollingInterval={intervalInSeconds}&code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ=="
    },
    "managementUrls": {
        "id": "INSTANCEID",
        "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/INSTANCEID?taskHub=TestHubName&connection=Storage&code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ==",
        "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/INSTANCEID/raiseEvent/{eventName}?taskHub=TestHubName&connection=Storage&code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ==",
        "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/INSTANCEID/terminate?reason={text}&taskHub=TestHubName&connection=Storage&code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ==",
        "rewindPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/INSTANCEID/rewind?reason={text}&taskHub=TestHubName&connection=Storage&code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ==",
        "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/INSTANCEID?taskHub=TestHubName&connection=Storage&code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ==",
        "restartPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/INSTANCEID/restart?taskHub=TestHubName&connection=Storage&code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ==",
        "suspendPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/INSTANCEID/suspend?reason={text}&taskHub=TestHubName&connection=Storage&code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ==",
        "resumePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/INSTANCEID/resume?reason={text}&taskHub=TestHubName&connection=Storage&code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ=="
    },
    "baseUrl": "http://localhost:7071/runtime/webhooks/durabletask",
    "requiredQueryStringParameters": "code=fMKqfur7tU1yidXikGCwP_z560dXaMhnKGsMy3RYd-bpAzFu1fnKRQ==",
    "rpcBaseUrl": "http://127.0.0.1:17071/durabletask/"
}

@davidmrdavid would you be able to help? Since you seem to be the author for the decorator that gets the starter = kwargs[parameter_name] ?

https://github.com/Azure/azure-functions-durable-python/blame/b30d0a64f7b8c1042f066006af57b74976cdf9d2/azure/durable_functions/decorators/durable_app.py#L194

I think I've found a way for v2 with generic_input_binding

app = df.DFApp(http_auth_level=func.AuthLevel.ANONYMOUS)


# An HTTP-Triggered Function with a Durable Functions Client binding
@app.route(route="bind/")
@app.generic_input_binding(arg_name="starter", type="durableClient")
async def mybind(req: func.HttpRequest, starter):
    return starter

I think I've found a way for v2 with generic_input_binding

Thanks for replying and sharing this solution. I will try your soultion next week :)

I think I've found a way for v2 with generic_input_binding

Thanks for replying and sharing this solution. I will try your soultion next week :)

I've tested it locally with a v2 function app

image

Note how there is no function.json

image

I've tested it locally with a v2 function app

I confirm that this solution works also in my case.
@AndreRicardo-Zoetis do you have any doc reference for this input binding?

I would be glad if someone from the dev team confirm that this is recommended approach as I need to introduce it in production ready system.

I've tested it locally with a v2 function app

I confirm that this solution works also in my case. @AndreRicardo-Zoetis do you have any doc reference for this input binding?

I would be glad if someone from the dev team confirm that this is recommended approach as I need to introduce it in production ready system.

No doc reference, I was just going through code in azure-functions-durable-python until I arrived here:

For context, I was trying to find a way around #444 to call the Orchestration from FastAPI.

The code for the generic_input_binding is here:
https://github.com/Azure/azure-functions-python-library/blob/0ca53b35491ce22569f012d485c9973050ea3227/azure/functions/decorators/function_app.py#L2180

I believe I've seen first usage in this repo:
https://github.com/search?q=repo%3AAzure%2Fazure-functions-python-worker%20generic_input_binding&type=code

I was just trying to map a way from v1 to v2, because in v1 in someway is more explicit to understand where this starter comes from.

Hi @AndreRicardo-Zoetis, @crypto-ralph - thank you for using Durable Functions! I'm a PM working on DF and would love to learn about your experience using the product. You can share your feedback in this quick survey to help influence what the team works on next. If you're building intelligent apps, there's also an opportunity to participate in a compensated UX study. Thanks!