Dela via


Utveckla Python Worker-tillägg för Azure Functions

Anmärkning

Från och med Python 3.13 stöds inte längre Python Worker-tillägg.

Med Azure Functions kan du integrera anpassade beteenden som en del av Python-funktionskörningen. Med den här funktionen kan du skapa affärslogik som kunderna enkelt kan använda i sina egna funktionsappar. Arbetstillägg stöds i python-programmeringsmodellerna v1 och v2.

I den här självstudien får du lära dig att:

  • Skapa ett Python-arbetstillägg på programnivå för Azure Functions.
  • Använd tillägget i en app på det sätt som dina kunder gör.
  • Paketera och publicera ett tillägg för användning.

Förutsättningar

Innan du börjar måste du uppfylla följande krav:

Skapa Python Worker-tillägget

Tillägget du skapar rapporterar den förflutna tiden för ett HTTP-utlösaranrop i konsolloggarna och i HTTP-svarstexten.

Mappstrukturen

Mappen för ditt tilläggsprojekt bör se ut ungefär så här:

<python_worker_extension_root>/
 | - .venv/
 | - python_worker_extension_timer/
 | | - __init__.py
 | - setup.py
 | - readme.md
Mapp/fil Description
.venv/ (Valfritt) Innehåller en virtuell Python-miljö som används för lokal utveckling.
python_worker_extension/ Innehåller källkoden för Python Worker-tillägget. Den här mappen innehåller den huvudsakliga Python-modulen som ska publiceras i PyPI.
setup.py Innehåller metadata för Python Worker-tilläggspaketet.
readme.md Innehåller instruktioner och användning av tillägget. Det här innehållet visas som beskrivning på startsidan i PyPI-projektet.

Konfigurera projektmetadata

Först skapar du setup.py, som innehåller viktig information om ditt paket. Kontrollera att tillägget är korrekt distribuerat och integrerat i kundens funktionsappar genom att bekräfta att det 'azure-functions >= 1.7.0, < 2.0.0' finns i install_requires avsnittet.

I följande mall bör du ändra authorfälten , author_email, install_requires, license, packagesoch url efter behov.

from setuptools import find_packages, setup
setup(
    name='python-worker-extension-timer',
    version='1.0.0',
    author='Your Name Here',
    author_email='your@email.here',
    classifiers=[
        'Intended Audience :: End Users/Desktop',
        'Development Status :: 5 - Production/Stable',
        'Intended Audience :: End Users/Desktop',
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: 3.9',
        'Programming Language :: Python :: 3.10',
    ],
    description='Python Worker Extension Demo',
    include_package_data=True,
    long_description=open('readme.md').read(),
    install_requires=[
        'azure-functions >= 1.7.0, < 2.0.0',
        # Any additional packages that will be used in your extension
    ],
    extras_require={},
    license='MIT',
    packages=find_packages(where='.'),
    url='https://your-github-or-pypi-link',
    zip_safe=False,
)

Därefter implementerar du tilläggskoden i programnivåomfånget.

Implementera timertillägget

Lägg till följande kod i python_worker_extension_timer/__init__.py för att implementera tillägget på programnivå:

import typing
from logging import Logger
from time import time
from azure.functions import AppExtensionBase, Context, HttpResponse
class TimerExtension(AppExtensionBase):
    """A Python worker extension to record elapsed time in a function invocation
    """

    @classmethod
    def init(cls):
        # This records the starttime of each function
        cls.start_timestamps: typing.Dict[str, float] = {}

    @classmethod
    def configure(cls, *args, append_to_http_response:bool=False, **kwargs):
        # Customer can use TimerExtension.configure(append_to_http_response=)
        # to decide whether the elapsed time should be shown in HTTP response
        cls.append_to_http_response = append_to_http_response

    @classmethod
    def pre_invocation_app_level(
        cls, logger: Logger, context: Context,
        func_args: typing.Dict[str, object],
        *args, **kwargs
    ) -> None:
        logger.info(f'Recording start time of {context.function_name}')
        cls.start_timestamps[context.invocation_id] = time()

    @classmethod
    def post_invocation_app_level(
        cls, logger: Logger, context: Context,
        func_args: typing.Dict[str, object],
        func_ret: typing.Optional[object],
        *args, **kwargs
    ) -> None:
        if context.invocation_id in cls.start_timestamps:
            # Get the start_time of the invocation
            start_time: float = cls.start_timestamps.pop(context.invocation_id)
            end_time: float = time()
            # Calculate the elapsed time
            elapsed_time = end_time - start_time
            logger.info(f'Time taken to execute {context.function_name} is {elapsed_time} sec')
            # Append the elapsed time to the end of HTTP response
            # if the append_to_http_response is set to True
            if cls.append_to_http_response and isinstance(func_ret, HttpResponse):
                func_ret._HttpResponse__body += f' (TimeElapsed: {elapsed_time} sec)'.encode()

Den här koden ärver från AppExtensionBase så att tillägget gäller för varje funktion i appen. Du kunde också ha implementerat tillägget på ett funktionsnivåomfång genom att ärva från FuncExtensionBase.

Metoden init är en klassmetod som anropas av arbetaren när tilläggsklassen importeras. Du kan utföra initieringsåtgärder här för tillägget. I det här fallet initieras en hash-karta för att registrera starttiden för anropet för varje funktion.

Metoden configure är kundriktad. I readme-filen kan du berätta för dina kunder när de behöver anropa Extension.configure(). Readme ska också dokumentera tilläggsfunktioner, möjlig konfiguration och användning av tillägget. I det här exemplet kan kunder välja om den förflutna tiden ska rapporteras i HttpResponse.

