您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

Azure Functions Python 开发人员指南Azure Functions Python developer guide

本文介绍了如何使用 Python 开发 Azure Functions。This article is an introduction to developing Azure Functions using Python. 以下内容假定你已阅读 Azure Functions 开发人员指南The content below assumes that you've already read the Azure Functions developers guide.

作为 Python 开发人员,你可能还会对下列某篇文章感兴趣:As a Python developer, you may also be interested in one of the following articles:

入门Getting started 概念Concepts 场景/示例Scenarios/Samples

备注

尽管可以在 Windows 上本地开发基于 Python 的 Azure Functions,但仅在 Azure 中运行时,基于 Linux 的托管计划才支持 Python。While you can develop your Python based Azure Functions locally on Windows, Python is only supported on a Linux based hosting plan when running in Azure. 请参阅支持的操作系统/运行时组合列表。See the list of supported operating system/runtime combinations.

编程模型Programming model

Azure Functions 要求函数是 Python 脚本中处理输入并生成输出的无状态方法。Azure Functions expects a function to be a stateless method in your Python script that processes input and produces output. 默认情况下,运行时期望该方法在 __init__.py 文件中作为名为 main() 的全局方法实现。By default, the runtime expects the method to be implemented as a global method called main() in the __init__.py file. 还可以指定备用入口点You can also specify an alternate entry point.

来自触发器和绑定的数据使用在 function.json 文件中定义的 name 属性,通过方法特性绑定到函数。Data from triggers and bindings is bound to the function via method attributes using the name property defined in the function.json file. 例如,下面的 function.json 描述一个由名为 req 的 HTTP 请求触发的简单函数:For example, the function.json below describes a simple function triggered by an HTTP request named req:

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

根据这一定义,包含函数代码的 __init__.py 文件可能类似于以下示例:Based on this definition, the __init__.py file that contains the function code might look like the following example:

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

还可以使用 Python 类型注释在函数中显式声明属性类型和返回类型。You can also explicitly declare the attribute types and return type in the function using Python type annotations. 这有助于使用许多 Python 代码编辑器提供的 intellisense 和自动完成功能。This helps you use the intellisense and autocomplete features provided by many Python code editors.

import azure.functions


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

使用 azure.functions.* 包中附带的 Python 注释将输入和输出绑定到方法。Use the Python annotations included in the azure.functions.* package to bind input and outputs to your methods.

备用入口点Alternate entry point

可以选择在 function.json 文件中指定 scriptFileentryPoint 属性来更改函数的默认行为。You can change the default behavior of a function by optionally specifying the scriptFile and entryPoint properties in the function.json file. 例如,下面的 function.json 指示运行时使用 main.py 文件中的 customentry() 方法作为 Azure 函数的入口点 。For example, the function.json below tells the runtime to use the customentry() method in the main.py file, as the entry point for your Azure Function.

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

文件夹结构Folder structure

Python 函数项目的建议文件夹结构如以下示例所示:The recommended folder structure for a Python Functions project looks like the following example:

 <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>) 可以包含以下文件:The main project folder (<project_root>) can contain the following files:

  • local.settings.json:用于在本地运行时存储应用设置和连接字符串。local.settings.json: Used to store app settings and connection strings when running locally. 此文件不会被发布到 Azure。This file doesn't get published to Azure. 若要了解详细信息,请参阅 local.settings.fileTo learn more, see local.settings.file.
  • requirements.txt:包含在发布到 Azure 时系统安装的 Python 包列表。requirements.txt: Contains the list of Python packages the system installs when publishing to Azure.
  • host.json:包含在函数应用中影响所有函数的全局配置选项。host.json: Contains global configuration options that affect all functions in a function app. 此文件会被发布到 Azure。This file does get published to Azure. 本地运行时,并非所有选项都受支持。Not all options are supported when running locally. 若要了解详细信息,请参阅 host.jsonTo learn more, see host.json.
  • .vscode/:(可选)包含存储 VSCode 配置。.vscode/: (Optional) Contains store VSCode configuration. 若要了解详细信息,请参阅 VSCode 设置To learn more, see VSCode setting.
  • .venv/:(可选)包含本地开发使用的 Python 虚拟环境。.venv/: (Optional) Contains a Python virtual environment used by local development.
  • Dockerfile:(可选)在自定义容器中发布项目时使用。Dockerfile: (Optional) Used when publishing your project in a custom container.
  • tests/:(可选)包含函数应用的测试用例。tests/: (Optional) Contains the test cases of your function app.
  • .funcignore:(可选)声明不应发布到 Azure 的文件。.funcignore: (Optional) Declares files that shouldn't get published to Azure. 通常,此文件包含 .vscode/ 以忽略编辑器设置,包含 .venv/ 以忽略本地 Python 虚拟环境,包含 tests/ 以忽略测试用例,包含 local.settings.json 以阻止发布本地应用设置。Usually, this file contains .vscode/ to ignore your editor setting, .venv/ to ignore local Python virtual environment, tests/ to ignore test cases, and local.settings.json to prevent local app settings being published.

每个函数都有自己的代码文件和绑定配置文件 (function.json)。Each function has its own code file and binding configuration file (function.json).

在 Azure 中将项目部署到函数应用时,主项目 (<project_root>) 文件夹的整个内容应包含在包中,但不包含该文件夹本身,这意味着 host.json 应位于包根目录中。When deploying your project to a function app in Azure, the entire contents of the main project (<project_root>) folder should be included in the package, but not the folder itself, which means host.json should be in the package root. 建议你在一个文件夹中维护测试以及其他函数,在此示例中为 tests/We recommend that you maintain your tests in a folder along with other functions, in this example tests/. 有关详细信息,请参阅单元测试For more information, see Unit Testing.

导入行为Import behavior

可以使用绝对引用和相对引用在函数代码中导入模块。You can import modules in your function code using both absolute and relative references. 根据以上所示的文件夹结构,以下导入在函数文件 <project_root>\my_first_function\__init__.py 中工作:Based on the folder structure shown above, the following imports work from within the function file <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 包。The shared_code/ folder needs to contain an __init__.py file to mark it as a Python package when using absolute import syntax.

以下 _app___ 导入和 beyond top-level 相对导入已弃用,因为不受静态类型检查器支持,且不受 Python 测试框架支持:The following __app__ import and beyond top-level relative import are deprecated, since it is not supported by static type checker and not supported by Python test frameworks:

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)

触发器和输入Triggers and Inputs

在 Azure Functions 中,输入分为两种类别:触发器输入和附加输入。Inputs are divided into two categories in Azure Functions: trigger input and additional input. 虽然它们在 function.json 文件中并不相同,但它们在 Python 代码中的使用方法却是相同的。Although they are different in the function.json file, usage is identical in Python code. 在本地运行时,触发器和输入源的连接字符串或机密映射到 local.settings.json 文件中的值,而在 Azure 中运行时则映射到应用程序设置。Connection strings or secrets for trigger and input sources map to values in the local.settings.json file when running locally, and the application settings when running in Azure.

例如,以下代码演示两者之间的差异:For example, the following code demonstrates the difference between the two:

// 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 传递给函数。When the function is invoked, the HTTP request is passed to the function as req. 将基于路由 URL 中的 ID 从 Azure Blob 存储检索一个条目,并在函数体中用作 objAn entry will be retrieved from the Azure Blob Storage based on the ID in the route URL and made available as obj in the function body. 此处指定的存储帐户是在 AzureWebJobsStorage 应用设置中找到的连接字符串,该帐户即函数应用使用的同一个存储帐户。Here, the storage account specified is the connection string found in the AzureWebJobsStorage app setting, which is the same storage account used by the function app.

OutputsOutputs

