概述
Python 运行时函数是 EdgeOne Pages 提供的 Python 服务端运行能力,允许开发者使用 Python 编写后端逻辑,与前端页面部署在同一项目中,实现全栈应用开发。
优势
零配置部署:基于文件系统自动生成路由,无需手动配置路由表。将 Python 文件放入
cloud-functions 目录即可自动映射为 API 端点。多框架兼容:同时支持 Handler 类、WSGI(Flask/Django)和 ASGI(FastAPI/Sanic)三种模式。框架自动检测,无需额外配置,还可在同一项目中混合使用不同模式。
智能依赖管理:自动扫描代码中的
import 语句检测依赖,结合用户 requirements.txt 进行合并去重,支持增量安装和缓存优化,大幅提升构建速度。开发模式
Python 函数支持多种开发模式:
模式 | 适用场景 | 路由方式 | 框架依赖 |
Handler 模式 | 简单 API、Serverless 风格 | 文件系统路由(文件即路由) | 无(纯标准库) |
WSGI 框架模式 | 完整 Web 应用、RESTful API | 框架内置路由 | Flask、Django |
ASGI 框架模式 | 完整 Web 应用、RESTful API | 框架内置路由 | FastAPI、Sanic |
快速开始
在项目的
./cloud-functions/api 目录下新建 hello.py,使用以下示例代码创建您的第一个 Python 函数:基础示例:Handler 类
# ./cloud-functions/api/hello.pyfrom http.server import BaseHTTPRequestHandlerclass handler(BaseHTTPRequestHandler):def do_GET(self):self.send_response(200)self.send_header('Content-Type', 'application/json')self.end_headers()self.wfile.write('{"message": "Hello from Python Functions!"}'.encode('utf-8'))
handler 类继承自 BaseHTTPRequestHandler,通过 do_GET、do_POST 等方法处理不同的 HTTP 请求。进阶示例:使用 Flask 框架
# ./cloud-functions/api/index.pyfrom flask import Flask, jsonify, requestapp = Flask(__name__)@app.route('/users', methods=['GET'])def get_users():return jsonify({'users': [{'id': 1, 'name': 'Alice'},{'id': 2, 'name': 'Bob'}]})@app.route('/users', methods=['POST'])def create_user():data = request.get_json()return jsonify({'message': 'User created', 'user': data}), 201
注意:
当使用框架模式时,运行时会自动剥离文件路由前缀。例如
api/index.py 对应路由前缀 /api,请求 /api/users 经剥离后 Flask 收到的路径为 /users,因此 Flask 内部路由只需定义相对路径即可。进阶示例:使用 FastAPI 框架
# ./cloud-functions/api/index.pyfrom fastapi import FastAPIapp = FastAPI()@app.get('/items')async def list_items():return {'items': [{'id': 1, 'name': 'Item A'}, {'id': 2, 'name': 'Item B'}]}@app.get('/items/{item_id}')async def get_item(item_id: int):return {'item_id': item_id, 'name': f'Item {item_id}'}@app.post('/items')async def create_item(item: dict):return {'message': 'Item created', 'item': item}
路由
Python 函数基于
/cloud-functions 目录结构生成访问路由。您可在项目仓库 /cloud-functions 目录下创建任意层级的子目录,参考下述示例。目录结构示例
...cloud-functions├── api│ ├── index.py│ ├── hello.py│ ├── users│ │ ├── index.py│ │ ├── list.py│ │ └── [id].py│ ├── orders│ │ └── index.py│ └── [[default]].py...
上述目录文件结构,经 EdgeOne Pages 平台构建后将生成以下路由。这些路由将 Pages URL 映射到
/cloud-functions 文件,当客户端访问 URL 时将触发对应的文件代码被运行:文件路径 | 路由 |
/cloud-functions/api/index.py | example.com/api |
/cloud-functions/api/hello.py | example.com/api/hello |
/cloud-functions/api/users/index.py | example.com/api/users |
/cloud-functions/api/users/list.py | example.com/api/users/list |
/cloud-functions/api/users/[id].py | example.com/api/users/:id |
/cloud-functions/api/orders/index.py | example.com/api/orders |
/cloud-functions/api/[[default]].py | example.com/api/* |
路由匹配优先级
路由按以下优先级进行匹配(从高到低):
1. 静态路由:精确匹配的路径优先(如
/api/users/list)。2. 单级动态路由:
[param] 匹配单个路径段(如 /api/users/[id])。3. 多级动态路由(Catch-all):
[[param]] 匹配一个或多个路径段(如 /api/[[default]])。同级别路由中,路径越长(越具体)优先级越高。
入口文件识别
并非所有
.py 文件都会被注册为路由。只有包含以下入口标识的 Python 文件才会生成路由:class handler(BaseHTTPRequestHandler) — Handler 类模式。app = Flask(...) / app = FastAPI(...) — 框架实例模式。application = get_wsgi_application() — Django WSGI 模式。 不包含入口标识的
.py 文件将被视为辅助模块,会被复制到构建产物中供其他入口文件引用,但不会注册为独立路由。动态路由
Python 函数支持动态路由。在文件名或目录名中使用方括号语法定义动态参数:
单级动态路径
[param]:匹配单个路径段。多级动态路径(Catch-all)
[[param]]:匹配一个或多个路径段。文件路径 | 路由 | 匹配示例 | 是否匹配 |
/cloud-functions/api/users/[id].py | example.com/api/users/:id | example.com/api/users/1024 | 是 |
| | example.com/api/users/vip/1024 | 否 |
| | example.com/api/vip/1024 | 否 |
/cloud-functions/api/[[default]].py | example.com/api/* | example.com/api/books/list | 是 |
| | example.com/api/1024 | 是 |
| | example.com/v2/vip/1024 | 否 |
动态路由参数获取
在 Handler 类中,可通过
self.path 获取请求路径并解析动态参数:# ./cloud-functions/api/users/[id].pyfrom http.server import BaseHTTPRequestHandlerclass handler(BaseHTTPRequestHandler):def do_GET(self):# self.path 为未剥离前缀的路径user_id = self.path.strip('/')self.send_response(200)self.send_header('Content-Type', 'application/json')self.end_headers()self.wfile.write(f'{{"user_id": "{user_id}"}}'.encode('utf-8'))
框架内置路由
使用 Flask、FastAPI 等框架时,路由分为文件系统路由和框架内部路由两层:
1. 文件系统路由(外层):由文件路径决定,如
api/index.py → /api。2. 框架内部路由(内层):由框架代码定义,如
@app.route('/users')。运行时会自动剥离文件系统路由前缀后再传给框架。例如:
请求路径
/api/users。文件系统路由匹配
/api(对应 api/index.py)。剥离前缀后,框架收到
/users。Flask 的
@app.route('/users') 匹配成功。注意:
框架内部的路由定义不需要包含文件系统路由前缀。例如
api/index.py 中的 Flask 路由应写 @app.route('/users') 而非 @app.route('/api/users')。每个入口文件对应一个独立的框架实例,文件之间互不影响。
同一个
index.py 中可以注册多个框架路由,运行时会将匹配该文件系统路由前缀的所有请求转发给同一个框架实例。Function Handlers
使用 Function Handlers 可为 Pages 创建自定义请求处理程序,以及定义 RESTful API 实现全栈应用。Handler 类模式,无需依赖任何框架即可快速开发 API 接口。
基本用法
Handler 类继承自
BaseHTTPRequestHandler,通过实现 do_GET、do_POST 等方法处理不同的 HTTP 请求:# ./cloud-functions/api/hello.pyfrom http.server import BaseHTTPRequestHandlerclass handler(BaseHTTPRequestHandler):def do_GET(self):self.send_response(200)self.send_header('Content-Type', 'text/plain')self.end_headers()self.wfile.write('Hello, world!'.encode('utf-8'))
处理多种请求方法
通过实现
do_POST、do_PUT、do_DELETE 等方法即可处理不同类型的 HTTP 请求:# ./cloud-functions/api/users/index.pyfrom http.server import BaseHTTPRequestHandlerimport jsonclass handler(BaseHTTPRequestHandler):def do_GET(self):self.send_response(200)self.send_header('Content-Type', 'application/json')self.end_headers()self.wfile.write('{"users": []}'.encode('utf-8'))def do_POST(self):content_length = int(self.headers.get('Content-Length', 0))body = self.rfile.read(content_length).decode('utf-8')data = json.loads(body) if body else {}self.send_response(201)self.send_header('Content-Type', 'application/json')self.end_headers()self.wfile.write(json.dumps({'message': 'Created', 'data': data}).encode('utf-8'))def do_DELETE(self):self.send_response(204)self.end_headers()
Handler 类属性和方法
handler 类继承自 BaseHTTPRequestHandler,可使用以下属性和方法:属性/方法 | 类型 | 描述 |
self.path | str | 请求路径(含查询参数) |
self.command | str | HTTP 请求方法(GET、POST 等) |
self.headers | dict-like | 请求头 |
self.rfile | file | 请求体输入流 |
self.wfile | file | 响应体输出流 |
self.send_response(code) | method | 发送 HTTP 状态码 |
self.send_header(key, value) | method | 发送响应头 |
self.end_headers() | method | 结束响应头 |
获取查询参数
# ./cloud-functions/api/search.pyfrom http.server import BaseHTTPRequestHandlerfrom urllib.parse import urlparse, parse_qsclass handler(BaseHTTPRequestHandler):def do_GET(self):# 解析查询参数parsed = urlparse(self.path)query_params = parse_qs(parsed.query)# query_params 示例:{'name': ['Alice'], 'age': ['25']}name = query_params.get('name', ['Guest'])[0]self.send_response(200)self.send_header('Content-Type', 'application/json')self.end_headers()self.wfile.write(f'{{"hello": "{name}"}}'.encode('utf-8'))
依赖管理
自动依赖检测
构建器会自动扫描
cloud-functions 目录下所有 Python 文件的 import 语句,检测使用的第三方库并自动添加到依赖列表。支持自动检测的常用框架和库包括:fastapi、django、sanic、bottle、falcon、httpx、requests、pydantic、sqlalchemy、redis、pymongo、numpy、pandas 等。手动声明依赖
如果需要指定精确版本或自动检测未覆盖的依赖,可在以下位置放置
requirements.txt:1.
cloud-functions/requirements.txt(优先使用)。2. 项目根目录
requirements.txt。# cloud-functions/requirements.txtflask>=2.0.0redis>=4.0.0openai>=1.0.0
构建时会将基础依赖、自动检测的依赖和用户声明的依赖合并去重,用户显式声明的版本具有最高优先级。
排除目录
以下目录不会被扫描和复制到构建产物中:
__pycache__、.git、node_modules。venv、.venv(虚拟环境)。scripts(本地测试脚本)。tests、.pytest_cache(测试文件)。示例模板
Python Handler 模板:
使用 FastAPI 框架:
使用 Flask 框架:
使用 Django 框架: