How do i create an Azure function w. a blob triggered python function, from an Azure function

Mikkel Skræddergaard 0 Reputation points
2024-08-20T06:28:20.99+00:00

I am trying to automate the creation of a new Azure resource group, with storage and Azure function, from an admin Azure function. So whenever i get a new customer, i want to send a http request, with a company name, to my admin function, which in turn should create a new resource group with storage and blob trigger function.

So far i am able to send the http request, create all the resources and trigger the blob triggered function when i upload a file. I have had a bunch of problems uploading my python script, but have ended up adding it as a file property, as raw text.

Here is the arm template i use to deploy the storage and function:

@description('Name of the company')
param companyName string

@description('Location for the resources')
param location string = resourceGroup().location

@description('Name of the storage account')
param storageAccountName string = '${uniqueString(companyName)}stacc'

@description('Name of the function app')
param functionAppName string = '${uniqueString(companyName)}funcApp'

var containerName = 'funcfiles'

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}

resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2023-01-01' = {
  parent: storageAccount
  name: 'default'
}

resource container 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {
  parent: blobServices
  name: containerName
}

resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: '${functionAppName}-plan'
  location: location
  kind: 'Linux'
  sku: {
    name: 'Y1'
    tier: 'Dynamic'
    size: 'Y1'
    family: 'Y'
    capacity: 0
  }
  properties: {
    reserved: true
  } 
}

resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
  name: functionAppName
  location: location
  kind: 'functionapp,linux'
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      pythonVersion: '3.10'
      linuxFxVersion: 'python|3.10'
      appSettings: [
        {
          name: 'AzureWebJobsStorage'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${storageAccount.listKeys().keys[0].value}'
        }
        {
          name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${storageAccount.listKeys().keys[0].value}'
        }
        {
          name: 'WEBSITE_CONTENTSHARE'
          value: toLower(functionAppName)
        }
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'python'
        }
        {
          name: 'AzureWebJobsFeatureFlags'
          value: 'EnableWorkerIndexing'
        }
      ]
    }
  }
}

resource blobTriggerFunction 'Microsoft.Web/sites/functions@2022-03-01' = {
  parent: functionApp
  name: 'BlobTrigger${functionAppName}'
  properties: {
    config: {
      bindings: [
        {
          name: 'myblob'
          type: 'blobTrigger'
          direction: 'in'
          path: containerName
          connection: 'AzureWebJobsStorage'
        }
      ]
      disabled: false
    }
    files:{
      '__init__.py': '''
import logging
import requests
import azure.functions as func

app = func.FunctionApp()

@app.blob_trigger(arg_name="myblob", path="funcfiles",
                               connection="AzureWebJobsStorage") 
def blob_trigger(myblob: func.InputStream):
    logging.info(f"File {myblob.name} was added to blob")

    API_URL = "****************"

    # use form data to upload files
    form_data = {
        "files": (myblob.name, myblob.read())
    }
    body_data = {
        'returnSourceDocuments': True
    }

    logging.info(f'Form data: {form_data}')
    logging.info(f'Body data: {body_data}')

    def query(form_data):
        response = requests.post(API_URL, files=form_data, data=body_data)
        return response.json()

    output = query(form_data)
    logging.info(f'Request send to api. Output: {output}')
      '''
    }
  }
}

The latest problem, and what I'm hoping to be the last problem, is ModuleNotFoundError. Which leads to my question: How can i add and run requirements.txt?

I did try to add the requirements under files as raw input, like ive done with _init.py, but that didn't work When i create an azure function app with a blob trigger, using the vscode tool, there is a bunch of extra files created and deployed. Here is an example of my admin function:
User's image

And here is the function made with the above bicep file:

User's image

The BobTigger is made manually in Azure Portal for comparison.

I want to add a requirement.txt, so i can use requests or other modules. Is this possible?

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,856 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.