1. 简介

Python 是一种热门的开源编程语言,广泛应用于数据科学家、Web 应用开发者、系统管理员等领域。
Cloud Functions 是一个事件驱动型无服务器计算平台。借助 Cloud Functions,您可以专注于编写代码,而不必担心资源预配或扩缩来应对不断变化的需求。
Cloud Functions 函数有两种类型:
- HTTP 函数可响应 HTTP 请求。在此 Codelab 中,您将构建几个。
- 后台函数由事件触发,例如向 Cloud Pub/Sub 发布消息或向 Cloud Storage 上传文件。我们在此实验中不会介绍这一点,但您可以在文档中了解详情。

此 Codelab 将引导您完成使用 Python 创建自己的 Cloud Functions 函数的过程。
构建内容
在此 Codelab 中,您将发布一个 Cloud Functions 函数,该函数在通过 HTTP 调用时会显示 “Python Powered”徽标:

学习内容
- 如何编写 HTTP Cloud Functions 函数。
- 如何编写接受实参的 HTTP Cloud Functions 函数。
- 如何测试 HTTP Cloud Functions 函数。
- 如何运行本地 Python HTTP 服务器来试用函数。
- 如何编写返回图片的 HTTP Cloud Functions 函数。
2. 设置和要求
自定进度的环境设置
- 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个。



- 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
- 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用
PROJECT_ID标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且此 ID 在项目期间会一直保留。 - 此外,还有第三个值,即部分 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档。
- 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除项目。Google Cloud 新用户符合参与 300 美元免费试用计划的条件。
启动 Cloud Shell
虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Cloud Shell,这是一个在云端运行的命令行环境。
激活 Cloud Shell
- 在 Cloud Console 中,点击激活 Cloud Shell
。

如果您是第一次启动 Cloud Shell,系统会显示一个介绍其功能的过渡页面。如果您看到了过渡页面,请点击继续。

预配和连接到 Cloud Shell 只需花几分钟时间。

这个虚拟机已加载了所需的所有开发工具。它提供了一个持久的 5 GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。只需使用一个浏览器即可完成本 Codelab 中的大部分工作。
连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的项目 ID。
- 在 Cloud Shell 中运行以下命令以确认您已通过身份验证:
gcloud auth list
命令输出
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- 在 Cloud Shell 中运行以下命令,以确认 gcloud 命令了解您的项目:
gcloud config list project
命令输出
[core] project = <PROJECT_ID>
如果不是上述结果,您可以使用以下命令进行设置:
gcloud config set project <PROJECT_ID>
命令输出
Updated property [core/project].
确保已启用 Cloud Functions 和 Cloud Build API
在 Cloud Shell 中运行以下命令,确保 Cloud Functions 和 Cloud Build API 已启用:
gcloud services enable \ cloudfunctions.googleapis.com \ cloudbuild.googleapis.com
注意:gcloud functions deploy 命令将调用 Cloud Build,后者会自动将您的代码构建到容器映像中。
下载源代码
在 Cloud Shell 终端中,运行以下命令:
REPO_NAME="codelabs" REPO_URL="https://github.com/GoogleCloudPlatform/$REPO_NAME" SOURCE_DIR="cloud-functions-python-http" git clone --no-checkout --filter=blob:none --depth=1 $REPO_URL cd $REPO_NAME git sparse-checkout set $SOURCE_DIR git checkout cd $SOURCE_DIR
查看源目录的内容:
ls
您应该有以下文件:
main.py python-powered.png test_main.py web_app.py
3. HTTP Cloud Functions 函数简介
Python 版 HTTP Cloud Functions 函数编写为常规 Python 函数。该函数必须接受一个 flask.Request 实参,该实参通常命名为 request。
main.py
import flask
def hello_world(request: flask.Request) -> flask.Response:
"""HTTP Cloud Function.
Returns:
- "Hello World! 👋"
"""
response = "Hello World! 👋"
return flask.Response(response, mimetype="text/plain")
# ...
您可以使用自己喜欢的命令行编辑器(例如 nano、vim 或 emacs)打开该文件。您还可以在将源目录设置为工作区后,在 Cloud Shell Editor 中打开该目录:
cloudshell open-workspace .
我们使用 gcloud functions deploy 命令将此函数部署为 HTTP Cloud Functions 函数:
FUNCTION_NAME="hello_world" gcloud functions deploy $FUNCTION_NAME \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
命令输出:
... Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 ... entryPoint: FUNCTION_NAME httpsTrigger: url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME ...
有关 gcloud functions deploy 选项的注意事项:
--runtime:用于指定语言运行时。对于 Python,目前可以是python37、python38、python39、python310或python312。请参阅运行时。--trigger-http:系统会为该函数分配一个端点。向端点发出的 HTTP 请求(POST、PUT、GET、DELETE 和 OPTIONS)会触发函数执行。--allow-unauthenticated:函数将公开,允许所有调用者访问,而不检查身份验证。- 如需了解详情,请参阅 gcloud functions deploy。
如需测试函数,您可以点击上述命令输出中显示的 httpsTrigger.url 网址。您还可以通过编程方式检索网址,并使用以下命令调用函数:
URL=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)") curl -w "\n" $URL
您应该会看到以下结果:
Hello World! 👋
4. 编写接受实参的 HTTP Cloud Functions 函数
如果函数接受参数,则会更加灵活。我们来定义一个支持 name 参数的新函数 hello_name:
main.py
# ...
def hello_name(request: flask.Request) -> flask.Response:
"""HTTP Cloud Function.
Returns:
- "Hello {NAME}! 🚀" if "name=NAME" is defined in the GET request
- "Hello World! 🚀" otherwise
"""
name = request.args.get("name", "World")
response = f"Hello {name}! 🚀"
return flask.Response(response, mimetype="text/plain")
# ...
我们来部署这个新函数:
FUNCTION_NAME="hello_name" gcloud functions deploy $FUNCTION_NAME \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
命令输出:
... Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 ... entryPoint: FUNCTION_NAME httpsTrigger: url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME ...
如需测试函数,您可以点击上述命令输出中显示的 httpsTrigger.url 网址。您还可以通过编程方式检索网址,并使用以下命令调用函数:
URL=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)") curl -w "\n" $URL
您应该会获得默认结果:
Hello World! 🚀
您之所以获得默认结果,是因为未设置 name 实参。向网址添加参数:
curl -w "\n" $URL?name=YOUR%20NAME
这次,您将获得自定义回答:
Hello YOUR NAME! 🚀
下一步是添加单元测试,以确保在更新源代码后,函数仍能按预期运行。
5. 编写测试
Python 版 HTTP Cloud Functions 函数使用标准库中的 unittest 模块进行测试。测试函数无需运行模拟器或其他模拟环境,只需使用常规 Python 代码即可。
以下是 hello_world 和 hello_name 函数的测试示例:
test_main.py
import unittest
import unittest.mock
import main
class TestHello(unittest.TestCase):
def test_hello_world(self):
request = unittest.mock.Mock()
response = main.hello_world(request)
assert response.status_code == 200
assert response.get_data(as_text=True) == "Hello World! 👋"
def test_hello_name_no_name(self):
request = unittest.mock.Mock(args={})
response = main.hello_name(request)
assert response.status_code == 200
assert response.get_data(as_text=True) == "Hello World! 🚀"
def test_hello_name_with_name(self):
name = "FirstName LastName"
request = unittest.mock.Mock(args={"name": name})
response = main.hello_name(request)
assert response.status_code == 200
assert response.get_data(as_text=True) == f"Hello {name}! 🚀"
- Python 测试的编写方式与其他 Python 文件相同。它们以一组导入语句开头,然后定义类和函数。
- 测试声明的形式为
class TestHello(TestCase)。它必须是一个继承自unittest.TestCase的类。 - 测试类具有多种方法,每种方法都必须以
test_开头,表示各个测试用例。 - 每个测试用例都会通过模拟
request参数(即将其替换为包含测试所需特定数据的虚假对象)来测试我们的某个函数。 - 在调用每个函数后,测试会检查 HTTP 响应,以确保其符合我们的预期。
由于 main.py 依赖于 flask,因此请确保在测试环境中安装了 Flask 框架:
pip install flask
安装 Flask 会输出类似如下的结果:
Collecting flask ... Successfully installed ... flask-3.0.2 ...
在本地运行以下测试:
python -m unittest
这三个单元测试应该会通过:
... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
接下来,您将创建一个新函数,用于返回“Python Powered”徽标。
6. 编写“Python Powered”HTTP Cloud Functions 函数
我们来创建一个更有趣的新函数,让它在每次收到请求时返回“Python Powered”图片:

