Sdílet prostřednictvím


Azure Functions – Příručka pro vývojáře v Pythonu

Tento průvodce představuje úvod do vývoje azure Functions pomocí Pythonu. Článek předpokládá, že jste už přečetli příručku pro vývojáře Azure Functions.

Důležité

Tento článek podporuje programovací model v1 i v2 pro Python ve službě Azure Functions. Model Pythonu v1 používá k definování funkcí soubor functions.json a nový model v2 umožňuje místo toho použít přístup založený na dekorátoru. Výsledkem tohoto nového přístupu je jednodušší struktura souborů, která je zaměřená na kód. V horní části článku zvolte selektor v2, abyste se dozvěděli o tomto novém programovacím modelu.

Jako vývojář Pythonu vás můžou zajímat také tato témata:

  • Visual Studio Code: Vytvořte svou první aplikaci v Pythonu pomocí editoru Visual Studio Code.
  • Terminál nebo příkazový řádek: Vytvořte svou první aplikaci v Pythonu z příkazového řádku pomocí nástrojů Azure Functions Core Tools.
  • Ukázky: Projděte si některé existující aplikace Pythonu v prohlížeči ukázek Learn.
  • Visual Studio Code: Vytvořte svou první aplikaci v Pythonu pomocí editoru Visual Studio Code.
  • Terminál nebo příkazový řádek: Vytvořte svou první aplikaci v Pythonu z příkazového řádku pomocí nástrojů Azure Functions Core Tools.
  • Ukázky: Projděte si některé existující aplikace Pythonu v prohlížeči ukázek Learn.

Možnosti vývoje

Oba programovací modely Python Functions podporují místní vývoj v jednom z následujících prostředí:

Programovací model Pythonu v2:

Programovací model Pythonu v1:

Funkce Pythonu můžete vytvářet také na webu Azure Portal.

Návod

I když můžete vyvíjet funkce Azure založené na Pythonu místně ve Windows, Python se podporuje jenom v plánu hostování založeném na Linuxu, když běží v Azure. Další informace najdete v seznamu podporovaných kombinací operačního systému nebo modulu runtime.

Programovací model

Služba Azure Functions očekává, že ve skriptu Pythonu bude funkce bezstavová metoda, která zpracuje vstup a vytvoří výstup. Modul runtime ve výchozím nastavení očekává, že se metoda implementuje jako globální metoda volaná main() v souboru __init__.py . Můžete také zadat alternativní vstupní bod.

Data se váže na funkci z triggerů a vazeb prostřednictvím atributů metody, které používají name vlastnost definovanou v souboru function.json . Například následující soubor function.json popisuje jednoduchou funkci aktivovanou požadavkem HTTP s názvem req:

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

Na základě této definice může soubor __init__.py, který obsahuje kód funkce, vypadat jako v následujícím příkladu:

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

Pomocí poznámek k typu Pythonu můžete také explicitně deklarovat typy atributů a návratový typ funkce. To vám pomůže používat IntelliSense a funkce automatického dokončování, které poskytuje mnoho editorů kódu Pythonu.

import azure.functions

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

Pomocí poznámek Pythonu, které jsou součástí balíčku azure.functions.* k vytvoření vazby vstupu a výstupů k vašim metodám.

Služba Azure Functions očekává, že ve skriptu Pythonu bude funkce bezstavová metoda, která zpracuje vstup a vytvoří výstup. Modul runtime ve výchozím nastavení očekává, že se metoda implementuje jako globální metoda v souboru function_app.py .

Triggery a vazby lze deklarovat a používat ve funkci v přístupu založeném na dekorátoru. Jsou definované ve stejném souboru function_app.py jako funkce. Například následující soubor function_app.py představuje funkci spuštěnou HTTP požadavkem.

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

Pomocí poznámek k typu Pythonu můžete také explicitně deklarovat typy atributů a návratový typ funkce. To vám pomůže používat funkce IntelliSense a automatické dokončování, které poskytuje mnoho editorů kódu Pythonu.

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}!"

Informace o známých omezeních modelu v2 a jejich alternativních řešeních najdete v tématu Řešení chyb Pythonu ve službě Azure Functions.

Alternativní vstupní bod

Výchozí chování funkce můžete změnit volitelně zadáním vlastností scriptFile a entryPoint v souboru function.json. Například následující function.json modulu runtime říká, aby jako vstupní bod vaší funkce Azure použil customentry() metodu v souboru main.py .

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

Vstupní bod je pouze v souboru function_app.py . Na funkce v projektu však můžete odkazovat v function_app.py pomocí podrobných plánů nebo importem.

Struktura složek

Doporučená struktura složek pro projekt funkcí Pythonu vypadá jako v následujícím příkladu:

 <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

Hlavní složka projektu, <project_root>, může obsahovat následující soubory:

  • local.settings.json: Používá se k ukládání nastavení aplikací a připojovací řetězec při místním spuštění. Tento soubor se nepublikuje do Azure. Další informace najdete v souboru local.settings.file.
  • requirements.txt: Obsahuje seznam balíčků Pythonu, které systém nainstaluje při publikování do Azure.
  • host.json: Obsahuje možnosti konfigurace, které ovlivňují všechny funkce v instanci aplikace funkcí. Tento soubor se publikuje do Azure. Při místním spuštění nejsou podporované všechny možnosti. Další informace najdete v tématu host.json.
  • .vscode/: (volitelné) Obsahuje uloženou konfiguraci editoru Visual Studio Code. Další informace najdete v nastavení editoru Visual Studio Code.
  • .venv/: (volitelné) Obsahuje virtuální prostředí Pythonu používané místním vývojem.
  • Dockerfile: (Volitelné) Používá se při publikování projektu ve vlastním kontejneru.
  • tests/: (Volitelné) Obsahuje testovací případy vaší aplikace funkcí.
  • .funcignore: (Volitelné) Deklaruje soubory, které by se neměly publikovat do Azure. Tento soubor obvykle obsahuje soubor .vscode/ pro ignorování nastavení editoru , .venv/ pro ignorování místního virtuálního prostředí Pythonu, testů a ignorování testovacích případů a local.settings.json , aby se zabránilo publikování místního nastavení aplikace.

Každá funkce má vlastní soubor kódu a konfigurační soubor vazby function.json.

Doporučená struktura složek pro projekt funkcí Pythonu vypadá jako v následujícím příkladu:

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

Hlavní složka projektu, <project_root>, může obsahovat následující soubory:

  • .venv/: (Volitelné) Obsahuje virtuální prostředí Pythonu, které používá místní vývoj.
  • .vscode/: (volitelné) Obsahuje uloženou konfiguraci editoru Visual Studio Code. Další informace najdete v nastavení editoru Visual Studio Code.
  • function_app.py: Výchozí umístění pro všechny funkce a související triggery a vazby.
  • additional_functions.py: (Volitelné) Všechny ostatní soubory Pythonu, které obsahují funkce (obvykle pro logické seskupení), které jsou odkazovány v function_app.py prostřednictvím podrobných plánů.
  • tests/: (Volitelné) Obsahuje testovací případy vaší aplikace funkcí.
  • .funcignore: (Volitelné) Deklaruje soubory, které by se neměly publikovat do Azure. Tento soubor obvykle obsahuje soubor .vscode/ pro ignorování nastavení editoru , .venv/ pro ignorování místního virtuálního prostředí Pythonu, testů/ ignorování testovacích případů a local.settings.json , aby se zabránilo publikování nastavení místní aplikace.
  • host.json: Obsahuje možnosti konfigurace, které ovlivňují všechny funkce v instanci aplikace funkcí. Tento soubor se publikuje do Azure. Při místním spuštění nejsou podporované všechny možnosti. Další informace najdete v tématu host.json.
  • local.settings.json: Slouží k ukládání nastavení aplikací a připojovacích řetězců při místním spuštění aplikace. Tento soubor se nepublikuje do Azure. Další informace najdete v souboru local.settings.file.
  • requirements.txt: Obsahuje seznam balíčků Pythonu, které systém nainstaluje při publikování do Azure.
  • Dockerfile: (Volitelné) Používá se při publikování projektu ve vlastním kontejneru.

Když projekt nasadíte do aplikace funkcí v Azure, celý obsah hlavní složky projektu project_root <>by měl být součástí balíčku, ale ne do samotné složky, což znamená, že host.json by měl být v kořenovém adresáři balíčku. Doporučujeme udržovat testy ve složce spolu s dalšími funkcemi (v tomto příkladu testy/). Další informace najdete v tématu Jednotkové testování.

Připojit k databázi

Azure Functions se dobře integruje se službou Azure Cosmos DB pro mnoho případů použití, včetně IoT, elektronického obchodování, hraní atd.

Například pro event sourcing jsou tyto dvě služby integrovány za účelem podpory architektur řízených událostmi pomocí funkce kanálu změn služby Azure Cosmos DB. Kanál změn umožňuje podřízeným mikroslužbám spolehlivě a postupně číst vkládané a aktualizované záznamy (například události objednávek). Tuto funkci lze použít k zajištění trvalého úložiště událostí, které slouží jako zprostředkovatel zpráv pro události změn stavu, a k řízení pracovního postupu zpracování objednávek mezi mnoha mikroslužbami (které je možné implementovat jako bezserverové funkce Azure Functions).

Referenční architektura zpracování objednávek ve službě Azure Cosmos DB

Pokud se chcete připojit ke službě Azure Cosmos DB, nejprve vytvořte účet, databázi a kontejner. Pak můžete kód funkce připojit ke službě Azure Cosmos DB pomocí triggeru a vazeb, jako je tento příklad.

Pokud chcete implementovat složitější logiku aplikace, můžete také použít knihovnu Pythonu pro Cosmos DB. Asynchronní implementace vstupně-výstupních operací vypadá takto:

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

Plány

Programovací model Pythonu v2 představuje koncept podrobných plánů. Blueprint je nová třída, která je inicializována pro registraci funkcí mimo hlavní funkční aplikaci. Funkce zaregistrované v instancích blueprintu nejsou indexovány přímo modulem runtime funkce. Aby se tyto funkce podrobného plánu indexovaly, musí aplikace funkcí zaregistrovat funkce z instancí podrobného plánu.

Použití podrobných plánů poskytuje následující výhody:

  • Umožňuje rozdělit aplikaci funkcí na modulární komponenty, které umožňují definovat funkce ve více souborech Pythonu a rozdělit je na jednotlivé soubory.
  • Poskytuje rozšiřitelná rozhraní veřejných aplikací funkcí pro sestavování a opakované použití vlastních rozhraní API.

Následující příklad ukazuje, jak používat podrobné plány:

Nejprve je v souboru http_blueprint.py definována funkce aktivovaná protokolem HTTP a přidána do objektu podrobného plánu.

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 
        ) 

Dále se v souboru function_app.py naimportuje objekt podrobného plánu a jeho funkce se zaregistrují do aplikace funkcí.

import azure.functions as func 
from http_blueprint import bp

app = func.FunctionApp() 

app.register_functions(bp) 

Poznámka:

Durable Functions také podporuje podrobné plány. Pokud chcete vytvářet podrobné plány pro aplikace Durable Functions, zaregistrujte orchestraci, aktivitu a triggery entit a vazby klientů pomocí azure-functions-durableBlueprint třídy, jak je znázorněno zde. Výsledný podrobný plán je pak možné zaregistrovat jako normální. Příklad najdete v naší ukázce .

Chování importu

Moduly v kódu funkce můžete importovat pomocí absolutních i relativních odkazů. Na základě dříve popsané struktury složek fungují následující importy z souboru <funkce project_root>\my_first_function\__init__.py:

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

Poznámka:

