Megosztás a következőn keresztül:


Azure Functions-útmutató Python-fejlesztőknek

Ez az útmutató az Azure Functions Python használatával történő fejlesztésének bemutatása. A cikk feltételezi, hogy már elolvasta az Azure Functions fejlesztői útmutatóját.

Fontos

Ez a cikk a Python 1- és 2-s verziós programozási modelljét is támogatja az Azure Functionsben. A Python v1-modell egy functions.json-fájlt használ a függvények definiálásához, az új v2-modell pedig dekorátoralapú megközelítést használ. Ez az új megközelítés egyszerűbb fájlstruktúrát eredményez, és kódközpontúbb. Az új programozási modell megismeréséhez válassza a cikk tetején található v2-választót.

Python-fejlesztőként az alábbi témakörök is érdekelhetik:

  • Visual Studio Code: Az első Python-alkalmazás létrehozása a Visual Studio Code használatával.
  • Terminál vagy parancssor: Hozza létre az első Python-alkalmazást a parancssorból az Azure Functions Core Tools használatával.
  • Minták: Tekintse át néhány meglévő Python-alkalmazást a Learn mintaböngészőben.
  • Visual Studio Code: Az első Python-alkalmazás létrehozása a Visual Studio Code használatával.
  • Terminál vagy parancssor: Hozza létre az első Python-alkalmazást a parancssorból az Azure Functions Core Tools használatával.
  • Minták: Tekintse át néhány meglévő Python-alkalmazást a Learn mintaböngészőben.

Fejlesztési lehetőségek

Mindkét Python Functions-programozási modell támogatja a helyi fejlesztést az alábbi környezetek egyikében:

Python v2 programozási modell:

Python v1 programozási modell:

Python v1-függvényeket is létrehozhat az Azure Portalon.

Tipp.

Bár a Python-alapú Azure-függvényeket helyileg fejlesztheti Windows rendszeren, a Python csak Linux-alapú üzemeltetési csomagban támogatott, amikor az Azure-ban fut. További információkért tekintse meg a támogatott operációs rendszerek/futtatókörnyezet-kombinációk listáját.

Programozási modell

Az Azure Functions azt várja, hogy egy függvény állapot nélküli metódus legyen a Python-szkriptben, amely feldolgozza a bemenetet, és kimenetet állít elő. Alapértelmezés szerint a futtatókörnyezet azt várja, hogy a metódus globális metódusként main() legyen implementálva a __init__.py fájlban. Másik belépési pontot is megadhat.

Az function.json fájlban definiált tulajdonságot használó name metódusattribútumokon keresztül köthet adatokat a függvényhez triggerekből és kötésekből. Az alábbi function.json fájl például egy egyszerű függvényt ír le, amelyet egy HTTP-kérés reqaktivál:

{
    "scriptFile": "__init__.py",
    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req",
            "methods": [
                "get",
                "post"
            ]
        },
        {
            "type": "http",
            "direction": "out",
            "name": "$return"
        }
    ]
}

A definíció alapján a függvénykódot tartalmazó __init__.py fájl a következő példához hasonlóan nézhet ki:

def main(req):
    user = req.params.get('user')
    return f'Hello, {user}!'

Az attribútumtípusok explicit deklarálhatók és visszaadhatók a függvényben Python-típusú széljegyzetek használatával. Ezzel segít a számos Python-kódszerkesztő által biztosított IntelliSense és automatikus kiegészítési funkciók használatában.

import azure.functions

def main(req: azure.functions.HttpRequest) -> str:
    user = req.params.get('user')
    return f'Hello, {user}!'

Az azure.functions.* csomagban található Python-széljegyzetekkel kötheti a bemenetet és a kimeneteket a metódusokhoz.

Az Azure Functions azt várja, hogy egy függvény állapot nélküli metódus legyen a Python-szkriptben, amely feldolgozza a bemenetet, és kimenetet állít elő. Alapértelmezés szerint a futtatókörnyezet elvárja, hogy a metódus globális metódusként legyen implementálva a function_app.py fájlban.

Az eseményindítók és kötések deklarálhatók és használhatók egy dekorátoralapú függvényben. Ezek ugyanabban a fájlban vannak definiálva, function_app.py, mint a függvények. A következő function_app.py fájl például egy HTTP-kérés által aktivált függvényt jelöl.

@app.function_name(name="HttpTrigger1")
@app.route(route="req")
def main(req):
    user = req.params.get("user")
    return f"Hello, {user}!"

Az attribútumtípusok explicit deklarálhatók és visszaadhatók a függvényben Python-típusú széljegyzetek használatával. Ezzel segít a számos Python-kódszerkesztő által biztosított IntelliSense és automatikus kiegészítési funkciók használatában.

import azure.functions as func

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="req")
def main(req: func.HttpRequest) -> str:
    user = req.params.get("user")
    return f"Hello, {user}!"

A v2-modell ismert korlátairól és kerülő megoldásairól az Azure Functions Python-hibáinak hibaelhárítása című témakörben olvashat.

Alternatív belépési pont

A függvények alapértelmezett viselkedését módosíthatja a function.json fájlban található tulajdonságok és entryPoint tulajdonságok opcionális megadásávalscriptFile. Az alábbi function.json például arra utasítja a futtatókörnyezetet, hogy a customentry() metódust a main.py fájlban használja az Azure-függvény belépési pontjaként.

{
  "scriptFile": "main.py",
  "entryPoint": "customentry",
  "bindings": [
      ...
  ]
}

A belépési pont csak a function_app.py fájlban található. A projekten belüli függvényekre azonban tervekkel vagy importálással hivatkozhat a function_app.py.

Mappastruktúra

Egy Python-függvényprojekt ajánlott mappastruktúrája a következő példához hasonlóan néz ki:

 <project_root>/
 | - .venv/
 | - .vscode/
 | - my_first_function/
 | | - __init__.py
 | | - function.json
 | | - example.py
 | - my_second_function/
 | | - __init__.py
 | | - function.json
 | - shared_code/
 | | - __init__.py
 | | - my_first_helper_function.py
 | | - my_second_helper_function.py
 | - tests/
 | | - test_my_second_function.py
 | - .funcignore
 | - host.json
 | - local.settings.json
 | - requirements.txt
 | - Dockerfile

A fő projektmappa ( <project_root>) a következő fájlokat tartalmazhatja:

  • local.settings.json: Alkalmazásbeállítások és kapcsolati sztring tárolása helyi futtatáskor. Ez a fájl nem lesz közzétéve az Azure-ban. További információ: local.settings.file.
  • requirements.txt: A rendszer által az Azure-ban való közzétételkor telepített Python-csomagok listáját tartalmazza.
  • host.json: Olyan konfigurációs beállításokat tartalmaz, amelyek egy függvényalkalmazás-példány összes függvényét érintik. Ez a fájl megjelenik az Azure-ban. Helyi futtatáskor nem minden beállítás támogatott. További információ: host.json.
  • .vscode/: (Nem kötelező) A tárolt Visual Studio Code-konfigurációt tartalmazza. További információ: Visual Studio Code-beállítások.
  • .venv/: (Nem kötelező) A helyi fejlesztés által használt Python virtuális környezetet tartalmaz.
  • Dockerfile: (Nem kötelező) A projekt egyéni tárolóban való közzétételekor használatos.
  • tesztek/: (Nem kötelező) A függvényalkalmazás teszteseteit tartalmazza.
  • .funcignore: (Nem kötelező) Deklarálja azokat a fájlokat, amelyeket nem szabad közzétenni az Azure-ban. Ez a fájl általában .vscode/-t tartalmaz, amely figyelmen kívül hagyja a szerkesztőbeállítást, a .venv/ parancsot a helyi Python virtuális környezet figyelmen kívül hagyásához, a teszteseteket és a local.settings.json a helyi alkalmazásbeállítások közzétételének megakadályozásához.

Minden függvény saját kódfájllal és kötéskonfigurációs fájllal rendelkezik, function.json.

Egy Python-függvényprojekt ajánlott mappastruktúrája a következő példához hasonlóan néz ki:

 <project_root>/
 | - .venv/
 | - .vscode/
 | - function_app.py
 | - additional_functions.py
 | - tests/
 | | - test_my_function.py
 | - .funcignore
 | - host.json
 | - local.settings.json
 | - requirements.txt
 | - Dockerfile

A fő projektmappa ( <project_root>) a következő fájlokat tartalmazhatja:

  • .venv/: (Nem kötelező) Olyan Python virtuális környezetet tartalmaz, amelyet a helyi fejlesztés használ.
  • .vscode/: (Nem kötelező) A tárolt Visual Studio Code-konfigurációt tartalmazza. További információ: Visual Studio Code-beállítások.
  • function_app.py: Az összes függvény és azok kapcsolódó eseményindítóinak és kötéseinek alapértelmezett helye.
  • additional_functions.py: (Nem kötelező) Minden más Python-fájl, amely függvényeket (általában logikai csoportosításhoz) tartalmaz, amelyek tervekkel hivatkoznak function_app.py.
  • tesztek/: (Nem kötelező) A függvényalkalmazás teszteseteit tartalmazza.
  • .funcignore: (Nem kötelező) Deklarálja azokat a fájlokat, amelyeket nem szabad közzétenni az Azure-ban. Ez a fájl általában .vscode/-t tartalmaz, amely figyelmen kívül hagyja a szerkesztőbeállítást, a .venv/ parancsot a helyi Python virtuális környezet figyelmen kívül hagyásához, a tesztelési esetek figyelmen kívül hagyásához, és local.settings.json a helyi alkalmazásbeállítások közzétételének megakadályozásához.
  • host.json: Olyan konfigurációs beállításokat tartalmaz, amelyek egy függvényalkalmazás-példány összes függvényét érintik. Ez a fájl megjelenik az Azure-ban. Helyi futtatáskor nem minden beállítás támogatott. További információ: host.json.
  • local.settings.json: Alkalmazásbeállítások és kapcsolati sztring tárolására szolgál, ha helyileg fut. Ez a fájl nem lesz közzétéve az Azure-ban. További információ: local.settings.file.
  • requirements.txt: A rendszer által az Azure-ban való közzétételkor telepített Python-csomagok listáját tartalmazza.
  • Dockerfile: (Nem kötelező) A projekt egyéni tárolóban való közzétételekor használatos.

Amikor üzembe helyezi a projektet egy függvényalkalmazásban az Azure-ban, a fő projektmappa teljes tartalmát ( <project_root>) a csomagban kell tartalmaznia, magát a mappát azonban nem, ami azt jelenti, hogy host.json a csomag gyökerében kell lennie. Javasoljuk, hogy a teszteket egy mappában tartsa karban más függvényekkel együtt (ebben a példában a tesztek/). További információ: Egységtesztelés.

Kapcsolódás adatbázishoz

Az Azure Functions számos használati esetben jól integrálható az Azure Cosmos DB-vel, beleértve az IoT-t, az e-kereskedelmet, a játékokat stb.

Az eseményforráshoz például a két szolgáltatás az Azure Cosmos DB változáscsatorna funkciójával integrálva van az eseményvezérelt architektúrákba. A változáscsatorna lehetővé teszi az alsóbb rétegbeli mikroszolgáltatások számára a beszúrások és frissítések megbízható és növekményes olvasását (például rendelési eseményeket). Ezzel a funkcióval egy állandó eseménytárat biztosíthat üzenetközvetítőként az állapotváltozási eseményekhez, és számos mikroszolgáltatás közötti rendelésfeldolgozási munkafolyamatot hajthat végre (amely kiszolgáló nélküli Azure Functionsként implementálható).

Azure Cosmos DB rendelési folyamat referenciaarchitektúrája

Az Azure Cosmos DB-hez való csatlakozáshoz először hozzon létre egy fiókot, adatbázist és tárolót. Ezután a függvénykódot triggerek és kötések használatával csatlakoztathatja az Azure Cosmos DB-hez, például ebben a példában.

Összetettebb alkalmazáslogika implementálásához a Cosmos DB-hez készült Python-kódtárat is használhatja. Az aszinkron I/O-implementáció a következőképpen néz ki:

pip install azure-cosmos
pip install aiohttp

from azure.cosmos.aio import CosmosClient
from azure.cosmos import exceptions
from azure.cosmos.partition_key import PartitionKey
import asyncio

# Replace these values with your Cosmos DB connection information
endpoint = "https://azure-cosmos-nosql.documents.azure.com:443/"
key = "master_key"
database_id = "cosmicwerx"
container_id = "cosmicontainer"
partition_key = "/partition_key"

# Set the total throughput (RU/s) for the database and container
database_throughput = 1000

# Singleton CosmosClient instance
client = CosmosClient(endpoint, credential=key)

# Helper function to get or create database and container
async def get_or_create_container(client, database_id, container_id, partition_key):
    database = await client.create_database_if_not_exists(id=database_id)
    print(f'Database "{database_id}" created or retrieved successfully.')

    container = await database.create_container_if_not_exists(id=container_id, partition_key=PartitionKey(path=partition_key))
    print(f'Container with id "{container_id}" created')
 
    return container
 
async def create_products():
    container = await get_or_create_container(client, database_id, container_id, partition_key)
    for i in range(10):
        await container.upsert_item({
            'id': f'item{i}',
            'productName': 'Widget',
            'productModel': f'Model {i}'
        })
 
async def get_products():
    items = []
    container = await get_or_create_container(client, database_id, container_id, partition_key)
    async for item in container.read_all_items():
        items.append(item)
    return items

async def query_products(product_name):
    container = await get_or_create_container(client, database_id, container_id, partition_key)
    query = f"SELECT * FROM c WHERE c.productName = '{product_name}'"
    items = []
    async for item in container.query_items(query=query, enable_cross_partition_query=True):
        items.append(item)
    return items

async def main():
    await create_products()
    all_products = await get_products()
    print('All Products:', all_products)

    queried_products = await query_products('Widget')
    print('Queried Products:', queried_products)

if __name__ == "__main__":
    asyncio.run(main())

Blueprints

A Python v2 programozási modell bemutatja a tervek fogalmát. A terv egy új osztály, amely példányosítva regisztrálja a függvényeket az alapfüggvényalkalmazáson kívül. A tervpéldányokban regisztrált függvényeket nem indexeli közvetlenül a függvény futtatókörnyezete. A tervfüggvények indexeléséhez a függvényalkalmazásnak regisztrálnia kell a függvényeket a tervpéldányokból.

A tervek használata a következő előnyöket nyújtja:

  • Lehetővé teszi, hogy a függvényalkalmazást moduláris összetevőkre bontsa, így több Python-fájlban definiálhat függvényeket, és fájlonként különböző összetevőkre oszthatja őket.
  • Bővíthető nyilvános függvényalkalmazás-felületeket biztosít saját API-k létrehozásához és újrafelhasználásához.

Az alábbi példa a tervek használatát mutatja be:

Először egy http_blueprint.py fájlban először egy HTTP-aktivált függvény lesz definiálva, és hozzáadódik egy tervobjektumhoz.

import logging 

import azure.functions as func 

bp = func.Blueprint() 

@bp.route(route="default_template") 
def default_template(req: func.HttpRequest) -> func.HttpResponse: 
    logging.info('Python HTTP trigger function processed a request.') 

    name = req.params.get('name') 
    if not name: 
        try: 
            req_body = req.get_json() 
        except ValueError: 
            pass 
        else: 
            name = req_body.get('name') 

    if name: 
        return func.HttpResponse( 
            f"Hello, {name}. This HTTP-triggered function " 
            f"executed successfully.") 
    else: 
        return func.HttpResponse( 
            "This HTTP-triggered function executed successfully. " 
            "Pass a name in the query string or in the request body for a" 
            " personalized response.", 
            status_code=200 
        ) 

Ezután a function_app.py fájlban importálja a tervobjektumot, és a függvények regisztrálva lesznek a függvényalkalmazásban.

import azure.functions as func 
from http_blueprint import bp

app = func.FunctionApp() 

app.register_functions(bp) 

Feljegyzés

A Durable Functions a terveket is támogatja. A Durable Functions-alkalmazások tervrajzainak létrehozásához regisztrálja vezénylési, tevékenységi és entitás-eseményindítóit és ügyfélkötéseit az azure-functions-durable Blueprint osztály használatával, az itt látható módon. Az eredményként kapott terv ezután a szokásos módon regisztrálható. Tekintse meg a mintánk egy példáját.

Importálási viselkedés

A függvénykódban lévő modulokat abszolút és relatív hivatkozások használatával is importálhatja. A korábban ismertetett mappastruktúra alapján a következő importálások működnek a project_root\my_first_function\__init__.py függvényfájlból<:>

from shared_code import my_first_helper_function #(absolute)
import shared_code.my_second_helper_function #(absolute)
from . import example #(relative)

Feljegyzés

Abszolút importálási szintaxis használatakor a shared_code/ mappának tartalmaznia kell egy __init__.py fájlt, hogy Python-csomagként jelölje meg.

A következő __app__ importálás és a felső szintű relatív importáláson túl elavult, mert a statikus típus-ellenőrző nem támogatja őket, és a Python-tesztkörnyezetek nem támogatják őket:

from __app__.shared_code import my_first_helper_function #(deprecated __app__ import)
from ..shared_code import my_first_helper_function #(deprecated beyond top-level relative import)

Triggerek és bemenetek

A bemenetek két kategóriába sorolhatók az Azure Functionsben: trigger bemenet és egyéb bemenetek. Bár a function.json fájlban eltérnek, a használatuk azonos a Python-kódban. Az eseményindítók és bemeneti források kapcsolati sztringjei vagy titkos kódjai a local.settings.json fájl értékeire vannak leképezve, amikor helyileg futnak, és az Azure-ban való futtatáskor az alkalmazásbeállításokhoz vannak megfeleltetve.

A következő kód például a két bemenet közötti különbséget mutatja be:

// function.json
{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "req",
      "direction": "in",
      "type": "httpTrigger",
      "authLevel": "anonymous",
      "route": "items/{id}"
    },
    {
      "name": "obj",
      "direction": "in",
      "type": "blob",
      "path": "samples/{id}",
      "connection": "STORAGE_CONNECTION_STRING"
    }
  ]
}
// local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "STORAGE_CONNECTION_STRING": "<AZURE_STORAGE_CONNECTION_STRING>",
    "AzureWebJobsStorage": "<azure-storage-connection-string>"
  }
}
# __init__.py
import azure.functions as func
import logging

def main(req: func.HttpRequest, obj: func.InputStream):
    logging.info(f'Python HTTP-triggered function processed: {obj.read()}')

A függvény meghívásakor a HTTP-kérést a függvény a következőképpen továbbítja a függvénynek req. A rendszer egy bejegyzést kér le az Azure Blob Storage-fiókból az útvonal URL-címében szereplő azonosító alapján, és a függvény törzséhez hasonlóan obj elérhetővé válik. Itt a megadott tárfiók az alkalmazásbeállításban CONNECTION_STRING található kapcsolati sztring.

A bemenetek két kategóriába sorolhatók az Azure Functionsben: trigger bemenet és egyéb bemenetek. Bár különböző dekorátorokkal vannak definiálva, a használatuk hasonló a Python-kódban. Az eseményindítók és bemeneti források kapcsolati sztringjei vagy titkos kódjai a local.settings.json fájl értékeire vannak leképezve, amikor helyileg futnak, és az Azure-ban való futtatáskor az alkalmazásbeállításokhoz vannak megfeleltetve.

A következő kód például bemutatja, hogyan definiálhat egy Blob Storage bemeneti kötést:

// local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "STORAGE_CONNECTION_STRING": "<AZURE_STORAGE_CONNECTION_STRING>",
    "AzureWebJobsStorage": "<azure-storage-connection-string>"
  }
}
# function_app.py
import azure.functions as func
import logging

app = func.FunctionApp()

@app.route(route="req")
@app.read_blob(arg_name="obj", path="samples/{id}", 
               connection="STORAGE_CONNECTION_STRING")
def main(req: func.HttpRequest, obj: func.InputStream):
    logging.info(f'Python HTTP-triggered function processed: {obj.read()}')

A függvény meghívásakor a HTTP-kérést a függvény a következőképpen továbbítja a függvénynek req. A rendszer egy bejegyzést kér le az Azure Blob Storage-fiókból az útvonal URL-címében szereplő azonosító alapján, és a függvény törzséhez hasonlóan obj elérhetővé válik. Itt a megadott tárfiók az alkalmazásbeállításban STORAGE_CONNECTION_STRING található kapcsolati sztring.

Az adatigényes kötési műveletekhez érdemes lehet külön tárfiókot használni. További információ: Tárfiókok útmutatója.

SDK típusú kötések (előzetes verzió)

Az eseményindítók és kötések kiválasztásához használhatja az alapul szolgáló Azure SDK-k és -keretrendszerek által implementált adattípusokat. Ezek az SDK-típusú kötések lehetővé teszik a kötési adatok interakcióját, mintha a mögöttes szolgáltatás SDK-t használták volna.

Fontos

Az SDK-típuskötések támogatásához a Python v2 programozási modell szükséges.

A Functions támogatja a Python SDK típusú kötéseket az Azure Blob Storage-hoz, amely lehetővé teszi a blobadatok használatát az alapul szolgáló BlobClient típus használatával.

Fontos

A Python SDK típusú kötéseinek támogatása jelenleg előzetes verzióban érhető el:

  • A Python v2 programozási modellt kell használnia.
  • Jelenleg csak a szinkron SDK-típusok támogatottak.

Előfeltételek

SDK-típuskötések engedélyezése a Blob Storage-bővítményhez

  1. Adja hozzá a azurefunctions-extensions-bindings-blob bővítménycsomagot a requirements.txt projekt fájljába, amelynek legalább az alábbi csomagokat kell tartalmaznia:

    azure-functions
    azurefunctions-extensions-bindings-blob
    
  2. Adja hozzá ezt a kódot a function_app.py projekt fájljába, amely importálja az SDK-típusú kötéseket:

    import azurefunctions.extensions.bindings.blob as blob
    

SDK-típusú kötések – példák

Ez a példa bemutatja, hogyan szerezheti be a BlobClient Blob Storage-eseményindítót (blob_trigger) és a HTTP-eseményindító bemeneti kötését (blob_input):

import logging

import azure.functions as func
import azurefunctions.extensions.bindings.blob as blob

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

@app.blob_trigger(
    arg_name="client", path="PATH/TO/BLOB", connection="AzureWebJobsStorage"
)
def blob_trigger(client: blob.BlobClient):
    logging.info(
        f"Python blob trigger function processed blob \n"
        f"Properties: {client.get_blob_properties()}\n"
        f"Blob content head: {client.download_blob().read(size=1)}"
    )


@app.route(route="file")
@app.blob_input(
    arg_name="client", path="PATH/TO/BLOB", connection="AzureWebJobsStorage"
)
def blob_input(req: func.HttpRequest, client: blob.BlobClient):
    logging.info(
        f"Python blob input function processed blob \n"
        f"Properties: {client.get_blob_properties()}\n"
        f"Blob content head: {client.download_blob().read(size=1)}"
    )
    return "ok"

A Blob Storage egyéb SDK-típusú kötésmintáit a Python-bővítmények adattárában tekintheti meg:

HTTP-streamek (előzetes verzió)

A HTTP-streamek lehetővé teszik, hogy a függvényekben engedélyezett FastAPI kérés- és válasz API-k használatával fogadjon és küldjön vissza adatokat a HTTP-végpontokról. Ezek az API-k lehetővé teszi a gazdagép számára, hogy a http-üzenetekben lévő nagyméretű adatokat adattömbökként dolgozzák fel ahelyett, hogy egy teljes üzenetet olvasnak a memóriába.

Ez a funkció lehetővé teszi a nagy adatstreamek, az OpenAI-integrációk kezelését, a dinamikus tartalom biztosítását, valamint a HTTP-en keresztüli valós idejű interakciót igénylő egyéb alapvető HTTP-forgatókönyvek támogatását. FastAPI-választípusokat HTTP-streamekkel is használhat. HTTP-streamek nélkül a HTTP-kérések és válaszok méretét memóriakorlátozások korlátozzák, amelyek a teljes üzenet hasznos adatainak feldolgozásakor a memóriában is előfordulhatnak.

Fontos

A HTTP-streamek támogatásához a Python v2 programozási modell szükséges.

Fontos

A Python HTTP-streamek támogatása jelenleg előzetes verzióban érhető el, és a Python v2 programozási modell használatát igényli.

Előfeltételek

HTTP-streamek engedélyezése

A HTTP-streamek alapértelmezés szerint le vannak tiltva. Engedélyeznie kell ezt a funkciót az alkalmazásbeállításokban, és frissítenie kell a kódot a FastAPI-csomag használatához. Vegye figyelembe, hogy a HTTP-streamek engedélyezésekor a függvényalkalmazás alapértelmezés szerint HTTP-streamelést használ, és az eredeti HTTP-funkció nem fog működni.

  1. Adja hozzá a azurefunctions-extensions-http-fastapi bővítménycsomagot a requirements.txt projekt fájljába, amelynek legalább az alábbi csomagokat kell tartalmaznia:

    azure-functions
    azurefunctions-extensions-http-fastapi
    
  2. Adja hozzá ezt a kódot a function_app.py projekt fájljához, amely importálja a FastAPI-bővítményt:

    from azurefunctions.extensions.http.fastapi import Request, StreamingResponse
    
  3. Az Azure-ban való üzembe helyezéskor adja hozzá a következő alkalmazásbeállítást a függvényalkalmazáshoz:

    "PYTHON_ENABLE_INIT_INDEXING": "1"

    Ha Linux-használatban van üzembe helyezve, vegye fel a

    "PYTHON_ISOLATE_WORKER_DEPENDENCIES": "1"

    Helyi futtatáskor ezeket a beállításokat is hozzá kell adnia a local.settings.json projektfájlhoz.

HTTP-streamek – példák

A HTTP-streamelési funkció engedélyezése után olyan függvényeket hozhat létre, amelyek HTTP-en keresztül streamelik az adatokat.

Ez a példa egy HTTP által aktivált függvény, amely HTTP-válaszadatokat streamel. Ezekkel a képességekkel olyan forgatókönyveket támogathat, mint az eseményadatok folyamaton keresztüli küldése valós idejű vizualizációhoz, vagy nagy adathalmazok rendellenességeinek észlelése és azonnali értesítések küldése.

import time

import azure.functions as func
from azurefunctions.extensions.http.fastapi import Request, StreamingResponse

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)


def generate_sensor_data():
    """Generate real-time sensor data."""
    for i in range(10):
        # Simulate temperature and humidity readings
        temperature = 20 + i
        humidity = 50 + i
        yield f"data: {{'temperature': {temperature}, 'humidity': {humidity}}}\n\n"
        time.sleep(1)


@app.route(route="stream", methods=[func.HttpMethod.GET])
async def stream_sensor_data(req: Request) -> StreamingResponse:
    """Endpoint to stream real-time sensor data."""
    return StreamingResponse(generate_sensor_data(), media_type="text/event-stream")

Ez a példa egy HTTP által aktivált függvény, amely valós időben fogad és dolgoz fel streamelési adatokat egy ügyféltől. Bemutatja a streamelési feltöltési képességeket, amelyek hasznosak lehetnek olyan helyzetekben, mint a folyamatos adatfolyamok feldolgozása és az IoT-eszközök eseményadatainak kezelése.

import azure.functions as func
from azurefunctions.extensions.http.fastapi import JSONResponse, Request

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)


@app.route(route="streaming_upload", methods=[func.HttpMethod.POST])
async def streaming_upload(req: Request) -> JSONResponse:
    """Handle streaming upload requests."""
    # Process each chunk of data as it arrives
    async for chunk in req.stream():
        process_data_chunk(chunk)

    # Once all data is received, return a JSON response indicating successful processing
    return JSONResponse({"status": "Data uploaded and processed successfully"})


def process_data_chunk(chunk: bytes):
    """Process each data chunk."""
    # Add custom processing logic here
    pass

HTTP-streamek meghívása

Http-ügyfélkódtár használatával kell streamelési hívásokat kezdeményeznie egy függvény FastAPI-végpontjára. Előfordulhat, hogy a használt ügyféleszköz vagy böngésző natív módon nem támogatja a streamelést, vagy csak az adatok első adattömbét tudta visszaadni.

Egy ilyen ügyfélszkripttel streamelési adatokat küldhet egy HTTP-végpontnak:

import httpx # Be sure to add 'httpx' to 'requirements.txt'
import asyncio

async def stream_generator(file_path):
    chunk_size = 2 * 1024  # Define your own chunk size
    with open(file_path, 'rb') as file:
        while chunk := file.read(chunk_size):
            yield chunk
            print(f"Sent chunk: {len(chunk)} bytes")

async def stream_to_server(url, file_path):
    timeout = httpx.Timeout(60.0, connect=60.0)
    async with httpx.AsyncClient(timeout=timeout) as client:
        response = await client.post(url, content=stream_generator(file_path))
        return response

async def stream_response(response):
    if response.status_code == 200:
        async for chunk in response.aiter_raw():
            print(f"Received chunk: {len(chunk)} bytes")
    else:
        print(f"Error: {response}")

async def main():
    print('helloworld')
    # Customize your streaming endpoint served from core tool in variable 'url' if different.
    url = 'http://localhost:7071/api/streaming_upload'
    file_path = r'<file path>'

    response = await stream_to_server(url, file_path)
    print(response)

if __name__ == "__main__":
    asyncio.run(main())

Kimenetek

A kimenet a visszatérési értékben és a kimeneti paraméterekben is kifejezhető. Ha csak egy kimenet van, javasoljuk a visszatérési érték használatát. Több kimenet esetén kimeneti paramétereket kell használnia.

Ha egy függvény visszatérési értékét kimeneti kötés értékeként szeretné használni, a name kötés tulajdonságát a function.json fájlban kell beállítani$return.

Több kimenet létrehozásához használja az set() interfész által azure.functions.Out biztosított metódust egy érték kötéshez való hozzárendeléséhez. Az alábbi függvény például leküldhet egy üzenetet egy üzenetsorba, és HTTP-választ is küldhet.

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "req",
      "direction": "in",
      "type": "httpTrigger",
      "authLevel": "anonymous"
    },
    {
      "name": "msg",
      "direction": "out",
      "type": "queue",
      "queueName": "outqueue",
      "connection": "STORAGE_CONNECTION_STRING"
    },
    {
      "name": "$return",
      "direction": "out",
      "type": "http"
    }
  ]
}
import azure.functions as func

def main(req: func.HttpRequest,
         msg: func.Out[func.QueueMessage]) -> str:

    message = req.params.get('body')
    msg.set(message)
    return message

A kimenet a visszatérési értékben és a kimeneti paraméterekben is kifejezhető. Ha csak egy kimenet van, javasoljuk a visszatérési érték használatát. Több kimenet esetén kimeneti paramétereket kell használnia.

Több kimenet létrehozásához használja az set() interfész által azure.functions.Out biztosított metódust egy érték kötéshez való hozzárendeléséhez. Az alábbi függvény például leküldhet egy üzenetet egy üzenetsorba, és HTTP-választ is küldhet.

# function_app.py
import azure.functions as func

app = func.FunctionApp()

@app.write_blob(arg_name="msg", path="output-container/{name}",
                connection="CONNECTION_STRING")
def test_function(req: func.HttpRequest,
                  msg: func.Out[str]) -> str:

    message = req.params.get('body')
    msg.set(message)
    return message

Naplózás

Az Azure Functions futtatókörnyezet-naplózójához való hozzáférés a függvényalkalmazás gyökérkezelőjével logging érhető el. Ez a naplózó az Application Insightshoz van kötve, és lehetővé teszi a függvény végrehajtása során előforduló figyelmeztetések és hibák megjelölését.

Az alábbi példa egy információs üzenetet naplóz, amikor a függvényt HTTP-eseményindítón keresztül hívják meg.

import logging

def main(req):
    logging.info('Python HTTP trigger function processed a request.')

További naplózási módszerek állnak rendelkezésre, amelyekkel különböző nyomkövetési szinteken írhat a konzolra:

Metódus Leírás
critical(_message_) Kritikus szintű üzenetet ír a gyökérnaplózón.
error(_message_) Olyan üzenetet ír, amely hibaszinttel rendelkezik a gyökérnaplózón.
warning(_message_) Figyelmeztetés szintű üzenetet ír a gyökérnaplózóra.
info(_message_) Olyan üzenetet ír, amely a legfelső szintű naplózón található információszinttel rendelkezik.
debug(_message_) Egy debug szintű üzenetet ír a gyökérnaplózón.

A naplózásról további információt az Azure Functions monitorozása című témakörben talál.

Naplózás létrehozott szálakból

A létrehozott szálakból származó naplók megtekintéséhez adja meg az context argumentumot a függvény aláírásában. Ez az argumentum egy helyi invocation_idattribútumot thread_local_storage tartalmaz. Ez a függvény aktuális invocation_id értékére állítható be a környezet módosításának biztosítása érdekében.

import azure.functions as func
import logging
import threading


def main(req, context):
    logging.info('Python HTTP trigger function processed a request.')
    t = threading.Thread(target=log_function, args=(context,))
    t.start()


def log_function(context):
    context.thread_local_storage.invocation_id = context.invocation_id
    logging.info('Logging from thread.')

Egyéni telemetriai adatok naplózása

Alapértelmezés szerint a Functions-futtatókörnyezet naplókat és egyéb telemetriai adatokat gyűjt, amelyeket a függvények hoznak létre. Ez a telemetria nyomkövetésként kerül az Application Insightsba. Az egyes Azure-szolgáltatások kérési és függőségi telemetriáját alapértelmezés szerint az eseményindítók és kötések is gyűjtik.

Az OpenCensus Python-bővítmények használatával egyéni kéréseket és egyéni függőségi telemetriát gyűjthet a kötéseken kívül. Ez a bővítmény egyéni telemetriai adatokat küld az Application Insights-példánynak. A támogatott bővítmények listáját az OpenCensus-adattárban találja.

Feljegyzés

Az OpenCensus Python-bővítmények használatához engedélyeznie kell a Python feldolgozóbővítményeket a függvényalkalmazásban a következő beállítással PYTHON_ENABLE_WORKER_EXTENSIONS 1: . Az Application Insights kapcsolati sztring használatára is át kell váltania, ha hozzáadja a beállítást az APPLICATIONINSIGHTS_CONNECTION_STRING alkalmazásbeállításokhoz, ha még nincs meg.

// requirements.txt
...
opencensus-extension-azure-functions
opencensus-ext-requests
import json
import logging

import requests
from opencensus.extension.azure.functions import OpenCensusExtension
from opencensus.trace import config_integration

config_integration.trace_integrations(['requests'])

OpenCensusExtension.configure()

def main(req, context):
    logging.info('Executing HttpTrigger with OpenCensus extension')

    # You must use context.tracer to create spans
    with context.tracer.span("parent"):
        response = requests.get(url='http://example.com')

    return json.dumps({
        'method': req.method,
        'response': response.status_code,
        'ctx_func_name': context.function_name,
        'ctx_func_dir': context.function_directory,
        'ctx_invocation_id': context.invocation_id,
        'ctx_trace_context_Traceparent': context.trace_context.Traceparent,
        'ctx_trace_context_Tracestate': context.trace_context.Tracestate,
        'ctx_retry_context_RetryCount': context.retry_context.retry_count,
        'ctx_retry_context_MaxRetryCount': context.retry_context.max_retry_count,
    })

HTTP-eseményindító

A HTTP-eseményindító a function.json fájlban van definiálva. A name kötésnek meg kell egyeznie a függvény elnevezett paraméterével. Az előző példákban egy kötésnevet req használunk. Ez a paraméter egy HttpRequest objektum, és a függvény egy HttpResponse objektumot ad vissza.

A HttpRequest objektumból lekérheti a kérésfejléceket, a lekérdezési paramétereket, az útvonalparamétereket és az üzenet törzsét.

Az alábbi példa a Python HTTP-triggersablonjából származik.

def main(req: func.HttpRequest) -> func.HttpResponse:
    headers = {"my-http-header": "some-value"}

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello {name}!", headers=headers)
    else:
        return func.HttpResponse(
             "Please pass a name on the query string or in the request body",
             headers=headers, status_code=400
        )

Ebben a függvényben a name lekérdezési paraméter értékét a params HttpRequest objektum paraméteréből szerzi be. A JSON-kódolt üzenettörzset a get_json metódus használatával olvassa el.

Hasonlóképpen beállíthatja a status_code válaszüzenetet és headers a válaszüzenetet a visszaadott HttpResponse objektumban.

A HTTP-eseményindító egy metódus, amely egy elnevezett kötési paramétert vesz fel, amely egy HttpRequest objektum, és egy HttpResponse objektumot ad vissza. A függvénynév meghatározásához alkalmazza a function_name dekoratőrt a metódusra, a HTTP-végpont pedig a route dekorátor alkalmazásával van beállítva.

Ez a példa a Python v2 programozási modell HTTP-triggersablonjából származik, ahol a kötési paraméter neve .req Ez a mintakód, amelyet a függvények Azure Functions Core Tools vagy Visual Studio Code használatával történő létrehozásakor ad meg.

@app.function_name(name="HttpTrigger1")
@app.route(route="hello")
def test_function(req: func.HttpRequest) -> func.HttpResponse:
     logging.info('Python HTTP trigger function processed a request.')

     name = req.params.get('name')
     if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

     if name:
        return func.HttpResponse(f"Hello, {name}. This HTTP-triggered function executed successfully.")
     else:
        return func.HttpResponse(
             "This HTTP-triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

A HttpRequest objektumból lekérheti a kérésfejléceket, a lekérdezési paramétereket, az útvonalparamétereket és az üzenet törzsét. Ebben a függvényben a name lekérdezési paraméter értékét a params HttpRequest objektum paraméteréből szerzi be. A JSON-kódolt üzenettörzset a get_json metódus használatával olvassa el.

Hasonlóképpen beállíthatja a status_code válaszüzenetet és headers a válaszüzenetet a visszaadott HttpResponse objektumban.

Ha egy nevet szeretne megadni ebben a példában, illessze be a függvény futtatásakor megadott URL-címet, majd fűzze hozzá "?name={name}".

Webes keretrendszerek

A Web Server Gateway Interface (WSGI)-kompatibilis és aszinkron kiszolgálóátjáró-adapterrel (ASGI) kompatibilis keretrendszereket, például a Flaskot és a FastAPI-t a HTTP által aktivált Python-függvényekkel használhatja. Ez a szakasz bemutatja, hogyan módosíthatja a függvényeket a keretrendszerek támogatásához.

Először is frissíteni kell a function.json fájlt, hogy belefoglaljon a route HTTP-eseményindítóba, ahogy az alábbi példában látható:

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
       "authLevel": "anonymous",
       "type": "httpTrigger",
       "direction": "in",
       "name": "req",
       "methods": [
           "get",
           "post"
       ],
       "route": "{*route}"
    },
    {
       "type": "http",
       "direction": "out",
       "name": "$return"
    }
  ]
}

A host.json fájlt is frissíteni kell, hogy tartalmazzon EGY HTTP-t routePrefix, ahogy az a következő példában is látható:

{
  "version": "2.0",
  "logging": 
  {
    "applicationInsights": 
    {
      "samplingSettings": 
      {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": 
  {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[3.*, 4.0.0)"
  },
  "extensions": 
  {
    "http": 
    {
        "routePrefix": ""
    }
  }
}

Frissítse a Python-kódfájlt init.py a keretrendszer által használt felülettől függően. Az alábbi példa egy ASGI kezelő megközelítést vagy a Flask WSGI burkoló megközelítését mutatja be:

app = fastapi.FastAPI()

@app.get("hello/{name}")
async def get_name(name: str):
  return {"name": name}

def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    return func.AsgiMiddleware(app).handle(req, context)

Az Aszinkron kiszolgálóátjáró-adapter (ASGI)-kompatibilis és webkiszolgálói átjárófelülettel (WSGI) kompatibilis keretrendszereket, például a Flaskot és a FastAPI-t a HTTP által aktivált Python-függvényekkel használhatja. Először frissítenie kell a host.json fájlt, hogy egy HTTP-t routePrefixtartalmazzon, ahogy az alábbi példában látható:

{
  "version": "2.0",
  "logging": 
  {
    "applicationInsights": 
    {
      "samplingSettings": 
      {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": 
  {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[2.*, 3.0.0)"
  },
  "extensions": 
  {
    "http": 
    {
        "routePrefix": ""
    }
  }
}

A keretrendszer kódja a következő példához hasonlóan néz ki:

AsgiFunctionApp az ASGI HTTP-függvények létrehozására szolgáló legfelső szintű függvényalkalmazás-osztály.

# function_app.py

import azure.functions as func 
from fastapi import FastAPI, Request, Response 

fast_app = FastAPI() 

@fast_app.get("/return_http_no_body") 
async def return_http_no_body(): 
    return Response(content="", media_type="text/plain") 

app = func.AsgiFunctionApp(app=fast_app, 
                           http_auth_level=func.AuthLevel.ANONYMOUS) 

Skálázás és teljesítmény

A Python-függvényalkalmazások méretezésével és teljesítményével kapcsolatos ajánlott eljárásokért tekintse meg a Python-skálázásról és a teljesítményről szóló cikket.

Környezet

Ha egy függvény meghívási környezetét szeretné lekérni futás közben, vegye fel az argumentumot az context aláírásba.

Példa:

import azure.functions


def main(req: azure.functions.HttpRequest,
         context: azure.functions.Context) -> str:
    return f'{context.invocation_id}'

Az Context osztály a következő sztringattribútumokkal rendelkezik:

Attribútum Leírás
function_directory Az a könyvtár, amelyben a függvény fut.
function_name A függvény neve.
invocation_id Az aktuális függvényhívás azonosítója.
thread_local_storage A függvény szál helyi tárolója. invocation_id A létrehozott szálakból való naplózás helyi beállítását tartalmazza.
trace_context Az elosztott nyomkövetés környezete. További információ: Trace Context.
retry_context A függvényre való újrapróbálkozáshoz használt környezet. További információ: retry-policies.

Globális változók

Nem garantált, hogy az alkalmazás állapota megmarad a jövőbeli végrehajtásokhoz. Az Azure Functions-futtatókörnyezet azonban gyakran ugyanazt a folyamatot használja fel ugyanazon alkalmazás több végrehajtásához is. A költséges számítások eredményeinek gyorsítótárazásához deklarálja globális változóként.

CACHED_DATA = None


def main(req):
    global CACHED_DATA
    if CACHED_DATA is None:
        CACHED_DATA = load_json()

    # ... use CACHED_DATA in code

Környezeti változók

Az Azure Functionsben az alkalmazásbeállítások, például a szolgáltatási kapcsolati sztring környezeti változókként jelennek meg futás közben. A kódban kétféleképpen érheti el ezeket a beállításokat.

Metódus Leírás
os.environ["myAppSetting"] Megpróbálja lekérni az alkalmazásbeállítást kulcsnév alapján, és sikertelenség esetén hibát jelez.
os.getenv("myAppSetting") Megpróbálja lekérni az alkalmazásbeállítást kulcsnév alapján, és sikertelenül adja vissza null .

Mindkét módszerhez deklarálnia kell a deklaráltat import os.

Az alábbi példa az alkalmazás beállításának lekérésére használja os.environ["myAppSetting"] a következő kulccsalmyAppSetting:

import logging
import os

import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:
  # Get the setting named 'myAppSetting'
  my_app_setting_value = os.environ["myAppSetting"]
  logging.info(f'My app setting value:{my_app_setting_value}')

A helyi fejlesztéshez az alkalmazásbeállítások megmaradnak a local.settings.json fájlban.

Az Azure Functionsben az alkalmazásbeállítások, például a szolgáltatási kapcsolati sztring környezeti változókként jelennek meg futás közben. A kódban kétféleképpen érheti el ezeket a beállításokat.

Metódus Leírás
os.environ["myAppSetting"] Megpróbálja lekérni az alkalmazásbeállítást kulcsnév alapján, és sikertelenség esetén hibát jelez.
os.getenv("myAppSetting") Megpróbálja lekérni az alkalmazásbeállítást kulcsnév alapján, és sikertelenül adja vissza null .

Mindkét módszerhez deklarálnia kell a deklaráltat import os.

Az alábbi példa az alkalmazás beállításának lekérésére használja os.environ["myAppSetting"] a következő kulccsalmyAppSetting:

import logging
import os

import azure.functions as func

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="req")
def main(req: func.HttpRequest) -> func.HttpResponse:
  # Get the setting named 'myAppSetting'
  my_app_setting_value = os.environ["myAppSetting"]
  logging.info(f'My app setting value:{my_app_setting_value}')

A helyi fejlesztéshez az alkalmazásbeállítások megmaradnak a local.settings.json fájlban.

Python-verzió

Az Azure Functions a következő Python-verziókat támogatja:

Functions-verzió Python*-verziók
4.x 3.11
3,10
3.9
3,8
3.7
3.x 3.9
3,8
3.7

* Hivatalos Python-disztribúciók

Ha egy adott Python-verziót szeretne kérni a függvényalkalmazás Azure-ban való létrehozásakor, használja a --runtime-version az functionapp create parancsot. A Functions futtatókörnyezet verzióját a --functions-version beállítás állítja be. A Python-verzió a függvényalkalmazás létrehozásakor van beállítva, és a Használat csomagban futó alkalmazások esetében nem módosítható.

A futtatókörnyezet az elérhető Python-verziót használja, amikor helyileg futtatja.

Python-verzió módosítása

Ha egy Python-függvényalkalmazást egy adott nyelvi verzióra szeretne beállítani, meg kell adnia a nyelv és a nyelv verzióját a LinuxFxVersion helykonfiguráció mezőjében. Ha például módosítani szeretné a Python alkalmazást a Python 3.8 használatára, állítsa be linuxFxVersion a következőt python|3.8: .

A webhelybeállítás megtekintéséről és módosításáról az linuxFxVersion Azure Functions futtatókörnyezeti verzióinak megcélzása című témakörben olvashat.

További általános információkért tekintse meg az Azure Functions futtatókörnyezet támogatási szabályzatát és az Azure Functions támogatott nyelveket.

Csomagkezelés

Ha a Core Tools vagy a Visual Studio Code használatával fejleszt helyileg, adja hozzá a szükséges csomagok nevét és verzióit a requirements.txt fájlhoz, majd telepítse őket a használatával pip.

Például a következő requirements.txt fájl és pip parancs használatával telepítheti a csomagot a requests PyPI-ból.

requests==2.19.1
pip install -r requirements.txt

Ha egy App Service-csomagban futtatja a függvényeket, a requirements.txt definiált függőségek elsőbbséget élveznek a beépített Python-modulokkal szemben, például logging. Ez az elsőbbség ütközéseket okozhat, ha a beépített modulok neve megegyezik a kód könyvtárainak nevével. Használatalapú csomagban vagy Rugalmas prémium csomagban való futtatás esetén az ütközések kevésbé valószínűek, mert a függőségek alapértelmezés szerint nem rangsorolásra kerülnek.

Az App Service-csomagban futó problémák elkerülése érdekében ne nevezze el a címtárakat ugyanúgy, mint bármely Python-natív modul, és ne foglalja bele a Python natív kódtárait a projekt requirements.txt fájljába.

Közzététel az Azure-ban

Ha készen áll a közzétételre, győződjön meg arról, hogy az összes nyilvánosan elérhető függőség szerepel a requirements.txt fájlban. Ezt a fájlt a projektkönyvtár gyökerében találja.

A közzétételből kizárt projektfájlokat és mappákat , beleértve a virtuális környezet mappát is, a projekt gyökérkönyvtárában találja.

A Python-projekt Azure-ban való közzétételéhez három buildelési művelet támogatott: távoli buildelés, helyi buildelés és egyéni függőségeket használó buildek.

Az Azure Pipelines használatával is létrehozhatja függőségeit, és folyamatos kézbesítéssel (CD) teheti közzé. További információ: Folyamatos teljesítés az Azure Pipelines használatával.

Távoli buildelés

Távoli build használatakor a kiszolgálón visszaállított függőségek és a natív függőségek megegyeznek az éles környezettel. Ez egy kisebb feltöltőcsomagot eredményez. Használjon távoli buildet, amikor Python-alkalmazásokat fejleszt Windows rendszeren. Ha a projekt egyéni függőségekkel rendelkezik, a távoli buildet további index URL-címmel is használhatja.

A függőségek a requirements.txt fájl tartalma alapján távolról lesznek lekértek . A távoli buildelés az ajánlott buildelési módszer. Alapértelmezés szerint a Core Tools távoli buildet kér, amikor az alábbi func azure functionapp publish paranccsal közzéteszi a Python-projektet az Azure-ban.

func azure functionapp publish <APP_NAME>

Ne felejtse el lecserélni <APP_NAME> a függvényalkalmazás nevét az Azure-ban.

A Visual Studio Code-hoz készült Azure Functions-bővítmény alapértelmezés szerint távoli buildet is kér.

Helyi build

A függőségek helyileg lesznek lekértek a requirements.txt fájl tartalma alapján. A távoli buildelést az alábbi func azure functionapp publish paranccsal megakadályozhatja, hogy helyi buildel tegye közzé a következőket:

func azure functionapp publish <APP_NAME> --build local

Ne felejtse el lecserélni <APP_NAME> a függvényalkalmazás nevét az Azure-ban.

A beállítás használatakor a --build local program beolvassa a projektfüggőségeket a requirements.txt fájlból, és ezek a függő csomagok helyileg lesznek letöltve és telepítve. A projektfájlok és függőségek a helyi számítógépről az Azure-ba vannak üzembe helyezve. Ez egy nagyobb üzembehelyezési csomagot eredményez az Azure-ba való feltöltéshez. Ha valamilyen okból nem tudja lekérni a requirements.txt fájlt a Core Tools használatával, a közzétételhez az egyéni függőségek lehetőséget kell használnia.

Nem javasoljuk, hogy helyi buildeket használjunk, amikor helyi fejlesztést használ Windows rendszeren.

Egyéni függőségek

Ha a projekt olyan függőségekkel rendelkezik, amelyek nem találhatók a Python-csomagindexben, kétféleképpen hozhatja létre a projektet. Az első módszer, a buildelési módszer attól függ, hogyan kell felépíteni a projektet.

Távoli build extra index URL-címmel

Ha a csomagok elérhetőek egy elérhető egyéni csomagindexből, használjon távoli buildet. A közzététel előtt mindenképpen hozzon létre egy alkalmazásbeállítástPIP_EXTRA_INDEX_URL. Ennek a beállításnak az értéke az egyéni csomagindex URL-címe. Ezzel a beállítással a távoli build a beállítással --extra-index-url futtathatópip install. További információkért tekintse meg a Python pip install dokumentációját.

Az alapszintű hitelesítési hitelesítő adatokat a csomagindex további URL-címeivel is használhatja. További információ: Alapszintű hitelesítési hitelesítő adatok a Python dokumentációjában.

Helyi csomagok telepítése

Ha a projekt olyan csomagokat használ, amelyek nem érhetők el nyilvánosan az eszközeink számára, azokat elérhetővé teheti az alkalmazás számára a __app__/.python_packages könyvtárba helyezésével. A közzététel előtt futtassa a következő parancsot a függőségek helyi telepítéséhez:

pip install  --target="<PROJECT_DIR>/.python_packages/lib/site-packages"  -r requirements.txt

Egyéni függőségek használatakor a közzétételi lehetőséget kell használnia --no-build , mert már telepítette a függőségeket a projektmappába.

func azure functionapp publish <APP_NAME> --no-build

Ne felejtse el lecserélni <APP_NAME> a függvényalkalmazás nevét az Azure-ban.

Egységtesztelés

A Pythonban írt függvények szabványos tesztelési keretrendszerek használatával tesztelhetők más Python-kódokkal. A legtöbb kötés esetében létrehozhat egy makett bemeneti objektumot egy megfelelő osztály példányának létrehozásával a azure.functions csomagból. Mivel a azure.functions csomag nem érhető el azonnal, mindenképpen telepítse a requirements.txt fájlon keresztül, a fenti csomagkezelési szakaszban leírtak szerint.

Ha például my_second_function , az alábbiakban egy HTTP-aktivált függvény modelltesztje látható:

Először hozzon létre egy <project_root/my_second_function>/function.json fájlt, majd definiálja ezt a függvényt HTTP-eseményindítóként.

{
  "scriptFile": "__init__.py",
  "entryPoint": "main",
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

Ezután implementálhatja és végrehajthatja my_second_function a shared_code.my_second_helper_function.

# <project_root>/my_second_function/__init__.py
import azure.functions as func
import logging

# Use absolute import to resolve shared_code modules
from shared_code import my_second_helper_function

# Define an HTTP trigger that accepts the ?value=<int> query parameter
# Double the value and return the result in HttpResponse
def main(req: func.HttpRequest) -> func.HttpResponse:
  logging.info('Executing my_second_function.')

  initial_value: int = int(req.params.get('value'))
  doubled_value: int = my_second_helper_function.double(initial_value)

  return func.HttpResponse(
    body=f"{initial_value} * 2 = {doubled_value}",
    status_code=200
    )
# <project_root>/shared_code/__init__.py
# Empty __init__.py file marks shared_code folder as a Python package
# <project_root>/shared_code/my_second_helper_function.py

def double(value: int) -> int:
  return value * 2

Elkezdhet teszteseteket írni a HTTP-eseményindítóhoz.

# <project_root>/tests/test_my_second_function.py
import unittest

import azure.functions as func
from my_second_function import main

class TestFunction(unittest.TestCase):
  def test_my_second_function(self):
    # Construct a mock HTTP request.
    req = func.HttpRequest(method='GET',
                           body=None,
                           url='/api/my_second_function',
                           params={'value': '21'})
    # Call the function.
    resp = main(req)

    # Check the output.
    self.assertEqual(resp.get_body(), b'21 * 2 = 42',)

.venv A Python virtuális környezet mappájában telepítse kedvenc Python-tesztkörnyezetét, példáulpip install pytest. Ezután futtassa pytest tests a teszt eredményét.

Először hozza létre a <project_root>/function_app.py fájlt, és implementálja a my_second_function függvényt HTTP-eseményindítóként és shared_code.my_second_helper_function.

# <project_root>/function_app.py
import azure.functions as func
import logging

# Use absolute import to resolve shared_code modules
from shared_code import my_second_helper_function

app = func.FunctionApp()

# Define the HTTP trigger that accepts the ?value=<int> query parameter
# Double the value and return the result in HttpResponse
@app.function_name(name="my_second_function")
@app.route(route="hello")
def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Executing my_second_function.')

    initial_value: int = int(req.params.get('value'))
    doubled_value: int = my_second_helper_function.double(initial_value)

    return func.HttpResponse(
        body=f"{initial_value} * 2 = {doubled_value}",
        status_code=200
    )
# <project_root>/shared_code/__init__.py
# Empty __init__.py file marks shared_code folder as a Python package
# <project_root>/shared_code/my_second_helper_function.py

def double(value: int) -> int:
  return value * 2

Elkezdhet teszteseteket írni a HTTP-eseményindítóhoz.

# <project_root>/tests/test_my_second_function.py
import unittest
import azure.functions as func

from function_app import main

class TestFunction(unittest.TestCase):
  def test_my_second_function(self):
    # Construct a mock HTTP request.
    req = func.HttpRequest(method='GET',
                           body=None,
                           url='/api/my_second_function',
                           params={'value': '21'})
    # Call the function.
    func_call = main.build().get_user_function()
    resp = func_call(req)
    # Check the output.
    self.assertEqual(
        resp.get_body(),
        b'21 * 2 = 42',
    )

A .venv Python virtuális környezet mappájában telepítse kedvenc Python-tesztkörnyezetét, példáulpip install pytest. Ezután futtassa pytest tests a teszt eredményét.

Ideiglenes fájlok

A tempfile.gettempdir() metódus egy ideiglenes mappát ad vissza, amely Linuxon / tmp. Az alkalmazás ezt a könyvtárat használhatja a függvények által létrehozott és használt ideiglenes fájlok tárolására, amikor azok futnak.

Fontos

Az ideiglenes könyvtárba írt fájlok nem garantáltan megmaradnak a meghívások között. A vertikális felskálázás során az ideiglenes fájlok nem lesznek megosztva a példányok között.

Az alábbi példa létrehoz egy elnevezett ideiglenes fájlt az ideiglenes könyvtárban (/tmp):

import logging
import azure.functions as func
import tempfile

from os import listdir

#---
   tempFilePath = tempfile.gettempdir()
   fp = tempfile.NamedTemporaryFile()
   fp.write(b'Hello world!')
   filesDirListInTemp = listdir(tempFilePath)

Javasoljuk, hogy a teszteket a projektmappától különálló mappában tartsa karban. Ez a művelet megakadályozza, hogy tesztkódot helyezzen üzembe az alkalmazással.

Előre telepített kódtárak

Néhány kódtár a Python-függvények futtatókörnyezetével rendelkezik.

A Python standard kódtára

A Python standard kódtára tartalmazza az egyes Python-disztribúciókhoz szállított beépített Python-modulok listáját. A kódtárak többsége segít elérni a rendszer funkcióit, például a fájlbemenetet/kimenetet (I/O). Windows rendszereken ezek a kódtárak Pythonnal vannak telepítve. Unix-alapú rendszereken csomaggyűjtemények biztosítják őket.

A Python-verzió kódtárának megtekintéséhez nyissa meg a következőt:

Az Azure Functions Python feldolgozói függőségei

Az Azure Functions Python-feldolgozónak egy adott kódtárkészletre van szüksége. Ezeket a kódtárakat a függvényekben is használhatja, de nem részei a Python szabványnak. Ha a függvények ezen kódtárak bármelyikére támaszkodnak, előfordulhat, hogy nem érhetők el a kódhoz, ha az Azure Functionsen kívül fut.

Feljegyzés

Ha a függvényalkalmazás requirements.txt fájlja tartalmaz egy bejegyzéstazure-functions-worker, távolítsa el. A függvényfeldolgozót automatikusan az Azure Functions platform felügyeli, és rendszeresen frissítjük új funkciókkal és hibajavításokkal. A feldolgozó egy régi verziójának manuális telepítése a requirements.txt fájlban váratlan problémákat okozhat.

Feljegyzés

Ha a csomag olyan kódtárakat tartalmaz, amelyek ütközhetnek a feldolgozó függőségeivel (például protobuf, tensorflow vagy grpcio), konfigurálja PYTHON_ISOLATE_WORKER_DEPENDENCIES 1 az alkalmazásbeállításokban, hogy az alkalmazás ne hivatkozhat a feldolgozó függőségeire.

Az Azure Functions Python-kódtára

Minden Python-feldolgozó frissítése tartalmazza az Azure Functions Python-kódtár (azure.functions) új verzióját. Ez a megközelítés megkönnyíti a Python-függvényalkalmazások folyamatos frissítését, mivel minden frissítés visszamenőlegesen kompatibilis. A kódtár kiadásainak listáját az Azure-functions PyPi-ban találja.

A futtatókörnyezeti kódtár verzióját az Azure kijavította, és a requirements.txt nem bírálhatja felül. A azure-functions requirements.txt bejegyzése csak a linting és az ügyfelek tudatosságára vonatkozik.

A pythonfüggvénytár aktuális verziójának nyomon követéséhez használja a következő kódot a futtatókörnyezetben:

getattr(azure.functions, '__version__', '< 1.2.1')

Futtatókörnyezeti rendszerkódtárak

A Python-feldolgozó Docker-lemezképeiben lévő előre telepített rendszerkódtárak listáját a következő témakörben találja:

Függvények futtatókörnyezete Debian-verzió Python-verziók
3.x-es verzió Buster Python 3.7
Python 3.8
Python 3.9

Python-feldolgozó bővítmények

Az Azure Functionsben futó Python-feldolgozó folyamat lehetővé teszi külső kódtárak integrálását a függvényalkalmazásba. Ezek a bővítménytárak köztes szoftverként működnek, amelyek adott műveleteket injektálhatnak a függvény végrehajtásának életciklusa során.

A bővítmények a függvénykódban ugyanúgy vannak importálva, mint egy szabványos Python-kódtármodul. A bővítmények a következő hatókörök alapján futnak:

Hatókör Leírás
Alkalmazásszintű Bármely függvény-eseményindítóba importálva a bővítmény az alkalmazás összes függvényvégrehajtására érvényes.
Függvényszint A végrehajtás csak arra a függvény-eseményindítóra korlátozódik, amelybe importálja.

Tekintse át az egyes bővítmények adatait, hogy többet tudjon meg arról a hatókörről, amelyben a bővítmény fut.

A bővítmények pythonos feldolgozóbővítmény-felületet implementálnak. Ez a művelet lehetővé teszi, hogy a Python-feldolgozó folyamat a függvény végrehajtási életciklusa során behívja a bővítménykódot. További információ: Bővítmények létrehozása.

Bővítmények használata

A Python-függvényekben pythonos feldolgozóbővítménytárat az alábbi módon használhat:

  1. Adja hozzá a bővítménycsomagot a projekt requirements.txt fájljához.
  2. Telepítse a kódtárat az alkalmazásba.
  3. Adja hozzá a következő alkalmazásbeállításokat:
  4. Importálja a bővítménymodult a függvényindítóba.
  5. Szükség esetén konfigurálja a bővítménypéldányt. A konfigurációs követelményeket a bővítmény dokumentációjában kell megadni.

Fontos

A Microsoft nem támogatja vagy garantálja a külső Python-feldolgozóbővítmény-kódtárakat. Győződjön meg arról, hogy a függvényalkalmazásban használt bővítmények megbízhatóak, és teljes mértékben fennáll a veszélye annak, hogy rosszindulatú vagy rosszul írt bővítményt használ.

A külső feleknek konkrét dokumentációt kell nyújtaniuk a bővítmények a függvényalkalmazásban való telepítéséről és felhasználásáról. A bővítmények használatára vonatkozó alapvető példa: A bővítmény használata.

Íme néhány példa a bővítmények függvényalkalmazásban való használatára hatókör szerint:

# <project_root>/requirements.txt
application-level-extension==1.0.0
# <project_root>/Trigger/__init__.py

from application_level_extension import AppExtension
AppExtension.configure(key=value)

def main(req, context):
  # Use context.app_ext_attributes here

Bővítmények létrehozása

A bővítményeket külső könyvtárfejlesztők hozzák létre, akik olyan funkciókat hoztak létre, amelyek integrálhatók az Azure Functionsbe. A bővítményfejlesztők olyan Python-csomagokat terveznek, implementálnak és bocsátanak ki, amelyek kifejezetten a függvényvégrehajtás kontextusában futtatandó egyéni logikát tartalmaznak. Ezek a bővítmények közzétehetők a PyPI-beállításjegyzékben vagy a GitHub-adattárakban.

A Python-feldolgozóbővítmény-csomagok létrehozásának, csomagolásának, közzétételének és felhasználásának megismeréséhez lásd : Python-feldolgozóbővítmények fejlesztése az Azure Functionshez.

Alkalmazásszintű bővítmények

Egy alkalmazás hatókörében futó futtatásoktól AppExtensionBase öröklődő bővítmény.

AppExtensionBase a következő absztrakt osztálymódszereket teszi elérhetővé a megvalósításhoz:

Metódus Leírás
init A bővítmény importálása után hívható meg.
configure Függvénykódból hívható meg, amikor a bővítmény konfigurálásához szükség van rá.
post_function_load_app_level Közvetlenül a függvény betöltése után hívva. A függvény nevét és függvénykönyvtárát a rendszer átadja a bővítménynek. Ne feledje, hogy a függvénykönyvtár írásvédett, és a könyvtárban lévő helyi fájlba való írási kísérlet meghiúsul.
pre_invocation_app_level Közvetlenül a függvény aktiválása előtt hívható meg. A függvénykörnyezet és a függvényhívás argumentumai a bővítménynek lesznek átadva. A függvénykód használatához általában más attribútumokat is átadhat a környezeti objektumban.
post_invocation_app_level Közvetlenül a függvény végrehajtása után hívva. A függvénykörnyezet, a függvényhívási argumentumok és a meghívás visszatérési objektuma át lesz adva a bővítménynek. Ez a megvalósítás jó hely annak ellenőrzésére, hogy az életciklus-horgok végrehajtása sikeres volt-e.

Függvényszintű bővítmények

A FuncExtensionBase-től öröklő bővítmény egy adott függvény-eseményindítóban fut.

FuncExtensionBase az implementációkhoz a következő absztrakt osztálymódszereket teszi elérhetővé:

Metódus Leírás
__init__ A bővítmény konstruktora. A függvény akkor hívja meg, ha egy bővítménypéldányt inicializál egy adott függvényben. Az absztrakt metódus megvalósításakor érdemes lehet elfogadni egy paramétert filename , és átadni a szülő metódusának super().__init__(filename) a megfelelő bővítményregisztrációhoz.
post_function_load Közvetlenül a függvény betöltése után hívva. A függvény nevét és függvénykönyvtárát a rendszer átadja a bővítménynek. Ne feledje, hogy a függvénykönyvtár írásvédett, és a könyvtárban lévő helyi fájlba való írási kísérlet meghiúsul.
pre_invocation Közvetlenül a függvény aktiválása előtt hívható meg. A függvénykörnyezet és a függvényhívás argumentumai a bővítménynek lesznek átadva. A függvénykód használatához általában más attribútumokat is átadhat a környezeti objektumban.
post_invocation Közvetlenül a függvény végrehajtása után hívva. A függvénykörnyezet, a függvényhívási argumentumok és a meghívás visszatérési objektuma át lesz adva a bővítménynek. Ez a megvalósítás jó hely annak ellenőrzésére, hogy az életciklus-horgok végrehajtása sikeres volt-e.

Eltérő eredetű erőforrások megosztása

Az Azure Functions támogatja a forrásközi erőforrás-megosztást (CORS). A CORS a portálon és az Azure CLI-ben van konfigurálva. A CORS által engedélyezett forráslista a függvényalkalmazás szintjén érvényes. Ha a CORS engedélyezve van, a válaszok tartalmazzák a fejlécet Access-Control-Allow-Origin . További információ: Eltérő eredetű erőforrás-megosztás

A több forrásból származó erőforrás-megosztás (CORS) teljes mértékben támogatott a Python-függvényalkalmazásokban.

Aszinkron

A Python gazdagéppéldányai alapértelmezés szerint egyszerre csak egy függvényhívást képesek feldolgozni. Ennek az az oka, hogy a Python egy egyszálas futtatókörnyezet. Olyan függvényalkalmazások esetében, amelyek nagy számú I/O-eseményt dolgoznak fel, vagy I/O-kötöttek, a függvények aszinkron futtatásával jelentősen javíthatja a teljesítményt. További információ: A Python-alkalmazások teljesítményének javítása az Azure Functionsben.

Megosztott memória (előzetes verzió)

Az átviteli sebesség javítása érdekében az Azure Functions lehetővé teszi, hogy a folyamaton kívüli Python-nyelvi feldolgozó memóriát osztson meg a Functions-gazdafolyamattal. Ha a függvényalkalmazás szűk keresztmetszeteket ér el, engedélyezheti a megosztott memóriát úgy, hogy hozzáad egy FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED nevű alkalmazásbeállítást, amelynek értéke a következő1. Ha engedélyezve van a megosztott memória, a DOCKER_SHM_SIZE beállítással a megosztott memóriát 256 MB-nak megfelelő értékre 268435456állíthatja.

Például engedélyezheti a megosztott memóriát, hogy csökkentse a szűk keresztmetszeteket, ha Blob Storage-kötéseket használ az 1 MB-nál nagyobb hasznos adatok átviteléhez.

Ez a funkció csak prémium és dedikált (Azure-alkalmazás szolgáltatáscsomagokban) futó függvényalkalmazásokhoz érhető el. További információ: Megosztott memória.

Ismert problémák és gyakori kérdések

Az alábbiakban két hibaelhárítási útmutatót talál a gyakori problémákhoz:

A v2 programozási modell ismert problémáihoz két hibaelhárítási útmutatót talál:

Az összes ismert probléma és funkciókérés nyomon követhető a GitHub-problémák listájában. Ha problémába ütközik, és nem találja a problémát a GitHubon, nyisson meg egy új problémát, és adja meg a probléma részletes leírását.

Következő lépések

További információt a következő források tartalmaznak:

Problémákat tapasztal a Python használatával kapcsolatban? Mondja el, mi folyik itt.