Edge Developer Platform
  • Pages
    • Product Introduction
    • Quick Start
      • Importing a Git Repository
      • Starting From a Template
      • Direct Upload
      • Start with AI
    • Framework Guide
      • Frontends
        • Vite
        • React
        • Vue
        • Hugo
        • Other Frameworks
      • Backends
      • Full-stack
        • Next.js
        • Nuxt
        • Astro
        • React Router
        • SvelteKit
        • TanStack Start
        • Vike
      • Custom 404 Page
    • Project Guide
      • Project Management
      • edgeone.json
      • Configuring Cache
      • Building Output Configuration
      • Error Codes
    • Build Guide
    • Deployment Guide
      • Overview
      • Create Deploys
      • Manage Deploys
      • Deploy Button
      • Using Github Actions
      • Using Gitlab CI/CD
      • Using CNB Plugin
      • Using IDE PlugIn
      • Using CodeBuddy IDE
    • Domain Management
      • Overview
      • Custom Domain
      • HTTPS Configuration
        • Overview
        • Apply for Free Certificate
        • Using Managed SSL Certificate
      • Configure DNS CNAME Record
    • Observability
      • Overview
      • Metric Analysis
      • Log Analysis
    • Pages Functions
      • Overview
      • Edge Functions
      • Cloud Functions
        • Overview
        • Node.js
        • Python
        • Go
    • Middleware
    • KV Storage
    • Edge AI
    • API Token
    • EdgeOne CLI
    • Copilot
      • Overview
      • Quick Start
    • Pages MCP
    • Pages Skills
    • Message Notification
    • Integration Guide
      • AI
        • Dialogue Large Models Integration
        • Large Models for Images Integration
      • Database
        • Supabase Integration
        • Pages KV Integration
      • Ecommerce
        • Shopify Integration
        • WooCommerce Integration
      • Payment
        • Stripe Integration
        • Integrating Paddle
      • CMS
        • WordPress Integration
        • Contentful Integration
        • Sanity Integration
        • Payload Integration
      • Authentication
        • Supabase Integration
        • Clerk Integration
    • Best Practices
      • AI Dialogue Deployment: Deploy Project with One Sentence Using Skill
      • Using General Large Model to Quickly Build AI Application
      • Use the DeepSeek model to quickly build a conversational AI site
      • Building an Ecommerce Platform with Shopify
      • Building a SaaS Site Using Supabase and Stripe
      • Building a Company Brand Site Quickly
      • How to Quickly Build a Blog Site
    • Migration Guides
      • Migrating from Vercel to EdgeOne Pages
      • Migrating from Cloudflare Pages to EdgeOne Pages
      • Migrating from Netlify to EdgeOne Pages
    • Troubleshooting
    • FAQs
    • Contact Us
    • Release Notes

Python

Overview

Python runtime functions are the Python server-side runtime capabilities provided by EdgeOne Pages, allowing developers to write backend logic in Python and deploy it in the same project as the frontend page, enabling full-stack application development.


Advantages

Zero-configuration deployment: Automatically generate routes based on the file system without manual configuration of the route table. Just place the Python file in the cloud-functions directory to automatically map it to an API endpoint.
Multi-framework compatibility: Simultaneously support three modes - Handler class, WSGI (Flask/Django), and ASGI (FastAPI/Sanic). Automatic framework detection with no additional configuration required, and different modes can be mixed in the same project.
Intelligent dependency management: Auto-scan import statements in code to detect dependencies, combine with user requirements.txt for merge and deduplication, support incremental installation and cache optimization, significantly enhance pull speed.


Development Mode

Python functions support various development modes:
Mode
Scenarios
Routing Mode
Framework Dependency
Handler mode
Simple API, Serverless style
File system route (file as route)
None (pure standard library)
WSGI framework mode
Complete Web application, RESTful API
Built-in framework routing
Flask,Django
ASGI framework mode
Complete Web application, RESTful API
Built-in framework routing
FastAPI,Sanic



Getting Started

Create a new hello.py in the ./cloud-functions/api directory of your project, and use the following example code to create your first Python function:

Basic Example: Handler Class

# ./cloud-functions/api/hello.py
from http.server import BaseHTTPRequestHandler

class 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 class inherits from BaseHTTPRequestHandler and handles different http requests through methods such as do_GET and do_POST.

Advanced Example: Using the Flask Framework

# ./cloud-functions/api/index.py
from flask import Flask, jsonify, request

app = 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
Note:
When using framework mode, the runtime automatically removes the file routing prefix. For example, api/index.py corresponds to the routing prefix /api. After removal, the path received by Flask for the request /api/users is /users, so Flask internal routing just needs to define the relative path.

Advanced Example: Using the FastAPI Framework

# ./cloud-functions/api/index.py
from fastapi import FastAPI

app = 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}


Routing

Python functions generate access routes based on the /cloud-functions directory structure. You can create subdirectories at any level under the /cloud-functions directory in your project repository. See the following example.

Directory Structure Example

