Reputation: 11
I am trying to use Azure Functions to wrap an application using Form-Recognizer written in Python. My issue is getting a JPEG using the BlobTrigger into a format that the Form-Recognizer can work with.
The basic code for opening the image is
from PIL import Image
from io import BytesIO
import azure.functions as func
def main(blobin: func.InputStream, blobout: func.Out[bytes], context: func.Context):
image = Image.open(blobin)
The image has class class: 'PIL.JpegImagePlugin.JpegImageFile'.
The code for calling the Form-Recognizer analyze is as follows:
base_url = r"<url>" + "/formrecognizer/v1.0-preview/custom"
model_id = "<model-id>"
headers = {
'Content-Type': 'image/jpeg',
'Ocp-Apim-Subscription-Key': '<subscription-key>',
}
resp = None
try:
url = base_url + "/models/" + model_id + "/analyze"
resp = http_post(url = url, data = image, headers = headers)
print("Response status code: %d" % resp.status_code)
except Exception as e:
print(str(e))
Unfortunately, the data = image in the http_post needs to be class: 'bytes'.
So, I tried various ways using PIL to convert the input image to a byte format.
My two main approaches were
with BytesIO() as output:
with Image.open(input_image) as img:
img.save(output, 'JPEG')
image = output.getvalue()
and
image = Image.open(input_image)
imgByteArr = io.BytesIO()
image.save(imgByteArr, format='JPEG')
imgByteArr = imgByteArr.getvalue()
Both of these approaches give me a byte format, however, it still doesn't work. Either way, I end up with this response:
{'error': {'code': '2018', 'innerError': {'requestId': '8cff8e76-c11a-4893-8b5d-33d11f7e7646'}, 'message': 'Content parsing error.'}}
Does anyone know the right way to approach this problem?
Upvotes: 1
Views: 2666
Reputation: 24138
According to the source code blob.py
for the class func.InputStream
from GitHub repo Azure/azure-functions-python-library
, you can directly get the image bytes from the blobin
variable of func.InputStream
class via its read
function, as the figure below.
Meanwhile, refer to the document Form Recognizer API
, the Content-Type
header should be multipart/form-data
.
So I changed the offical sample code to use in Azure Function as below.
import http.client, urllib.request, urllib.parse, urllib.error, base64
import azure.functions as func
headers = {
# Request headers
'Content-Type': 'multipart/form-data',
'Ocp-Apim-Subscription-Key': '{subscription key}',
}
params = urllib.parse.urlencode({
# Request parameters
'keys': '{string}',
})
def main(blobin: func.InputStream):
body = blobin.read()
try:
conn = http.client.HTTPSConnection('westus2.api.cognitive.microsoft.com')
conn.request("POST", "/formrecognizer/v1.0-preview/custom/models/{id}/analyze?%s" % params, body, headers)
response = conn.getresponse()
data = response.read()
print(data)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
Please don't use any Python 2 functions in Azure Functions which only support Python 3.6.
Upvotes: 1