'How to pass multiple parameters to Azure Durable Activity Function
My orchestrator receives a payload, with that payload it contains instructions that need to be passed along with other sets of data to activity functions.
how do I pass multiple parameters to an activity function? Or do I have to mash all my data together?
def orchestrator_function(context: df.DurableOrchestrationContext):
# User defined configuration
instructions: str = context.get_input()
task_batch = yield context.call_activity("get_tasks", None)
# Need to pass in instructions too
parallel_tasks = [context.call_activity("perform_task", task) for task in task_batch]
results = yield context.task_all(parallel_tasks)
return results
The perform_task activity needs both the items from task_batch and the user input instructions
Do I do something in my function.json?
Workaround Not ideal, but I can pass multiple parameters as a single Tuple
something = yield context.call_activity("activity", ("param_1", "param_2"))
I then just need to reference the correct index of the parameter in the activity.
Solution 1:[1]
Just to add to @Ari's great answer, here code to pass data from client function (HTTP request in this case) all the way to activity function:
Client -> Orchestrator -> Activity
Client
async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
req_data = req.get_json()
img_url = req_data['img_url']
payload = {"img_url": img_url}
instance_id = await client.start_new(req.route_params["functionName"], None, payload)
logging.info(f"Started orchestration with ID = '{instance_id}'.")
return client.create_check_status_response(req, instance_id)
Orchestrator
def orchestrator_function(context: df.DurableOrchestrationContext):
input_context = context.get_input()
img_url = input_context.get('img_url')
some_response= yield context.call_activity('MyActivity', img_url)
return [some_response]
Activity
def main(imgUrl: str) -> str:
print(f'.... Image URL = {imgUrl}')
return imgUrl
Solution 2:[2]
You can use @dataclass and @dataclass_json class decorators for your input and output types, like this:
@dataclass_json
@dataclass
class Command:
param1: str
param2: int
@dataclass_json
@dataclass
class Result:
val1: str
val2: int
and then you can use those in Azure Functions, e.g. in Activity ones:
def main(input: DownloadFileRequest) -> DownloadFileResponse:
# function code
result: DownloadFileResponse = DownloadFileResponse("some", 123)
return result
This provides you with a clean API and descriptive code. Much better approach than using dictionaries, at least for me.
Solution 3:[3]
I would also suggest the dataclass-wizard as a viable option, and one which should also be a bit more lightweight alternative to dataclasses-json; it is lighter in the sense that it does not use external libraries like marshmallow for generating schemas. It also performs a little better FWIW anyway.
I didn't really understand the schema of the data as outlined in the question unfortunately, thus I decided to roll my own for the purposes of a quick and dirty demo, so check it out:
from dataclasses import dataclass
from dataclass_wizard import JSONWizard
@dataclass
class Batman(JSONWizard):
suit_color: str
side: 'Sidekick'
@dataclass
class Sidekick:
name: str
mood: str
# usage
bats = Batman.from_dict({'suitColor': 'BLACK',
'side': {'Name': 'Robin', 'mood': 'Mildly depressed'}})
print(repr(bats))
# prints:
# Batman(suit_color='BLACK', side=Sidekick(name='Robin', mood='Mildly depressed'))
print(bats.to_dict())
# prints:
# {'suitColor': 'BLACK', 'side': {'name': 'Robin', 'mood': 'Mildly depressed'}}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | gary |
| Solution 2 | Kokos |
| Solution 3 | rv.kvetch |
