Azure Functions Python 開發人員指南

本指南是使用 Python 開發Azure Functions的簡介。 本文假設您已經閱讀Azure Functions開發人員指南

重要

本文支援 Azure Functions 中適用于 Python 的 v1 和 v2 程式設計模型。 Python v2 程式設計模型目前為預覽狀態。 Python v1 模型會使用 functions.json 檔案來定義函式,而新的 v2 模型可讓您改用裝飾專案型方法。 這個新方法會產生更簡單的檔案結構,而且更以程式碼為主。 選擇文章頂端的 v2 選取器,以瞭解這個新的程式設計模型。

身為 Python 開發人員,您可能也對下列其中一篇文章感興趣:

注意

雖然您可以在 Windows 本機開發以 Python 為基礎的 Azure 函式,但在 Azure 中執行 Python 時,只有在以 Linux 為基礎的主控方案上才支援 Python。 如需詳細資訊,請參閱 支援的作業系統/執行時間組合清單

程式設計模型

Azure Functions 預期函式是 Python 指令碼中的無狀態方法,用來處理輸入及產生輸出。 根據預設,執行時間預期方法會實作為__init__.py檔案中呼叫 main() 的全域方法。 您也可以 指定替代進入點

您可以透過使用 namefunction.json 檔案中定義之屬性的方法屬性,將資料系結至觸發程式和系結。 例如,下列 function.json 檔案描述由名為 req 的 HTTP 要求所觸發的簡單函式:

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

根據此定義,包含函式程式碼 的 __init__.py 檔案看起來可能如下列範例所示:

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

您也可以使用 Python 型別註釋,在函式中明確地宣告參數類型並傳回型別。 這麼做可協助您使用許多 Python 程式碼編輯器所提供的 IntelliSense 和自動完成功能。

import azure.functions


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

使用 azure.functions.* 套件中包含的 Python 批註,將輸入和輸出系結至您的方法。

Azure Functions 預期函式是 Python 指令碼中的無狀態方法,用來處理輸入及產生輸出。 根據預設,執行時間預期方法會實作為 function_app.py 檔案中的全域方法。

觸發程式和系結可以在裝飾專案型方法的函式中宣告及使用。 它們定義于與函式相同的檔案 function_app.py中。 例如,下列 function_app.py 檔案代表 HTTP 要求所觸發的函式。

@app.function_name(name="HttpTrigger1")
@app.route(route="req")

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

您也可以使用 Python 型別註釋,在函式中明確地宣告參數類型並傳回型別。 這麼做可協助您使用許多 Python 程式碼編輯器所提供的 IntelliSense 和自動完成功能。

import azure.functions

@app.function_name(name="HttpTrigger1")
@app.route(route="req")

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

目前,Python v2 程式設計模型僅支援特定的觸發程式和系結。 如需詳細資訊,請參閱 觸發程式和輸入

若要瞭解 v2 模型的已知限制及其因應措施,請參閱針對Azure Functions中的 Python 錯誤進行疑難排解

替代進入點

您可以在 function.json 檔案中選擇性地指定 scriptFileentryPoint 屬性,來變更函式的預設行為。 例如,下列 function.json 會指示執行時間使用 customentry()main.py 檔案中的 方法作為 Azure 函式的進入點。

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

在預覽期間,進入點只會位於 function_app.py 檔案中。 不過,您可以使用藍圖或匯入,在 function_app.py中參考專案中的函式。

資料夾結構

Python 函式專案的建議資料夾結構看起來像下列範例:

 <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

主要專案資料夾< project_root >可以包含下列檔案:

  • local.settings.json:在本機執行時用來儲存應用程式設定和連接字串。 此檔案不會發行至 Azure。 若要深入瞭解,請參閱 local.settings.file
  • requirements.txt:包含發佈至 Azure 時系統所安裝的 Python 套件清單。
  • host.json:包含會對函數應用程式執行個體中所有函式產生影響的設定選項。 此檔案會發行至 Azure。 在本機執行時,不支援所有選項。 若要深入了解,請參閱host.json
  • .vscode/: (選擇性) 包含預存Visual Studio Code組態。 若要深入瞭解,請參閱Visual Studio Code設定
  • .venv/: (選擇性) 包含本機開發所使用的 Python 虛擬環境。
  • Dockerfile: (選擇性) 在 自訂容器中發佈專案時使用。
  • tests/:(選擇性) 包含函數應用程式的測試案例。
  • .funcignore: (選擇性) 宣告不應該發佈至 Azure 的檔案。 通常,此檔案包含 .vscode/ 以忽略您的編輯器設定. venv/ 忽略本機 Python 虛擬環境、 測試/ 忽略測試案例,以及 local.settings.json 以避免發佈本機應用程式設定。

每個函式都有自己的程式碼檔案和系結組態檔 function.json

Python 函式專案的建議資料夾結構看起來像下列範例:

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

主要專案資料夾< project_root >可以包含下列檔案:

  • .venv/: (選擇性) 包含本機開發所使用的 Python 虛擬環境。
  • .vscode/: (選擇性) 包含預存Visual Studio Code組態。 若要深入瞭解,請參閱Visual Studio Code設定
  • function_app.py:所有函式及其相關觸發程式和系結的預設位置。
  • additional_functions.py: (選擇性) 任何其他包含函式 (的 Python 檔案,通常適用于透過藍圖 function_app.py 參考的邏輯群組) 。
  • tests/:(選擇性) 包含函數應用程式的測試案例。
  • .funcignore: (選擇性) 宣告不應該發佈至 Azure 的檔案。 通常,此檔案包含 .vscode/ 以忽略編輯器設定、 .venv/ 忽略本機 Python 虛擬環境、 測試/ 忽略測試案例,以及 local.settings.json 以避免發佈本機應用程式設定。
  • host.json:包含會對函數應用程式執行個體中所有函式產生影響的設定選項。 此檔案會發行至 Azure。 在本機執行時,不支援所有選項。 若要深入了解,請參閱host.json
  • local.settings.json:用來在本機執行時儲存應用程式設定和連接字串。 此檔案不會發行至 Azure。 若要深入瞭解,請參閱 local.settings.file
  • requirements.txt:包含系統發行至 Azure 時所安裝的 Python 套件清單。
  • Dockerfile: (選擇性) 在 自訂容器中發佈專案時使用。

當您將專案部署至 Azure 中的函式應用程式時,主要專案資料夾< 的整個內容project_root >應該包含在套件中,但不包含資料夾本身,這表示host.json應該位於套件根目錄中。 建議您在此範例中, 測試/) 與其他函式一起維護資料夾中的測試 (。 如需詳細資訊,請參閱單元測試

藍圖

Python v2 程式設計模型引進 了藍圖的概念。 藍圖是新的類別,可具現化以在核心函式應用程式外部註冊函式。 在藍圖實例中註冊的函式不會直接由函式執行時間編制索引。 若要編制索引這些藍圖函式,函式應用程式必須從藍圖實例註冊函式。

使用藍圖可提供下列優點:

  • 可讓您將函式應用程式分成模組化元件,可讓您在多個 Python 檔案中定義函式,並將它們分割成每個檔案的不同元件。
  • 提供可延伸的公用函式應用程式介面,以建置及重複使用您自己的 API。

下列範例示範如何使用藍圖:

首先,在 HTTP_blueprint.py 檔案中,HTTP 觸發的函式會先定義並新增至藍圖物件。

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 
        ) 

接下來,在 function_app.py 檔案中,藍圖物件會匯入,且其函式會註冊至函式應用程式。

import azure.functions as func 
from http_blueprint import bp

app = func.FunctionApp() 

app.register_functions(bp) 

匯入行為

您可以透過同時使用絕對和相對參考,並在函式程式碼中匯入模組。 根據先前描述的資料夾結構,下列匯入會從函式檔案< 內運作, > 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)

注意

當您使用絕對匯入語法時, shared_code/ 資料夾必須包含 __init__.py 檔案,才能將其標示為 Python 套件。

下列__app__匯入和超過最上層相對匯入的已淘汰,因為它們不受靜態類型檢查程式支援,且 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)

觸發程序及輸入

輸入分成兩個類別,Azure Functions:觸發程式輸入和其他輸入。 雖然它們在 function.json 檔案中不同,但其使用方式在 Python 程式碼中相同。 觸發程式和輸入來源的連接字串或秘密會對應至 在本機執行時 local.settings.json 檔案中的值,並在 Azure 中執行時對應至應用程式設定。

例如,下列程式碼示範兩個輸入之間的差異:

// 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": "AzureWebJobsStorage"
    }
  ]
}
// local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "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()}')

叫用此函式時,HTTP 要求會以 req 形式傳遞至函式。 系統會根據路由 URL 中的識別碼,從Azure Blob 儲存體帳戶擷取專案,並在函式主體中提供 obj 。 在這裡,指定的儲存體帳戶是在應用程式設定中找到 AzureWebJobsStorage 的連接字串,這是函式應用程式所使用的相同儲存體帳戶。

輸入分成兩個類別,Azure Functions:觸發程式輸入和其他輸入。 雖然它們是使用不同的裝飾專案來定義,但其使用方式在 Python 程式碼中很類似。 觸發程式和輸入來源的連接字串或秘密會對應至 在本機執行時 local.settings.json 檔案中的值,並在 Azure 中執行時對應至應用程式設定。

例如,下列程式碼示範如何定義 Blob 儲存體輸入系結:

// local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsStorage": "<azure-storage-connection-string>",
    "AzureWebJobsFeatureFlags": "EnableWorkerIndexing"
  }
}
# 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="AzureWebJobsStorage")

def main(req: func.HttpRequest,
         obj: func.InputStream):
    logging.info(f'Python HTTP-triggered function processed: {obj.read()}')

叫用此函式時,HTTP 要求會以 req 形式傳遞至函式。 系統會根據路由 URL 中的識別碼,從Azure Blob 儲存體帳戶擷取專案,並在函式主體中提供 obj 。 在這裡,指定的儲存體帳戶是在 AzureWebJobsStorage 應用程式設定中找到的連接字串,這是函式應用程式所使用的相同儲存體帳戶。

目前,Python v2 程式設計模型只支援特定的觸發程式和系結。 支援的觸發程式和系結如下所示:

類型 觸發程序 輸入繫結 輸出繫結
HTTP x
計時器 x
Azure 佇列儲存體 x x
Azure 服務匯流排主題 x x
Azure 服務匯流排佇列 x x
Azure Cosmos DB x x x
Azure Blob 儲存體 x x x
Azure 中樞 x x

如需更多範例,請參閱Python V2 模型Azure Functions觸發程式和系結, (預覽)

輸出

輸出可以使用傳回值和輸出參數來表示。 如果只有一個輸出,我們建議使用傳回的值。 若為多個輸出,您必須使用輸出參數。

若要使用函式的傳回值做為輸出系結的值, name 系結的 屬性應該在function.json檔案中設定為 $return

若要產生多個輸出,請使用 azure.functions.Out 介面提供的 set() 方法為繫結指派值。 例如,下列函式可以將訊息推送至佇列,同時也會傳回 HTTP 回應。

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "req",
      "direction": "in",
      "type": "httpTrigger",
      "authLevel": "anonymous"
    },
    {
      "name": "msg",
      "direction": "out",
      "type": "queue",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    },
    {
      "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

輸出可以使用傳回值和輸出參數來表示。 如果只有一個輸出,我們建議使用傳回的值。 若為多個輸出,您必須使用輸出參數。

若要產生多個輸出,請使用 azure.functions.Out 介面提供的 set() 方法為繫結指派值。 例如,下列函式可以將訊息推送至佇列,同時也會傳回 HTTP 回應。

# function_app.py
import azure.functions as func


@app.write_blob(arg_name="msg", path="output-container/{name}",
                connection="AzureWebJobsStorage")

def test_function(req: func.HttpRequest,
                  msg: func.Out[str]) -> str:

    message = req.params.get('body')
    msg.set(message)
    return message

記錄

可以透過函式應用程式中的根 logging 處理常式來存取 Azure Functions 執行階段記錄器。 這個記錄器會與 Application Insights 連結,並可讓您將函式執行期間遇到的警告和錯誤加上旗標。

下列範例在透過 HTTP 觸發程序叫用函式時,會記錄一則資訊訊息。

import logging


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

還有更多記錄方法,能讓您在不同追蹤層級寫入主控台記錄︰

方法 描述
critical(_message_) 在根記錄器上寫入層級為 CRITICAL (重大) 的訊息。
error(_message_) 在根記錄器上寫入層級為 ERROR (錯誤) 的訊息。
warning(_message_) 在根記錄器上寫入層級為 WARNING (警告) 的訊息。
info(_message_) 在根記錄器上寫入層級為 INFO (資訊) 的訊息。
debug(_message_) 在根記錄器上寫入層級為 DEBUG (偵錯) 的訊息。

若要深入了解記錄,請參閱監視 Azure Functions

記錄自訂遙測資料

根據預設,Functions 執行時間會收集函式所產生的記錄和其他遙測資料。 而遙測資料最終會成為 Application Insights 的追蹤。 根據預設,觸發程式和系結也會收集特定 Azure 服務的要求 相依性遙測。

若要收集系結外部的自訂要求和自訂相依性遙測,您可以使用 OpenCensus Python 延伸模組。 此延伸模組會將自訂遙測資料傳送至 Application Insights 實例。 您可以在 OpenCensus 存放庫 (英文) 找到支援的延伸模組清單。

注意

如要使用 OpenCensus Python 延伸模組,您必須將 PYTHON_ENABLE_WORKER_EXTENSIONS 設定為 1,在函數應用程式中啟用 Python 背景工作角色延伸模組。 如果還沒將APPLICATIONINSIGHTS_CONNECTION_STRING設定新增至您的應用程式設定,則也需切換至使用 Application Insights 連接字串。

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

HTTP 觸發程序

HTTP 觸發程序定義於 function.json 檔案中。 繫結的 name 必須符合函式中的具名引數。 在先前的範例中,使用的是繫結名稱 req。 這個參數是 HttpRequest 物件,而且會傳回 HttpResponse 物件。

HttpRequest 物件中,您可以取得要求標題、查詢參數、路由參數和訊息內文。

下列範例來自 Python 的 HTTP 觸發程序範本

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
        )