Metoden pre_invocation_app_level anropas av Python-arbetaren innan funktionen körs. Den innehåller information från funktionen, till exempel funktionskontext och argument. I det här exemplet loggar tillägget ett meddelande och registrerar starttiden för ett anrop baserat på dess invocation_id.

På samma sätt anropas post_invocation_app_level efter funktionskörningen. I det här exemplet beräknas den förflutna tiden baserat på starttid och aktuell tid. Det skriver också över returvärdet för HTTP-svaret.

Skapa en README.md

Skapa en readme.md fil i roten för ditt tilläggsprojekt. Den här filen innehåller instruktioner och användning av tillägget. Det readme.md innehållet visas som beskrivning på startsidan i PyPI-projektet.

# Python Worker Extension Timer

In this file, tell your customers when they need to call `Extension.configure()`.

The readme should also document the extension capabilities, possible configuration,
and usage of your extension.

Använd ditt tillägg lokalt

Nu när du har skapat ett tillägg kan du använda det i ett appprojekt för att kontrollera att det fungerar som avsett.

Skapa en HTTP-utlösarfunktion

  1. Skapa en ny mapp för appprojektet och navigera till den.

  2. Från lämpligt gränssnitt, till exempel Bash, kör du följande kommando för att initiera projektet:

    func init --python
    
  3. Använd följande kommando för att skapa en ny HTTP-utlösarfunktion som tillåter anonym åtkomst:

    func new -t HttpTrigger -n HttpTrigger -a anonymous
    

Aktivera en virtuell miljö

  1. Skapa en virtuell Python-miljö baserat på operativsystemet på följande sätt:

    python3 -m venv .venv
    
  2. Aktivera den virtuella Python-miljön baserat på operativsystemet på följande sätt:

    source .venv/bin/activate
    

Konfigurera tillägget

  1. Installera fjärrpaket för funktionsappprojektet med hjälp av följande kommando:

    pip install -r requirements.txt
    
  2. Installera tillägget från din lokala filsökväg i redigerbart läge på följande sätt:

    pip install -e <PYTHON_WORKER_EXTENSION_ROOT>
    

    I det här exemplet ersätter du <PYTHON_WORKER_EXTENSION_ROOT> med rotfilens plats för ditt tilläggsprojekt.

    När en kund använder ditt tillägg lägger de i stället till paketplatsen för ditt tillägg i filen requirements.txt, som i följande exempel:

    # requirements.txt
    python_worker_extension_timer==1.0.0
    
  3. Öppna local.settings.json-projektfilen och lägg till följande fält i Values:

    "PYTHON_ENABLE_WORKER_EXTENSIONS": "1" 
    

    När du kör i Azure lägger du i stället till PYTHON_ENABLE_WORKER_EXTENSIONS=1appinställningarna i funktionsappen.

  4. Lägg till följande två rader före main funktionen i __init.py___ -filen för programmeringsmodellen v1 eller i function_app.py-filen för programmeringsmodellen v2:

    from python_worker_extension_timer import TimerExtension
    TimerExtension.configure(append_to_http_response=True)
    

    Den här koden importerar modulen TimerExtension och anger konfigurationsvärdet append_to_http_response .

Verifiera tillägget

  1. Från rotmappen för ditt appprojekt, starta funktionsvärden med hjälp av func host start --verbose. Du bör se den lokala slutpunkten för funktionen i utdata som https://localhost:7071/api/HttpTrigger.

  2. I webbläsaren skickar du en GET-begäran till https://localhost:7071/api/HttpTrigger. Du bör se ett svar som följande, med TimeElapsed-data för den bifogade begäran.

    This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response. (TimeElapsed: 0.0009996891021728516 sec)
    

Publicera ditt tillägg

När du har skapat och verifierat tillägget måste du fortfarande slutföra följande återstående publiceringsuppgifter:

  • Välj en licens.
  • Skapa en readme.md och annan dokumentation.
  • Publicera tilläggsbiblioteket till ett Python-paketregister eller ett versionskontrollsystem (VCS).

Så här publicerar du tillägget till PyPI:

  1. Kör följande kommando för att installera twine och wheel i din standardmiljö eller i en virtuell miljö:

    pip install twine wheel
    
  2. Ta bort den gamla dist/ mappen från lagringsplatsen för tillägget.

  3. Kör följande kommando för att generera ett nytt paket i dist/:

    python setup.py sdist bdist_wheel
    
  4. Kör följande kommando för att ladda upp paketet till PyPI:

    twine upload dist/*
    

    Du kan behöva ange dina autentiseringsuppgifter för PyPI-kontot under uppladdningen. Du kan också testa paketuppladdningen med twine upload -r testpypi dist/*. Mer information finns i Twine-dokumentationen.

Efter de här stegen kan kunderna använda ditt tillägg genom att inkludera ditt paketnamn i deras requirements.txt.

För mer information, se den officiella guiden för Python-paketering.

Examples

  • Du kan visa slutfört exempeltilläggsprojekt från den här artikeln på python_worker_extension_timer exempellagringsplats.

  • OpenCensus-integrering är ett projekt med öppen källkod som använder tilläggsgränssnittet för att integrera telemetrispårning i Azure Functions Python-appar. Se opencensus-python-extensions-azure-lagringsplatsen för att granska implementeringen av det här Python-arbetstillägget.

Nästa steg

Mer information om Azure Functions Python-utveckling finns i följande resurser: