0

I have a blob container and two folders in it.(inputs,outputs)When an excel file is placed in the input folder I want to trigger the function and after compiling the code I want to place the output excel file in the folder named 'outputs'.I'm using python.

I have used input binding to trigger the function.After compiling the code I've done output binding to place the newly created file into output folder.But, it's not happening.

I'm doing this locally using Azure storage emulator and Azure storage explorer.

This is my function.json file.

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "inputblob",
      "type": "blobTrigger",
      "direction": "in",
      "path": "cloudops-resources/inputs/{name}",
      "connection": "AzureWebJobsStorage"
    },
    {
    "name": "outputblob",
    "type": "blob",
    "direction": "out",
    "path": "cloudops-resources/outputs/{name}",
    "connection": "AzureWebJobsStorage"
    }
  ],
  "disabled": false
}

This is my local.settings.json file.

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "AzureWebJobs.my_function.Disabled": "true"
  }
}

I tried using this code.

This is my init.py


def main(inputblob: func.InputStream, outputblob: func.Out[func.InputStream]):
    logging.info(f"Python blob trigger function processed blob \n"
                 f"Name: {inputblob.name}\n"
                 f"Blob Size: {inputblob.length} bytes")

.
.#some code here
.
.

#Reading the input xlsx file from customer
    df0 = pd.read_excel(inputblob)

    #Opening a new workbook and a worksheet
    wb = Workbook()
    sheet = wb.active

.
.#some code here
.

  #Saving the file
    today = date.today()
    date_today = today.strftime("%m-%d-%y")
    outputblob = "{}_COMPLETE_{}.xlsx".format(date_today,inputblob)
    wb.save(outputblob)
    return func.Out[func.InputStream](
         body=outputblob,
         status_code=200
    )

I referred to these as well.

https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-python?tabs=asgi%2Capplication-level&pivots=python-mode-configuration#outputs:~:text=account%20guidance.-,Outputs,-Output%20can%20be

https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob-output?tabs=in-process&pivots=programming-language-python#:~:text=Here%27s%20the%20Python%20code%3A

Can someone please help me to resolve this issue?

PS: My edited code.

init.py

def main(inputblob: func.InputStream, outputblob: 
func.Out[func.InputStream]):
logging.info(f"Python blob trigger function processed blob \n"
             f"Name: {inputblob.name}\n"
             f"file: {inputblob}\n"
             f"Blob Size: {inputblob.length} bytes")

...some code here...

df0 = pd.read_excel(inputblob.read())
logging.info(f"{df0}")

#Opening a new workbook and a worksheet
wb = Workbook()
sheet = wb.active

...some code here...

#Saving the file
today = date.today()
date_today = today.strftime("%m-%d-%y")
outputfile = "{}_COMPLETE_{}".format(date_today,inputblob.name)
wb.save(outputfile)

outputblob.set(wb)
logging.info(f"Name: {outputblob.name}\n"
             f"file: {outputblob}\n"
             f"Blob Size: {outputblob.length} bytes")

return()

This doesn't place the output file in the output container and giving an error as well.

System.Private.CoreLib: Exception while executing function: Functions.BlobTrigger. System.Private.CoreLib: Result: Failure Exception: FileNotFoundError: [Errno 2] No such file or directory: '03-29-23_COMPLETE_cloudops-resources/inputs/Input_file123.xlsx' Stack: File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.9/WINDOWS/X64\azure_functions_worker\dispatcher.py", line 452, in _handle__invocation_request call_result = await self._loop.run_in_executor( File "C:\Users\Asu\AppData\Local\Programs\Python\Python39\lib\concurrent\futures\thread.py", line 58, in run result = self.fn(*self.args, **self.kwargs) File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.9/WINDOWS/X64\azure_functions_worker\dispatcher.py", line 718, in _run_sync_func
return ExtensionManager.get_sync_invocation_wrapper(context, File "C:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.9/WINDOWS/X64\azure_functions_worker\extension.py", line 215, in raw_invocation_wrapper result = function(**args) File "D:\Service Projects\Customers\InvoiceCompare\BlobTrigger_init.py", line 360, in main wb.save(outputfile) File "D:\Service Projects\Customers\InvoiceCompare\env\lib\site-packages\openpyxl\workbook\workbook.py", line 386, in save save_workbook(self, filename) File "D:\Service Projects-1\Customers\InvoiceCompare\env\lib\site-packages\openpyxl\writer\excel.py", line 291, in save_workbook archive = ZipFile(filename, 'w', ZIP_DEFLATED, allowZip64=True) File "C:\Users\Asu\AppData\Local\Programs\Python\Python39\lib\zipfile.py", line 1246, in init self.fp = io.open(file, filemode) .

Asu
  • 7
  • 4

1 Answers1

0

I followed the steps below and got the desired results:-

My init.py code:-

import  logging

  

import  openpyxl

  

import  azure.functions  as  func

  
  

def  main(myblob: func.InputStream, outputBlob: func.Out[func.InputStream], context: func.Context):

logging.info(f"Python blob trigger function processed blob \n"

f"Name: {myblob.name}\n"

f"Blob Size: {myblob.length} bytes")

# wb = openpyxl.load_workbook(myblob)

# sheet = wb.active

  

outputBlob.set(myblob)

logging.info(f"Excel file has been copied to the output container.")

I did not use any openpyxl code, But directly uploaded the file in the outputBlob.

My function.json file:-

{

"scriptFile": "__init__.py",

"bindings": [

{

"name": "myblob",

"type": "blobTrigger",

"direction": "in",

"path": "strg65/{name}",

"connection": "sidstrg54_STORAGE"

},

{

"type": "blob",

"direction": "out",

"name": "outputBlob",

"path": "strg66/{name}",

"connection": "sidstrg54_STORAGE"

}

]

}

I used {name} for both input and output blob storage binding in my function.json so the file with excel extension gets copied with same name without getting corrupted in the output container.

My local.settings.json containg azure blob storage connection string:-

{

"IsEncrypted": false,

"Values": {

"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=<storage-account>;AccountKey=<account-key>;EndpointSuffix=core.windows.net",

"FUNCTIONS_WORKER_RUNTIME": "python",

"sidstrg54_STORAGE": "DefaultEndpointsProtocol=https;AccountName=<storage-account>;AccountKey=<account-key>;EndpointSuffix=core.windows.net"

}

}

Output:-

enter image description here

File got copied to outputBlob container like below:-

enter image description here

Downloaded the copied blob and the content was visible:-

enter image description here

SiddheshDesai
  • 3,668
  • 1
  • 2
  • 11
  • thank you. But I don't want to just copy the input blob to output container.I'm reading it and creating a new excel file and then doing some processing(comparing stuff) and then I want to place the new excel file in the output container. I'll include my edited code in the question – Asu Mar 29 '23 at 10:51
  • If u have any idea on how to do that please help – Asu Mar 29 '23 at 11:11
  • Did you upload the complete code, Cause I see ..some code here? – SiddheshDesai Mar 29 '23 at 11:13
  • I think if I can convert the workbook object into an output stream I can solve the problem.Do u know how to do that? I've asked the question here. https://stackoverflow.com/questions/75884956/how-to-convert-a-workbook-object-into-an-output-stream-in-python – Asu Mar 30 '23 at 06:58