Sdílet prostřednictvím


Přenesení závislostí nebo knihovny třetích stran do Azure Functions

V tomto článku se dozvíte, jak do aplikací funkcí vnést závislosti třetích stran. Příklady závislostí třetích stran jsou soubory JSON, binární soubory a modely strojového učení.

V tomto článku získáte informace o těchto tématech:

  • Přenesení závislostí prostřednictvím projektu Kódu služby Functions
  • Přenesení závislostí prostřednictvím připojení sdílené složky Azure

Přenesení závislostí z adresáře projektu

Jedním z nejjednodušších způsobů, jak přenést závislosti, je dát soubory nebo artefakty dohromady s kódem aplikace funkcí v adresářové struktuře projektu Functions. Tady je příklad ukázek adresářů v projektu funkcí Pythonu:

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

Umístěním závislostí do složky v adresáři projektu aplikace funkcí se složka dependencies nasadí společně s kódem. V důsledku toho může kód funkce přistupovat k závislostem v cloudu prostřednictvím rozhraní API systému souborů.

Přístup k závislostem v kódu

Tady je příklad přístupu a spouštění ffmpeg závislostí, které se vloží do <project_root>/ffmpeg_lib adresáře.

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)

Poznámka

Možná budete muset použít k poskytnutí Execute práv ke binárnímu souboru ffmpeg v prostředí Linuxu.chmod

Jedním z nejjednodušších způsobů, jak zahrnout závislosti, je dát soubory nebo artefakty dohromady s kódem aplikace funkcí v adresářové struktuře projektu funkcí. Tady je příklad ukázek adresářů v projektu Funkcí v Javě:

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

Konkrétně pro Javu musíte při kopírování prostředků konkrétně zahrnout artefakty do složky sestavení nebo cíle. Tady je příklad, jak to udělat v Mavenu:

...
<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>
...

Umístěním závislostí do složky v adresáři projektu aplikace funkcí se složka dependencies nasadí společně s kódem. V důsledku toho může kód funkce přistupovat k závislostem v cloudu prostřednictvím rozhraní API systému souborů.

Přístup k závislostem v kódu

Tady je příklad přístupu a spouštění ffmpeg závislostí, které se vloží do <project_root>/ffmpeg_lib adresáře.

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();

    }

Poznámka

Aby tento fragment kódu fungoval v Azure, musíte zadat vlastní nastavení aplikace BASE_PATH s hodnotou /home/site/wwwroot.

Přenesení závislostí připojením sdílené složky

Při spuštění aplikace funkcí v Linuxu existuje jiný způsob, jak zavést závislosti třetích stran. Funkce umožňují připojit sdílenou složku hostované v Azure Files. Tento přístup zvažte, když chcete oddělit závislosti nebo artefakty od kódu aplikace.

Nejprve musíte vytvořit účet úložiště Azure. V účtu musíte také vytvořit sdílenou složku v Azure Files. Pokud chcete tyto prostředky vytvořit, postupujte podle tohoto průvodce.

Po vytvoření účtu úložiště a sdílené složky připojte sdílenou složku k aplikaci Functions pomocí příkazu az webapp config storage-account add , jak je znázorněno v následujícím příkladu.

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>
Příznak Hodnota
vlastní ID Libovolný jedinečný řetězec
typ úložiště V současné době se podporují pouze soubory AzureFiles.
název sdílené složky Existující sdílená složka
mount-path Cesta, při které bude sdílená složka přístupná uvnitř kontejneru Hodnota musí být ve formátu /dir-name a nemůže začínat na /home

Další příkazy pro úpravu nebo odstranění konfigurace sdílené složky najdete tady.

Nahrání závislostí do Azure Files

Jednou z možností, jak nahrát závislost do Azure Files, je Azure Portal. Pokyny k nahrání závislostí pomocí portálu najdete v tomto průvodci . Další možnosti, jak nahrát závislosti do Azure Files, jsou prostřednictvím Azure CLI a PowerShellu.

Přístup k závislostem v kódu

Po nahrání závislostí do sdílené složky můžete k závislostem přistupovat ze svého kódu. Připojená sdílená složka je k dispozici v zadané cestě připojení, například /path/to/mount. K cílovému adresáři můžete přistupovat pomocí rozhraní API systému souborů.

Následující příklad ukazuje kód triggeru HTTP, který přistupuje ke ffmpeg knihovně, která je uložená v připojené sdílené složce.

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)

Když tento kód nasadíte do aplikace funkcí v Azure, musíte vytvořit nastavení aplikace s názvem FILE_SHARE_MOUNT_PATH klíče a hodnotou cesty připojené sdílené složky, což je /azure-files-sharev tomto příkladu . Pokud chcete provést místní ladění, musíte FILE_SHARE_MOUNT_PATH naplnit cestu k souboru, kde jsou vaše závislosti uložené v místním počítači. Tady je příklad nastavení FILE_SHARE_MOUNT_PATH pomocí local.settings.json:

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

Další kroky