Reputation: 469
I want to upload JSON data as a .json file to Azure storage blobs using Azure Functions in Python.
Because I am using Azure Functions and not an actual server, I do not want to (and probably cannot) create a temporary file in local memory and upload that file to Azure blob storage using the Azure Blob storage client library v2.1 for Python (reference link here). Therefore, I want to use output blob storage bindings for Azure Functions (reference link here).
I am testing this out in an Azure Functions with an HTTP Trigger. I take in an Azure blob through an input blob storage binding (which is working just fine), process it, and update it by uploading a new Azure blob that overrides it (which is what I need help with). My function.json file looks like this:
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"name": "inputblob",
"type": "blob",
"path": "{containerName}/{blobName}.json",
"connection": "MyStorageConnectionAppSetting",
"direction": "in"
},
{
"name": "outputblob",
"type": "blob",
"path": "{containerName}/{blobName}.json",
"connection": "MyStorageConnectionAppSetting",
"direction": "out"
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
And my Python code looks like this:
import logging
import azure.functions as func
import azure.storage.blob
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient
import json, os
def main(req: func.HttpRequest, inputblob: func.InputStream, outputblob: func.Out[func.InputStream]) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
# Initialize variable for tracking any changes
anyChanges= False
# Read JSON file
jsonData= json.loads(inputblob.read())
# Make changes to jsonData (omitted for simplicity) and update anyChanges
# Upload new JSON file
if anyChanges:
outputblob.set(jsonData)
return func.HttpResponse(f"Input data: {jsonData}. Any changes: {anyChanges}.")
However, this isn't working at all, with the following error being thrown (screenshot):
Value 'func.Out' is unsubscriptable
What am I missing?
Upvotes: 1
Views: 11980
Reputation: 26314
You want bytes
or str
, not InputStream
, like this:
def main(inputblob: func.InputStream, outputblob: func.Out[bytes], context: func.Context):
...
# Write to output blob
outputblob.set(jsonData)
InputStream
represents an input blob.
See this sample for str
and this one for bytes
.
Later update:
The call to json.loads()
returns a dictionary and for some reason outputblob.set()
freaks out and needs some handholding, like this:
def main(req: func.HttpRequest,
inputblob: func.InputStream,
outputblob: func.Out[bytes]) -> func.HttpResponse:
jsonData = json.loads(inputblob.read())
outputblob.set(str(jsonData))
return func.HttpResponse(f"Input JSON: {jsonData}")
That should work (well it works on func
version
2.7.1948
at least).
Upvotes: 2