...
cloud-functions
├── api
│ ├── index.py
│ ├── hello.py
│ ├── users
│ │ ├── index.py
│ │ ├── list.py
│ │ └── [id].py
│ ├── orders
│ │ └── index.py
│ └── [[default]].py
...
The above directory file structure will generate the following routes after EdgeOne Pages platform construction. These routes map Pages URLs to /cloud-functions files. When client access the URL, it will trigger the corresponding file code to run:
File path
Routing
/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/*

Route Match Priority

Routes are matched based on the following priorities (from high to low):
1. Static route: Path priority with exact matching (for example /api/users/list)
2. Single-level dynamic route: [param] matches one path segment (for example /api/users/[id])
3. Multi-level dynamic route (Catch-all): [[param]] matches one or more path segments (for example /api/[[default]])
In routes of the same level, the longer (more specific) the path, the higher priority.

Entry Point Identification

Not all .py files will be registered as routes. Only Python files containing the following entry flag will generate routes:
class handler(BaseHTTPRequestHandler) - Handler class mode
app = Flask(...) / app = FastAPI(...) - Framework instance mode
application = get_wsgi_application() - Django WSGI mode
.py files  excluding entry flags will be deemed as auxiliary modules, will be copied to build artifacts for other entry files to refer, but will not register as standalone routes.

Dynamic routing

Python functions support dynamic routing. Use square brackets in the file name or directory name to define dynamic parameters:
Single-level dynamic path[param]: matches one path segment
Multi-level dynamic path (Catch-all)[[param]]: matches one or more path segments
File path
Routing
Match Example
Whether to Match
/cloud-functions/api/users/[id].py
example.com/api/users/:id
example.com/api/users/1024
Yes
example.com/api/users/vip/1024
No
example.com/api/vip/1024
No
/cloud-functions/api/[[default]].py
example.com/api/*
example.com/api/books/list
Yes
example.com/api/1024
Yes
example.com/v2/vip/1024
No

Dynamic Routing Parameter Retrieval

In the Handler class, you can get the request path via self.path and parse dynamic parameters:
# ./cloud-functions/api/users/[id].py
from http.server import BaseHTTPRequestHandler

class handler(BaseHTTPRequestHandler):

def do_GET(self):
# self.path is the path without the prefix removed
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'))

Built-in Routing Framework

When using frameworks such as Flask and FastAPI, routing is divided into file system route and built-in framework routing two layers:
1. File system route (outer layer): Determined by file path, for example api/index.py/api
2. Framework internal routing (inner layer): Defined by skeleton code, for example @app.route('/users')
The runtime automatically removes the file system routing prefix before transmitting it to the framework. For example:
request path /api/users
file system route matching /api (corresponds to api/index.py)
After removing the prefix, the framework received /users
Flask's @app.route('/users') match successful
Note:
Internal framework route definitions do not require file system routing prefixes. For example, Flask routes in api/index.py should be written as @app.route('/users') instead of @app.route('/api/users').
Each entry file corresponds to an independent framework instance, and files do not affect each other.
The same index.py can register multiple framework routes, and at runtime all requests matching the file system routing prefix will be forwarded to the same framework instance.


Function Handlers

Use Function Handlers to create custom request handlers for Pages and define RESTful APIs to implement full-stack applications. The Handler class mode allows rapid development of API interfaces without depending on any framework.

Basic Usage

The Handler class inherits from BaseHTTPRequestHandler and handles different http requests by implementing methods such as do_GET and do_POST.
# ./cloud-functions/api/hello.py
from http.server import BaseHTTPRequestHandler

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

Handling Multiple Request Methods

By implementing methods such as do_POST, do_PUT, and do_DELETE, you can handle different types of HTTP requests:
# ./cloud-functions/api/users/index.py
from http.server import BaseHTTPRequestHandler
import json

class 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 Class Properties and Methods

handler class inherits from BaseHTTPRequestHandler and can use the following properties and methods:
Attribute/Method
Type
Description
self.path
str
request path (with query parameter)
self.command
str
HTTP request method (GET, POST)
self.headers
dict-like
Request header.
self.rfile
file
Request body input stream
self.wfile
file
response body output stream
self.send_response(code)
method
Send HTTP Status Code
self.send_header(key, value)
method
Send Response Headers
self.end_headers()
method
End Response Headers

Query Parameter Retrieval

# ./cloud-functions/api/search.py
from http.server import BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs

class handler(BaseHTTPRequestHandler):

def do_GET(self):
# Parse query parameters
parsed = urlparse(self.path)
query_params = parse_qs(parsed.query)
# query_params example: {'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'))


Dependency Management

Automated Dependency Detection

The builder will automatically scan ALL Python files under the cloud-functions directory for import statements, detect used third-party libraries and add them to the dependency list automatically. Common frameworks and libraries supporting auto-detection include:
fastapi, django, sanic, bottle, falcon, httpx, requests, pydantic, sqlalchemy, redis, pymongo, numpy, pandas.

Manual Dependency Declaration

If you need to specify an exact version or automatically detect uncovered dependencies, you can place requirements.txt in the following location:
1. cloud-functions/requirements.txt (prioritize)
2. project root directory requirements.txt
# cloud-functions/requirements.txt
flask>=2.0.0
redis>=4.0.0
openai>=1.0.0
During the build, basic dependencies, automatically detected dependencies, and user claims will be merged and deduplicated. The version explicitly declared by the user has the highest priority.

Exclude Directories

The following directories will not be scanned and copied to build artifacts:
__pycache__,.git,node_modules
venv,.venv (virtual environment)
scripts (local test script)
tests,.pytest_cache (test file)


Sample Template

Python Handler template:

Use FastApi framework:

Use Flask framework:

Use Django framework: