Skip to content

Latest commit

 

History

History
498 lines (373 loc) · 19.2 KB

functions-bindings-storage-blob-output.md

File metadata and controls

498 lines (373 loc) · 19.2 KB
title description ms.topic ms.date ms.devlang ms.custom zone_pivot_groups
Azure Blob storage output binding for Azure Functions
Learn how to provide Azure Blob storage output binding data to an Azure Function.
reference
03/02/2023
csharp, java, javascript, powershell, python
devx-track-csharp, devx-track-python, ignite-2022, devx-track-extended-java, devx-track-js
programming-languages-set-functions-lang-workers

Azure Blob storage output binding for Azure Functions

The output binding allows you to modify and delete blob storage data in an Azure Function.

For information on setup and configuration details, see the overview.

::: zone pivot="programming-language-python" Azure Functions supports two programming models for Python. The way that you define your bindings depends on your chosen programming model.

The Python v2 programming model lets you define bindings using decorators directly in your Python function code. For more information, see the Python developer guide.

The Python v1 programming model requires you to define bindings in a separate function.json file in the function folder. For more information, see the Python developer guide.


This article supports both programming models.

Important

The Python v2 programming model is currently in preview. ::: zone-end

Example

::: zone pivot="programming-language-csharp"

[!INCLUDE functions-bindings-csharp-intro]

The following example is a C# function that runs in-process and uses a blob trigger and two output blob bindings. The function is triggered by the creation of an image blob in the sample-images container. It creates small and medium size copies of the image blob.

using System.Collections.Generic;
using System.IO;
using Microsoft.Azure.WebJobs;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;

public class ResizeImages
{
    [FunctionName("ResizeImage")]
    public static void Run([BlobTrigger("sample-images/{name}")] Stream image,
        [Blob("sample-images-sm/{name}", FileAccess.Write)] Stream imageSmall,
        [Blob("sample-images-md/{name}", FileAccess.Write)] Stream imageMedium)
    {
        IImageFormat format;

        using (Image<Rgba32> input = Image.Load<Rgba32>(image, out format))
        {
            ResizeImage(input, imageSmall, ImageSize.Small, format);
        }

        image.Position = 0;
        using (Image<Rgba32> input = Image.Load<Rgba32>(image, out format))
        {
            ResizeImage(input, imageMedium, ImageSize.Medium, format);
        }
    }

    public static void ResizeImage(Image<Rgba32> input, Stream output, ImageSize size, IImageFormat format)
    {
        var dimensions = imageDimensionsTable[size];

        input.Mutate(x => x.Resize(dimensions.Item1, dimensions.Item2));
        input.Save(output, format);
    }

    public enum ImageSize { ExtraSmall, Small, Medium }

    private static Dictionary<ImageSize, (int, int)> imageDimensionsTable = new Dictionary<ImageSize, (int, int)>() {
        { ImageSize.ExtraSmall, (320, 200) },
        { ImageSize.Small,      (640, 400) },
        { ImageSize.Medium,     (800, 600) }
    };

}

The following example is a C# function that runs in an isolated worker process and uses a blob trigger with both blob input and blob output blob bindings. The function is triggered by the creation of a blob in the test-samples-trigger container. It reads a text file from the test-samples-input container and creates a new text file in an output container based on the name of the triggered file.

:::code language="csharp" source="~/azure-functions-dotnet-worker/samples/Extensions/Blob/BlobFunction.cs" range="4-26":::


::: zone-end ::: zone pivot="programming-language-java"

This section contains the following examples:

HTTP trigger, using OutputBinding (Java)

The following example shows a Java function that uses the HttpTrigger annotation to receive a parameter containing the name of a file in a blob storage container. The BlobInput annotation then reads the file and passes its contents to the function as a byte[]. The BlobOutput annotation binds to OutputBinding outputItem, which is then used by the function to write the contents of the input blob to the configured storage container.

  @FunctionName("copyBlobHttp")
  @StorageAccount("Storage_Account_Connection_String")
  public HttpResponseMessage copyBlobHttp(
    @HttpTrigger(name = "req", 
      methods = {HttpMethod.GET}, 
      authLevel = AuthorizationLevel.ANONYMOUS) 
    HttpRequestMessage<Optional<String>> request,
    @BlobInput(
      name = "file", 
      dataType = "binary", 
      path = "samples-workitems/{Query.file}") 
    byte[] content,
    @BlobOutput(
      name = "target", 
      path = "myblob/{Query.file}-CopyViaHttp")
    OutputBinding<String> outputItem,
    final ExecutionContext context) {
      // Save blob to outputItem
      outputItem.setValue(new String(content, StandardCharsets.UTF_8));

      // build HTTP response with size of requested blob
      return request.createResponseBuilder(HttpStatus.OK)
        .body("The size of \"" + request.getQueryParameters().get("file") + "\" is: " + content.length + " bytes")
        .build();
  }

Queue trigger, using function return value (Java)

The following example shows a Java function that uses the QueueTrigger annotation to receive a message containing the name of a file in a blob storage container. The BlobInput annotation then reads the file and passes its contents to the function as a byte[]. The BlobOutput annotation binds to the function return value, which is then used by the runtime to write the contents of the input blob to the configured storage container.

  @FunctionName("copyBlobQueueTrigger")
  @StorageAccount("Storage_Account_Connection_String")
  @BlobOutput(
    name = "target", 
    path = "myblob/{queueTrigger}-Copy")
  public String copyBlobQueue(
    @QueueTrigger(
      name = "filename", 
      dataType = "string",
      queueName = "myqueue-items") 
    String filename,
    @BlobInput(
      name = "file", 
      path = "samples-workitems/{queueTrigger}") 
    String content,
    final ExecutionContext context) {
      context.getLogger().info("The content of \"" + filename + "\" is: " + content);
      return content;
  }

In the Java functions runtime library, use the @BlobOutput annotation on function parameters whose value would be written to an object in blob storage. The parameter type should be OutputBinding<T>, where T is any native Java type or a POJO.

::: zone-end
::: zone pivot="programming-language-javascript"

The following example shows blob input and output bindings in a function.json file and JavaScript code that uses the bindings. The function makes a copy of a blob. The function is triggered by a queue message that contains the name of the blob to copy. The new blob is named {originalblobname}-Copy.

In the function.json file, the queueTrigger metadata property is used to specify the blob name in the path properties:

{
  "bindings": [
    {
      "queueName": "myqueue-items",
      "connection": "MyStorageConnectionAppSetting",
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in"
    },
    {
      "name": "myInputBlob",
      "type": "blob",
      "path": "samples-workitems/{queueTrigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "in"
    },
    {
      "name": "myOutputBlob",
      "type": "blob",
      "path": "samples-workitems/{queueTrigger}-Copy",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "out"
    }
  ],
  "disabled": false
}

The configuration section explains these properties.

Here's the JavaScript code:

module.exports = async function(context) {
    context.log('Node.js Queue trigger function processed', context.bindings.myQueueItem);
    context.bindings.myOutputBlob = context.bindings.myInputBlob;
};

::: zone-end
::: zone pivot="programming-language-powershell"

The following example demonstrates how to create a copy of an incoming blob as the output from a PowerShell function.

In the function's configuration file (function.json), the trigger metadata property is used to specify the output blob name in the path properties.

Note

To avoid infinite loops, make sure your input and output paths are different.

{
  "bindings": [
    {
      "name": "myInputBlob",
      "path": "data/{trigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "in",
      "type": "blobTrigger"
    },
    {
      "name": "myOutputBlob",
      "type": "blob",
      "path": "data/copy/{trigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "out"
    }
  ],
  "disabled": false
}

Here's the PowerShell code:

# Input bindings are passed in via param block.
param([byte[]] $myInputBlob, $TriggerMetadata)
Write-Host "PowerShell Blob trigger function Processed blob Name: $($TriggerMetadata.Name)"
Push-OutputBinding -Name myOutputBlob -Value $myInputBlob

::: zone-end
::: zone pivot="programming-language-python"

The following example shows blob input and output bindings. The example depends on whether you use the v1 or v2 Python programming model.

The code creates a copy of a blob.

import logging
import azure.functions as func

app = func.FunctionApp()

@app.function_name(name="BlobOutput1")
@app.route(route="file")
@app.blob_input(arg_name="inputblob",
                path="sample-workitems/test.txt",
                connection="<BLOB_CONNECTION_SETTING>")
@app.blob_output(arg_name="outputblob",
                path="newblob/test.txt",
                connection="<BLOB_CONNECTION_SETTING>")
def main(req: func.HttpRequest, inputblob: str, outputblob: func.Out[str]):
    logging.info(f'Python Queue trigger function processed {len(inputblob)} bytes')
    outputblob.set(inputblob)
    return "ok"

The function makes a copy of a blob. The function is triggered by a queue message that contains the name of the blob to copy. The new blob is named {originalblobname}-Copy.

In the function.json file, the queueTrigger metadata property is used to specify the blob name in the path properties:

{
  "bindings": [
    {
      "queueName": "myqueue-items",
      "connection": "MyStorageConnectionAppSetting",
      "name": "queuemsg",
      "type": "queueTrigger",
      "direction": "in"
    },
    {
      "name": "inputblob",
      "type": "blob",
      "dataType": "binary",
      "path": "samples-workitems/{queueTrigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "in"
    },
    {
      "name": "outputblob",
      "type": "blob",
      "dataType": "binary",
      "path": "samples-workitems/{queueTrigger}-Copy",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "out"
    }
  ],
  "disabled": false,
  "scriptFile": "__init__.py"
}