在此函式中,您會從 paramsHttpRequest物件的 參數取得查詢參數的值 name 。 您可以使用 方法來讀取 JSON 編碼的訊息本文 get_json

同樣地,您可以在傳回的 HttpResponse 物件中設定回應訊息的 status_codeheaders

HTTP 觸發程序定義於 function.json 檔案中。 繫結的 name 必須符合函式中的具名引數。

在先前的範例中,使用的是繫結名稱 req。 這個參數是 HttpRequest 物件,而且會傳回 HttpResponse 物件。

HttpRequest 物件中,您可以取得要求標題、查詢參數、路由參數和訊息內文。

下列範例來自 Python v2 程式設計模型的 HTTP 觸發程式範本。 這是使用 Azure Functions Core Tools 或 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
        )

在此函式中,您會從 paramsHttpRequest物件的 參數取得查詢參數的值 name 。 您可以使用 方法來讀取 JSON 編碼的訊息本文 get_json

同樣地,您可以在傳回的 HttpResponse 物件中設定回應訊息的 status_codeheaders

若要傳入此範例中的名稱,請貼上執行函式時所提供的 URL,然後使用 附加它 "?name={name}"

Web 架構

您可以使用 Web 服務器閘道介面 (WSGI) 相容和非同步伺服器閘道介面, (ASGI) 相容的架構,例如 Flask 和 FastAPI,搭配 HTTP 觸發的 Python 函式。 本節說明如何修改函式來支援這些架構。

首先,必須更新 function.json 檔案,才能在 HTTP 觸發程式中包含 route ,如下列範例所示:

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

host.json檔案也必須更新為包含 HTTP routePrefix ,如下列範例所示:

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

視架構所使用的介面而定,更新 python 程式碼檔案 init.py。 下列範例顯示 Flask 的 ASGI 處理常式方法或 WSGI 包裝函式方法:

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 AsgiMiddleware(app).handle(req, context)

您可以使用非同步伺服器閘道介面 (ASGI) 相容和 Web 服務器閘道介面, (WSGI) 相容的架構,例如 Flask 和 FastAPI,搭配 HTTP 觸發的 Python 函式。 您必須先更新 host.json 檔案以包含 HTTP routePrefix ,如下列範例所示:

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

架構程式碼看起來像下列範例:

AsgiFunctionApp 是建構 ASGI HTTP 函式的最上層函式應用程式類別。

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

調整和效能

如需 Python 函式應用程式的調整和效能最佳做法,請參閱 Python 調整和效能 一文。

Context

若要在執行函式時取得函式的調用內容, context 請在其簽章中包含 引數。

例如:

import azure.functions


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

類別 Context 具有下列字串屬性:

屬性 描述
function_directory 函式執行所在的目錄。
function_name 函數的名稱。
invocation_id 目前函式調用的識別碼。
trace_context 分散式追蹤的內容。 如需詳細資訊,請參閱Trace Context
retry_context 重試函式的內容。 如需詳細資訊,請參閱retry-policies

全域變數

不保證您應用程式的狀態將保留給未來執行使用。 不過,Azure Functions 執行階段通常會針對相同應用程式的多個執行重複使用相同的處理序。 若要快取昂貴計算的結果,請將它宣告為全域變數。

CACHED_DATA = None


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

    # ... use CACHED_DATA in code

環境變數

在Azure Functions中,應用程式設定,例如服務連接字串,會在執行時公開為環境變數。 在您的程式碼中存取這些設定有兩種主要方式。

方法 描述
os.environ["myAppSetting"] 嘗試依金鑰名稱取得應用程式設定,並在失敗時引發錯誤。
os.getenv("myAppSetting") 嘗試依金鑰名稱取得應用程式設定,並在失敗時傳 null 回。

這兩種方式都需要您宣告 import os

下列範例使用 os.environ["myAppSetting"] 來取得應用程式設定,並使用名為 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}')

針對本機開發,應用程式設定會 保留在 local.settings.json 檔案中

在Azure Functions中,應用程式設定,例如服務連接字串,會在執行時公開為環境變數。 在您的程式碼中存取這些設定有兩種主要方式。

方法 描述
os.environ["myAppSetting"] 嘗試依金鑰名稱取得應用程式設定,並在失敗時引發錯誤。
os.getenv("myAppSetting") 嘗試依金鑰名稱取得應用程式設定,並在失敗時傳 null 回。

這兩種方式都需要您宣告 import os

下列範例使用 os.environ["myAppSetting"] 來取得應用程式設定,並使用名為 myAppSetting 的金鑰:

import logging
import os
import azure.functions as func

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

針對本機開發,應用程式設定會 保留在 local.settings.json 檔案中

當您使用新的程式設計模型時,請在 local.settings.json 檔案中啟用下列應用程式設定,如下所示:

"AzureWebJobsFeatureFlags": "EnableWorkerIndexing"

當您部署函式時,不會自動建立此設定。 您必須在 Azure 中的函式應用程式中明確建立此設定,才能使用 v2 模型執行。

v2 程式設計模型目前不支援多個 Python 背景工作角色設定。 這表示使用 v2 模型開發的函式不支援將 設定 FUNCTIONS_WORKER_PROCESS_COUNT 為大於 1

Python 版本

Azure Functions 支援下列 Python 版本:

Functions 版本 Python* 版本
4.x 3.9
3.8
3.7
3.x 3.9
3.8
3.7
3.6
2.x 3.7
3.6

* 官方 Python 發行版本

若要在 Azure 中建立函式應用程式時要求特定的 Python 版本,請使用 az functionapp create 命令的 --runtime-version 選項。 Functions 執行階段版本是由 --functions-version 選項設定。 建立函式應用程式時會設定 Python 版本,而且無法變更。

當您在本機執行時,執行時間會使用可用的 Python 版本。

變更 Python 版本

若要將 Python 函式應用程式設定為特定語言版本,您必須在 LinuxFxVersion 網站組態的 欄位中指定語言和語言版本。 例如,若要將 Python 應用程式變更為使用 Python 3.8,請將 設定 linuxFxVersionpython|3.8

若要瞭解如何檢視和變更月臺 linuxFxVersion 設定,請參閱如何將目標設為Azure Functions執行時間版本

如需詳細資訊,請參閱Azure Functions執行時間支援原則Azure Functions支援的語言

套件管理

當您使用 Core Tools 或 Visual Studio Code 在本機開發時,請將所需套件的名稱和版本新增至requirements.txt檔案,然後使用 加以安裝 pip

例如,您可以使用下列 requirements.txt 檔案和 pip 命令,從 PyPI 安裝 requests 套件。

requests==2.19.1
pip install -r requirements.txt

發佈到 Azure

當您準備發佈時,請確保所有可公開使用的相依性都列在 requirements.txt 檔案中。 您可以在專案目錄的根目錄找到此檔案。

您可以在專案的根目錄中,找到排除在發行的專案檔和資料夾,包括虛擬環境資料夾。

支援將 Python 專案發佈至 Azure 的三個建置動作:使用自訂相依性進行遠端建置、本機建置和組建。

您也可以使用 Azure Pipelines 組建相依性,並使用持續傳遞 (CD) 加以發佈。 若要深入瞭解,請參閱 使用 Azure Pipelines 持續傳遞

遠端組建

當您使用遠端組建時,在伺服器上還原的相依性與原生相依性符合生產環境。 因此會上傳較小的部署套件。 當您在 Windows 上開發 Python 應用程式時,請使用遠端組建。 如果您的專案具有自訂相依性,您可以使用 遠端組建搭配額外的索引 URL

相依性是根據 requirements.txt 檔案的內容從遠端取得。 遠端組建是建議的組建方法。 根據預設,Core Tools 會在您使用下列 func azure functionapp publish 命令將 Python 專案發佈至 Azure 時,要求遠端組建。

func azure functionapp publish <APP_NAME>

在 Azure 中,請記得以您的函式應用程式名稱取代 <APP_NAME>

根據預設,適用於 Visual Studio Code 的 Azure Functions 擴充功能也會要求遠端組建。

本機組建

系統會根據 requirements.txt 檔案的內容,在本機取得相依性。 您可以使用下列 func azure functionapp publish 命令來搭配本機組建發佈,以防止執行遠端建置:

func azure functionapp publish <APP_NAME> --build local

在 Azure 中,請記得以您的函式應用程式名稱取代 <APP_NAME>

當您使用 選項時 --build local ,會從 requirements.txt 檔案讀取專案相依性,並在本機下載並安裝這些相依套件。 專案檔案和相依性會從您的本機電腦部署至 Azure。 這會導致更大的部署套件上傳至 Azure。 如果基於某些原因,您無法使用 Core Tools 取得 requirements.txt 檔案,則必須使用自訂相依性選項進行發佈。

當您在 Windows 上本機開發時,不建議使用本機組建。

自訂相依性

當您的專案具有 Python 套件索引中找不到的相依性時,有兩種方式可以建置專案。 建 方法的第一種方式取決於您建置專案的方式。

具額外索引 URL 的遠端組建

若您的套件能從可存取的自訂套件索引中獲取,請使用遠端組建。 發佈之前,請務必建立名為 PIP_EXTRA_INDEX_URL的應用程式設定。 此設定的值是自訂套件索引的 URL。 使用此設定會指示遠端組建使用 --extra-index-url 選項來執行 pip install 。 若要深入瞭解,請參閱 Python pip install

您也可以使用基本驗證認證搭配額外的套件索引 URL。 若要深入瞭解,請參閱 Python 檔中 的基本驗證認證

安裝本機套件

如果您的專案使用未公開提供給工具使用的套件,您可以將這些套件放在 __app__/.python_packages 目錄中,讓應用程式可供使用。 發佈之前,請執行下列命令以在本機安裝相依性:

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

當您使用自訂相依性時,應該使用 --no-build 發佈選項,因為您已經將相依性安裝到專案資料夾中。

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

在 Azure 中,請記得以您的函式應用程式名稱取代 <APP_NAME>

單元測試

使用標準測試架構,可以像其他 Python 程式碼一樣測試以 Python 撰寫的函式。 對於大部分繫結,您可以從 azure.functions 套件建立適當類別的執行個體,以建立模擬輸入物件。 azure.functions由於套件無法立即使用,因此請務必透過您的requirements.txt檔案進行安裝,如上述套件管理一節中所述。

my_second_function 為例,以下是 HTTP 觸發函式的模擬測試:

首先,建立< project_root > /my_second_function/function.json檔案,然後將此函式定義為 HTTP 觸發程式。

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

接下來,您可以實作 my_second_functionshared_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

您可以開始撰寫 HTTP 觸發程式的測試案例。

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

.venv Python 虛擬環境資料夾內,安裝您慣用的 Python 測試架構,例如 pip install pytest 。 然後執行 pytest tests 並檢查測試結果。

首先,建立< project_root > /function_app.py檔案,並將 函 my_second_function 式實作為 HTTP 觸發程式和 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

您可以開始撰寫 HTTP 觸發程式的測試案例。

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

.venv Python 虛擬環境資料夾內,安裝您慣用的 Python 測試架構,例如 pip install pytest 。 然後執行 pytest tests 並檢查測試結果。

暫存檔案

tempfile.gettempdir() 方法會傳回暫存資料夾,在 Linux 上是 /tmp。 您的應用程式可以使用此目錄來儲存函式在執行時所產生的和使用暫存檔案。

重要

寫入臨時目錄的檔案不保證會在叫用之間持續存在。 在擴增期間,暫存檔案不會在執行個體之間共用。

下列範例會在暫存目錄 (/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)

建議您在與專案資料夾不同的資料夾中保存您的測試。 這個動作讓您可免於將測試程式碼與應用程式一起部署。

預先安裝的程式庫

一些程式庫隨附于 Python 函式執行時間。

Python 標準程式庫

Python 標準程式庫包含隨附于每個 Python 散發套件的內建 Python 模組清單。 這些程式庫大部分都協助您存取系統功能,例如檔案輸入/輸出 (I/O) 。 在 Windows 系統上,這些程式庫會伴隨 Python 一同安裝。 在 Unix 系統上,它們是由套件集合所提供。

若要檢視 Python 版本的程式庫,請移至:

Azure Functions Python 背景工作角色相依性

Azure Functions Python 背景工作角色需要一組特定的程式庫。 您也可以在函式中使用這些程式庫,但程式庫並不屬於 Python 標準。 如果您的函式依賴這些程式庫的任何一個,當程式碼在Azure Functions外部執行時,可能無法使用它們。 您可以在 setup.py 檔案的「install_requires」區段中找到詳細的相依性清單。

注意

如果您的函數應用程式 requirements.txt 檔案包含 azure-functions-worker 輸入,請將之移除。 函式背景工作角色是由Azure Functions平臺自動管理,我們會定期使用新功能和錯誤修正進行更新。 在 requirements.txt 檔案中手動安裝舊版的背景工作角色,可能會導致非預期的問題。

注意

如果您的套件包含可能會與背景工作角色相依性衝突的特定程式庫 (,例如 protobuf、tensorflow 或 grpcio) ,請在 PYTHON_ISOLATE_WORKER_DEPENDENCIES1 應用程式設定中設定 為 ,以防止您的應用程式參考背景工作角色的相依性。 這項功能處於預覽狀態。

Azure Functions Python 程式庫

每個 Python 背景工作更新都包含新版本的Azure Functions Python 程式庫, (azure.functions) 。 這種方法可讓您更輕鬆地持續更新 Python 函式應用程式,因為每個更新都回溯相容。 如需此程式庫的版本清單,請移至 azure-functions PyPi

執行時間程式庫版本是由 Azure 修正,而且無法由 requirements.txt覆寫。 requirements.txt 中的 azure-functions 輸入僅供 Lint 分析與客戶感知之用。

使用下列程式碼來追蹤執行時間中 Python 函式程式庫的實際版本:

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

執行階段系統程式庫

如需 Python 背景工作角色 Docker 映射中預先安裝系統程式庫的清單,請參閱下列各項:

Functions 執行階段 Debian 版本 Python 版本
3.x 版 Buster Python 3.7
Python 3.8
Python 3.9 (英文)

Python 背景工作角色延伸模組

在 Azure Functions 中執行的 Python 背景工作處理序可讓您將協力廠商的程式庫整合到函數應用程式中。 這些延伸模組程式庫可作為中介軟體,在函式的執行生命週期內插入特定作業。

延伸模組匯入函式程式碼的方式,跟標準 Python 程式庫模組並無二致。 擴充功能會根據下列範圍執行:

範圍 描述
應用程式層級 匯入任何函式觸發程式時,擴充功能會套用至應用程式中的每個函式執行。
函數層級 僅匯入的特定函式觸發程序會套用執行。

檢閱每個延伸模組的資訊,以深入瞭解延伸模組執行的範圍。

延伸模組會實作 Python 背景工作角色延伸模組介面。 此動作可讓 Python 背景工作進程在函式的執行生命週期期間呼叫延伸模組程式碼。 若要深入瞭解,請參閱 建立延伸模組

使用擴充功能

您可以執行下列動作,在 Python 函式中使用 Python 背景工作角色延伸模組程式庫:

  1. 在專案的 requirements.txt 檔案中新增延伸模組套件。
  2. 將程式庫安裝至您的應用程式。
  3. 新增下列應用程式設定:
  4. 將延伸模組匯入您的函式觸發程序。
  5. 視需要設定延伸模組執行個體。 延伸模組文件應會指明相關設定需求。

重要

Microsoft不支援或保證協力廠商 Python 背景工作角色擴充程式庫。 您必須確定您在函式應用程式中使用的任何延伸模組都值得信任,而且您承擔使用惡意或不良寫入延伸模組的完整風險。

協力廠商應該提供如何在函式應用程式中安裝和取用其擴充功能的特定檔。 如需取用延伸模組的基本範例,請參閱取用延伸模組

以下是依範圍在函數應用程式中使用延伸模組的範例:

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

建立延伸模組

延伸模組是由協力廠商程式庫開發人員所建立,且所建立的功能可整合至 Azure Functions。 延伸模組開發人員會設計、實作並發行 Python 套件,其中包含專為在函式執行內容中執行而設計的自訂邏輯。 這些延伸模組可發佈至 PyPI 登錄或 GitHub 存放庫。

欲了解如何建立、封裝、發佈及取用 Python 背景工作角色延伸模組套件,請參閱開發適用於 Azure Functions 的 Python 背景工作角色延伸模組

應用等級延伸模組

繼承自 AppExtensionBase 的延伸模組會在應用程式範圍中 執行

AppExtensionBase 會公開下列抽象類別方法供您實作:

方法 描述
init 匯入延伸模組後呼叫。
configure 視需要從函式程式碼呼叫以設定延伸模組。
post_function_load_app_level 載入函式後立即呼叫。 函式名稱和目錄會傳遞至延伸模組。 請記住,函式目錄是唯讀的,而且任何嘗試寫入此目錄中的本機檔案都會失敗。
pre_invocation_app_level 在觸發函式前呼叫。 函式內容和函式叫用引數會傳遞至延伸模組。 通常您可傳遞內容物件中的其他屬性,供函式程式碼取用。
post_invocation_app_level 函式執行完成後立即呼叫。 函式內容、函式叫用引數和叫用傳回物件皆會傳遞至延伸模組。 此實作是驗證生命週期勾點是否成功執行的好方法。

函式等級延伸模組

繼承自 FuncExtensionBase (英文) 的延伸模組會在特定函式觸發程序中執行。

FuncExtensionBase 會公開下列抽象類別方法供您實作:

方法 描述
__init__ 延伸模組的建構函式。 當擴充實例在特定函式中初始化時,就會呼叫它。 當您實作這個抽象方法時,您可能會想要接受 filename 參數,並將它傳遞至父系的 方法來 super().__init__(filename) 註冊適當的延伸模組。
post_function_load 載入函式後立即呼叫。 函式名稱和目錄會傳遞至延伸模組。 請記住,函式目錄是唯讀的,而且任何嘗試寫入此目錄中的本機檔案都會失敗。
pre_invocation 在觸發函式前呼叫。 函式內容和函式叫用引數會傳遞至延伸模組。 通常您可傳遞內容物件中的其他屬性,供函式程式碼取用。
post_invocation 函式執行完成後立即呼叫。 函式內容、函式叫用引數和叫用傳回物件皆會傳遞至延伸模組。 此實作是驗證生命週期勾點是否成功執行的好方法。

跨原始資源共用

Azure Functions 支援跨原始資源共用 (CORS)。 您可在入口網站中,以及透過 Azure CLI 來設定 CORS。 CORS 允許的原始來源清單適用於函數應用程式層級。 在啟用 CORS 的情況下,回應會包含 Access-Control-Allow-Origin 標頭。 如需詳細資訊,請參閱 跨原始來源資源分享(英文)。

Python 函式應用程式完全支援跨原始來源資源分享 (CORS) 。

Async

根據預設,Python 的主機執行個體一次只能處理一個函式的叫用, 因為 Python 屬於單一執行緒的執行階段。 針對處理大量 I/O 事件和/或擁有 I/O 繫結的函數應用程式,您可以非同步方式執行函式,以便大幅提升效能。 如需詳細資訊,請參閱在 Azure Functions 中改善 Python 應用程式的整體效能

共用記憶體 (預覽版)

為了改善輸送量,Azure Functions可讓您的跨進程 Python 語言背景工作角色與 Functions 主機進程共用記憶體。 若函數應用程式達到瓶頸,則可新增名為 FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED 且值為 1 的應用程式設定,藉此啟用共用記憶體。 啟用共用記憶體後,您可用 DOCKER_SHM_SIZE 設定將共用記憶體設定為268435456 之類的數值,相當於 256 MB。

例如,當您使用 Blob 儲存體系結來傳輸大於 1 MB 的承載時,您可能會啟用共用記憶體來降低瓶頸。

這項功能僅適用于在 Premium 和 Dedicated (Azure App 服務) 方案中執行的函式應用程式。 若要深入了解,請參閱共用記憶體

已知問題和常見問題集

以下是常見問題的兩個疑難排解指南:

以下是 v2 程式設計模型已知問題的兩個疑難排解指南:

所有已知問題和功能要求都會在 GitHub 問題清單中追蹤。 如果您遇到問題,而且在 GitHub 中找不到問題,請開啟新的問題,並包含問題的詳細描述。

後續步驟

如需詳細資訊,請參閱下列資源:

使用 Python 時遇到問題? 告訴我們發生什麼事。