Bereitstellen von Abhängigkeiten und Bibliotheken von Drittanbietern in Azure Functions
In diesem Artikel erfahren Sie, wie Sie Abhängigkeiten von Drittanbietern in Ihre Funktions-Apps übernehmen. Beispiele für Abhängigkeiten von Drittanbietern sind .json-Dateien, Binärdateien und Machine Learning-Modelle.
In diesem Artikel werden folgende Vorgehensweisen behandelt:
- Einbringen von Abhängigkeiten über das Functions Code-Projekt
- Einbinden von Abhängigkeiten durch Einbinden der Azure-Dateifreigabe
Einbringen von Abhängigkeiten aus dem Projektverzeichnis
Eine der einfachsten Möglichkeiten, Abhängigkeiten einzubringen, ist das Zusammenbringen der Dateien/Artefakte mit dem Funktions-App-Code in der Verzeichnisstruktur des Functions-Projekts. Hier sehen Sie ein Beispiel für die Verzeichnisbeispiele in einem Python-Funktionsprojekt:
<project_root>/
| - my_first_function/
| | - __init__.py
| | - function.json
| | - example.py
| - dependencies/
| | - dependency1
| - .funcignore
| - host.json
| - local.settings.json
Indem die Abhängigkeiten in einem Ordner im Projektverzeichnis der Functions-App abgelegt werden, wird der Abhängigkeiten-Ordner zusammen mit dem Code bereitgestellt. Daher kann Ihr Funktionscode über die Dateisystem-API auf die Abhängigkeiten in der Cloud zugreifen.
Zugreifen auf die Abhängigkeiten in Ihrem Code
Im Folgenden finden Sie ein Beispiel für den Zugriff auf und die Ausführung von ffmpeg
-Abhängigkeiten, die im <project_root>/ffmpeg_lib
-Verzeichnis gespeichert werden.
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)
Hinweis
Möglicherweise müssen Sie chmod
verwenden, um Execute
-Rechte für die ffmpeg-Binärdatei in einer Linux-Umgebung zu bieten
Eine der einfachsten Möglichkeiten, Abhängigkeiten einzubringen, ist das Zusammenbringen der Dateien/Artefakte mit dem Funktions-App-Code in der Verzeichnisstruktur des Funktionsprojekts. Hier sehen Sie ein Beispiel für die Verzeichnisbeispiele in einem Java-Funktionsprojekt:
<project_root>/
| - src/
| | - main/java/com/function
| | | - Function.java
| | - test/java/com/function
| - artifacts/
| | - dependency1
| - host.json
| - local.settings.json
| - pom.xml
Insbesondere für Java müssen Sie die Artefakte beim Kopieren von Ressourcen explizit in den Build-/Zielordner hinzufügen. Hier sehen Sie ein Beispiel für die Verwendung 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>
...
Indem die Abhängigkeiten in einem Ordner im Projektverzeichnis der Functions-App abgelegt werden, wird der Abhängigkeiten-Ordner zusammen mit dem Code bereitgestellt. Daher kann Ihr Funktionscode über die Dateisystem-API auf die Abhängigkeiten in der Cloud zugreifen.
Zugreifen auf die Abhängigkeiten in Ihrem Code
Im Folgenden finden Sie ein Beispiel für den Zugriff auf und die Ausführung von ffmpeg
-Abhängigkeiten, die im <project_root>/ffmpeg_lib
-Verzeichnis gespeichert werden.
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();
}
Hinweis
Damit dieser Codeausschnitt in Azure funktioniert, müssen Sie die benutzerdefinierte Anwendungseinstellung „BASE_PATH“ mit dem Wert „/home/site/wwwroot“ angeben
Einbinden von Abhängigkeiten durch Einbinden einer Dateifreigabe
Wenn Sie Ihre Funktions-App unter Linux ausführen, gibt es eine andere Möglichkeit, Abhängigkeiten von Drittanbietern einzubringen. Mit Functions können Sie eine Dateifreigabe einbinden, die in Azure Files gehostet wird. Wählen Sie diesen Ansatz, wenn Sie Abhängigkeiten oder Artefakte von Ihrem Anwendungscode entkoppeln möchten.
Zunächst müssen Sie ein Azure-Speicherkonto erstellen. Im Konto müssen Sie auch eine Dateifreigabe in Azure Files erstellen. Befolgen Sie diese Anleitung, um diese Ressourcen zu erstellen
Nachdem Sie das Speicherkonto und die Dateifreigabe erstellt haben, verwenden Sie den Befehl az webapp config storage-account add, um die Dateifreigabe an Ihre Funktions-App anzufügen, wie im folgenden Beispiel gezeigt.
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>
Flag | Wert |
---|---|
custom-id | Eine beliebige eindeutige Zeichenfolge |
storage-type | Derzeit wird nur AzureFiles unterstützt |
share-name | Bereits vorhandene Freigabe |
mount-path | Pfad, unter dem innerhalb des Containers auf die Freigabe zugegriffen werden kann. Der Wert muss das Format /dir-name aufweisen und kann nicht mit /home beginnen |
Weitere Befehle zum Ändern/Löschen der Dateifreigabekonfiguration finden Sie hier
Hochladen der Abhängigkeiten in Azure Files
Eine Möglichkeit zum Hochladen Ihrer Abhängigkeit in Azure Files ist über das Azure-Portal. Anweisungen zum Hochladen von Abhängigkeiten über das Portal finden Sie in diesem Leitfaden. Weitere Optionen zum Hochladen Ihrer Abhängigkeiten in Azure Files sind Azure CLI und PowerShell.
Zugreifen auf die Abhängigkeiten in Ihrem Code
Nachdem Ihre Abhängigkeiten in die Dateifreigabe hochgeladen wurden, können Sie über Ihren Code auf die Abhängigkeiten zugreifen. Die bereitgestellte Freigabe ist unter dem angegebenen Bereitstellungspfad verfügbar, z. B. /path/to/mount
. Sie können mithilfe von Dateisystem-APIs auf das Zielverzeichnis zugreifen.
Das folgende Beispiel zeigt den HTTP-Triggercode, der auf die ffmpeg
-Bibliothek zugreift, die in einer bereitgestellten Dateifreigabe gespeichert ist.
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)
Wenn Sie diesen Code für eine Funktions-App in Azure bereitstellen, müssen Sie eine App-Einstellung mit dem Schlüsselnamen FILE_SHARE_MOUNT_PATH
und dem Wert des bereitgestellten Dateifreigabepfads erstellen, in diesem Beispiel /azure-files-share
. Zum lokalen Debuggen müssen Sie FILE_SHARE_MOUNT_PATH
mit dem Dateipfad auffüllen, in dem Ihre Abhängigkeiten auf Ihrem lokalen Computer gespeichert sind. Hier ist ein Beispiel, das mit local.settings.json
auf FILE_SHARE_MOUNT_PATH
festgelegt werden soll:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "python",
"FILE_SHARE_MOUNT_PATH" : "PATH_TO_LOCAL_FFMPEG_DIR"
}
}