The configuration section explains these properties.

Here's the Python code:

import logging
import azure.functions as func


def main(queuemsg: func.QueueMessage, inputblob: bytes, outputblob: func.Out[bytes]):
    logging.info(f'Python Queue trigger function processed {len(inputblob)} bytes')
    outputblob.set(inputblob)

::: zone-end
::: zone pivot="programming-language-csharp"

Attributes

Both in-process and isolated worker process C# libraries use attribute to define the function. C# script instead uses a function.json configuration file as described in the C# scripting guide.

The BlobAttribute attribute's constructor takes the following parameters:

Parameter Description
BlobPath The path to the blob.
Connection The name of an app setting or setting collection that specifies how to connect to Azure Blobs. See Connections.
Access Indicates whether you will be reading or writing.

The following example sets the path to the blob and a FileAccess parameter indicating write for an output binding:

[FunctionName("ResizeImage")]
public static void Run(
    [BlobTrigger("sample-images/{name}")] Stream image,
    [Blob("sample-images-md/{name}", FileAccess.Write)] Stream imageSmall)
{
    ...
}

[!INCLUDE functions-bindings-storage-attribute]

The BlobOutputAttribute constructor takes the following parameters:

Parameter Description
BlobPath The path to the blob.
Connection The name of an app setting or setting collection that specifies how to connect to Azure Blobs. See Connections.

[!INCLUDE app settings to local.settings.json]

::: zone-end
::: zone pivot="programming-language-python"

Decorators

Applies only to the Python v2 programming model.

For Python v2 functions defined using decorators, the following properties on the blob_input and blob_output decorators define the Blob Storage triggers:

Property Description
arg_name The name of the variable that represents the blob in function code.
path The path to the blob For the blob_input decorator, it's the blob read. For the blob_output decorator, it's the output or copy of the input blob.
connection The storage account connection string.
dataType For dynamically typed languages, specifies the underlying data type. Possible values are string, binary, or stream. For more detail, refer to the triggers and bindings concepts.

For Python functions defined by using function.json, see the Configuration section. ::: zone-end

::: zone pivot="programming-language-java"

Annotations

The @BlobOutput attribute gives you access to the blob that triggered the function. If you use a byte array with the attribute, set dataType to binary. Refer to the output example for details. ::: zone-end
::: zone pivot="programming-language-javascript,programming-language-powershell,programming-language-python"

Configuration

::: zone-end

::: zone pivot="programming-language-python" Applies only to the Python v1 programming model.

::: zone-end ::: zone pivot="programming-language-javascript,programming-language-powershell,programming-language-python"

The following table explains the binding configuration properties that you set in the function.json file.

function.json property Attribute property Description
type Must be set to blob.
direction Must be set to out for an output binding. Exceptions are noted in the usage section.
name The name of the variable that represents the blob in function code. Set to $return to reference the function return value.
path The path to the blob container.
connection The name of an app setting or setting collection that specifies how to connect to Azure Blobs. See Connections.

::: zone-end

See the Example section for complete examples.

Usage

::: zone pivot="programming-language-csharp"

The binding types supported by blob output depend on the extension package version and the C# modality used in your function app.

See Binding types for a list of supported types.

[!INCLUDE functions-bindings-storage-blob-output-dotnet-isolated-types]


Binding to string, or Byte[] is only recommended when the blob size is small. This is recommended because the entire blob contents are loaded into memory. For most blobs, use a Stream or BlobClient type. For more information, see Concurrency and memory usage.

If you get an error message when trying to bind to one of the Storage SDK types, make sure that you have a reference to the correct Storage SDK version.

[!INCLUDE functions-bindings-blob-storage-attribute] ::: zone-end

::: zone pivot="programming-language-java"

The @BlobOutput attribute gives you access to the blob that triggered the function. If you use a byte array with the attribute, set dataType to binary. Refer to the output example for details.

::: zone-end
::: zone pivot="programming-language-javascript"

Access the blob data using context.bindings.<BINDING_NAME>, where the binding name is defined in the function.json file.

::: zone-end
::: zone pivot="programming-language-powershell"

Access the blob data via a parameter that matches the name designated by binding's name parameter in the function.json file.

::: zone-end
::: zone pivot="programming-language-python"

You can declare function parameters as the following types to write out to blob storage:

  • Strings as func.Out[str]
  • Streams as func.Out[func.InputStream]

Refer to the output example for details.

::: zone-end

[!INCLUDE functions-storage-blob-connections]

Exceptions and return codes

Binding Reference
Blob Blob Error Codes
Blob, Table, Queue Storage Error Codes
Blob, Table, Queue Troubleshooting

Next steps