Delen via


Afhankelijkheden of bibliotheek van derden naar Azure Functions

In dit artikel leert u hoe u afhankelijkheden van derden in uw Functions-apps kunt opnemen. Voorbeelden van afhankelijkheden van derden zijn json-bestanden, binaire bestanden en machine learning-modellen.

In dit artikel leert u het volgende:

  • Afhankelijkheden binnenhalen via het Functions Code-project
  • Afhankelijkheden binnenhalen via koppelen van Azure Fileshare

Afhankelijkheden uit de projectmap binnenhalen

Een van de eenvoudigste manieren om afhankelijkheden in te brengen, is door de bestanden/artefact samen te voegen met de code van de Functions-app in de structuur van de functions-projectmap. Hier volgt een voorbeeld van de mapvoorbeelden in een Python Functions-project:

<project_root>/
 | - my_first_function/
 | | - __init__.py
 | | - function.json
 | | - example.py
 | - dependencies/
 | | - dependency1
 | - .funcignore
 | - host.json
 | - local.settings.json

Door de afhankelijkheden in een map in de projectmap van de Functions-app te plaatsen, wordt de map met afhankelijkheden samen met de code geïmplementeerd. Als gevolg hiervan heeft uw functiecode toegang tot de afhankelijkheden in de cloud via de bestandssysteem-API.

Toegang tot de afhankelijkheden in uw code

Hier volgt een voorbeeld van het openen en uitvoeren ffmpeg van afhankelijkheid die in <project_root>/ffmpeg_lib de map wordt geplaatst.

import logging

import azure.functions as func
import subprocess

FFMPEG_RELATIVE_PATH = "../ffmpeg_lib/ffmpeg"

def main(req: func.HttpRequest,
         context: func.Context) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    command = req.params.get('command')
    # If no command specified, set the command to help
    if not command:
        command = "-h"

    # context.function_directory returns the current directory in which functions is executed 
    ffmpeg_path = "/".join([str(context.function_directory), FFMPEG_RELATIVE_PATH])

    try:
        byte_output  = subprocess.check_output([ffmpeg_path, command])
        return func.HttpResponse(byte_output.decode('UTF-8').rstrip(),status_code=200)
    except Exception as e:
        return func.HttpResponse("Unexpected exception happened when executing ffmpeg. Error message:" + str(e),status_code=200)

Notitie

Mogelijk moet u gebruiken chmod om rechten op te geven Execute voor het binaire bestand ffmpeg in een Linux-omgeving

Een van de eenvoudigste manieren om afhankelijkheden in te brengen, is door de bestanden/het artefact samen te voegen met de code van de functions-app in de mapstructuur van het functions-project. Hier volgt een voorbeeld van de mapvoorbeelden in een Java Functions-project:

<project_root>/
 | - src/
 | | - main/java/com/function
 | | | - Function.java
 | | - test/java/com/function
 | - artifacts/
 | | - dependency1
 | - host.json
 | - local.settings.json
 | - pom.xml

Specifiek voor Java moet u de artefacten specifiek opnemen in de map build/doel bij het kopiëren van resources. Hier volgt een voorbeeld van hoe u dit doet in Maven:

...
<execution>
    <id>copy-resources</id>
    <phase>package</phase>
    <goals>
        <goal>copy-resources</goal>
    </goals>
    <configuration>
        <overwrite>true</overwrite>
        <outputDirectory>${stagingDirectory}</outputDirectory>
        <resources>
            <resource>
                <directory>${project.basedir}</directory>
                <includes>
                    <include>host.json</include>
                    <include>local.settings.json</include>
                    <include>artifacts/**</include>
                </includes>
            </resource>
        </resources>
    </configuration>
</execution>
...

Door de afhankelijkheden in een map in de projectmap van de Functions-app te plaatsen, wordt de map met afhankelijkheden samen met de code geïmplementeerd. Als gevolg hiervan heeft uw functiecode toegang tot de afhankelijkheden in de cloud via de bestandssysteem-API.

Toegang tot de afhankelijkheden in uw code

Hier volgt een voorbeeld van het openen en uitvoeren ffmpeg van afhankelijkheid die in <project_root>/ffmpeg_lib de map wordt geplaatst.

public class Function {
    final static String BASE_PATH = "BASE_PATH";
    final static String FFMPEG_PATH = "/artifacts/ffmpeg/ffmpeg.exe";
    final static String HELP_FLAG = "-h";
    final static String COMMAND_QUERY = "command";

    @FunctionName("HttpExample")
    public HttpResponseMessage run(
            @HttpTrigger(
                name = "req",
                methods = {HttpMethod.GET, HttpMethod.POST},
                authLevel = AuthorizationLevel.ANONYMOUS)
                HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) throws IOException{
        context.getLogger().info("Java HTTP trigger processed a request.");

        // Parse query parameter
        String flags = request.getQueryParameters().get(COMMAND_QUERY);

        if (flags == null || flags.isBlank()) {
            flags = HELP_FLAG;
        }

        Runtime rt = Runtime.getRuntime();
        String[] commands = { System.getenv(BASE_PATH) + FFMPEG_PATH, flags};
        Process proc = rt.exec(commands);

        BufferedReader stdInput = new BufferedReader(new 
        InputStreamReader(proc.getInputStream()));

        String out = stdInput.lines().collect(Collectors.joining("\n"));
        if(out.isEmpty()) {
            BufferedReader stdError = new BufferedReader(new 
                InputStreamReader(proc.getErrorStream()));
            out = stdError.lines().collect(Collectors.joining("\n"));
        }
        return request.createResponseBuilder(HttpStatus.OK).body(out).build();

    }

Notitie

Als u dit codefragment wilt laten werken in Azure, moet u een aangepaste toepassingsinstelling opgeven van 'BASE_PATH' met de waarde '/home/site/wwwroot'

Afhankelijkheden overbrengen door een bestandsshare te koppelen

Wanneer u uw functie-app uitvoert in Linux, is er een andere manier om afhankelijkheden van derden in te voeren. Met Functions kunt u een bestandsshare koppelen die wordt gehost in Azure Files. Overweeg deze benadering wanneer u afhankelijkheden of artefacten wilt loskoppelen van uw toepassingscode.

Eerst moet u een Azure Storage-account maken. In het account moet u ook een bestandsshare maken in Azure Files. Volg deze handleiding om deze resources te maken

Nadat u het opslagaccount en de bestandsshare hebt gemaakt, gebruikt u de opdracht az webapp config storage-account add om de bestandsshare toe te voegen aan uw Functions-app, zoals wordt weergegeven in het volgende voorbeeld.

az webapp config storage-account add \
  --name < Function-App-Name > \
  --resource-group < Resource-Group > \
  --subscription < Subscription-Id > \
  --custom-id < Unique-Custom-Id > \
  --storage-type AzureFiles \
  --account-name < Storage-Account-Name > \
  --share-name < File-Share-Name >  \
  --access-key < Storage-Account-AccessKey > \
  --mount-path </path/to/mount>
Vlag Waarde
custom-id Elke unieke tekenreeks
opslagtype Momenteel wordt alleen AzureFiles ondersteund
share-name Bestaande share
mount-path Pad waarop de share toegankelijk is in de container. De waarde moet de indeling /dir-name hebben en kan niet beginnen met /home

Meer opdrachten voor het wijzigen/verwijderen van de configuratie van de bestandsshare vindt u hier

De afhankelijkheden uploaden naar Azure Files

Een optie voor het uploaden van uw afhankelijkheid naar Azure Files is via Azure Portal. Raadpleeg deze handleiding voor instructies voor het uploaden van afhankelijkheden met behulp van de portal. Andere opties voor het uploaden van uw afhankelijkheden naar Azure Files zijn via Azure CLI en PowerShell.

Toegang tot de afhankelijkheden in uw code

Nadat uw afhankelijkheden zijn geüpload in de bestandsshare, hebt u toegang tot de afhankelijkheden vanuit uw code. De gekoppelde share is beschikbaar op het opgegeven koppelingspad, zoals /path/to/mount. U kunt toegang krijgen tot de doelmap met behulp van bestandssysteem-API's.

In het volgende voorbeeld ziet u HTTP-triggercode die toegang heeft tot de ffmpeg bibliotheek, die is opgeslagen in een gekoppelde bestandsshare.

import logging

import azure.functions as func
import subprocess 

FILE_SHARE_MOUNT_PATH = os.environ['FILE_SHARE_MOUNT_PATH']
FFMPEG = "ffmpeg"

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    command = req.params.get('command')
    # If no command specified, set the command to help
    if not command:
        command = "-h"

    try:
        byte_output  = subprocess.check_output(["/".join(FILE_SHARE_MOUNT_PATH, FFMPEG), command])
        return func.HttpResponse(byte_output.decode('UTF-8').rstrip(),status_code=200)
    except Exception as e:
        return func.HttpResponse("Unexpected exception happened when executing ffmpeg. Error message:" + str(e),status_code=200)

Wanneer u deze code implementeert in een functie-app in Azure, moet u een app-instelling maken met de sleutelnaam FILE_SHARE_MOUNT_PATH en de waarde van het gekoppelde bestandssharepad, in dit voorbeeld ./azure-files-share Als u lokale foutopsporing wilt uitvoeren, moet u het FILE_SHARE_MOUNT_PATH bestandspad invullen waar uw afhankelijkheden zijn opgeslagen op uw lokale computer. Hier volgt een voorbeeld om in te stellen FILE_SHARE_MOUNT_PATH met behulp van local.settings.json:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "FILE_SHARE_MOUNT_PATH" : "PATH_TO_LOCAL_FFMPEG_DIR"
  }
}

Volgende stappen