Pokud používáte absolutní syntaxi importu, musí shared_code/ složka obsahovat soubor __init__.py , který ho označí jako balíček Pythonu.

Následující __app__ import a nad rámec relativního importu nejvyšší úrovně jsou zastaralé, protože nejsou podporovány kontrolou statického typu a nepodporují se testovacími architekturami Pythonu:

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)

Triggery a vstupy

Vstupy jsou ve službě Azure Functions rozdělené do dvou kategorií: spouštěcí vstup a jiný vstup. I když se v souboru function.json liší, jejich použití je v kódu Pythonu stejné. Připojovací řetězce nebo tajemství pro spouštěč a vstupní zdroje se mapují na hodnoty v souboru local.settings.json , když jsou spuštěné místně, a při spuštění v Azure se mapují na nastavení aplikace.

Například následující kód ukazuje rozdíl mezi těmito dvěma vstupy:

// 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()}')

Při vyvolání funkce se požadavek HTTP předá funkci jako req. Položka se načte z účtu služby Azure Blob Storage podle ID v adrese URL trasy a následně je zpřístupněna jako obj v těle funkce. Tady je účet úložiště zadaný pomocí připojovacího řetězce, který se nachází v nastavení aplikace <*_CONNECTION_STRING>. Další informace naleznete v tématu Další informace naleznete v tématu Připojení.

Vstupy jsou ve službě Azure Functions rozdělené do dvou kategorií: spouštěcí vstup a jiný vstup. I když jsou definované pomocí různých dekorátorů, jejich použití je podobné v kódu Pythonu. Připojovací řetězce nebo tajemství pro spouštěč a vstupní zdroje se mapují na hodnoty v souboru local.settings.json , když jsou spuštěné místně, a při spuštění v Azure se mapují na nastavení aplikace.

Následující kód například ukazuje, jak definovat vstupní vazbu služby Blob Storage:

// 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.blob_input(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()}')

Při vyvolání funkce se požadavek HTTP předá funkci jako req. Položka se načte z účtu služby Azure Blob Storage podle ID v adrese URL trasy a následně je zpřístupněna jako obj v těle funkce. Určený účet úložiště je připojovací řetězec, který je nalezen v <*_CONNECTION_STRING> nastavení aplikace. Další informace naleznete v tématu Další informace naleznete v tématu Připojení.

Pro operace s vazbami náročnými na data můžete chtít použít samostatný účet úložiště. Pro více informací se podívejte na Pokyny k účtům úložiště.

Vazby typu sady SDK

U vybraných triggerů a vazeb můžete pracovat s datovými typy implementovanými podkladovými sadami Azure SDK a architekturami. Tyto vazby typu sady SDK vám umožňují pracovat s daty vazby, jako kdybyste používali základní sadu SDK služby.

"> [! DŮLEŽITÉ]

Použití vazeb typu sady SDK vyžaduje programovací model Pythonu v2.

Důležité

Podpora vazeb typu sady SDK pro Python je podporována pouze v programovacím modelu Pythonu v2.

Požadavky

Typy SDK

Služba Spouštěč Vstupní vazba Výstupní vazba Vzorky
Azure Blob Obecná dostupnost Obecná dostupnost Nedoporučují se typy sad SDK.1 Rychlý start
BlobClient,
ContainerClient,
StorageStreamDownloader
Azure Cosmos DB Typy sad SDK se nepoužívají2 Náhled Nedoporučují se typy sad SDK.1 Rychlý start
ContainerProxy,
CosmosClient,
DatabaseProxy
Azure Event Hubs Náhled Vstupní vazba neexistuje. Nedoporučují se typy sad SDK.1 Rychlý start
EventData
Azure Service Bus Náhled Vstupní vazba neexistuje. Nedoporučují se typy sad SDK.1 Rychlý start
ServiceBusReceivedMessage

1 Pro výstupní scénáře, ve kterých byste použili typ sady SDK, byste měli vytvořit a pracovat s klienty sady SDK přímo místo použití výstupní vazby. 2 Trigger služby Cosmos DB používá kanál změn služby Azure Cosmos DB a zveřejňuje položky kanálu změn jako serializovatelné typy JSON. Absence typů sady SDK je pro tento scénář záměrná.

Streamy HTTP

Streamy HTTP umožňují přijímat a vracet data z koncových bodů HTTP pomocí rozhraní API požadavků FastAPI a odpovědí povolených ve vašich funkcích. Tato rozhraní API umožňují hostiteli zpracovávat velká data ve zprávách HTTP jako bloky dat místo čtení celé zprávy do paměti.

Tato funkce umožňuje zpracovávat velké datové proudy, integrace OpenAI, dodávat dynamický obsah a podporovat další základní scénáře HTTP vyžadující interakce v reálném čase přes HTTP. U streamů HTTP můžete také použít typy odpovědí FastAPI. Bez datových proudů HTTP jsou velikost požadavků a odpovědí HTTP omezena omezeními paměti, ke kterým může dojít při zpracování celých datových částí zpráv v paměti.

Další informace, včetně povolení streamů HTTP v projektu, najdete v tématu Streamy HTTP.

Důležité

Podpora datových proudů HTTP vyžaduje programovací model Pythonu v2.

Důležité

Podpora datových proudů HTTP pro Python je obecně dostupná a vyžaduje, abyste používali programovací model Pythonu v2.

Výstupy

Výstup se dá vyjádřit jak ve návratové hodnotě, tak ve výstupních parametrech. Pokud existuje jenom jeden výstup, doporučujeme použít návratovou hodnotu. Pro více výstupů musíte použít výstupní parametry.

Chcete-li použít návratovou hodnotu funkce jako hodnotu výstupní vazby, name vlastnost vazby by měla být nastavena na $return v souboru function.json .

Chcete-li vytvořit více výstupů, použijte metodu set() poskytovanou azure.functions.Out rozhraním k přiřazení hodnoty k vazbě. Například následující funkce může odeslat zprávu do fronty a také vrátit odpověď HTTP.

{
  "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

Výstup se dá vyjádřit jak ve návratové hodnotě, tak ve výstupních parametrech. Pokud existuje jenom jeden výstup, doporučujeme použít návratovou hodnotu. Pro více výstupů budete muset použít výstupní parametry.

Chcete-li vytvořit více výstupů, použijte metodu set() poskytovanou azure.functions.Out rozhraním k přiřazení hodnoty k vazbě. Například následující funkce může odeslat zprávu do fronty a také vrátit odpověď HTTP.

# 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

Protokolování

Přístup k protokolovacímu modulu runtime Azure Functions je k dispozici prostřednictvím kořenové logging obslužné rutiny ve vaší aplikaci funkcí. Tento protokolovací modul je svázaný s Application Insights a umožňuje označit upozornění a chyby, ke kterým dochází během provádění funkce.

Následující příklad zaznamená informační zprávu při vyvolání funkce prostřednictvím triggeru HTTP.

import logging

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

K dispozici jsou další metody protokolování, které umožňují zapisovat do konzoly na různých úrovních trasování:

metoda Popis
critical(_message_) Zapíše zprávu s úrovní KRITICKÁ v kořenovém protokolovacím nástroji.
error(_message_) Zapíše zprávu s úrovní ERROR v kořenovém protokolovacím nástroji.
warning(_message_) Zapíše zprávu s úrovní WARNING do kořenového loggeru.
info(_message_) Zapíše zprávu s informací o úrovni v kořenovém protokolovacím systému.
debug(_message_) Zapíše zprávu na kořenovém loggeru s úrovní DEBUG.

Další informace o protokolování najdete v tématu Monitorování Azure Functions.

Protokolování z vytvořených vláken

Pokud chcete zobrazit protokoly pocházející z vytvořených vláken, zahrňte context do podpisu funkce argument. Tento argument obsahuje atribut thread_local_storage , který ukládá místní invocation_id. To lze nastavit na aktuální invocation_id funkci, aby se zajistilo, že se kontext změní.

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

Protokolování vlastní telemetrie

Modul runtime služby Functions ve výchozím nastavení shromažďuje protokoly a další telemetrická data generovaná vašimi funkcemi. Tato telemetrie končí jako stopy ve službě Application Insights. Telemetrie požadavků a závislostí pro určité služby Azure se ve výchozím nastavení shromažďují také pomocí triggers a vazeb.

Pokud chcete shromažďovat telemetrii vlastních požadavků a vlastních závislostí mimo vazby, můžete použít OpenCensus Python rozšíření. Toto rozšíření odesílá vlastní telemetrická data do vaší instance Application Insights. Seznam podporovaných rozšíření najdete v úložišti OpenCensus.

Poznámka:

Pokud chcete použít rozšíření OpenCensus Python, musíte ve své aplikaci funkcí povolit rozšíření pracovních procesů Pythonu nastavením PYTHON_ENABLE_WORKER_EXTENSIONS na 1. Také musíte přepnout na používání připojovacího řetězce Application Insights tím, že do APPLICATIONINSIGHTS_CONNECTION_STRING přidáte , pokud tam ještě není.

// 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 spouštěč

Trigger HTTP je definován v souboru function.json . Vazba name musí odpovídat pojmenovaného parametru ve funkci. V předchozích příkladech se používá vazební název req. Tento parametr je objekt HttpRequest a je vrácen objekt HttpResponse .

Z objektu HttpRequest můžete získat hlavičky požadavku, parametry dotazu, parametry trasy a text zprávy.

Následující příklad je ze šablony triggeru HTTP pro Python.

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
        )

V této funkci získáte hodnotu parametru name dotazu z params parametru HttpRequest objektu. Text zprávy kódovaný ve formátu JSON si můžete přečíst pomocí get_json metody.

Podobně můžete nastavit status_code a headers pro zprávu odpovědi ve vráceném objektu HttpResponse.

Trigger HTTP je definován jako metoda, která přebírá pojmenovaný binding parametr, což je HttpRequest objekt a vrací HttpResponse objekt. Dekorátor function_name použijete na metodu pro definování názvu funkce, zatímco dekorátor route je použit pro nastavení koncového bodu HTTP.

Tento příklad pochází ze šablony triggeru HTTP pro programovací model Pythonu v2, kde je reqnázev parametru vazby . Jedná se o ukázkový kód, který je k dispozici při vytváření funkce pomocí nástrojů Azure Functions Core Tools nebo editoru Visual Studio Code.

@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
        )

Z objektu HttpRequest můžete získat hlavičky požadavku, parametry dotazu, parametry trasy a text zprávy. V této funkci získáte hodnotu parametru name dotazu z params parametru HttpRequest objektu. Text zprávy kódovaný ve formátu JSON si můžete přečíst pomocí get_json metody.

Podobně můžete nastavit status_code a headers pro zprávu odpovědi ve vráceném objektu HttpResponse.

Pokud chcete předat název v tomto příkladu, vložte adresu URL, která je zadaná při spuštění funkce, a pak ji připojte pomocí "?name={name}".

Webové architektury

S funkcemi Pythonu aktivovanými protokolem HTTP můžete použít rozhraní kompatibilní s WSGI (Web Server Gateway Interface) a ASGI (Asynchronous Server Gateway Interface) frameworky, jako jsou Flask a FastAPI. Tato část ukazuje, jak upravit funkce tak, aby podporovaly tyto architektury.

Nejprve musí být soubor function.json aktualizován tak, aby zahrnoval route trigger HTTP, jak je znázorněno v následujícím příkladu:

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

Soubor host.json musí být také aktualizován tak, aby zahrnoval PROTOKOL HTTP routePrefix, jak je znázorněno v následujícím příkladu:

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

Aktualizujte soubor kódu Pythonu init.py v závislosti na rozhraní používaném vaší architekturou. Následující příklad ukazuje buď přístup obslužné rutiny ASGI nebo obálkový přístup WSGI pro Flask aplikaci.

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)

