Python-werkrolextensies ontwikkelen voor Azure Functions
met Azure Functions kunt u aangepast gedrag integreren als onderdeel van de uitvoering van Python-functies. Met deze functie kunt u bedrijfslogica maken die klanten eenvoudig kunnen gebruiken in hun eigen functie-apps. Zie de naslaginformatie voor Python-ontwikkelaars voor meer informatie. Werkrolextensies worden ondersteund in zowel het Python-programmeermodel v1 als het v2-programmeermodel.
In deze zelfstudie leert u het volgende:
- Maak een Python-werkrolextensie op toepassingsniveau voor Azure Functions.
- Gebruik uw extensie in een app zoals uw klanten dat doen.
- Een extensie verpakken en publiceren voor verbruik.
Vereisten
Voordat u begint, moet u aan deze vereisten voldoen:
Python 3.7 of hoger. Als u de volledige lijst met ondersteunde Python-versies in Azure Functions wilt bekijken, raadpleegt u de Python-ontwikkelaarshandleiding.
De Azure Functions Core Tools, versie 4.0.5095 of hoger, die ondersteuning biedt voor het gebruik van de extensie met het v2 Python-programmeermodel. Controleer uw versie met
func --version
.Visual Studio Code geïnstalleerd op een van de ondersteunde platforms.
De Python Worker-extensie maken
De extensie die u maakt, rapporteert de verstreken tijd van een HTTP-triggeraanroep in de consolelogboeken en in de hoofdtekst van het HTTP-antwoord.
Mapstructuur
De map voor uw extensieproject moet er ongeveer als volgt uitzien:
<python_worker_extension_root>/
| - .venv/
| - python_worker_extension_timer/
| | - __init__.py
| - setup.py
| - readme.md
Map/bestand | Beschrijving |
---|---|
.venv/ | (Optioneel) Bevat een virtuele Python-omgeving die wordt gebruikt voor lokale ontwikkeling. |
python_worker_extension/ | Bevat de broncode van de Python-werkrolextensie. Deze map bevat de belangrijkste Python-module die moet worden gepubliceerd in PyPI. |
setup.py | Bevat de metagegevens van het Python-werkuitbreidingspakket. |
readme.md | Bevat de instructies en het gebruik van uw extensie. Deze inhoud wordt weergegeven als de beschrijving op de startpagina van uw PyPI-project. |
Projectmetagegevens configureren
Eerst maakt setup.py
u , dat essentiële informatie over uw pakket bevat. Als u ervoor wilt zorgen dat uw extensie correct wordt gedistribueerd en geïntegreerd in de functie-apps van uw klant, controleert u of dit 'azure-functions >= 1.7.0, < 2.0.0'
in de install_requires
sectie staat.
In de volgende sjabloon moet u de velden , author_email
, install_requires
, license
packages
, en url
indien nodig wijzigenauthor
.
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,
)
Vervolgens implementeert u de extensiecode in het bereik op toepassingsniveau.
De timerextensie implementeren
Voeg de volgende code toe in python_worker_extension_timer/__init__.py
om de extensie op toepassingsniveau te implementeren:
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()
Deze code wordt overgenomen van AppExtensionBase , zodat de extensie van toepassing is op elke functie in de app. U kunt de extensie ook implementeren op een bereik op functieniveau door deze over te nemen van FuncExtensionBase.
De init
methode is een klassemethode die wordt aangeroepen door de werkrol wanneer de extensieklasse wordt geïmporteerd. U kunt hier initialisatieacties uitvoeren voor de extensie. In dit geval wordt een hash-toewijzing geïnitialiseerd voor het vastleggen van de begintijd van de aanroep voor elke functie.
De configure
methode is klantgericht. In uw leesmij-bestand kunt u uw klanten laten weten wanneer ze moeten aanroepen Extension.configure()
. De leesmij moet ook de uitbreidingsmogelijkheden, mogelijke configuratie en het gebruik van uw extensie documenteert. In dit voorbeeld kunnen klanten kiezen of de verstreken tijd wordt gerapporteerd in de HttpResponse
.
De pre_invocation_app_level
methode wordt aangeroepen door de Python-werkrol voordat de functie wordt uitgevoerd. Het biedt de informatie van de functie, zoals functiecontext en argumenten. In dit voorbeeld registreert de extensie een bericht en registreert de begintijd van een aanroep op basis van de invocation_id.
Op dezelfde manier wordt de aangeroepen na de post_invocation_app_level
uitvoering van de functie. In dit voorbeeld wordt de verstreken tijd berekend op basis van de begintijd en de huidige tijd. Ook wordt de retourwaarde van het HTTP-antwoord overschreven.
Een readme.md maken
Maak een readme.md-bestand in de hoofdmap van uw extensieproject. Dit bestand bevat de instructies en het gebruik van uw extensie. De readme.md inhoud wordt weergegeven als de beschrijving op de startpagina van uw PyPI-project.
# 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.
Uw extensie lokaal gebruiken
Nu u een extensie hebt gemaakt, kunt u deze gebruiken in een app-project om te controleren of deze werkt zoals bedoeld.
Een HTTP-triggerfunctie maken
Maak een nieuwe map voor uw app-project en navigeer ernaartoe.
Voer vanuit de juiste shell, zoals Bash, de volgende opdracht uit om het project te initialiseren:
func init --python
Gebruik de volgende opdracht om een nieuwe HTTP-triggerfunctie te maken die anonieme toegang toestaat:
func new -t HttpTrigger -n HttpTrigger -a anonymous
Een virtuele omgeving activeren
Maak als volgt een virtuele Python-omgeving op basis van het besturingssysteem:
Activeer de virtuele Python-omgeving als volgt op basis van het besturingssysteem:
De extensie configureren
Installeer externe pakketten voor uw functie-app-project met behulp van de volgende opdracht:
pip install -r requirements.txt
Installeer de extensie als volgt vanuit uw lokale bestandspad in de bewerkbare modus:
pip install -e <PYTHON_WORKER_EXTENSION_ROOT>
Vervang in dit voorbeeld door
<PYTHON_WORKER_EXTENSION_ROOT>
de locatie van het hoofdbestand van uw extensieproject.Wanneer een klant uw extensie gebruikt, voegt deze in plaats daarvan de locatie van het extensiepakket toe aan het requirements.txt-bestand, zoals in de volgende voorbeelden:
Open het projectbestand local.settings.json en voeg het volgende veld toe aan
Values
:"PYTHON_ENABLE_WORKER_EXTENSIONS": "1"
Wanneer u in Azure uitvoert, voegt u in plaats daarvan toe
PYTHON_ENABLE_WORKER_EXTENSIONS=1
aan de app-instellingen in de functie-app.Voeg de volgende twee regels toe vóór de
main
functie in het bestand __init.py__ voor het v1-programmeermodel of in het bestand function_app.py voor het v2-programmeermodel:from python_worker_extension_timer import TimerExtension TimerExtension.configure(append_to_http_response=True)
Met deze code wordt de
TimerExtension
module geïmporteerd en wordt deappend_to_http_response
configuratiewaarde ingesteld.
De extensie controleren
Start vanuit de hoofdmap van uw app-project de functiehost met behulp van
func host start --verbose
. U ziet het lokale eindpunt van uw functie in de uitvoer alshttps://localhost:7071/api/HttpTrigger
.Verzend in de browser een GET-aanvraag naar
https://localhost:7071/api/HttpTrigger
. U ziet een antwoord dat lijkt op het volgende, met de TimeElapsed-gegevens voor de aanvraag toegevoegd.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)
Uw extensie publiceren
Nadat u uw extensie hebt gemaakt en geverifieerd, moet u nog steeds deze resterende publicatietaken uitvoeren:
- Kies een licentie.
- Maak een readme.md en andere documentatie.
- Publiceer de extensiebibliotheek naar een Python-pakketregister of een versiebeheersysteem (VCS).
Uw extensie publiceren naar PyPI:
Voer de volgende opdracht uit om en
wheel
te installerentwine
in uw standaard Python-omgeving of een virtuele omgeving:pip install twine wheel
Verwijder de oude
dist/
map uit uw extensieopslagplaats.Voer de volgende opdracht uit om een nieuw pakket te genereren in
dist/
:python setup.py sdist bdist_wheel
Voer de volgende opdracht uit om het pakket te uploaden naar PyPI:
twine upload dist/*
Mogelijk moet u uw PyPI-accountreferenties opgeven tijdens het uploaden. U kunt het uploaden van uw pakket ook testen met
twine upload -r testpypi dist/*
. Zie de Twine-documentatie voor meer informatie.
Na deze stappen kunnen klanten uw extensie gebruiken door uw pakketnaam op te slaan in hun requirements.txt.
Zie de officiële zelfstudie voor Python-pakketten voor meer informatie.
Voorbeelden
U kunt het voltooide voorbeeldextensieproject in dit artikel bekijken in de python_worker_extension_timer voorbeeldopslagplaats.
OpenCensus-integratie is een opensource-project dat gebruikmaakt van de extensie-interface om telemetrietracering te integreren in Azure Functions Python-apps. Zie de opslagplaats opencensus-python-extensions-azure om de implementatie van deze Python-werkextensie te controleren.
Volgende stappen
Zie de volgende resources voor meer informatie over Azure Functions python-ontwikkeling: