Skip to content

Commit

Permalink
fix: enable missed return types for generic (#1485)
Browse files Browse the repository at this point in the history
* tests, support for dict & httpresp

* support for returning list

* added support for int, double

* bool support, unit tests

---------

Co-authored-by: Victoria Hall <[email protected]>
  • Loading branch information
hallvictoria and Victoria Hall authored May 29, 2024
1 parent b0bacf0 commit 8214d0c
Show file tree
Hide file tree
Showing 31 changed files with 624 additions and 17 deletions.
13 changes: 13 additions & 0 deletions azure_functions_worker/bindings/datumdef.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@ def datum_as_proto(datum: Datum) -> protos.TypedData:
))
elif datum.type is None:
return None
elif datum.type == 'dict':
# TypedData doesn't support dict, so we return it as json
return protos.TypedData(json=json.dumps(datum.value))
elif datum.type == 'list':
# TypedData doesn't support list, so we return it as json
return protos.TypedData(json=json.dumps(datum.value))
elif datum.type == 'int':
return protos.TypedData(int=datum.value)
elif datum.type == 'double':
return protos.TypedData(double=datum.value)
elif datum.type == 'bool':
# TypedData doesn't support bool, so we return it as an int
return protos.TypedData(int=int(datum.value))
else:
raise NotImplementedError(
'unexpected Datum type: {!r}'.format(datum.type)
Expand Down
10 changes: 10 additions & 0 deletions azure_functions_worker/bindings/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ def encode(cls, obj: Any, *,
return datumdef.Datum(type='bytes', value=bytes(obj))
elif obj is None:
return datumdef.Datum(type=None, value=obj)
elif isinstance(obj, dict):
return datumdef.Datum(type='dict', value=obj)
elif isinstance(obj, list):
return datumdef.Datum(type='list', value=obj)
elif isinstance(obj, int):
return datumdef.Datum(type='int', value=obj)
elif isinstance(obj, float):
return datumdef.Datum(type='double', value=obj)
elif isinstance(obj, bool):
return datumdef.Datum(type='bool', value=obj)
else:
raise NotImplementedError

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
import azure.functions as func

import logging

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
Expand Down Expand Up @@ -45,7 +46,91 @@ def mytimer(mytimer: func.TimerRequest, testEntity) -> None:
logging.info("This timer trigger function executed successfully")


@app.function_name(name="mytimer2")
@app.function_name(name="return_string")
@app.schedule(schedule="*/1 * * * * *", arg_name="mytimer",
run_on_startup=False,
use_monitor=False)
@app.generic_input_binding(
arg_name="testEntity",
type="table",
connection="AzureWebJobsStorage",
table_name="EventHubBatchTest")
def return_string(mytimer: func.TimerRequest, testEntity):
logging.info("Return string")
return "hi!"


@app.function_name(name="return_bytes")
@app.schedule(schedule="*/1 * * * * *", arg_name="mytimer",
run_on_startup=False,
use_monitor=False)
@app.generic_input_binding(
arg_name="testEntity",
type="table",
connection="AzureWebJobsStorage",
table_name="EventHubBatchTest")
def return_bytes(mytimer: func.TimerRequest, testEntity):
logging.info("Return bytes")
return "test-dată"


@app.function_name(name="return_dict")
@app.schedule(schedule="*/1 * * * * *", arg_name="mytimer",
run_on_startup=False,
use_monitor=False)
@app.generic_input_binding(
arg_name="testEntity",
type="table",
connection="AzureWebJobsStorage",
table_name="EventHubBatchTest")
def return_dict(mytimer: func.TimerRequest, testEntity):
logging.info("Return dict")
return {"hello": "world"}


@app.function_name(name="return_list")
@app.schedule(schedule="*/1 * * * * *", arg_name="mytimer",
run_on_startup=False,
use_monitor=False)
@app.generic_input_binding(
arg_name="testEntity",
type="table",
connection="AzureWebJobsStorage",
table_name="EventHubBatchTest")
def return_list(mytimer: func.TimerRequest, testEntity):
logging.info("Return list")
return [1, 2, 3]


@app.function_name(name="return_int")
@app.schedule(schedule="*/1 * * * * *", arg_name="mytimer",
run_on_startup=False,
use_monitor=False)
@app.generic_input_binding(
arg_name="testEntity",
type="table",
connection="AzureWebJobsStorage",
table_name="EventHubBatchTest")
def return_int(mytimer: func.TimerRequest, testEntity):
logging.info("Return int")
return 12


@app.function_name(name="return_double")
@app.schedule(schedule="*/1 * * * * *", arg_name="mytimer",
run_on_startup=False,
use_monitor=False)
@app.generic_input_binding(
arg_name="testEntity",
type="table",
connection="AzureWebJobsStorage",
table_name="EventHubBatchTest")
def return_double(mytimer: func.TimerRequest, testEntity):
logging.info("Return double")
return 12.34


@app.function_name(name="return_bool")
@app.schedule(schedule="*/1 * * * * *", arg_name="mytimer",
run_on_startup=False,
use_monitor=False)
Expand All @@ -54,5 +139,6 @@ def mytimer(mytimer: func.TimerRequest, testEntity) -> None:
type="table",
connection="AzureWebJobsStorage",
table_name="EventHubBatchTest")
def mytimer2(mytimer: func.TimerRequest, testEntity):
logging.info("Timer trigger with none return and no type hint")
def return_bool(mytimer: func.TimerRequest, testEntity):
logging.info("Return bool")
return True
21 changes: 21 additions & 0 deletions tests/endtoend/generic_functions/return_bool/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"scriptFile": "main.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "*/1 * * * * *",
"runOnStartup": false
},
{
"direction": "in",
"type": "table",
"name": "testEntity",
"partitionKey": "test",
"rowKey": "WillBePopulatedWithGuid",
"tableName": "BindingTestTable",
"connection": "AzureWebJobsStorage"
}
]
}
11 changes: 11 additions & 0 deletions tests/endtoend/generic_functions/return_bool/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import logging

import azure.functions as func


def main(mytimer: func.TimerRequest, testEntity):
logging.info("Return bool")
return True
21 changes: 21 additions & 0 deletions tests/endtoend/generic_functions/return_bytes/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"scriptFile": "main.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "*/1 * * * * *",
"runOnStartup": false
},
{
"direction": "in",
"type": "table",
"name": "testEntity",
"partitionKey": "test",
"rowKey": "WillBePopulatedWithGuid",
"tableName": "BindingTestTable",
"connection": "AzureWebJobsStorage"
}
]
}
11 changes: 11 additions & 0 deletions tests/endtoend/generic_functions/return_bytes/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import logging

import azure.functions as func


def main(mytimer: func.TimerRequest, testEntity):
logging.info("Return bytes")
return "test-dată"
21 changes: 21 additions & 0 deletions tests/endtoend/generic_functions/return_dict/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"scriptFile": "main.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "*/1 * * * * *",
"runOnStartup": false
},
{
"direction": "in",
"type": "table",
"name": "testEntity",
"partitionKey": "test",
"rowKey": "WillBePopulatedWithGuid",
"tableName": "BindingTestTable",
"connection": "AzureWebJobsStorage"
}
]
}
11 changes: 11 additions & 0 deletions tests/endtoend/generic_functions/return_dict/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import logging

import azure.functions as func


def main(mytimer: func.TimerRequest, testEntity):
logging.info("Return dict")
return {"hello": "world"}
21 changes: 21 additions & 0 deletions tests/endtoend/generic_functions/return_double/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"scriptFile": "main.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "*/1 * * * * *",
"runOnStartup": false
},
{
"direction": "in",
"type": "table",
"name": "testEntity",
"partitionKey": "test",
"rowKey": "WillBePopulatedWithGuid",
"tableName": "BindingTestTable",
"connection": "AzureWebJobsStorage"
}
]
}
11 changes: 11 additions & 0 deletions tests/endtoend/generic_functions/return_double/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import logging

import azure.functions as func


def main(mytimer: func.TimerRequest, testEntity):
logging.info("Return double")
return 12.34
21 changes: 21 additions & 0 deletions tests/endtoend/generic_functions/return_int/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"scriptFile": "main.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "*/1 * * * * *",
"runOnStartup": false
},
{
"direction": "in",
"type": "table",
"name": "testEntity",
"partitionKey": "test",
"rowKey": "WillBePopulatedWithGuid",
"tableName": "BindingTestTable",
"connection": "AzureWebJobsStorage"
}
]
}
11 changes: 11 additions & 0 deletions tests/endtoend/generic_functions/return_int/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import logging

import azure.functions as func


def main(mytimer: func.TimerRequest, testEntity):
logging.info("Return int")
return 12
21 changes: 21 additions & 0 deletions tests/endtoend/generic_functions/return_list/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"scriptFile": "main.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "*/1 * * * * *",
"runOnStartup": false
},
{
"direction": "in",
"type": "table",
"name": "testEntity",
"partitionKey": "test",
"rowKey": "WillBePopulatedWithGuid",
"tableName": "BindingTestTable",
"connection": "AzureWebJobsStorage"
}
]
}
11 changes: 11 additions & 0 deletions tests/endtoend/generic_functions/return_list/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import logging

import azure.functions as func


def main(mytimer: func.TimerRequest, testEntity):
logging.info("Return list")
return [1, 2, 3]
21 changes: 21 additions & 0 deletions tests/endtoend/generic_functions/return_string/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"scriptFile": "main.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "*/1 * * * * *",
"runOnStartup": false
},
{
"direction": "in",
"type": "table",
"name": "testEntity",
"partitionKey": "test",
"rowKey": "WillBePopulatedWithGuid",
"tableName": "BindingTestTable",
"connection": "AzureWebJobsStorage"
}
]
}
11 changes: 11 additions & 0 deletions tests/endtoend/generic_functions/return_string/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import logging

import azure.functions as func


def main(mytimer: func.TimerRequest, testEntity):
logging.info("Return string")
return "hi!"
Loading

0 comments on commit 8214d0c

Please sign in to comment.