Azure / Azure/azure-functions-host

Python (V2) blob output-bindings get created but stay empty

Open
#9,680 2 comments 0 reactions 1 assignee Claimed by @bhagyshricompany View on GitHub
needs-investigation
Dominant language
C#
Stars
2k
Forks
482
Avg merge
2d 12h
Merged PRs (30d)
38

Description

When using multiple `blob_output` decorators to create blob output bindings for a Python Function (V2) the blobs are created, but no data is uploaded and the blobs stay empty.

#### Repro steps

1. create app service plan from Premium V3
- e.g. pricing plan: P0V3
1. create function app (and implicit config storage account)
- deployment: code
- runtime stack: Python
- Version: 3.10
- OS: Linux
1. create separate storage account for output
- performance: standard
- redundancy: GRS
- Hierarchical Namespace: yes
1. create container in output storage account
1. create SAS token for output storage account and set it as env variable in function app

1. create function using func core tools (version 4.0.5441)
- e.g. `func init demofunc --python -m V2`
1. add code (see snippet below)
1. deploy code to function app
1. generate load to function (causing it to output blobs)

#### Expected behavior

All blobs are written correctly using output bindings, i.e. none of them are empty after the function returned successfully.

#### Actual behavior

Some blobs stay empty when using blob_output binding, e.g. when running 2048 calls (supposed to generate 4096 blobs) between 15-25 remain empty, even though the function returned successfully every time. (HTTP status-code 200 in this case).

#### Known workarounds

Use a library to write to the blob storage instead of an output binding. Tested with `azure-storage-file-datalake`.
Also it seems that changing the application plan to Premium V2 (e.g. P1V2) solves the problem.

#### Related information

Provide any related information

* Programming language used: Python (V2)
* source: see below
* Bindings used: blob output binding

Source

```python
import logging
import random

import azure.functions as func

BLOB_SIZE = 32 * 1024

app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)

@app.route(route="use_binding")
@app.blob_output(
arg_name="blob01",
path="output/binding/{rand-guid}.dat",
connection="outputBlobStorage",
)
@app.blob_output(
arg_name="blob02",
path="output/binding/{rand-guid}.dat",
connection="outputBlobStorage",
)
async def write_blobs_with_binding(
req: func.HttpRequest,
blob01: func.Out[str],
blob02: func.Out[str],
) -> func.HttpResponse:
try:
blob01.set(random.randbytes(BLOB_SIZE))
blob02.set(random.randbytes(BLOB_SIZE))
except Exception as e:
logging.exception(e)
return func.HttpResponse(f"EXCEPTION: {e}", status_code=500)

return func.HttpResponse("OK", status_code=200)

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.