Bagikan melalui


Membawa dependensi dan pustaka pihak ketiga ke Azure Functions

Dalam artikel ini, Anda belajar untuk memasukkan dependensi pihak ketiga ke dalam aplikasi fungsi Anda. Contoh dependensi pihak ketiga adalah file json, file biner, dan model pembelajaran mesin.

Dalam artikel ini, Anda akan pelajari cara:

  • Memasukkan dependensi melalui proyek Kode Functions
  • Memasukkan dependensi melalui pemasangan Azure Fileshare

Memasukkan dependensi dari direktori proyek

Salah satu cara paling sederhana untuk memasukkan dependensi adalah dengan menyatukan file/artefak dengan kode aplikasi fungsi dalam struktur direktori proyek Functions. Berikut adalah contoh sampel direktori dalam proyek fungsi Python:

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

Dengan menempatkan dependensi dalam folder di dalam direktori proyek aplikasi fungsi, folder dependensi akan diterapkan bersama dengan kode. Akibatnya, kode fungsi dapat mengakses dependensi di cloud melalui api sistem file.

Mengakses dependensi dalam kode

Berikut adalah contoh untuk mengakses dan menjalankan ffmpeg dependensi yang dimasukkan ke dalam <project_root>/ffmpeg_lib direktori.

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)

Catatan

Anda mungkin perlu menggunakan chmod untuk memberikan Execute hak atas biner ffmpeg di lingkungan Linux

Salah satu cara paling sederhana untuk memasukkan dependensi adalah dengan menyatukan file/artefak dengan kode aplikasi fungsi dalam struktur direktori proyek fungsi. Berikut adalah contoh sampel direktori dalam proyek fungsi Java:

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

Khusus Java, Anda perlu secara khusus memasukkan artefak ke dalam folder build/target saat menyalin sumber daya. Berikut adalah contoh cara melakukannya di 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>
...

Dengan menempatkan dependensi dalam folder di dalam direktori proyek aplikasi fungsi, folder dependensi akan diterapkan bersama dengan kode. Akibatnya, kode fungsi dapat mengakses dependensi di cloud melalui api sistem file.

Mengakses dependensi dalam kode

Berikut adalah contoh untuk mengakses dan menjalankan ffmpeg dependensi yang dimasukkan ke dalam <project_root>/ffmpeg_lib direktori.

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

    }

Catatan

Untuk mendapatkan cuplikan kode ini agar berfungsi di Azure, Anda perlu menentukan pengaturan aplikasi kustom "BASE_PATH" dengan nilai "/home/site/wwwroot"

Membawa dependensi dengan memasang berbagi file

Saat menjalankan aplikasi fungsi di Linux, ada cara lain untuk memasukkan dependensi pihak ketiga. Functions memungkinkan Anda memasang berbagi file yang dihost di Azure Files. Pertimbangkan pendekatan ini saat Anda ingin memisahkan dependensi atau artefak dari kode aplikasi.

Pertama, Anda perlu membuat Akun Azure Storage. Dalam akun tersebut, Anda juga perlu membuat berbagi file di file Azure. Untuk membuat sumber daya ini, ikuti panduan ini

Setelah membuat akun penyimpanan dan berbagi file, gunakan perintah tambahkan akun penyimpanan konfigurasi az webapp untuk melampirkan berbagi file ke aplikasi fungsi, seperti yang ditunjukkan dalam contoh berikut.

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>
Bendera Nilai
custom-id String unik apa pun
storage-type Hanya AzureFiles yang didukung saat ini
share-name Berbagi yang sudah ada sebelumnya
mount-path Jalur tempat berbagi akan dapat diakses di dalam kontainer. Nilai harus dalam format /dir-name dan tidak dapat dimulai dengan /home

Perintah lainnya untuk mengubah/menghapus konfigurasi berbagi file dapat ditemukan di sini

Mengunggah dependensi ke Azure Files

Salah satu opsi untuk mengunggah dependensi ke Azure Files adalah melalui portal Microsoft Azure. Lihat panduan ini untuk mengetahui instruksi mengunggah dependensi menggunakan portal. Opsi lain untuk mengunggah dependensi ke Azure Files adalah melalui Azure CLI dan PowerShell.

Mengakses dependensi dalam kode

Setelah dependensi diunggah di berbagi file, Anda dapat mengakses dependensi dari kode. Berbagi yang dipasang tersedia di jalur mount-path yang ditentukan, seperti /path/to/mount. Anda dapat mengakses direktori target menggunakan API sistem file.

Contoh berikut menunjukkan kode pemicu HTTP yang mengakses ffmpeg pustaka, yang disimpan dalam berbagi file yang dipasang.

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)

Saat Anda menyebarkan kode ini ke aplikasi fungsi di Azure, Anda perlu membuat pengaturan aplikasi dengan nama kunciFILE_SHARE_MOUNT_PATH dan nilai jalur berbagi file yang dipasang, yang untuk contoh ini adalah /azure-files-share. Untuk melakukan debugging lokal, Anda perlu mengisi FILE_SHARE_MOUNT_PATH jalur file tempat dependensi disimpan di komputer lokal. Berikut adalah contoh untuk mengatur FILE_SHARE_MOUNT_PATH menggunakan local.settings.json:

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

Langkah berikutnya