S vašimi Python funkcemi aktivovanými protokolem HTTP můžete použít frameworky kompatibilní s asynchronním rozhraním serveru (ASGI) a rozhraním webového serveru (WSGI), jako jsou Flask a FastAPI. Nejprve je nutné aktualizovat soubor host.json tak, aby zahrnoval PROTOKOL HTTP routePrefix, jak je znázorněno v následujícím příkladu:

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

Kód architektury vypadá jako v následujícím příkladu:

AsgiFunctionApp je třída aplikace funkcí nejvyšší úrovně pro vytváření funkcí ASGI HTTP.

# 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) 

Škálování a výkon

Osvědčené postupy škálování a výkonu pro aplikace funkcí Pythonu najdete v článku o škálování a výkonu Pythonu.

Kontext

Pokud chcete získat kontext vyvolání funkce při jeho spuštění, zahrňte context do podpisu argument.

Příklad:

import azure.functions


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

Třída Context má následující řetězcové atributy:

Atribut Popis
function_directory Adresář, ve kterém je funkce spuštěná.
function_name Název funkce.
invocation_id ID vyvolání aktuální funkce.
thread_local_storage Lokální úložiště vlákna funkce. Obsahuje místní invocation_id prostředí pro protokolování z vytvořených vláken.
trace_context Kontext distribuovaného trasování. Další informace najdete na webu Trace Context.
retry_context Kontext pro opakování pokusů funkce. Další informace najdete na webu retry-policies.

Globální proměnné

Není zaručeno, že se stav vaší aplikace zachová pro budoucí spuštění. Modul runtime Azure Functions ale často používá stejný proces pro více spuštění stejné aplikace. Pokud chcete výsledky nákladného výpočtu uložit do mezipaměti, deklarujte ho jako globální proměnnou.

CACHED_DATA = None


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

    # ... use CACHED_DATA in code

Proměnné prostředí

V rámci Azure Functions jsou nastavení aplikace, jako jsou připojovací řetězce služeb, vystaveny jako proměnné prostředí při běhu. Existují dva hlavní způsoby přístupu k těmto nastavením v kódu.

metoda Popis
os.environ["myAppSetting"] Pokusí se získat nastavení aplikace podle názvu klíče a vyvolá chybu, když je neúspěšná.
os.getenv("myAppSetting") Pokusí se získat nastavení aplikace podle názvu klíče a vrátí None , když je neúspěšná.

Oba tyto způsoby vyžadují, abyste deklarovali import os.

Následující příklad používá os.environ["myAppSetting"] k získání nastavení aplikace s klíčem pojmenovaným :

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}')

Pro místní vývoj se nastavení aplikace udržuje v souboru local.settings.json.

V rámci Azure Functions jsou nastavení aplikace, jako jsou připojovací řetězce služeb, vystaveny jako proměnné prostředí při běhu. Existují dva hlavní způsoby přístupu k těmto nastavením v kódu.

metoda Popis
os.environ["myAppSetting"] Pokusí se získat nastavení aplikace podle názvu klíče a vyvolá chybu, když je neúspěšná.
os.getenv("myAppSetting") Pokusí se získat nastavení aplikace podle názvu klíče a vrátí None , když je neúspěšná.

Oba tyto způsoby vyžadují, abyste deklarovali import os.

Následující příklad používá os.environ["myAppSetting"] k získání nastavení aplikace s klíčem pojmenovaným :

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}')

Pro místní vývoj se nastavení aplikace udržuje v souboru local.settings.json.

Verze Pythonu

Azure Functions podporuje následující verze Pythonu:

Verze služby Functions Verze Pythonu*
4.x 3.12
3.11
3,10

* Oficiální distribuce Pythonu

Pokud chcete při vytváření aplikace funkcí v Azure požádat o konkrétní verzi Pythonu, použijte možnost --runtime-version příkazu az functionapp create. Verze runtime Functions je nastavena možností --functions-version. Verze Pythonu se nastavuje při vytváření aplikace funkcí a nedá se změnit pro aplikace spuštěné v plánu Consumption.

Modul runtime používá dostupnou verzi Pythonu při místním spuštění.

Změna verze Pythonu

Pokud chcete nastavit aplikaci funkcí Pythonu na konkrétní jazykovou verzi, musíte zadat jazyk a verzi jazyka v LinuxFxVersion poli v konfiguraci webu. Pokud chcete například změnit aplikaci Python tak, aby používala Python 3.12, nastavte linuxFxVersion na python|3.12.

Informace o tom, jak zobrazit a změnit nastavení webu, najdete v tématu linuxFxVersionJak cílit na verze modulu runtime Azure Functions.

Další obecné informace najdete v zásadách podpory modulu runtime Azure Functions a podporovaných jazycích ve službě Azure Functions.

Správa balíčků

Při místním vývoji pomocí nástrojů Core Tools nebo editoru Visual Studio Code přidejte názvy a verze požadovaných balíčků do souboru requirements.txt a pak je nainstalujte pomocí pip.

Můžete například použít následující PyPI.

requests==2.19.1
pip install -r requirements.txt

Při spouštění funkcí v plánu služby App Service mají závislosti, které definujete v requirements.txt, přednost před integrovanými moduly Pythonu, například logging. Tato priorita může způsobit konflikty v případě, že integrované moduly mají v kódu stejné názvy jako adresáře. Při spuštění v plánu Consumption nebo v plánu Elastic Premium jsou konflikty méně pravděpodobné, protože vaše závislosti nejsou ve výchozím nastavení upřednostňovány.

Pokud chcete zabránit problémům během běhu v plánu služby App Service, nepojmenovávejte adresáře stejně jako některé nativní moduly Pythonu a ani nezahrnujte nativní knihovny Pythonu do souboru requirements.txt projektu.

Publikování do Azure

Až budete připraveni publikovat, ujistěte se, že jsou všechny veřejně dostupné závislosti uvedené v souboru requirements.txt . Tento soubor můžete najít v kořenovém adresáři projektu.

Soubory a složky projektu, které jsou vyloučené z publikování, včetně složky virtuálního prostředí, najdete v kořenovém adresáři projektu.

Publikování projektu Pythonu do Azure podporuje tři akce sestavení: vzdálené sestavení, místní sestavení a sestavení s využitím vlastních závislostí.

Azure Pipelines můžete také použít k sestavení závislostí a publikování pomocí průběžného doručování (CD). Další informace najdete v tématu Průběžné doručování pomocí Azure Pipelines.

Vzdálené sestavení

Při použití vzdáleného sestavení se závislosti obnovené na serveru a nativní závislosti shodují s produkčním prostředím. Výsledkem je menší balíček pro nasazení, který se má nahrát. Při vývoji aplikací Pythonu ve Windows používejte vzdálené sestavení. Pokud má váš projekt vlastní závislosti, můžete použít vzdálené sestavení s dodatečnou adresou URL indexu.

Závislosti se získávají vzdáleně na základě obsahu souboru requirements.txt . Vzdálené sestavení je doporučená metoda sestavení. Core Tools ve výchozím nastavení požádá o vzdálené sestavení, když k publikování projektu Pythonu do Azure použijete následující func azure functionapp publish příkaz.

func azure functionapp publish <APP_NAME>

Nezapomeňte nahradit <APP_NAME> názvem vaší aplikace funkcí v Azure.

Rozšíření Azure Functions pro Visual Studio Code také ve výchozím nastavení vyžaduje vzdálené sestavení.

Místní sestavení

Závislosti se získávají místně na základě obsahu souboru requirements.txt . Vzdálenému sestavení můžete zabránit tak, že pomocí následujícího func azure functionapp publish příkazu publikujete místní sestavení:

func azure functionapp publish <APP_NAME> --build local

Nezapomeňte nahradit <APP_NAME> názvem vaší aplikace funkcí v Azure.

Při použití --build local této možnosti se závislosti projektu čtou ze souboru requirements.txt a závislé balíčky se stáhnou a nainstalují místně. Soubory a závislosti projektu se nasazují z místního počítače do Azure. Výsledkem je nahrání většího nasazovacího balíčku do Azure. Pokud z nějakého důvodu nemůžete získat soubor requirements.txt pomocí nástrojů Core Tools, musíte pro publikování použít vlastní závislosti.

Při místním vývoji ve Windows nedoporučujeme používat místní buildy.

Vlastní závislosti

Pokud projekt obsahuje závislosti, které nejsou nalezeny v indexu balíčků Pythonu, existují dva způsoby sestavení projektu. První způsob, metoda sestavení , závisí na tom, jak sestavíte projekt.

Vzdálené sestavení s dodatečnou adresou URL indexu

Pokud jsou balíčky dostupné z přístupného vlastního indexu balíčků, použijte vzdálené sestavení. Před publikováním nezapomeňte vytvořit nastavení aplikace s názvem PIP_EXTRA_INDEX_URL. Hodnota tohoto nastavení je adresa URL vlastního indexu balíčku. Pomocí tohoto nastavení sdělíte vzdálenému sestavení, aby se spustilo pip install s použitím této možnosti --extra-index-url. Další informace najdete v dokumentacipip install

Základní ověřovací přihlašovací údaje můžete použít také s dalšími adresami URL indexu balíčků. Další informace najdete v dokumentaci k Základním ověřovacím přihlašovacím údajům v Pythonu.

Instalace místních balíčků

Pokud váš projekt používá balíčky, které nejsou veřejně dostupné pro naše nástroje, můžete je zpřístupnit vaší aplikaci tak, že je vložíte do adresáře __app__/.python_packages . Před publikováním nainstalujte závislosti místně spuštěním následujícího příkazu:

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

Pokud používáte vlastní závislosti, měli byste použít --no-build možnost publikování, protože jste už do složky projektu nainstalovali závislosti.

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

Nezapomeňte nahradit <APP_NAME> názvem vaší aplikace funkcí v Azure.

Testování částí

Testování jednotek prostřednictvím pytestu

Funkce napsané v Pythonu je možné testovat stejně jako ostatní kódy Pythonu pomocí standardních testovacích architektur. U většiny vazeb je možné vytvořit napodobený vstupní objekt vytvořením instance příslušné třídy z azure.functions balíčku. azure.functions Vzhledem k tomu, že balíček není okamžitě dostupný, nezapomeňte ho nainstalovat přes soubor requirements.txt, jak je popsáno v části správa balíčků výše.

V případě my_second_function jako příkladu je následující test funkce aktivované protokolem HTTP:

Nejprve vytvořte <soubor project_root>/my_second_function/function.json a pak tuto funkci definujte jako trigger HTTP.

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

Dále můžete implementovat 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

Můžete začít psát testovací případy pro trigger HTTP.

# <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 Ve složce virtuálního prostředí Pythonu nainstalujte oblíbenou testovací architekturu Pythonu, například pip install pytest. Pak spusťte pytest tests k ověření výsledku testu.

Nejprve vytvořte <soubor project_root>/function_app.py a implementujte my_second_function funkci jako trigger HTTP a 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

Můžete začít psát testovací případy pro trigger HTTP.

# <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',
    )

Ve složce virtuálního prostředí .venv Pythonu nainstalujte oblíbenou testovací architekturu Pythonu, například pip install pytest. Pak spusťte pytest tests k ověření výsledku testu.

Testování jednotek vyvoláním funkce přímo

Pomocí azure-functions >= 1.21.0 lze volat funkce přímo pomocí interpretu Pythonu. Tento příklad ukazuje, jak testovat trigger HTTP pomocí programovacího modelu v2:

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

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

@app.route(route="http_trigger")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
    return "Hello, World!"

print(http_trigger(None))

Mějte na paměti, že s tímto přístupem není potřeba žádný další balíček ani nastavení. Funkci lze testovat voláním python function_app.pya výsledkem je Hello, World! výstup v terminálu.

Poznámka:

Durable Functions pro testování jednotek vyžadují speciální syntaxi. Další informace najdete v tématu Testování jednotek Durable Functions v Pythonu.

Dočasné soubory

Metoda tempfile.gettempdir() vrátí dočasnou složku, která v Linuxu je /tmp. Aplikace může tento adresář použít k ukládání dočasných souborů generovaných a používaných funkcemi při jejich spuštění.

Důležité

Soubory zapsané do dočasného adresáře nejsou zaručeny, že se zachovají napříč vyvoláním. Během škálování se mezi instancemi nesdílí dočasné soubory.

Následující příklad vytvoří pojmenovaný dočasný soubor v dočasném adresáři (/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)

Doporučujeme udržovat testy ve složce, která je oddělená od složky projektu. Tato akce vám brání v nasazení testovacího kódu s vaší aplikací.

Předinstalované knihovny

Několik knihoven je součástí běhového prostředí funkcí Pythonu.

Standardní knihovna Pythonu

Standardní knihovna Pythonu obsahuje seznam integrovaných modulů Pythonu, které se dodávají s každou distribucí Pythonu. Většina těchto knihoven vám pomůže získat přístup k funkcím systému, jako je vstup/výstup souboru (vstupně-výstupní operace). V systémech Windows se tyto knihovny instalují s Pythonem. V systémech Unix jsou poskytovány kolekcemi balíčků.

Pokud chcete zobrazit knihovnu pro vaši verzi Pythonu, přejděte na:

Závislosti pracovních procesů Azure Functions v Pythonu

Pracovní proces Azure Functions v Pythonu vyžaduje konkrétní sadu knihoven. Tyto knihovny můžete použít také ve svých funkcích, ale nejsou součástí standardu Pythonu. Pokud vaše funkce spoléhají na některou z těchto knihoven, může být pro váš kód nedostupný, když běží mimo Službu Azure Functions.

Poznámka:

Pokud soubor requirements.txt vaší funkční aplikace obsahuje azure-functions-worker položku, odeberte ji. Pracovní proces functions je automaticky spravován platformou Azure Functions a pravidelně ho aktualizujeme novými funkcemi a opravami chyb. Ruční instalace staré verze pracovního procesu v souboru requirements.txt může způsobit neočekávané problémy.

Poznámka:

Pokud váš balíček obsahuje určité knihovny, které můžou kolidovat se závislostmi pracovního procesu (například protobuf, tensorflow nebo grpcio), nakonfigurujte PYTHON_ISOLATE_WORKER_DEPENDENCIES1 v nastavení aplikace tak, aby aplikace nemohla odkazovat na závislosti pracovního procesu.

Knihovna Pythonu pro Azure Functions

Každá aktualizace pracovního procesu Pythonu zahrnuje novou verzi knihovny Pythonu Azure Functions (azure.functions). Tento přístup usnadňuje nepřetržitou aktualizaci aplikací funkcí Pythonu, protože každá aktualizace je zpětně kompatibilní. Seznam verzí této knihovny najdete v části Azure-Functions PyPi.

Verze knihovny modulu runtime je stanovena Azure a nelze ji přepsat pomocí requirements.txt. Položka azure-functions v requirements.txt je určená pouze pro lintování a informovanost zákazníků.

Ke sledování skutečné verze knihovny funkcí Pythonu v modulu runtime použijte následující kód:

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

Systémové knihovny modulu runtime

Seznam předinstalovaných systémových knihoven v Dockerových imagích pythonového pracovního prostředí najdete zde:

Modul runtime služby Functions Verze Debianu Verze Pythonu
Verze 3.x Chlapík Python 3.7
Python 3.8
Python 3.9

Rozšíření pro pracovníky v Pythonu

Pracovní proces Pythonu, který běží ve službě Azure Functions, umožňuje integrovat knihovny třetích stran do vaší aplikace funkcí. Tyto rozšiřující knihovny fungují jako middleware, který může během životního cyklu provádění vaší funkce vkládat konkrétní operace.

Rozšíření se do kódu funkce importují podobně jako standardní modul knihovny Pythonu. Rozšíření se spouští na základě následujících oborů:

Rozsah Popis
Úroveň aplikace Při importu do libovolné aktivační události funkce se rozšíření vztahuje na každé spuštění funkce v aplikaci.
Úroveň funkce Spouštění je omezené jenom na konkrétní aktivační událost funkce, do které se importuje.

Další informace o oboru, ve kterém rozšíření běží, najdete v informacích o jednotlivých rozšířeních.

Rozšíření implementují rozhraní rozšíření pracovního procesu Pythonu. Tato akce umožňuje volání pracovního procesu Pythonu do kódu rozšíření během životního cyklu provádění funkce. Další informace najdete v tématu Vytváření rozšíření.

Použití rozšíření

V funkcích Pythonu můžete použít knihovnu rozšíření pracovních procesů Pythonu následujícím způsobem:

  1. Přidejte rozšiřující balíček do souboru requirements.txt vašeho projektu.
  2. Nainstalujte knihovnu do aplikace.
  3. Přidejte následující nastavení aplikace:
    • Místně: Zadejte "PYTHON_ENABLE_WORKER_EXTENSIONS": "1" v části Values vašeho souboru local.settings.json.
    • Azure: Zadejte PYTHON_ENABLE_WORKER_EXTENSIONS=1 do nastavení aplikace.
  4. Importujte modul rozšíření do triggeru funkce.
  5. V případě potřeby nakonfigurujte instanci rozšíření. Požadavky na konfiguraci by se měly zobrazit v dokumentaci k rozšíření.

Důležité

Microsoft nepodporuje nebo zaručuje externí knihovny rozšíření pracovních procesů Pythonu. Musíte se ujistit, že všechna rozšíření, která používáte ve své aplikaci funkcí, jsou důvěryhodná a nesete úplné riziko použití škodlivého nebo špatně napsaného rozšíření.

Třetí strany by měly poskytnout konkrétní dokumentaci k instalaci a využívání jejich rozšíření ve vaší aplikaci funkcí. Základní příklad využití rozšíření najdete v tématu Využití rozšíření.

Tady jsou příklady použití rozšíření v aplikaci funkcí podle oboru:

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

Vytváření rozšíření

Rozšíření vytvářejí vývojáři knihoven třetích stran, kteří vytvořili funkce, které je možné integrovat do Azure Functions. Vývojář rozšíření navrhuje, implementuje a vydává balíčky Pythonu, které obsahují vlastní logiku navrženou speciálně pro spuštění v kontextu provádění funkcí. Tato rozšíření je možné publikovat buď do registru PyPI, nebo do úložišť GitHub.

Informace o vytváření, balení, publikování a využívání balíčku rozšíření pracovního procesu Pythonu najdete v tématu Vývoj rozšíření pracovních procesů Pythonu pro Azure Functions.

Rozšíření na úrovni aplikace

Rozšíření zděděné z AppExtensionBase běží v rozsahu aplikace.

AppExtensionBase zveřejňuje následující abstraktní metody třídy, které můžete implementovat:

metoda Popis
init Volá se po importu rozšíření.
configure Volá se z kódu funkce, když je potřeba nakonfigurovat rozšíření.
post_function_load_app_level Volá se hned po načtení funkce. Do rozšíření jsou předány název a adresář funkce. Mějte na paměti, že adresář funkce je jen pro čtení a všechny pokusy o zápis do místního souboru v tomto adresáři selžou.
pre_invocation_app_level Volá se těsně před spuštěním funkce. Do rozšíření se předají kontext funkce a argumenty vyvolání funkce. Obvykle můžete předat další atributy v kontextovém objektu, aby je kód funkce mohl využít.
post_invocation_app_level Volá se ihned po dokončení vykonání funkce. Kontext funkce, argumenty vyvolání funkce a návratový objekt vyvolání se předají rozšíření. Tato implementace je vhodným místem k ověření, zda bylo spuštění hooků životního cyklu úspěšné.

Rozšíření na úrovni funkce

Rozšíření, které dědí z FuncExtensionBase, běží ve specifickém spouštěči funkce.

FuncExtensionBase zveřejňuje následující abstraktní metody třídy pro implementace:

metoda Popis
__init__ Konstruktor rozšíření. Volá se, když je instance rozšíření inicializována v konkrétní funkci. Při implementaci této abstraktní metody můžete chtít přijmout filename parametr a předat ho metodě nadřazeného objektu super().__init__(filename) pro správnou registraci rozšíření.
post_function_load Volá se hned po načtení funkce. Do rozšíření jsou předány název a adresář funkce. Mějte na paměti, že adresář funkce je jen pro čtení a všechny pokusy o zápis do místního souboru v tomto adresáři selžou.
pre_invocation Volá se těsně před spuštěním funkce. Do rozšíření se předají kontext funkce a argumenty vyvolání funkce. Obvykle můžete předat další atributy v kontextovém objektu, aby je kód funkce mohl využít.
post_invocation Volá se ihned po dokončení vykonání funkce. Kontext funkce, argumenty vyvolání funkce a návratový objekt vyvolání se předají rozšíření. Tato implementace je vhodným místem k ověření, zda bylo spuštění hooků životního cyklu úspěšné.

Sdílení prostředků různého původu

Azure Functions podporuje sdílení prostředků mezi různými zdroji (CORS). CORS se konfiguruje na portálu a prostřednictvím Azure CLI. Seznam povolených zdrojů CORS se vztahuje na úrovni aplikace funkcí. S povoleným CORS zahrnují odpovědi hlavičku Access-Control-Allow-Origin . Další informace naleznete v tématu Sdílení prostředků různého původu.

Sdílení prostředků mezi zdroji (CORS) je plně podporováno pro aplikace Pythonových funkcí.

Asynchronní

Ve výchozím nastavení může instance hostitele pro Python zpracovat pouze jedno vyvolání funkce najednou. Důvodem je, že Python je modul runtime s jedním vláknem. U aplikace funkcí, která zpracovává velký počet vstupně-výstupních událostí nebo je vázaná na vstupně-výstupní operace, můžete výrazně zlepšit výkon spouštěním funkcí asynchronně. Další informace najdete v tématu Vylepšení výkonu aplikací Pythonu ve službě Azure Functions.

Sdílená paměť (Preview)

Kvůli zlepšení propustnosti umožňuje Azure Functions, aby váš pracovní proces jazyka Pythonu mimo proces sdílel paměť s hostitelským procesem Functions. Když aplikace funkcí naráží na kritické body, můžete povolit sdílenou paměť přidáním nastavení aplikace s názvem FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED s hodnotou 1. Když je povolená sdílená paměť, můžete pomocí nastavení DOCKER_SHM_SIZE nastavit sdílenou paměť na něco podobného 268435456, což odpovídá 256 MB.

Můžete například povolit sdílenou paměť, abyste snížili kritické body při použití vazeb Blob Storage k přenosu datových částí větších než 1 MB.

Tato funkce je dostupná jenom pro aplikace funkcí, které běží v plánech Premium a Dedicated (Aplikace Azure Service). Další informace najdete v tématu Sdílená paměť.

Známé problémy a nejčastější dotazy

Tady jsou dva průvodci odstraňováním potíží pro běžné problémy:

Tady jsou dva průvodci odstraňováním potíží se známými problémy s programovacím modelem v2:

Všechny známé problémy a žádosti o funkce se sledují v seznamu problémů GitHubu. Pokud narazíte na problém a nemůžete problém najít na GitHubu, otevřete nový problém a uveďte podrobný popis problému.

Další kroky

Další informace naleznete v následujících zdrojích:

Máte problémy s používáním Pythonu? Řekněte nám, co se děje.