Bagikan melalui


Panduan Pengembang Azure Functions Python

Panduan ini adalah pengantar untuk mengembangkan Azure Functions dengan menggunakan Python. Artikel ini mengasumsikan bahwa Anda telah membaca panduan pengembang Azure Functions.

Penting

Artikel ini mendukung model pemrograman v1 dan v2 untuk Python di Azure Functions. Model Python v1 menggunakan file functions.json untuk menentukan fungsi, dan model v2 baru memungkinkan Anda menggunakan pendekatan berbasis dekorator. Pendekatan baru ini menghasilkan struktur file yang lebih sederhana, dan lebih sentris kode. Pilih pemilih v2 di bagian atas artikel untuk mempelajari tentang model pemrograman baru ini.

Sebagai pengembang Python, Anda mungkin juga tertarik dengan topik-topik ini:

  • Visual Studio Code: Buat aplikasi Python pertama Anda menggunakan Visual Studio Code.
  • Terminal atau prompt perintah: Buat aplikasi Python pertama Anda dari prompt perintah menggunakan Azure Functions Core Tools.
  • Sampel: Tinjau beberapa aplikasi Python yang ada di browser Sampel Learn.
  • Visual Studio Code: Buat aplikasi Python pertama Anda menggunakan Visual Studio Code.
  • Terminal atau prompt perintah: Buat aplikasi Python pertama Anda dari prompt perintah menggunakan Azure Functions Core Tools.
  • Sampel: Tinjau beberapa aplikasi Python yang ada di browser Sampel Learn.

Opsi pengembangan

Kedua model pemrograman Python Functions mendukung pengembangan lokal di salah satu lingkungan berikut:

Model pemrograman Python v2:

Model pemrograman Python v1:

Anda juga dapat membuat fungsi Python v1 di portal Azure.

Tip

Meskipun Anda dapat mengembangkan fungsi Azure berbasis Python secara lokal di Windows, Python hanya didukung pada paket hosting berbasis Linux saat berjalan di Azure. Untuk informasi selengkapnya, lihat daftar kombinasi sistem operasi/runtime yang didukung.

Model pemrograman

Azure Functions mengharapkan fungsi menjadi metode stateless dalam skrip Python Anda yang memproses input dan menghasilkan output. Secara default, runtime mengharapkan metode diimplementasikan sebagai metode global yang disebut main() dalam file __init__.py . Anda juga dapat menentukan titik masuk alternatif.

Anda mengikat data ke fungsi dari pemicu dan pengikatan melalui atribut metode yang menggunakan name properti yang ditentukan dalam file function.json . Misalnya, file function.json berikut menjelaskan fungsi sederhana yang dipicu oleh permintaan HTTP bernama req:

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

Berdasarkan definisi ini, file __init__.py yang berisi kode fungsi mungkin terlihat seperti contoh berikut:

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

Anda juga dapat secara eksplisit mendeklarasikan tipe atribut dan menampilkan jenis dalam fungsi menggunakan anotasi jenis Python. Melakukannya membantu Anda menggunakan fitur IntelliSense dan pelengkapan otomatis yang disediakan oleh banyak editor kode Python.

import azure.functions

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

Gunakan anotasi Python yang disertakan dalam paket azure.functions.* untuk mengikat input dan output ke metode Anda.

Azure Functions mengharapkan fungsi menjadi metode stateless dalam skrip Python Anda yang memproses input dan menghasilkan output. Secara default, runtime mengharapkan metode diimplementasikan sebagai metode global dalam file function_app.py .

Pemicu dan pengikatan dapat dideklarasikan dan digunakan dalam fungsi dalam pendekatan berbasis dekorator. Mereka didefinisikan dalam file yang sama, function_app.py, sebagai fungsi. Sebagai contoh, file function_app.py berikut mewakili pemicu fungsi oleh permintaan HTTP.

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

Anda juga dapat secara eksplisit mendeklarasikan tipe atribut dan menampilkan jenis dalam fungsi menggunakan anotasi jenis Python. Melakukannya membantu Anda menggunakan fitur IntelliSense dan pelengkapan otomatis yang disediakan oleh banyak editor kode Python.

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

Untuk mempelajari tentang batasan yang diketahui dengan model v2 dan solusinya, lihat Memecahkan masalah kesalahan Python di Azure Functions.

Titik masuk alternatif

Anda dapat mengubah perilaku default fungsi secara opsional dengan menentukan properti scriptFile dan entryPoint di file function.json. Misalnya, function.json berikut memberi tahu runtime untuk menggunakan customentry() metode dalam file main.py sebagai titik masuk untuk fungsi Azure Anda.

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

Titik entri hanya ada di file function_app.py . Namun, Anda dapat mereferensikan fungsi dalam proyek di function_app.py dengan menggunakan cetak biru atau dengan mengimpor.

Struktur folder

Struktur folder yang direkomendasikan untuk proyek fungsi Python terlihat seperti contoh berikut:

 <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

Folder proyek utama, <project_root>, dapat berisi file berikut:

  • local.settings.json: Untuk menyimpan pengaturan aplikasi dan string koneksi yang digunakan saat berjalan secara lokal. File ini tidak dipublikasikan ke Azure. Untuk mempelajari lebih lanjut, lihat local.settings.file.
  • requirements.txt: Berisi daftar paket Python yang diinstal sistem saat menerbitkan ke Azure.
  • host.json: Berisi opsi konfigurasi yang memengaruhi semua fungsi dalam instans aplikasi fungsi. File ini dipublikasikan ke Azure. Tidak semua opsi didukung saat berjalan secara lokal. Untuk mempelajari lebih lanjut, lihat host.json.
  • .vscode/: (Opsional) Berisi konfigurasi Visual Studio Code yang disimpan. Untuk mempelajari selengkapnya, lihat Pengaturan Visual Studio Code.
  • .venv/: (Opsional) Berisi lingkungan virtual Python yang digunakan oleh pengembangan lokal.
  • Dockerfile: (Opsional) Digunakan saat menerbitkan proyek Anda dalam kontainer kustom.
  • tests/: (Opsional) Berisi kasus pengujian aplikasi fungsi Anda.
  • .funcignore: (Opsional) Mendeklarasikan file yang seharusnya tidak dipublikasikan ke Azure. Biasanya, file ini berisi .vscode/ untuk mengabaikan pengaturan editor Anda, .venv/ untuk mengabaikan lingkungan virtual Python lokal, pengujian/ untuk mengabaikan kasus pengujian, dan local.settings.json untuk mencegah pengaturan aplikasi lokal diterbitkan.

Setiap fungsi memiliki file kode dan file konfigurasi pengikatannya sendiri, function.json.

Struktur folder yang direkomendasikan untuk proyek fungsi Python terlihat seperti contoh berikut:

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

Folder proyek utama, <project_root>, dapat berisi file berikut:

  • .venv/: (Opsional) Berisi lingkungan virtual Python yang digunakan oleh pengembangan lokal.
  • .vscode/: (Opsional) Berisi konfigurasi Visual Studio Code yang disimpan. Untuk mempelajari selengkapnya, lihat Pengaturan Visual Studio Code.
  • function_app.py: Lokasi default untuk semua fungsi dan pemicu dan pengikatan terkait.
  • additional_functions.py: (Opsional) File Python lainnya yang berisi fungsi (biasanya untuk pengelompokan logis) yang dirujuk dalam function_app.py melalui cetak biru.
  • tests/: (Opsional) Berisi kasus pengujian aplikasi fungsi Anda.
  • .funcignore: (Opsional) Mendeklarasikan file yang seharusnya tidak dipublikasikan ke Azure. Biasanya, file ini berisi .vscode/ untuk mengabaikan pengaturan editor Anda, .venv/ untuk mengabaikan lingkungan virtual Python lokal, pengujian/ untuk mengabaikan kasus pengujian, dan local.settings.json untuk mencegah pengaturan aplikasi lokal diterbitkan.
  • host.json: Berisi opsi konfigurasi yang memengaruhi semua fungsi dalam instans aplikasi fungsi. File ini dipublikasikan ke Azure. Tidak semua opsi didukung saat berjalan secara lokal. Untuk mempelajari lebih lanjut, lihat host.json.
  • local.settings.json: Digunakan untuk menyimpan pengaturan aplikasi dan string koneksi saat berjalan secara lokal. File ini tidak dipublikasikan ke Azure. Untuk mempelajari lebih lanjut, lihat local.settings.file.
  • requirements.txt: Berisi daftar paket Python yang diinstal sistem saat diterbitkan ke Azure.
  • Dockerfile: (Opsional) Digunakan saat menerbitkan proyek Anda dalam kontainer kustom.

Saat Anda menyebarkan proyek ke aplikasi fungsi di Azure, seluruh konten folder proyek utama, <project_root>, harus disertakan dalam paket, tetapi bukan folder itu sendiri, yang berarti bahwa host.json harus berada di akar paket. Sebaiknya Pertahankan pengujian Anda di folder bersama dengan fungsi lain (dalam contoh ini, pengujian/). Untuk informasi selengkapnya, lihat Pengujian Unit.

Sambungkan ke database

Azure Functions terintegrasi dengan baik dengan Azure Cosmos DB untuk banyak kasus penggunaan, termasuk IoT, e-niaga, game, dll.

Misalnya, untuk sumber peristiwa, kedua layanan terintegrasi ke arsitektur berbasis peristiwa daya menggunakan fungsionalitas umpan perubahan Azure Cosmos DB. Umpan perubahan menyediakan layanan mikro hilir kemampuan untuk membaca sisipan dan pembaruan yang andal dan bertahap (misalnya, peristiwa pesanan). Fungsionalitas ini dapat digunakan untuk menyediakan penyimpanan peristiwa persisten sebagai broker pesan untuk peristiwa yang mengubah status dan alur kerja pemrosesan pesanan drive antara banyak layanan mikro (yang dapat diimplementasikan sebagai Azure Functions tanpa server).

Arsitektur referensi alur pemesanan Azure Cosmos DB

Untuk menyambungkan ke Azure Cosmos DB, pertama-tama buat akun, database, dan kontainer. Kemudian Anda dapat menyambungkan kode fungsi Anda ke Azure Cosmos DB menggunakan pemicu dan pengikatan, seperti contoh ini.

Untuk menerapkan logika aplikasi yang lebih kompleks, Anda juga dapat menggunakan pustaka Python untuk Cosmos DB. Implementasi I/O asinkron terlihat seperti ini:

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

Blueprints

Model pemrograman Python v2 memperkenalkan konsep cetak biru. Cetak biru adalah kelas baru yang dibuat untuk mendaftarkan fungsi di luar aplikasi fungsi inti. Fungsi yang terdaftar dalam instans cetak biru tidak diindeks langsung oleh runtime fungsi. Untuk mengindeks fungsi cetak biru ini, aplikasi fungsi perlu mendaftarkan fungsi dari instans cetak biru.

Menggunakan cetak biru memberikan manfaat berikut:

  • Memungkinkan Anda memecah aplikasi fungsi menjadi komponen modular, yang memungkinkan Anda menentukan fungsi dalam beberapa file Python dan membaginya menjadi komponen yang berbeda per file.
  • Menyediakan antarmuka aplikasi fungsi publik yang dapat diperluas untuk membangun dan menggunakan kembali API Anda sendiri.

Contoh berikut menunjukkan cara menggunakan cetak biru:

Pertama, dalam file http_blueprint.py , fungsi yang dipicu HTTP pertama kali ditentukan dan ditambahkan ke objek cetak biru.

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 
        ) 

Selanjutnya, dalam file function_app.py , objek cetak biru diimpor dan fungsinya didaftarkan ke aplikasi fungsi.

import azure.functions as func 
from http_blueprint import bp

app = func.FunctionApp() 

app.register_functions(bp) 

Catatan

Durable Functions juga mendukung cetak biru. Untuk membuat cetak biru untuk aplikasi Durable Functions, daftarkan pemicu orkestrasi, aktivitas, dan entitas Anda dan pengikatan klien menggunakan kelas , seperti yang azure-functions-durable Blueprint ditunjukkan di sini. Cetak biru yang dihasilkan kemudian dapat didaftarkan seperti biasa. Lihat contoh kami untuk contoh.

Perilaku impor

Anda dapat mengimpor modul dalam kode fungsi menggunakan referensi absolut dan relatif. Berdasarkan struktur folder yang dijelaskan sebelumnya, impor berikut berfungsi dari dalam file <fungsi 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)

Catatan

Saat Anda menggunakan sintaks impor absolut, folder shared_code/ perlu berisi file __init__.py untuk menandainya sebagai paket Python.

Impor __app__ berikut dan melebihi impor relatif tingkat atas tidak digunakan lagi, karena tidak didukung oleh pemeriksa jenis statis dan tidak didukung oleh kerangka kerja pengujian Python:

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)

Pemicu dan Input

Input dibagi menjadi dua kategori di Azure Functions: input pemicu dan input tambahan. Meskipun berbeda dalam file function.json , penggunaannya identik dalam kode Python. String koneksi atau rahasia untuk sumber pemicu dan input dipetakan ke nilai dalam file local.settings.json saat berjalan secara lokal, dan mereka memetakan ke pengaturan aplikasi saat berjalan di Azure.

Misalnya, kode berikut menunjukkan perbedaan antara dua input:

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

Ketika fungsi dipanggil, permintaan HTTP diteruskan ke fungsi sebagai req. Entri diambil dari akun Azure Blob Storage berdasarkan ID di URL rute dan tersedia seperti obj dalam isi fungsi. Di sini, akun penyimpanan yang ditentukan adalah string koneksi yang ditemukan di CONNECTION_STRING pengaturan aplikasi.

Input dibagi menjadi dua kategori di Azure Functions: input pemicu dan input tambahan. Meskipun didefinisikan menggunakan dekorator yang berbeda, penggunaannya mirip dalam kode Python. String koneksi atau rahasia untuk sumber pemicu dan input dipetakan ke nilai dalam file local.settings.json saat berjalan secara lokal, dan mereka memetakan ke pengaturan aplikasi saat berjalan di Azure.

Sebagai contoh, kode berikut menunjukkan cara menentukan pengikatan input 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.read_blob(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()}')

Ketika fungsi dipanggil, permintaan HTTP diteruskan ke fungsi sebagai req. Entri diambil dari akun Azure Blob Storage berdasarkan ID di URL rute dan tersedia seperti obj dalam isi fungsi. Di sini, akun penyimpanan yang ditentukan adalah string koneksi yang ditemukan di STORAGE_CONNECTION_STRING pengaturan aplikasi.

Untuk operasi pengikatan intensif data, Anda mungkin ingin menggunakan akun penyimpanan terpisah. Untuk informasi selengkapnya, lihat Panduan akun penyimpanan.

Pengikatan jenis SDK (pratinjau)

Untuk pemicu dan pengikatan tertentu, Anda dapat bekerja dengan jenis data yang diimplementasikan oleh Azure SDK dan kerangka kerja yang mendasar. Pengikatan jenis SDK ini memungkinkan Anda berinteraksi mengikat data seolah-olah Anda menggunakan SDK layanan yang mendasar.

Penting

Dukungan untuk pengikatan jenis SDK memerlukan model pemrograman Python v2.

Functions mendukung pengikatan jenis Python SDK untuk penyimpanan Azure Blob, yang memungkinkan Anda bekerja dengan data blob menggunakan jenis yang mendasar BlobClient .

Penting

Dukungan pengikatan jenis SDK untuk Python saat ini dalam pratinjau:

  • Anda harus menggunakan model pemrograman Python v2.
  • Saat ini, hanya jenis SDK sinkron yang didukung.

Prasyarat

Mengaktifkan pengikatan jenis SDK untuk ekstensi penyimpanan Blob

  1. azurefunctions-extensions-bindings-blob Tambahkan paket ekstensi ke requirements.txt file dalam proyek, yang harus menyertakan setidaknya paket ini:

    azure-functions
    azurefunctions-extensions-bindings-blob
    
  2. Tambahkan kode ini ke function_app.py file dalam proyek, yang mengimpor pengikatan jenis SDK:

    import azurefunctions.extensions.bindings.blob as blob
    

Contoh pengikatan jenis SDK

Contoh ini menunjukkan cara mendapatkan BlobClient dari pemicu penyimpanan Blob (blob_trigger) dan dari pengikatan input pada pemicu HTTP (blob_input):

import logging

import azure.functions as func
import azurefunctions.extensions.bindings.blob as blob

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

@app.blob_trigger(
    arg_name="client", path="PATH/TO/BLOB", connection="AzureWebJobsStorage"
)
def blob_trigger(client: blob.BlobClient):
    logging.info(
        f"Python blob trigger function processed blob \n"
        f"Properties: {client.get_blob_properties()}\n"
        f"Blob content head: {client.download_blob().read(size=1)}"
    )


@app.route(route="file")
@app.blob_input(
    arg_name="client", path="PATH/TO/BLOB", connection="AzureWebJobsStorage"
)
def blob_input(req: func.HttpRequest, client: blob.BlobClient):
    logging.info(
        f"Python blob input function processed blob \n"
        f"Properties: {client.get_blob_properties()}\n"
        f"Blob content head: {client.download_blob().read(size=1)}"
    )
    return "ok"

Anda dapat melihat sampel pengikatan jenis SDK lainnya untuk penyimpanan Blob di repositori ekstensi Python:

Aliran HTTP (pratinjau)

Aliran HTTP memungkinkan Anda menerima dan mengembalikan data dari titik akhir HTTP menggunakan API permintaan dan respons FastAPI yang diaktifkan dalam fungsi Anda. API ini memungkinkan host memproses data besar dalam pesan HTTP sebagai gugus alih-alih membaca seluruh pesan ke dalam memori.

Fitur ini memungkinkan untuk menangani aliran data besar, integrasi OpenAI, mengirimkan konten dinamis, dan mendukung skenario HTTP inti lainnya yang memerlukan interaksi real-time melalui HTTP. Anda juga dapat menggunakan jenis respons FastAPI dengan aliran HTTP. Tanpa aliran HTTP, ukuran permintaan dan respons HTTP Anda dibatasi oleh pembatasan memori yang dapat ditemui saat memproses seluruh payload pesan dalam memori.

Penting

Dukungan untuk aliran HTTP memerlukan model pemrograman Python v2.

Penting

Dukungan aliran HTTP untuk Python saat ini dalam pratinjau dan mengharuskan Anda menggunakan model pemrograman Python v2.

Prasyarat

Mengaktifkan aliran HTTP

Aliran HTTP dinonaktifkan secara default. Anda perlu mengaktifkan fitur ini di pengaturan aplikasi Anda dan juga memperbarui kode Anda untuk menggunakan paket FastAPI. Perhatikan bahwa saat mengaktifkan aliran HTTP, aplikasi fungsi akan default menggunakan streaming HTTP, dan fungsionalitas HTTP asli tidak akan berfungsi.

  1. azurefunctions-extensions-http-fastapi Tambahkan paket ekstensi ke requirements.txt file dalam proyek, yang harus menyertakan setidaknya paket ini:

    azure-functions
    azurefunctions-extensions-http-fastapi
    
  2. Tambahkan kode ini ke function_app.py file dalam proyek, yang mengimpor ekstensi FastAPI:

    from azurefunctions.extensions.http.fastapi import Request, StreamingResponse
    
  3. Saat Anda menyebarkan ke Azure, tambahkan pengaturan aplikasi berikut di aplikasi fungsi Anda:

    "PYTHON_ENABLE_INIT_INDEXING": "1"

    Jika Anda menyebarkan ke Konsumsi Linux, tambahkan juga

    "PYTHON_ISOLATE_WORKER_DEPENDENCIES": "1"

    Saat berjalan secara lokal, Anda juga perlu menambahkan pengaturan yang sama ini ke local.settings.json file proyek.

Contoh aliran HTTP

Setelah mengaktifkan fitur streaming HTTP, Anda dapat membuat fungsi yang mengalirkan data melalui HTTP.

Contoh ini adalah fungsi yang dipicu HTTP yang mengalirkan data respons HTTP. Anda dapat menggunakan kemampuan ini untuk mendukung skenario seperti mengirim data peristiwa melalui alur untuk visualisasi real time atau mendeteksi anomali dalam sekumpulan besar data dan memberikan pemberitahuan instan.

import time

import azure.functions as func
from azurefunctions.extensions.http.fastapi import Request, StreamingResponse

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


def generate_sensor_data():
    """Generate real-time sensor data."""
    for i in range(10):
        # Simulate temperature and humidity readings
        temperature = 20 + i
        humidity = 50 + i
        yield f"data: {{'temperature': {temperature}, 'humidity': {humidity}}}\n\n"
        time.sleep(1)


@app.route(route="stream", methods=[func.HttpMethod.GET])
async def stream_sensor_data(req: Request) -> StreamingResponse:
    """Endpoint to stream real-time sensor data."""
    return StreamingResponse(generate_sensor_data(), media_type="text/event-stream")

Contoh ini adalah fungsi yang dipicu HTTP yang menerima dan memproses data streaming dari klien secara real time. Ini menunjukkan kemampuan pengunggahan streaming yang dapat membantu skenario seperti memproses aliran data berkelanjutan dan menangani data peristiwa dari perangkat IoT.

import azure.functions as func
from azurefunctions.extensions.http.fastapi import JSONResponse, Request

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


@app.route(route="streaming_upload", methods=[func.HttpMethod.POST])
async def streaming_upload(req: Request) -> JSONResponse:
    """Handle streaming upload requests."""
    # Process each chunk of data as it arrives
    async for chunk in req.stream():
        process_data_chunk(chunk)

    # Once all data is received, return a JSON response indicating successful processing
    return JSONResponse({"status": "Data uploaded and processed successfully"})


def process_data_chunk(chunk: bytes):
    """Process each data chunk."""
    # Add custom processing logic here
    pass

Memanggil aliran HTTP

Anda harus menggunakan pustaka klien HTTP untuk melakukan panggilan streaming ke titik akhir FastAPI fungsi. Alat klien atau browser yang Anda gunakan mungkin tidak mendukung streaming secara asli atau hanya dapat mengembalikan potongan data pertama.

Anda dapat menggunakan skrip klien seperti ini untuk mengirim data streaming ke titik akhir HTTP:

import httpx # Be sure to add 'httpx' to 'requirements.txt'
import asyncio

async def stream_generator(file_path):
    chunk_size = 2 * 1024  # Define your own chunk size
    with open(file_path, 'rb') as file:
        while chunk := file.read(chunk_size):
            yield chunk
            print(f"Sent chunk: {len(chunk)} bytes")

async def stream_to_server(url, file_path):
    timeout = httpx.Timeout(60.0, connect=60.0)
    async with httpx.AsyncClient(timeout=timeout) as client:
        response = await client.post(url, content=stream_generator(file_path))
        return response

async def stream_response(response):
    if response.status_code == 200:
        async for chunk in response.aiter_raw():
            print(f"Received chunk: {len(chunk)} bytes")
    else:
        print(f"Error: {response}")

async def main():
    print('helloworld')
    # Customize your streaming endpoint served from core tool in variable 'url' if different.
    url = 'http://localhost:7071/api/streaming_upload'
    file_path = r'<file path>'

    response = await stream_to_server(url, file_path)
    print(response)

if __name__ == "__main__":
    asyncio.run(main())

Output

Output dapat dinyatakan baik sebagai parameter nilai kembali maupun output. Jika hanya ada satu output, sebaiknya gunakan nilai yang dikembalikan. Untuk beberapa output, Anda harus menggunakan parameter output.

Untuk menggunakan nilai pengembalian fungsi sebagai nilai pengikatan output, name properti pengikatan harus diatur ke $return dalam file function.json .

Untuk menghasilkan beberapa output, gunakan metode set() yang disediakan oleh antarmuka azure.functions.Out untuk menetapkan nilai ke pengikatan. Misalnya, fungsi berikut dapat mendorong pesan ke antrean dan juga mengembalikan respons 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

Output dapat dinyatakan baik sebagai parameter nilai kembali maupun output. Jika hanya ada satu output, sebaiknya gunakan nilai yang dikembalikan. Bila ada beberapa output, Anda harus menggunakan parameter output.

Untuk menghasilkan beberapa output, gunakan metode set() yang disediakan oleh antarmuka azure.functions.Out untuk menetapkan nilai ke pengikatan. Misalnya, fungsi berikut dapat mendorong pesan ke antrean dan juga mengembalikan respons 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

Pencatatan

Akses ke pencatat runtime Azure Functions tersedia melalui penangan root logging di aplikasi fungsi Anda. Pencatat ini terikat pada Application Insights dan memungkinkan Anda menandai peringatan dan kesalahan yang terjadi selama eksekusi fungsi.

Contoh berikut mencatat pesan info saat fungsi dipanggil melalui pemicu HTTP.

import logging

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

Tersedia lebih banyak metode pencatatan yang memungkinkan Anda menulis ke konsol pada tingkat pelacakan yang berbeda:

Metode Deskripsi
critical(_message_) Menulis pesan dengan tingkat KRITIS pada pencatat akar.
error(_message_) Menulis pesan dengan level ERROR pada pencatat akar.
warning(_message_) Menulis pesan dengan tingkat PERINGATAN pada pencatat akar.
info(_message_) Menulis pesan dengan tingkat INFO pada pencatat akar.
debug(_message_) Menulis pesan dengan tingkat DEBUG pada pencatat akar.

Untuk mempelajari selengkapnya tentang pengelogan, lihat Memantau Azure Functions.

Pengelogan dari utas yang dibuat

Untuk melihat log yang berasal dari utas yang Anda buat, sertakan context argumen dalam tanda tangan fungsi. Argumen ini berisi atribut thread_local_storage yang menyimpan lokal invocation_id. Ini dapat diatur ke fungsi saat ini invocation_id untuk memastikan konteks diubah.

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

Log telemetri kustom

Secara default, runtime Functions mengumpulkan log dan data telemetri lainnya yang dihasilkan oleh fungsi Anda. Telemetri ini berakhir sebagai jejak di Application Insights. Telemetri permintaan dan ketergantungan untuk layanan Azure tertentu juga dikumpulkan secara default oleh pemicu dan pengikatan.

Untuk mengumpulkan permintaan khusus dan telemetri ketergantungan khusus di luar pengikatan, Anda dapat menggunakan OpenCensus Python Extensions. Ekstensi ini mengirimkan data telemetri kustom ke instans Application Insights Anda. Anda dapat menemukan daftar ekstensi yang didukung di repositori OpenCensus.

Catatan

Untuk menggunakan ekstensi OpenCensus Python, Anda harus mengaktifkan ekstensi pekerja Python di aplikasi fungsi Anda dengan mengatur PYTHON_ENABLE_WORKER_EXTENSIONS ke 1. Anda juga perlu beralih menggunakan string koneksi Application Insights dengan menambahkan pengaturan APPLICATIONINSIGHTS_CONNECTION_STRING ke pengaturan aplikasi Anda, jika belum ada.

// 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,
    })

Pemicu HTTP

Pemicu HTTP didefinisikan dalam file function.json. name pengikatan harus cocok dengan parameter bernama di dalam fungsi. Dalam contoh sebelumnya, digunakan nama pengikatan req. Parameter ini adalah objek HttpRequest, dan objek HttpResponse dikembalikan.

Dari objek HttpRequest, Anda bisa mendapatkan header permintaan, parameter kueri, parameter rute, dan isi pesan.

Contoh berikut adalah dari templat pemicu HTTP untuk 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
        )

Dalam fungsi ini, Anda mendapatkan nilai name parameter kueri dari params parameter objek HttpRequest . Anda membaca isi pesan yang dikodekan JSON dengan menggunakan metode .get_json

Anda juga dapat mengatur status_code dan headers untuk pesan respons di objek HttpResponse yang dikembalikan.

Pemicu HTTP didefinisikan sebagai metode yang mengambil parameter pengikatan bernama, yang merupakan objek HttpRequest , dan mengembalikan objek HttpResponse . Anda menerapkan function_name dekorator ke metode untuk menentukan nama fungsi, sementara titik akhir HTTP diatur dengan menerapkan route dekorator.

Contoh ini berasal dari templat pemicu HTTP untuk model pemrograman Python v2, di mana nama parameter pengikatan adalah req. Ini adalah kode sampel yang disediakan saat Anda membuat fungsi dengan menggunakan Azure Functions Core Tools atau 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
        )

Dari objek HttpRequest, Anda bisa mendapatkan header permintaan, parameter kueri, parameter rute, dan isi pesan. Dalam fungsi ini, Anda mendapatkan nilai name parameter kueri dari params parameter objek HttpRequest . Anda membaca isi pesan yang dikodekan JSON dengan menggunakan metode .get_json

Anda juga dapat mengatur status_code dan headers untuk pesan respons di objek HttpResponse yang dikembalikan.

Untuk meneruskan nama dalam contoh ini, tempelkan URL yang disediakan saat Anda menjalankan fungsi, lalu tambahkan dengan "?name={name}".

Kerangka kerja web

Anda dapat menggunakan kerangka kerja yang kompatibel dengan Web Server Gateway Interface (WSGI) dan Asinkron yang kompatibel dengan Antarmuka Gateway Server (ASGI), seperti Flask dan FastAPI, dengan fungsi Python yang dipicu HTTP Anda. Bagian ini menunjukkan cara memodifikasi fungsi Anda agar mendukung kerangka kerja ini.

Pertama, file function.json harus diperbarui untuk menyertakan route dalam pemicu HTTP, seperti yang ditunjukkan dalam contoh berikut:

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

File host.json juga harus diperbarui untuk menyertakan HTTP routePrefix, seperti yang ditunjukkan dalam contoh berikut:

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

Perbarui file kode Python init.py, bergantung pada antarmuka yang digunakan oleh kerangka kerja Anda. Contoh berikut menunjukkan pendekatan handler ASGI atau pendekatan wrapper WSGI untuk Flask:

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)

Anda dapat menggunakan kerangka kerja yang kompatibel dengan Antarmuka Gateway Server Asinkron (ASGI) dan Antarmuka Gateway Server Web (WSGI), seperti Flask dan FastAPI, dengan fungsi Python yang dipicu HTTP Anda. Anda harus terlebih dahulu memperbarui file host.json untuk menyertakan HTTP routePrefix, seperti yang ditunjukkan dalam contoh berikut:

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

Kode kerangka kerja terlihat seperti contoh berikut:

AsgiFunctionApp adalah kelas aplikasi fungsi tingkat atas untuk membangun fungsi HTTP ASGI.

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

Penskalaan dan performa

Untuk penskalaan dan praktik terbaik performa untuk aplikasi fungsi Python, lihat artikel penskalaan dan performa Python.

Konteks

Untuk mendapatkan konteks pemanggilan fungsi saat berjalan, sertakan context argumen dalam tanda tangannya.

Contohnya:

import azure.functions


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

Kelas Context memiliki atribut string berikut:

Atribut Deskripsi
function_directory Direktori tempat fungsi berjalan.
function_name Nama fungsi.
invocation_id ID pemanggilan fungsi saat ini.
thread_local_storage Penyimpanan lokal utas fungsi. Berisi lokal invocation_id untuk pengelogan dari utas yang dibuat.
trace_context Konteks untuk pelacakan terdistribusi. Untuk informasi selengkapnya, lihat Trace Context .
retry_context Konteks untuk mencoba kembali ke fungsi. Untuk informasi selengkapnya, lihat retry-policies .

Variabel global

Tidak ada jaminan status aplikasi Anda akan dipertahankan untuk eksekusi di masa mendatang. Namun, runtime Azure Functions sering menggunakan kembali proses yang sama untuk beberapa eksekusi aplikasi yang sama. Untuk menyimpan hasil komputasi yang mahal, nyatakan sebagai variabel global.

CACHED_DATA = None


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

    # ... use CACHED_DATA in code

Variabel lingkungan

Di Azure Functions, pengaturan aplikasi, seperti string koneksi layanan, diekspos sebagai variabel lingkungan saat dijalankan. Ada dua cara utama untuk mengakses pengaturan ini dalam kode Anda.

Metode Deskripsi
os.environ["myAppSetting"] Mencoba mendapatkan pengaturan aplikasi berdasarkan nama kunci, dan menimbulkan kesalahan ketika tidak berhasil.
os.getenv("myAppSetting") Mencoba untuk mendapatkan pengaturan aplikasi berdasarkan nama kunci, dan mengembalikan null ketika tidak berhasil.

Kedua cara ini mengharuskan Anda untuk menyatakanimport os.

Contoh berikut os.environ["myAppSetting"] mendapatkan pengaturan aplikasi, dengan kunci bernama myAppSetting:

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

Untuk pengembangan lokal, pengaturan aplikasi dipertahankan dalam file local.settings.json.

Di Azure Functions, pengaturan aplikasi, seperti string koneksi layanan, diekspos sebagai variabel lingkungan saat dijalankan. Ada dua cara utama untuk mengakses pengaturan ini dalam kode Anda.

Metode Deskripsi
os.environ["myAppSetting"] Mencoba mendapatkan pengaturan aplikasi berdasarkan nama kunci, dan menimbulkan kesalahan ketika tidak berhasil.
os.getenv("myAppSetting") Mencoba untuk mendapatkan pengaturan aplikasi berdasarkan nama kunci, dan mengembalikan null ketika tidak berhasil.

Kedua cara ini mengharuskan Anda untuk menyatakanimport os.

Contoh berikut os.environ["myAppSetting"] mendapatkan pengaturan aplikasi, dengan kunci bernama myAppSetting:

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

Untuk pengembangan lokal, pengaturan aplikasi dipertahankan dalam file local.settings.json.

Versi Python

Azure Functions mendukung versi Python berikut:

Versi Azure Functions Versi Python*
4.x 3.11
3.10
3.9
3.8
3.7
3.x 3.9
3.8
3.7

* Distribusi Python resmi

Untuk meminta versi Python tertentu saat Anda membuat aplikasi fungsi di Azure, gunakan opsi --runtime-version dari perintah az functionapp create. Versi runtime Functions diatur oleh opsi --functions-version. Versi Python diatur saat aplikasi fungsi dibuat, dan tidak dapat diubah untuk aplikasi yang berjalan dalam paket Konsumsi.

Runtime menggunakan versi Python yang tersedia saat Anda menjalankannya secara lokal.

Mengubah versi Python

Untuk mengatur aplikasi fungsi Python ke versi bahasa tertentu, Anda perlu menentukan bahasa dan versi bahasa di LinuxFxVersion bidang dalam konfigurasi situs. Misalnya, untuk mengubah aplikasi Python untuk menggunakan Python 3.8, atur linuxFxVersion ke python|3.8.

Untuk mempelajari cara menampilkan dan mengubah linuxFxVersion pengaturan situs, lihat Cara menargetkan versi runtime Azure Functions.

Untuk informasi umum selengkapnya, lihat kebijakan dukungan runtime Bahasa Umum Azure Functions dan Bahasa yang didukung di Azure Functions.

Pengelolaan paket

Saat Anda mengembangkan secara lokal dengan menggunakan Core Tools atau Visual Studio Code, tambahkan nama dan versi paket yang diperlukan ke file requirements.txt , lalu instal dengan menggunakan pip.

Misalnya, Anda dapat menggunakan file dan pip perintah requirements.txt berikut untuk menginstal requests paket dari PyPI.

requests==2.19.1
pip install -r requirements.txt

Saat menjalankan fungsi Anda dalam paket App Service, dependensi yang Anda tentukan dalam requirements.txt diberikan prioritas daripada modul Python bawaan, seperti logging. Prioritas ini dapat menyebabkan konflik ketika modul bawaan memiliki nama yang sama dengan direktori dalam kode Anda. Saat berjalan dalam paket Konsumsi atau paket Elastic Premium, konflik kemungkinannya lebih kecil karena dependensi Anda tidak diprioritaskan secara default.

Untuk mencegah masalah yang berjalan dalam paket App Service, jangan beri nama direktori Anda sama dengan modul asli Python dan jangan sertakan pustaka asli Python dalam file requirements.txt proyek Anda.

Menerbitkan ke Azure

Saat Anda siap untuk menerbitkan, pastikan semua dependensi yang tersedia untuk umum telah tercantum dalam file requirements.txt. Anda dapat menemukan file ini di akar direktori proyek Anda.

Anda dapat menemukan file dan folder proyek yang dikecualikan dari penerbitan, termasuk folder lingkungan virtual, di direktori akar proyek Anda.

Ada tiga tindakan build yang didukung untuk menerbitkan proyek Python Anda ke Azure: build jarak jauh, build lokal, dan build dengan dependensi kustom.

Anda juga dapat menggunakan Azure Pipelines untuk membangun dependensi dan memublikasikan menggunakan pengiriman berkelanjutan (CD). Untuk mempelajari selengkapnya, lihat Pengiriman berkelanjutan dengan Azure Pipelines.

Build jarak jauh

Saat Anda menggunakan build jarak jauh, dependensi yang dipulihkan pada server dan dependensi asli cocok dengan lingkungan produksi. Build ini menghasilkan paket penyebaran yang lebih kecil untuk diunggah. Gunakan build jarak jauh saat Anda mengembangkan aplikasi Python di Windows. Jika project Anda memiliki dependensi kustom, Anda dapat menggunakan build jarak jauh dengan URL indeks tambahan.

Dependensi diperoleh secara jarak jauh berdasarkan konten file requirements.txt. Build jarak jauh adalah metode build yang direkomendasikan. Secara default, Core Tools meminta build jarak jauh saat Anda menggunakan perintah berikut func azure functionapp publish untuk menerbitkan proyek Python Anda ke Azure.

func azure functionapp publish <APP_NAME>

Ingatlah untuk mengganti <APP_NAME> dengan nama aplikasi fungsi Anda di Azure.

Ekstensi Azure Functions untuk Visual Studio Code juga meminta build jarak jauh secara default.

Build lokal

Dependensi diperoleh secara lokal berdasarkan konten file requirements.txt. Anda dapat mencegah melakukan build jarak jauh dengan menggunakan perintah berikut func azure functionapp publish untuk menerbitkan dengan build lokal:

func azure functionapp publish <APP_NAME> --build local

Ingatlah untuk mengganti <APP_NAME> dengan nama aplikasi fungsi Anda di Azure.

Saat Anda menggunakan opsi , --build local dependensi proyek dibaca dari file requirements.txt , dan paket dependen tersebut diunduh dan diinstal secara lokal. File dan dependensi proyek disebarkan dari komputer lokal Anda ke Azure. Build ini menghasilkan paket penyebaran yang lebih besar yang diunggah ke Azure. Jika karena alasan tertentu Anda tidak bisa mendapatkan file requirements.txt dengan menggunakan Core Tools, Anda harus menggunakan opsi dependensi kustom untuk penerbitan.

Penggunaan build lokal saat mengembangkan secara lokal di Windows tidak disarankan.

Dependensi kustom

Saat proyek Anda memiliki dependensi yang tidak ditemukan di Indeks Paket Python, ada dua cara untuk membangun proyek. Cara pertama, metode build , tergantung pada cara Anda membangun proyek.

Build jarak jauh dengan URL indeks tambahan

Ketika paket Anda tersedia dari indeks paket kustom yang dapat diakses, gunakan build jarak jauh. Sebelum menerbitkan, pastikan untuk membuat pengaturan aplikasi bernama PIP_EXTRA_INDEX_URL. Nilai untuk pengaturan ini adalah URL indeks paket kustom Anda. Menggunakan pengaturan ini memberi tahu build jarak jauh untuk dijalankan pip install dengan menggunakan --extra-index-url opsi . Untuk mempelajari lebih lanjut, lihat dokumentasi Pythonpip install.

Anda juga dapat menggunakan kredensial autentikasi dasar dengan URL indeks paket tambahan Anda. Untuk mempelajari selengkapnya, lihat Kredensial autentikasi dasar dalam dokumentasi Python.

Pasang paket lokal

Jika proyek Anda menggunakan paket yang tidak tersedia untuk umum untuk alat kami, Anda dapat membuatnya tersedia untuk aplikasi Anda dengan menempatkannya di direktori __app__/.python_packages . Sebelum Anda menerbitkan, jalankan perintah berikut untuk menginstal dependensi secara lokal:

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

Saat Anda menggunakan dependensi kustom, Anda harus menggunakan --no-build opsi penerbitan, karena Anda telah menginstal dependensi ke dalam folder proyek.

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

Ingatlah untuk mengganti <APP_NAME> dengan nama aplikasi fungsi Anda di Azure.

Pengujian Unit

Fungsi yang ditulis dalam Python dapat diuji seperti kode Python lainnya dengan menggunakan kerangka kerja pengujian standar. Untuk sebagian besar pengikatan, dimungkinkan untuk membuat objek input tiruan dengan membuat instans kelas yang sesuai dari paket azure.functions. azure.functions Karena paket tidak segera tersedia, pastikan untuk menginstalnya melalui file requirements.txt Anda seperti yang dijelaskan di bagian manajemen paket di atas.

Dengan my_second_function sebagai contoh, berikut ini adalah tes tiruan dari fungsi yang dipicu HTTP:

Pertama, buat <file project_root>/my_second_function/function.json , lalu tentukan fungsi ini sebagai pemicu HTTP.

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

Selanjutnya, Anda dapat menerapkan my_second_function dan 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

Anda dapat mulai menulis kasus pengujian untuk pemicu HTTP Anda.

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

Di dalam folder lingkungan virtual Python Anda .venv , instal kerangka kerja pengujian Python favorit Anda, seperti pip install pytest. Jalankan pytest tests untuk memeriksa hasil pengujian.

Pertama, buat <file project_root>/function_app.py dan terapkan my_second_function fungsi sebagai pemicu HTTP dan 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

Anda dapat mulai menulis kasus pengujian untuk pemicu HTTP Anda.

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

Di dalam folder lingkungan virtual .venv Python Anda, instal kerangka kerja pengujian Python favorit Anda, seperti pip install pytest. Jalankan pytest tests untuk memeriksa hasil pengujian.

File sementara

Metode tempfile.gettempdir() menampilkan folder sementara, yang mana di Linux adalah /tmp. Aplikasi Anda dapat menggunakan direktori ini untuk menyimpan file sementara yang dihasilkan dan digunakan oleh fungsi Anda saat dijalankan.

Penting

File yang ditulis ke direktori sementara tidak dijamin akan bertahan di seluruh pemanggilan. Selama peluasan skala, file sementara tidak dibagikan antarinstans.

Contoh berikut membuat file sementara bernama di direktori sementara (/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)

Kami menyarankan agar Anda mempertahankan pengujian di folder yang terpisah dari folder proyek. Tindakan ini mencegah Anda menyebarkan kode pengujian dengan aplikasi Anda.

Pustaka yang sebelumnya terinstal

Beberapa pustaka dilengkapi dengan runtime fungsi Python.

Pustaka standar Python

Pustaka standar Python berisi daftar modul Python bawaan yang dikirim dengan setiap distribusi Python. Sebagian besar pustaka ini membantu Anda mengakses fungsionalitas sistem, seperti input/output file (I/O). Pada sistem Windows, pustaka ini terinstal dengan Python. Pada sistem berbasis Unix, mereka disediakan oleh koleksi paket.

Untuk melihat pustaka untuk versi Python Anda, buka:

Dependensi pekerja Azure Functions Python

Pekerja Python Azure Functions memerlukan sekumpulan pustaka tertentu. Anda juga dapat menggunakan pustaka ini di fungsi Anda, tetapi bukan merupakan bagian dari standar Python. Jika fungsi Anda mengandalkan salah satu pustaka ini, fungsi tersebut mungkin tidak tersedia untuk kode Anda saat berjalan di luar Azure Functions.

Catatan

Jika requirements.txt aplikasi fungsi Anda mengandung entri azure-functions-worker, hapus entri tersebut. Pekerja fungsi dikelola secara otomatis oleh platform Azure Functions, dan kami memperbaruinya secara teratur dengan fitur baru dan perbaikan bug. Menginstal versi lama pekerja secara manual dalam file requirements.txt dapat menyebabkan masalah yang tidak terduga.

Catatan

Jika paket Anda berisi pustaka tertentu yang mungkin bertabrakan dengan dependensi pekerja (misalnya, protobuf, tensorflow, atau grpcio), konfigurasikan PYTHON_ISOLATE_WORKER_DEPENDENCIES ke 1 dalam pengaturan aplikasi untuk mencegah aplikasi Anda mengacu pada dependensi pekerja.

Pustaka Python Azure Functions

Setiap pembaruan pekerja Python menyertakan versi baru pustaka Azure Functions Python (azure.functions). Pendekatan ini memudahkan pembaruan yang kontinyu terhadap aplikasi fungsi Python Anda, karena setiap pembaruan selalu kompatibel dengan versi sebelumnya. Untuk daftar rilis pustaka ini, buka PyPi azure-functions.

Versi pustaka runtime diperbaiki oleh Azure, dan tidak dapat ditimpa oleh requirements.txt. Entri azure-functions di requirements.txt hanya untuk linting dan kesadaran pelanggan.

Gunakan kode berikut untuk melacak versi aktual pustaka fungsi Python di runtime Anda:

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

Pustaka sistem runtime

Untuk daftar pustaka sistem yang telah diinstal sebelumnya di gambar Docker pekerja Python, lihat yang berikut ini:

Waktu proses fungsi Versi Debian Versi Python
Versi 3.x Buster Python 3.7
Python 3.8
Python 3.9

Ekstensi pekerja Python

Proses pekerja Python yang berjalan di Azure Functions memungkinkan Anda mengintegrasikan pustaka pihak ketiga ke dalam aplikasi fungsi Anda. Pustaka ekstensi ini bertindak sebagai middleware yang dapat menginjeksi operasi tertentu selama siklus hidup eksekusi fungsi Anda.

Ekstensi diimpor dalam kode fungsi Anda seperti modul pustaka Python standar. Ekstensi dijalankan berdasarkan cakupan berikut:

Cakupan Deskripsi
Tingkat aplikasi Saat diimpor ke pemicu fungsi apa pun, ekstensi berlaku untuk setiap eksekusi fungsi di aplikasi.
Tingkat fungsi Eksekusi hanya terbatas pada pemicu fungsi tertentu tempat diimpor.

Tinjau informasi untuk setiap ekstensi untuk mempelajari selengkapnya tentang cakupan tempat ekstensi berjalan.

Ekstensi mengimplementasikan antarmuka ekstensi pekerja Python. Tindakan ini memungkinkan pekerja Python memproses panggilan ke dalam kode ekstensi selama siklus hidup eksekusi fungsi. Untuk mempelajari selengkapnya, lihat Membuat ekstensi.

Menggunakan ekstensi

Anda dapat menggunakan pustaka ekstensi pekerja Python di fungsi Python Anda dengan melakukan hal berikut:

  1. Tambahkan paket ekstensi dalam file requirements.txt untuk proyek Anda.
  2. Instal pustaka ke aplikasi Anda.
  3. Tambahkan pengaturan aplikasi berikut:
  4. Impor modul ekstensi ke pemicu fungsi Anda.
  5. Konfigurasikan instans ekstensi, jika diperlukan. Persyaratan konfigurasi harus dipanggil dalam dokumentasi ekstensi.

Penting

Pustaka ekstensi pekerja Python pihak ketiga tidak didukung atau dijaga oleh Microsoft. Anda harus memastikan bahwa ekstensi apa pun yang Anda gunakan di aplikasi fungsi Anda dapat dipercaya, dan Anda menanggung risiko penuh menggunakan ekstensi berbahaya atau buruk ditulis.

Pihak ketiga harus memberikan dokumentasi khusus tentang cara menginstal dan menggunakan ekstensi mereka di aplikasi fungsi Anda. Untuk contoh dasar cara menggunakan ekstensi, lihat Menggunakan ekstensi Anda.

Berikut adalah contoh penggunaan ekstensi di aplikasi fungsi, menurut cakupan:

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

Membuat ekstensi

Ekstensi dibuat oleh pengembang pustaka pihak ketiga yang telah membuat fungsionalitas yang dapat diintegrasikan ke dalam Azure Functions. Pengembang ekstensi mendesain, menerapkan, dan merilis paket Python yang berisi logika kustom yang dirancang khusus untuk dijalankan dalam konteks eksekusi fungsi. Ekstensi ini dapat diterbitkan baik ke registri PyPI atau repositori GitHub.

Untuk mempelajari cara membuat, mengemas, menerbitkan, dan menggunakan paket ekstensi pekerja Python, lihat Mengembangkan ekstensi pekerja Python untuk Azure Functions.

Ekstensi tingkat aplikasi

Ekstensi yang diwarisi dari AppExtensionBase eksekusi dalam cakupan aplikasi .

AppExtensionBase mengekspos metode kelas abstrak berikut untuk Anda terapkan:

Metode Deskripsi
init Dipanggil setelah ekstensi diimpor.
configure Dipanggil dari kode fungsi saat diperlukan untuk mengonfigurasi ekstensi.
post_function_load_app_level Dipanggil tepat setelah fungsi dimuat. Nama fungsi dan direktori fungsi diteruskan ke ekstensi. Perlu diingat bahwa direktori fungsi bersifat baca-saja, dan setiap upaya untuk menulis ke file lokal di direktori ini gagal.
pre_invocation_app_level Dipanggil tepat sebelum fungsi dipicu. Konteks fungsi dan argumen pemanggilan fungsi diteruskan ke ekstensi. Anda biasanya dapat meneruskan atribut lain dalam objek konteks untuk digunakan oleh kode fungsi.
post_invocation_app_level Dipanggil tepat setelah eksekusi fungsi selesai. Konteks fungsi, argumen pemanggilan fungsi, dan objek pengembalian pemanggilan diteruskan ke ekstensi. Penerapan ini adalah tempat yang baik untuk memvalidasi apakah eksekusi kait siklus hidup berhasil.

Ekstensi tingkat aplikasi

Ekstensi yang mewarisi dari FuncExtensionBase berjalan dalam pemicu fungsi tertentu.

FuncExtensionBase mengekspos metode kelas abstrak berikut untuk penerapan:

Metode Deskripsi
__init__ Konstruktor ekstensi. Ini dipanggil saat instans ekstensi diinisialisasi dalam fungsi tertentu. Saat menerapkan metode abstrak ini, Anda mungkin ingin menerima parameter dan meneruskannya ke metode super().__init__(filename) induk untuk pendaftaran ekstensi yang filename tepat.
post_function_load Dipanggil tepat setelah fungsi dimuat. Nama fungsi dan direktori fungsi diteruskan ke ekstensi. Perlu diingat bahwa direktori fungsi bersifat baca-saja, dan setiap upaya untuk menulis ke file lokal di direktori ini gagal.
pre_invocation Dipanggil tepat sebelum fungsi dipicu. Konteks fungsi dan argumen pemanggilan fungsi diteruskan ke ekstensi. Anda biasanya dapat meneruskan atribut lain dalam objek konteks untuk digunakan oleh kode fungsi.
post_invocation Dipanggil tepat setelah eksekusi fungsi selesai. Konteks fungsi, argumen pemanggilan fungsi, dan objek pengembalian pemanggilan diteruskan ke ekstensi. Penerapan ini adalah tempat yang baik untuk memvalidasi apakah eksekusi kait siklus hidup berhasil.

Berbagi sumber daya lintas asal

Azure Functions mendukung berbagi sumber daya lintas asal (CORS). CORS dikonfigurasi di portal dan melalui Azure CLI. Daftar asal yang diizinkan CORS berlaku di tingkat aplikasi fungsi. Dengan mengaktifkan CORS, respons menyertakan header Access-Control-Allow-Origin. Untuk mengetahui informasi selengkapnya, lihat Berbagi sumber daya lintas asal.

Berbagi sumber daya lintas asal (CORS) didukung penuh untuk aplikasi fungsi Python.

Asinkron

Secara default, sebuah instans host untuk Python hanya dapat memproses satu permintaan fungsi pada satu waktu. Ini karena Python adalah runtime berutas tunggal. Untuk aplikasi yang memproses sejumlah besar peristiwa I/O dan/atau terikat I/O, Anda dapat melakukan peningkatan performa secara signifikan dengan menjalankan fungsi secara asinkron. Untuk informasi lebih lanjut, lihat Meningkatkan performa throughput dari aplikasi Python di Azure Functions.

Memori bersama (pratinjau)

Untuk meningkatkan throughput, Azure Functions memungkinkan pekerja bahasa Python Anda yang tidak diproses berbagi memori dengan proses host Functions. Saat aplikasi fungsi Anda mengalami penyempitan, Anda dapat mengaktifkan memori bersama dengan menambahkan pengaturan aplikasi bernama FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED dengan nilai 1. Dengan memori bersama diaktifkan, Anda kemudian dapat menggunakan pengaturan DOCKER_SHM_SIZE untuk mengatur memori bersama ke sesuatu seperti 268435456, yang setara dengan 256 MB.

Misalnya, Anda dapat mengaktifkan memori bersama untuk mengurangi hambatan saat menggunakan pengikatan Blob Storage untuk mentransfer payload yang lebih besar dari 1 MB.

Fungsionalitas ini hanya tersedia untuk aplikasi fungsi yang berjalan dalam paket Premium dan Dedicated (Azure App Service). Untuk mempelajari selengkapnya, lihat Memori bersama.

Masalah umum dan FAQ

Berikut adalah dua panduan pemecahan masalah untuk masalah umum:

Berikut adalah dua panduan pemecahan masalah untuk masalah yang diketahui dengan model pemrograman v2:

Semua masalah yang diketahui dan permintaan fitur dilacak dalam daftar masalah GitHub. Jika Anda mengalami masalah dan tidak dapat menemukan masalah di GitHub, buka masalah baru, dan sertakan deskripsi terperinci tentang masalah tersebut.

Langkah berikutnya

Untuk informasi selengkapnya, lihat sumber daya berikut:

Mengalami masalah saat menggunakan Python? Beritahu kami apa yang terjadi.