diff --git a/SyncGetBlobAsBytesReturnHttpResponse/function.json b/SyncGetBlobAsBytesReturnHttpResponse/function.json new file mode 100644 index 0000000..90f1ffa --- /dev/null +++ b/SyncGetBlobAsBytesReturnHttpResponse/function.json @@ -0,0 +1,28 @@ +{ + "scriptFile": "main.py", + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "get", + "post" + ] + }, + { + "type": "blob", + "direction": "in", + "name": "file", + "dataType": "binary", + "connection": "AzureWebJobsStorage", + "path": "python-worker-perf-tests/{infile}" + }, + { + "type": "http", + "direction": "out", + "name": "$return" + } + ] +} diff --git a/SyncGetBlobAsBytesReturnHttpResponse/main.py b/SyncGetBlobAsBytesReturnHttpResponse/main.py new file mode 100644 index 0000000..a10faca --- /dev/null +++ b/SyncGetBlobAsBytesReturnHttpResponse/main.py @@ -0,0 +1,30 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import json +import hashlib +import azure.functions as azf + + +def main(req: azf.HttpRequest, file: bytes) -> azf.HttpResponse: + """ + Read a blob (bytes) and respond back (in HTTP response) with the number of + bytes read and the MD5 digest of the content. + """ + assert isinstance(file, bytes) + + content_size = len(file) + content_md5 = hashlib.md5(file).hexdigest() + + response_dict = { + 'content_size': content_size, + 'content_md5': content_md5 + } + + response_body = json.dumps(response_dict, indent=2) + + return azf.HttpResponse( + body=response_body, + mimetype="application/json", + status_code=200 + ) diff --git a/SyncGetBlobAsBytesStreamReturnHttpResponse/function.json b/SyncGetBlobAsBytesStreamReturnHttpResponse/function.json new file mode 100644 index 0000000..90f1ffa --- /dev/null +++ b/SyncGetBlobAsBytesStreamReturnHttpResponse/function.json @@ -0,0 +1,28 @@ +{ + "scriptFile": "main.py", + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "get", + "post" + ] + }, + { + "type": "blob", + "direction": "in", + "name": "file", + "dataType": "binary", + "connection": "AzureWebJobsStorage", + "path": "python-worker-perf-tests/{infile}" + }, + { + "type": "http", + "direction": "out", + "name": "$return" + } + ] +} diff --git a/SyncGetBlobAsBytesStreamReturnHttpResponse/main.py b/SyncGetBlobAsBytesStreamReturnHttpResponse/main.py new file mode 100644 index 0000000..6b49a94 --- /dev/null +++ b/SyncGetBlobAsBytesStreamReturnHttpResponse/main.py @@ -0,0 +1,30 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import json +import hashlib +import azure.functions as azf + + +def main(req: azf.HttpRequest, file: azf.InputStream) -> azf.HttpResponse: + """ + Read a blob (as azf.InputStream) and respond back (in HTTP response) with + the number of bytes read and the MD5 digest of the content. + """ + file_bytes = file.read() + + content_size = len(file_bytes) + content_md5 = hashlib.md5(file_bytes).hexdigest() + + response_dict = { + 'content_size': content_size, + 'content_md5': content_md5 + } + + response_body = json.dumps(response_dict, indent=2) + + return azf.HttpResponse( + body=response_body, + mimetype="application/json", + status_code=200 + ) diff --git a/SyncGetBlobAsStrReturnHttpResponse/function.json b/SyncGetBlobAsStrReturnHttpResponse/function.json new file mode 100644 index 0000000..f6f7258 --- /dev/null +++ b/SyncGetBlobAsStrReturnHttpResponse/function.json @@ -0,0 +1,28 @@ +{ + "scriptFile": "main.py", + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "get", + "post" + ] + }, + { + "type": "blob", + "direction": "in", + "name": "file", + "dataType": "string", + "connection": "AzureWebJobsStorage", + "path": "python-worker-perf-tests/{infile}" + }, + { + "type": "http", + "direction": "out", + "name": "$return" + } + ] +} diff --git a/SyncGetBlobAsStrReturnHttpResponse/main.py b/SyncGetBlobAsStrReturnHttpResponse/main.py new file mode 100644 index 0000000..0e03f7d --- /dev/null +++ b/SyncGetBlobAsStrReturnHttpResponse/main.py @@ -0,0 +1,31 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import json +import hashlib +import azure.functions as azf + + +def main(req: azf.HttpRequest, file: str) -> azf.HttpResponse: + """ + Read a blob (string) and respond back (in HTTP response) with the number of + characters read and the MD5 digest of the utf-8 encoded content. + """ + assert isinstance(file, str) + + num_chars = len(file) + content_bytes = file.encode('utf-8') + content_md5 = hashlib.md5(content_bytes).hexdigest() + + response_dict = { + 'num_chars': num_chars, + 'content_md5': content_md5 + } + + response_body = json.dumps(response_dict, indent=2) + + return azf.HttpResponse( + body=response_body, + mimetype="application/json", + status_code=200 + ) diff --git a/SyncPutBlobAsBytesReturnHttpResponse/function.json b/SyncPutBlobAsBytesReturnHttpResponse/function.json new file mode 100644 index 0000000..160142c --- /dev/null +++ b/SyncPutBlobAsBytesReturnHttpResponse/function.json @@ -0,0 +1,28 @@ +{ + "scriptFile": "main.py", + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "get", + "post" + ] + }, + { + "type": "blob", + "direction": "out", + "name": "file", + "dataType": "binary", + "connection": "AzureWebJobsStorage", + "path": "python-worker-perf-tests/{outfile}" + }, + { + "type": "http", + "direction": "out", + "name": "$return" + } + ] +} diff --git a/SyncPutBlobAsBytesReturnHttpResponse/main.py b/SyncPutBlobAsBytesReturnHttpResponse/main.py new file mode 100644 index 0000000..e6e7109 --- /dev/null +++ b/SyncPutBlobAsBytesReturnHttpResponse/main.py @@ -0,0 +1,41 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import random +import json +import hashlib +import azure.functions as azf + + +def main(req: azf.HttpRequest, file: azf.Out[bytes]) -> azf.HttpResponse: + """ + Write a blob (bytes) and respond back (in HTTP response) with the number of + bytes written and the MD5 digest of the content. + The number of bytes to write are specified in the input HTTP request. + """ + content_size = int(req.params['content_size']) + + # When this is set, then 0x01 byte is repeated content_size number of + # times to use as input. + # This is to avoid generating random input for large size which can be + # slow. + if 'no_random_input' in req.params: + content = b'\x01' * content_size + else: + content = bytearray(random.getrandbits(8) for _ in range(content_size)) + content_md5 = hashlib.md5(content).hexdigest() + + file.set(content) + + response_dict = { + 'content_size': content_size, + 'content_md5': content_md5 + } + + response_body = json.dumps(response_dict, indent=2) + + return azf.HttpResponse( + body=response_body, + mimetype="application/json", + status_code=200 + ) diff --git a/SyncPutBlobAsStrReturnHttpResponse/function.json b/SyncPutBlobAsStrReturnHttpResponse/function.json new file mode 100644 index 0000000..207b2e6 --- /dev/null +++ b/SyncPutBlobAsStrReturnHttpResponse/function.json @@ -0,0 +1,28 @@ +{ + "scriptFile": "main.py", + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "get", + "post" + ] + }, + { + "type": "blob", + "direction": "out", + "name": "file", + "dataType": "string", + "connection": "AzureWebJobsStorage", + "path": "python-worker-perf-tests/{outfile}" + }, + { + "type": "http", + "direction": "out", + "name": "$return" + } + ] +} diff --git a/SyncPutBlobAsStrReturnHttpResponse/main.py b/SyncPutBlobAsStrReturnHttpResponse/main.py new file mode 100644 index 0000000..901a7f3 --- /dev/null +++ b/SyncPutBlobAsStrReturnHttpResponse/main.py @@ -0,0 +1,39 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import string +import random +import json +import hashlib +import azure.functions as azf + + +def main(req: azf.HttpRequest, file: azf.Out[str]) -> azf.HttpResponse: + """ + Write a blob (string) and respond back (in HTTP response) with the number of + characters written and the MD5 digest of the utf-8 encoded content. + The number of characters to write are specified in the input HTTP request. + """ + num_chars = int(req.params['num_chars']) + + content = ''.join(random.choices(string.ascii_uppercase + string.digits, + k=num_chars)) + content_bytes = content.encode('utf-8') + content_size = len(content_bytes) + content_md5 = hashlib.md5(content_bytes).hexdigest() + + file.set(content) + + response_dict = { + 'num_chars': num_chars, + 'content_size': content_size, + 'content_md5': content_md5 + } + + response_body = json.dumps(response_dict, indent=2) + + return azf.HttpResponse( + body=response_body, + mimetype="application/json", + status_code=200 + ) diff --git a/SyncPutGetMultipleBlobsAsBytesReturnHttpResponse/function.json b/SyncPutGetMultipleBlobsAsBytesReturnHttpResponse/function.json new file mode 100644 index 0000000..a4b251c --- /dev/null +++ b/SyncPutGetMultipleBlobsAsBytesReturnHttpResponse/function.json @@ -0,0 +1,52 @@ +{ + "scriptFile": "main.py", + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "get", + "post" + ] + }, + { + "type": "blob", + "direction": "in", + "name": "inputfile1", + "dataType": "binary", + "connection": "AzureWebJobsStorage", + "path": "python-worker-perf-tests/{infile1}" + }, + { + "type": "blob", + "direction": "in", + "name": "inputfile2", + "dataType": "binary", + "connection": "AzureWebJobsStorage", + "path": "python-worker-perf-tests/{infile2}" + }, + { + "type": "blob", + "direction": "out", + "name": "outputfile1", + "dataType": "binary", + "connection": "AzureWebJobsStorage", + "path": "python-worker-perf-tests/{outfile1}" + }, + { + "type": "blob", + "direction": "out", + "name": "outputfile2", + "dataType": "binary", + "connection": "AzureWebJobsStorage", + "path": "python-worker-perf-tests/{outfile2}" + }, + { + "type": "http", + "direction": "out", + "name": "$return" + } + ] +} diff --git a/SyncPutGetMultipleBlobsAsBytesReturnHttpResponse/main.py b/SyncPutGetMultipleBlobsAsBytesReturnHttpResponse/main.py new file mode 100644 index 0000000..abb87fb --- /dev/null +++ b/SyncPutGetMultipleBlobsAsBytesReturnHttpResponse/main.py @@ -0,0 +1,63 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import random +import json +import hashlib +import azure.functions as azf + + +def _generate_content_and_digest(content_size): + content = bytearray(random.getrandbits(8) for _ in range(content_size)) + content_md5 = hashlib.md5(content).hexdigest() + return content, content_md5 + + +def main( + req: azf.HttpRequest, + inputfile1: bytes, + inputfile2: bytes, + outputfile1: azf.Out[bytes], + outputfile2: azf.Out[bytes]) -> azf.HttpResponse: + """ + Read two blobs (bytes) and respond back (in HTTP response) with the number + of bytes read from each blob and the MD5 digest of the content of each. + Write two blobs (bytes) and respond back (in HTTP response) with the number + bytes written in each blob and the MD5 digest of the content of each. + The number of bytes to write are specified in the input HTTP request. + """ + input_content_size_1 = len(inputfile1) + input_content_size_2 = len(inputfile2) + + input_content_md5_1 = hashlib.md5(inputfile1).hexdigest() + input_content_md5_2 = hashlib.md5(inputfile2).hexdigest() + + output_content_size_1 = int(req.params['output_content_size_1']) + output_content_size_2 = int(req.params['output_content_size_2']) + + output_content_1, output_content_md5_1 = \ + _generate_content_and_digest(output_content_size_1) + output_content_2, output_content_md5_2 = \ + _generate_content_and_digest(output_content_size_2) + + outputfile1.set(output_content_1) + outputfile2.set(output_content_2) + + response_dict = { + 'input_content_size_1': input_content_size_1, + 'input_content_size_2': input_content_size_2, + 'input_content_md5_1': input_content_md5_1, + 'input_content_md5_2': input_content_md5_2, + 'output_content_size_1': output_content_size_1, + 'output_content_size_2': output_content_size_2, + 'output_content_md5_1': output_content_md5_1, + 'output_content_md5_2': output_content_md5_2 + } + + response_body = json.dumps(response_dict, indent=2) + + return azf.HttpResponse( + body=response_body, + mimetype="application/json", + status_code=200 + )