Dela via


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

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. Mer information finns i Python-utvecklarreferensen. 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 ditt tillägg i en app på samma sätt som dina kunder gör.
  • Paketera och publicera ett tillägg för förbrukning.

Förutsättningar

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

Skapa Python Worker-tillägget

Tillägget som 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 så här:

<python_worker_extension_root>/
 | - .venv/
 | - python_worker_extension_timer/
 | | - __init__.py
 | - setup.py
 | - readme.md
Mapp/fil Beskrivning
.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 beskrivningen på startsidan i PyPI-projektet.

Konfigurera projektmetadata

Först skapar setup.pydu , 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 alla funktioner i appen. Du kunde också ha implementerat tillägget i 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 kunderna 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.

post_invocation_app_level På samma sätt anropas efter funktionskörning. I det här exemplet beräknas den förflutna tiden baserat på starttid och aktuell tid. Den 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 beskrivningen 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 det.

  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 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 rotfilsplatsen för ditt tilläggsprojekt.

    När en kund använder tillägget lägger de i stället till din plats för tilläggspaket i requirements.txt-filen, som i följande exempel:

    # requirements.txt
    python_worker_extension_timer==1.0.0
    
  3. Öppna projektfilen local.settings.json 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 filen function_app.py för v2-programmeringsmodellen:

    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. Starta funktionsvärden med hjälp av func host start --verbosefrån rotmappen för appprojektet. 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 begäran tillagd.

    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 utfö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ö för Python eller 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 kunder använda ditt tillägg genom att inkludera paketnamnet i sina requirements.txt.

Mer information finns i den officiella självstudien om Python-paketering.

Exempel

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

  • 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 databasen opencensus-python-extensions-azure 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: