Sviluppare estensioni di lavoro Python per Funzioni di Azure
Articolo
Funzioni di Azure consente di integrare comportamenti personalizzati come parte dell'esecuzione della funzione Python. Questa funzionalità consente di creare logica di business che i clienti possono usare facilmente nelle proprie app per le funzioni. Per altre informazioni, vedere il riferimento per sviluppatori Python. Le estensioni di lavoro sono supportate sia nei modelli di programmazione v1 che v2 Python.
In questa esercitazione si apprenderà come:
Creare un'estensione di lavoro Python a livello di applicazione per Funzioni di Azure.
Usare l'estensione in un'app nel modo in cui i clienti fanno.
Pacchetto e pubblicazione di un'estensione per l'utilizzo.
Prerequisiti
Prima di iniziare, è necessario soddisfare questi requisiti:
(Facoltativo) Contiene un ambiente virtuale Python usato per lo sviluppo locale.
python_worker_extension/
Contiene il codice sorgente dell'estensione di lavoro Python. Questa cartella contiene il modulo Python principale da pubblicare in PyPI.
setup.py
Contiene i metadati del pacchetto di estensione del ruolo di lavoro Python.
readme.md
Contiene le istruzioni e l'utilizzo dell'estensione. Questo contenuto viene visualizzato come descrizione nella home page del progetto PyPI.
Configurare i metadati del progetto
Prima di tutto si crea setup.py, che fornisce informazioni essenziali sul pacchetto. Per assicurarsi che l'estensione sia distribuita e integrata nelle app per le funzioni del cliente correttamente, verificare che 'azure-functions >= 1.7.0, < 2.0.0' sia presente nella install_requires sezione.
Nel modello seguente è necessario modificare author, licensepackagesauthor_emailinstall_requirese url i campi in base alle esigenze.
Python
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,
)
Successivamente, si implementerà il codice di estensione nell'ambito a livello di applicazione.
Implementare l'estensione timer
Aggiungere il codice seguente in python_worker_extension_timer/__init__.py per implementare l'estensione a livello di applicazione:
Python
import typing
from logging import Logger
from time import time
from azure.functions import AppExtensionBase, Context, HttpResponse
classTimerExtension(AppExtensionBase):"""A Python worker extension to record elapsed time in a function invocation
""" @classmethoddefinit(cls):# This records the starttime of each function
cls.start_timestamps: typing.Dict[str, float] = {}
@classmethoddefconfigure(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
@classmethoddefpre_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()
@classmethoddefpost_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 Trueif cls.append_to_http_response and isinstance(func_ret, HttpResponse):
func_ret._HttpResponse__body += f' (TimeElapsed: {elapsed_time} sec)'.encode()
Questo codice eredita da AppExtensionBase in modo che l'estensione si applica a ogni funzione nell'app. È anche possibile implementare l'estensione in un ambito a livello di funzione ereditando da FuncExtensionBase.
Il init metodo è un metodo di classe chiamato dal ruolo di lavoro quando viene importata la classe di estensione. È possibile eseguire azioni di inizializzazione qui per l'estensione. In questo caso, viene inizializzata una mappa hash per registrare l'ora di inizio della chiamata per ogni funzione.
Il configure metodo è rivolto al cliente. Nel file readme è possibile indicare ai clienti quando devono chiamare Extension.configure(). Il readme deve inoltre documentare le funzionalità di estensione, la possibile configurazione e l'utilizzo dell'estensione. In questo esempio, i clienti possono scegliere se il tempo trascorso viene segnalato in HttpResponse.
Il pre_invocation_app_level metodo viene chiamato dal ruolo di lavoro Python prima dell'esecuzione della funzione. Fornisce le informazioni della funzione, ad esempio contesto di funzione e argomenti. In questo esempio l'estensione registra un messaggio e registra l'ora di inizio di una chiamata in base al relativo invocation_id.
Analogamente, viene chiamato dopo l'esecuzione della post_invocation_app_level funzione. In questo esempio viene calcolato il tempo trascorso in base all'ora di inizio e all'ora corrente. Sovrascrive anche il valore restituito della risposta HTTP.
Creare un readme.md
Creare un file readme.md nella radice del progetto di estensione. Questo file contiene le istruzioni e l'utilizzo dell'estensione. Il contenuto readme.md viene visualizzato come descrizione nella home page del progetto PyPI.
markdown
# 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.
Usare l'estensione in locale
Dopo aver creato un'estensione, è possibile usarla in un progetto di app per verificare che funzioni come previsto.
Creare una funzione trigger HTTP
Creare una nuova cartella per il progetto dell'app e spostarla.
Dalla shell appropriata, ad esempio Bash, eseguire il comando seguente per inizializzare il progetto:
Bash
func init --python
Usare il comando seguente per creare una nuova funzione trigger HTTP che consente l'accesso anonimo:
Bash
func new -t HttpTrigger -n HttpTrigger -a anonymous
Attivare un ambiente virtuale
Creare un ambiente virtuale Python basato sul sistema operativo come indicato di seguito:
Aprire il file di progetto local.settings.json e aggiungere il campo seguente a Values:
JSON
"PYTHON_ENABLE_WORKER_EXTENSIONS": "1"
Quando si esegue in Azure, si aggiunge PYTHON_ENABLE_WORKER_EXTENSIONS=1 invece alle impostazioni dell'app nell'app per le funzioni.
Aggiungere due righe seguenti prima della main funzione nel file __init.py__ per il modello di programmazione v1 o nel file function_app.py per il modello di programmazione v2:
Python
from python_worker_extension_timer import TimerExtension
TimerExtension.configure(append_to_http_response=True)
Questo codice importa il TimerExtension modulo e imposta il valore di append_to_http_response configurazione.
Verificare l'estensione
Dalla cartella radice del progetto dell'app avviare l'host della funzione usando func host start --verbose. Verrà visualizzato l'endpoint locale della funzione nell'output come https://localhost:7071/api/HttpTrigger.
Nel browser inviare una richiesta GET a https://localhost:7071/api/HttpTrigger. Verrà visualizzata una risposta simile alla seguente, con i dati TimeElapsed per la richiesta aggiunta.
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)
Pubblicare l'estensione
Dopo aver creato e verificato l'estensione, è comunque necessario completare queste attività di pubblicazione rimanenti:
Scegliere una licenza.
Creare una readme.md e altre documentazione.
Pubblicare la libreria di estensioni in un registro pacchetti Python o in un sistema di controllo della versione (VCS).
Eseguire il comando seguente per installare twine e wheel nell'ambiente Python predefinito o in un ambiente virtuale:
Bash
pip install twine wheel
Rimuovere la cartella precedente dist/ dal repository dell'estensione.
Eseguire il comando seguente per generare un nuovo pacchetto all'interno dist/di :
Bash
python setup.py sdist bdist_wheel
Eseguire il comando seguente per caricare il pacchetto in PyPI:
Bash
twine upload dist/*
Potrebbe essere necessario specificare le credenziali dell'account PyPI durante il caricamento. È anche possibile testare il caricamento del pacchetto con twine upload -r testpypi dist/*. Per altre informazioni, vedere la documentazione di Twine.
Dopo questi passaggi, i clienti possono usare l'estensione includendo il nome del pacchetto nella requirements.txt.
È anche possibile pubblicare il codice sorgente dell'estensione con il file setup.py in un repository GitHub, come illustrato in questo repository di esempio.
L'integrazione di OpenCensus è un progetto open source che usa l'interfaccia di estensione per integrare la traccia dei dati di telemetria nelle app Python Funzioni di Azure. Vedere il repository opencensus-python-extensions-azure per esaminare l'implementazione di questa estensione del ruolo di lavoro Python.
Passaggi successivi
Per altre informazioni sullo sviluppo di Funzioni di Azure Python, vedere le risorse seguenti:
Questo percorso di apprendimento illustra Funzioni di Azure, che crea sistemi di calcolo on demand basati su eventi usando la logica lato server per creare architetture serverless.
Progettare soluzioni end-to-end in Microsoft Azure per creare Funzioni di Azure, implementare e gestire app Web, sviluppare soluzioni che usano Archiviazione di Azure e altro ancora.
Informazioni su come sviluppare, convalidare e distribuire i progetti di codice Python in Funzioni di Azure usando la libreria Python per Funzioni di Azure.
Informazioni su come creare una funzione in Python e quindi pubblicare il progetto locale nell'hosting serverless in Funzioni di Azure usando l'estensione Funzioni di Azure in Visual Studio Code.
Gavin Aguiar e Shreya Batra si uniscono a Scott Hanselman per discutere il modello di programmazione v2 per Funzioni di Azure usando Python, che offre un'esperienza di sviluppo Funzioni di Azure più familiare agli sviluppatori Python. Le funzionalità principali includono trigger e associazioni dichiarati come decorator, una struttura di cartelle semplificata e supporto tramite la documentazione di facile riferimento. Capitoli 00:00 - Introduzione 01:18 - Backgrounder Funzioni di Azure 04:30 - Modello di pr
Informazioni su come creare una funzione Python dalla riga di comando e quindi pubblicare il progetto locale nell'hosting serverless in Funzioni di Azure.