输出可以在返回值和输出参数中进行表示。Output can be expressed both in return value and output parameters. 如果只有一个输出,则建议使用返回值。If there's only one output, we recommend using the return value. 对于多个输出,必须使用输出参数。For multiple outputs, you'll have to use output parameters.

若要使用函数的返回值作为输出绑定的值,则绑定的 name 属性应在 function.json 中设置为 $returnTo use the return value of a function as the value of an output binding, the name property of the binding should be set to $return in function.json.

若要生成多个输出,请使用 azure.functions.Out 接口提供的 set() 方法将值分配给绑定。To produce multiple outputs, use the set() method provided by the azure.functions.Out interface to assign a value to the binding. 例如,以下函数可以将消息推送到队列,还可返回 HTTP 响应。For example, the following function can push a message to a queue and also return an HTTP response.

{
  "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

日志记录Logging

可在函数应用中通过根 logging 处理程序来访问 Azure Functions 运行时记录器。Access to the Azure Functions runtime logger is available via a root logging handler in your function app. 此记录器绑定到 Application Insights,并允许标记在函数执行期间遇到的警告和错误。This logger is tied to Application Insights and allows you to flag warnings and errors encountered during the function execution.

下面的示例在通过 HTTP 触发器调用函数时记录信息消息。The following example logs an info message when the function is invoked via an HTTP trigger.

import logging


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

有其他日志记录方法可用于在不同跟踪级别向控制台进行写入:Additional logging methods are available that let you write to the console at different trace levels:

方法Method 说明Description
critical(_message_) 在根记录器中写入具有 CRITICAL 级别的消息。Writes a message with level CRITICAL on the root logger.
error(_message_) 在根记录器中写入具有 ERROR 级别的消息。Writes a message with level ERROR on the root logger.
warning(_message_) 在根记录器中写入具有 WARNING 级别的消息。Writes a message with level WARNING on the root logger.
info(_message_) 在根记录器中写入具有 INFO 级别的消息。Writes a message with level INFO on the root logger.
debug(_message_) 在根记录器中写入具有 DEBUG 级别的消息。Writes a message with level DEBUG on the root logger.

若要详细了解日志记录,请参阅监视 Azure FunctionsTo learn more about logging, see Monitor Azure Functions.

HTTP 触发器和绑定HTTP Trigger and bindings

HTTP 触发器在 function.json 文件中定义。The HTTP trigger is defined in the function.json file. 绑定的 name 必须与函数中的命名参数匹配。The name of the binding must match the named parameter in the function. 前面的示例中使用了绑定名称 reqIn the previous examples, a binding name req is used. 此参数是 HttpRequest 对象,并返回 HttpResponse 对象。This parameter is an HttpRequest object, and an HttpResponse object is returned.

HttpRequest 对象中,可以获取请求标头、查询参数、路由参数和消息正文。From the HttpRequest object, you can get request headers, query parameters, route parameters, and the message body.

以下示例来自适用于 Python 的 HTTP 触发器模版The following example is from the HTTP trigger template for 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
        )

在此函数中,name 查询参数的值从 HttpRequest 对象的 params 参数获取。In this function, the value of the name query parameter is obtained from the params parameter of the HttpRequest object. JSON 编码的消息正文使用 get_json 方法来读取。The JSON-encoded message body is read using the get_json method.

同样,你可以在返回的 HttpResponse 对象中为响应消息设置 status_codeheadersLikewise, you can set the status_code and headers for the response message in the returned HttpResponse object.

缩放和性能Scaling and Performance

有关 Python 函数应用的缩放和性能最佳做法,请参阅 Python 缩放和性能一文。For scaling and performance best practices for Python function apps, please refer to the Python scale and performance article.

上下文Context

若要在执行过程中获取函数的调用上下文,请在其签名中包含 context 参数。To get the invocation context of a function during execution, include the context argument in its signature.

例如:For example:

import azure.functions


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

Context 类具有以下字符串属性:The Context class has the following string attributes:

function_directory 在其中运行函数的目录。function_directory The directory in which the function is running.

function_name 函数的名称。function_name Name of the function.

invocation_id 当前函数调用的 ID。invocation_id ID of the current function invocation.

全局变量Global variables

应用的状态是否将保留,以供将来执行使用,这一点不能保证。It is not guaranteed that the state of your app will be preserved for future executions. 但是,Azure Functions 运行时通常会为同一应用的多次执行重复使用同一进程。However, the Azure Functions runtime often reuses the same process for multiple executions of the same app. 为缓存成本昂贵的计算结果,请将其声明为全局变量。In order to cache the results of an expensive computation, declare it as a global variable.

CACHED_DATA = None


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

    # ... use CACHED_DATA in code

环境变量Environment variables

在 Functions 中,服务连接字符串等应用程序设置在执行过程中将公开为环境变量。In Functions, application settings, such as service connection strings, are exposed as environment variables during execution. 可以通过声明 import os 并使用 setting = os.environ["setting-name"] 来访问这些设置。You can access these settings by declaring import os and then using, setting = os.environ["setting-name"].

以下示例获取了应用程序设置,其中键名为 myAppSettingThe following example gets the application setting, with the key named 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 文件中维护For local development, application settings are maintained in the local.settings.json file.

Python 版本Python version

Azure Functions 支持以下 Python 版本:Azure Functions supports the following Python versions:

Functions 版本Functions version Python* 版本Python* versions
3.x3.x 3.9(预览版)3.9 (Preview)
3.83.8
3.73.7
3.63.6
2.x2.x 3.73.7
3.63.6

*正式 CPython 分发*Official CPython distributions

若要在 Azure 中创建函数应用时请求特定的 Python 版本,请使用 az functionapp create 命令的 --runtime-version 选项。To request a specific Python version when you create your function app in Azure, use the --runtime-version option of the az functionapp create command. 函数运行时版本由 --functions-version 选项设置。The Functions runtime version is set by the --functions-version option. Python 版本在创建函数应用时设置,并且无法更改。The Python version is set when the function app is created and can't be changed.

在本地运行时,运行时使用可用的 Python 版本。When running locally, the runtime uses the available Python version.

包管理Package management

在使用 Azure Functions Core Tools 或 Visual Studio Code 进行本地开发时,将所需包的名称和版本添加到 requirements.txt 文件并使用 pip 安装它们。When developing locally using the Azure Functions Core Tools or Visual Studio Code, add the names and versions of the required packages to the requirements.txt file and install them using pip.

例如,可以使用以下要求文件和 pip 命令从 PyPI 安装 requests 包。For example, the following requirements file and pip command can be used to install the requests package from PyPI.

requests==2.19.1
pip install -r requirements.txt

发布到 AzurePublishing to Azure

准备好进行发布时,确保所有公开发布的依赖项都在 requirements.txt 文件(位于项目目录的根目录)中列出。When you're ready to publish, make sure that all your publicly available dependencies are listed in the requirements.txt file, which is located at the root of your project directory.

发布中排除的项目文件和文件夹(包括虚拟环境文件夹)列在 .funcignore 文件中。Project files and folders that are excluded from publishing, including the virtual environment folder, are listed in the .funcignore file.

将 Python 项目发布到 Azure 时,支持三种生成操作:远程生成、本地生成以及使用自定义依赖项生成。There are three build actions supported for publishing your Python project to Azure: remote build, local build, and builds using custom dependencies.

还可使用 Azure Pipelines 生成依赖项并使用持续交付 (CD) 发布。You can also use Azure Pipelines to build your dependencies and publish using continuous delivery (CD). 若要了解详细信息,请参阅使用 Azure DevOps 持续交付To learn more, see Continuous delivery by using Azure DevOps.

远程生成Remote build

使用远程生成时,服务器上还原的依赖项和本机依赖项与生产环境匹配。When using remote build, dependencies restored on the server and native dependencies match the production environment. 这导致要上传的部署包较小。This results in a smaller deployment package to upload. 在 Windows 上开发 Python 应用时使用远程生成。Use remote build when developing Python apps on Windows. 如果你的项目具有自定义依赖项,可使用具有额外索引 URL 的远程生成If your project has custom dependencies, you can use remote build with extra index URL.

依赖项根据 requirements.txt 文件的内容远程获取。Dependencies are obtained remotely based on the contents of the requirements.txt file. 远程生成是推荐的生成方法。Remote build is the recommended build method. 默认情况下,使用下面的 func azure functionapp publish 命令将 Python 项目发布到 Azure 时,Azure Functions Core Tools 会请求远程生成。By default, the Azure Functions Core Tools requests a remote build when you use the following func azure functionapp publish command to publish your Python project to Azure.

func azure functionapp publish <APP_NAME>

请记住将 <APP_NAME> 替换为 Azure 中的函数应用名称。Remember to replace <APP_NAME> with the name of your function app in Azure.

默认情况下,适用于 Visual Studio Code 的 Azure Functions 扩展还会请求远程生成。The Azure Functions Extension for Visual Studio Code also requests a remote build by default.

本地生成Local build

依赖项根据 requirements.txt 文件的内容在本地获取。Dependencies are obtained locally based on the contents of the requirements.txt file. 可以使用下面的 func azure functionapp publish 命令发布本地生成,从而防止执行远程生成。You can prevent doing a remote build by using the following func azure functionapp publish command to publish with a local build.

func azure functionapp publish <APP_NAME> --build local

请记住将 <APP_NAME> 替换为 Azure 中的函数应用名称。Remember to replace <APP_NAME> with the name of your function app in Azure.

使用 --build local 选项,从 requirements.txt 文件中读取项目依赖项,同时在本地下载并安装这些依赖包。Using the --build local option, project dependencies are read from the requirements.txt file and those dependent packages are downloaded and installed locally. 项目文件和依赖项从本地计算机部署到 Azure。Project files and dependencies are deployed from your local computer to Azure. 这会将较大的部署包上传到 Azure。This results in a larger deployment package being uploaded to Azure. 如果由于某种原因,Core Tools 无法获取 requirements.txt 文件中的依赖项,则必须使用自定义依赖项选项进行发布。If for some reason, dependencies in your requirements.txt file can't be acquired by Core Tools, you must use the custom dependencies option for publishing.

在 Windows 上进行本地开发时,不建议使用本地生成。We don't recommend using local builds when developing locally on Windows.

自定义依赖项Custom dependencies

如果项目的依赖项在 Python 包索引中找不到,可通过两种方式生成该项目。When your project has dependencies not found in the Python Package Index, there are two ways to build the project. 生成方法取决于你生成项目的方式。The build method depends on how you build the project.

具有额外索引 URL 的远程生成Remote build with extra index URL

如果包可以从可访问的自定义包索引中获取,请使用远程生成。When your packages are available from an accessible custom package index, use a remote build. 在发布之前,请务必创建一个 名为 PIP_EXTRA_INDEX_URL 的应用设置。Before publishing, make sure to create an app setting named PIP_EXTRA_INDEX_URL. 此设置的值是自定义包索引的 URL。The value for this setting is the URL of your custom package index. 使用此设置可告诉远程生成使用 --extra-index-url 选项运行 pip installUsing this setting tells the remote build to run pip install using the --extra-index-url option. 若要了解详细信息,请参阅 Python pip install 文档To learn more, see the Python pip install documentation.

还可将基本身份验证凭据与额外的包索引 URL 结合使用。You can also use basic authentication credentials with your extra package index URLs. 若要了解详细信息,请参阅 Python 文档中的基本身份验证凭据To learn more, see Basic authentication credentials in Python documentation.

安装本地包Install local packages

如果你的项目使用未向我们的工具公开发布的包,则可以通过将包放在 __app__/.python_packages 目录中,使其可供应用使用。If your project uses packages not publicly available to our tools, you can make them available to your app by putting them in the __app__/.python_packages directory. 发布之前,运行以下命令以在本地安装依赖项:Before publishing, run the following command to install the dependencies locally:

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

使用自定义依赖项时,应使用 --no-build 发布选项,因为你已将依赖项安装到项目文件夹中。When using custom dependencies, you should use the --no-build publishing option, since you have already installed the dependencies into the project folder.

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

请记住将 <APP_NAME> 替换为 Azure 中的函数应用名称。Remember to replace <APP_NAME> with the name of your function app in Azure.

单元测试Unit Testing

可以使用标准测试框架像测试其他 Python 代码那样测试使用 Python 编写的函数。Functions written in Python can be tested like other Python code using standard testing frameworks. 对于大多数绑定,可以通过从 azure.functions 包创建适当类的实例来创建 mock 输入对象。For most bindings, it's possible to create a mock input object by creating an instance of an appropriate class from the azure.functions package. 由于 azure.functions 包不可供立即可用,请务必通过 requirements.txt 文件安装该包,如上文包管理部分所述。Since the azure.functions package is not immediately available, be sure to install it via your requirements.txt file as described in the package management section above.

以 my_second_function 为例,下面是 HTTP 触发器函数的模拟测试:Take my_second_function as an example, following is a mock test of an HTTP triggered function:

首先需要创建 <project_root>/my_second_function/function.json 文件并将此函数定义为 http 触发器。First we need to create <project_root>/my_second_function/function.json file and define this function as an http trigger.

{
  "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_function 和 shared_code.my_second_helper_function 。Now, we can implement the my_second_function and the 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 which accepts ?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 触发器编写测试用例。We can start writing test cases for our http trigger.

# <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)。Inside your .venv Python virtual environment, install your favorite Python test framework (e.g. pip install pytest). 只需运行 pytest tests 即可检查测试结果。Simply run pytest tests to check the test result.

临时文件Temporary files

tempfile.gettempdir() 方法返回一个临时文件夹,这在 Linux 上为 /tmpThe tempfile.gettempdir() method returns a temporary folder, which on Linux is /tmp. 应用程序可使用此目录存储函数在执行期间生成和使用的临时文件。Your application can use this directory to store temporary files generated and used by your functions during execution.

重要

不能保证写入临时目录的文件会在调用之间保留。Files written to the temporary directory aren't guaranteed to persist across invocations. 在横向扩展期间,临时文件不会在实例之间进行共享。During scale out, temporary files aren't shared between instances.

以下示例在临时目录 (/tmp) 中创建一个命名的临时文件:The following example creates a named temporary file in the temporary directory (/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)

建议你在独立于项目文件夹的文件夹中维护测试。We recommend that you maintain your tests in a folder separate from the project folder. 这样可防止对应用部署测试代码。This keeps you from deploying test code with your app.

预安装的库Preinstalled libraries

Python 函数运行时附带了一些库。There are a few libraries come with the Python Functions runtime.

Python 标准库Python Standard Library

Python 标准库包含每个 Python 发行版附带的内置 Python 模块列表。The Python Standard Library contain a list of built-in Python modules that are shipped with each Python distribution. 其中的大多数库有助于你访问系统功能,如文件 I/O。Most of these libraries help you access system functionality, like file I/O. 在 Windows 系统上,这些库随 Python 一起安装。On Windows systems, these libraries are installed with Python. 在基于 Unix 的系统上,它们由包集合提供。On the Unix-based systems, they are provided by package collections.

若要查看这些库的列表的完整详细信息,请访问以下链接:To view the full details of the list of these libraries, please visit the links below:

Azure Functions Python 辅助角色依赖项Azure Functions Python worker dependencies

Functions Python 辅助角色需要一组特定的库。The Functions Python worker requires a specific set of libraries. 你也可以在函数中使用这些库,但它们并不属于 Python 标准库。You can also use these libraries in your functions, but they aren't a part of the Python standard. 如果你的函数依赖于这些库中的任何一个库,则在 Azure Functions 之外运行时,这些函数可能无法用于代码。If your functions rely on any of these libraries, they may not be available to your code when running outside of Azure Functions. 可在 setup.py 文件中的 install_requires 部分找到依赖项的详细列表。You can find a detailed list of dependencies in the install_requires section in the setup.py file.

备注

如果函数应用的 requirements.txt 包含 azure-functions-worker 条目,请将其删除。If your function app's requirements.txt contains an azure-functions-worker entry, remove it. 函数辅助角色由 Azure Functions 平台自动管理,我们会定期更新新功能和 Bug 修补程序。The functions worker is automatically managed by Azure Functions platform, and we regularly update it with new features and bug fixes. 在 requirements.txt 中手动安装旧版本的辅助角色可能会导致意外问题。Manually installing an old version of worker in requirements.txt may cause unexpected issues.

Azure Functions Python 库Azure Functions Python library

每次 Python 辅助角色更新都包含一个新版本的 Azure Functions Python 库 (azure.functions)Every Python worker update includes a new version of Azure Functions Python library (azure.functions). 这种方法使持续更新 Python 函数应用变得更容易,因为每次更新都是向后兼容的。This approach makes it easier to continuously update your Python function apps, because each update is backwards-compatible. 可在 azure-functions PyPi 中找到此库的版本列表。A list of releases of this library can be found in azure-functions PyPi.

运行时库版本由 Azure 修复,不能通过 requirements.txt 替代。The runtime library version is fixed by Azure, and it can't be overridden by requirements.txt. requirements.txt 中的 azure-functions 条目仅供 Lint 分析和客户认知。The azure-functions entry in requirements.txt is only for linting and customer awareness.

使用以下代码在运行时中跟踪 Python 函数库的实际版本:Use the following code to track the actual version of the Python Functions library in your runtime:

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

运行时系统库Runtime system libraries

有关 Python 辅助角色 Docker 映像中预安装的系统库列表,请访问以下链接:For a list of preinstalled system libraries in Python worker Docker images, please follow the links below:

Functions 运行时Functions runtime Debian 版本Debian version Python 版本Python versions
版本 2.xVersion 2.x 拉伸Stretch Python 3.6Python 3.6
Python 3.7Python 3.7
3.x 版Version 3.x BusterBuster Python 3.6Python 3.6
Python 3.7Python 3.7
Python 3.8Python 3.8
Python 3.9Python 3.9

跨域资源共享Cross-origin resource sharing

Azure Functions 支持跨域资源共享 (CORS)。Azure Functions supports cross-origin resource sharing (CORS). CORS 在门户中以及通过 Azure CLI 进行配置。CORS is configured in the portal and through the Azure CLI. CORS 允许的来源列表应用于函数应用级别。The CORS allowed origins list applies at the function app level. 启用 CORS 后,响应包含 Access-Control-Allow-Origin 标头。With CORS enabled, responses include the Access-Control-Allow-Origin header. 有关详细信息,请参阅 跨域资源共享For more information, see Cross-origin resource sharing.

Python 函数应用完全支持 CORS。CORS is fully supported for Python function apps.

已知问题和常见问题解答Known issues and FAQ

下面列出了常见问题的疑难解答指南:Following is a list of troubleshooting guides for common issues:

所有已知问题和功能请求都使用 GitHub 问题列表进行跟踪。All known issues and feature requests are tracked using GitHub issues list. 如果遇到 GitHub 中未列出的问题,请打开“新问题”并提供问题的详细说明。If you run into a problem and can't find the issue in GitHub, open a new issue and include a detailed description of the problem.

后续步骤Next steps

有关详细信息,请参阅以下资源:For more information, see the following resources:

存在问题?请告诉我们。Having issues? Let us know.