以下代码展示了实现这一功能的代码:
main.py
# ...
def python_powered(request: flask.Request) -> flask.Response:
"""HTTP Cloud Function.
Returns:
- The official "Python Powered" logo
"""
return flask.send_file("python-powered.png")
部署新的 python_powered 函数:
FUNCTION_NAME="python_powered" gcloud functions deploy $FUNCTION_NAME \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
命令输出:
... Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 ... entryPoint: FUNCTION_NAME httpsTrigger: url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME ...
如需测试函数,请点击上述命令输出中显示的 httpsTrigger.url 网址。如果一切正常,您会在新的浏览器标签页中看到“Python Powered”徽标!
接下来,您将创建一个应用,以便在部署之前在本地运行和试用函数。
7. 在本地运行函数
您可以通过创建 Web 应用并在路由中调用函数来在本地运行 HTTP 函数。您可以将其添加到与函数相同的目录中。名为 web_app.py 的文件包含以下内容:
web_app.py
import flask
import main
app = flask.Flask(__name__)
@app.get("/")
def index():
return main.python_powered(flask.request)
if __name__ == "__main__":
# Local development only
# Run "python web_app.py" and open http://localhost:8080
app.run(host="localhost", port=8080, debug=True)
- 此文件会创建一个 Flask 应用。
- 它会在基本网址处注册一个路由,该路由由名为
index()的函数处理。 - 然后,
index()函数会调用我们的python_powered函数,并将当前请求传递给该函数。
确保您的开发环境中已安装 Flask 框架:
pip install flask
安装 Flask 会输出类似如下的结果:
Collecting flask ... Successfully installed ... flask-3.0.2 ...
如需在本地运行此应用,请运行以下命令:
python web_app.py
现在,使用 Cloud Shell 的网页预览功能在浏览器中测试 Web 应用。在 Cloud Shell 中,点击“网页预览”按钮,然后选择“在端口 8080 上预览”:

Cloud Shell 会在新的浏览器窗口中,通过其代理服务打开预览网址。网页预览功能会限制访问权限,仅允许您的用户账号通过 HTTPS 进行访问。如果一切正常,您应该会看到“Python Powered”徽标!

8. 恭喜!

您已部署 HTTP Cloud Functions 函数,该函数使用惯用函数通过 Flask 框架处理 Web 请求。
Cloud Functions 价格取决于函数的调用频率,对于不经常运行的函数,我们还提供免费层级。完成 Cloud Functions 函数测试后,您可以使用 gcloud 将其删除:
gcloud functions delete hello_world --quiet gcloud functions delete hello_name --quiet gcloud functions delete python_powered --quiet
您也可以通过 Google Cloud 控制台删除函数。
希望您能喜欢使用 Python 中的 Cloud Functions!