Building FunctionGraph HTTP Functions with Python from scratch¶
Following chapter describes in short how to build FunctionGraph HTTP functions using Python from scratch.
Introduction¶
For general details about creating HTTP functions from scratch and executing an HTTP function, see Creating a Function from Scratch and Executing the Function in the user manual.
Function Development Overview¶
See also General Constraints for HTTP Functions
Step 1: Create a function¶
In FunctionGraph console, create a function with the following parameters:
Create with: Create from scratch
Function Type: HTTP Function
Region: select the region where you want to create the function
Function Name: http-function-scratch
leave the other parameters with default values, and click Create Function to create the function.
Step 2: Write code for the function¶
For HTTP functions, the code is expected to listen for HTTP requests and send responses. You can use any Python web framework or library to implement the function code.
The following is a sample code using Python built-in HTTP module.
In the code editor, delete the default index.js file, create a new folder src and a new file index.py inside with the following code, and click Deploy to save the code.
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
from urllib.parse import urlparse, parse_qs
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
parsed_path = urlparse(self.path)
query = parse_qs(parsed_path.query)
name = query.get("name", ["World"])[0]
if parsed_path.path == "/":
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
response = {"message": f"Hello, {name}!"}
self.wfile.write(json.dumps(response).encode("utf-8"))
else:
self.send_response(404)
self.end_headers()
self.wfile.write(b"Not Found")
return
def do_POST(self):
parsed_path = urlparse(self.path)
if parsed_path.path == "/":
content_len = int(self.headers.get("Content-Length"))
post_body = self.rfile.read(content_len)
self.send_response(200)
self.end_headers()
self.wfile.write(post_body)
else:
self.send_response(404)
self.end_headers()
response = {"message": "Not found!"}
self.wfile.write(json.dumps(response).encode("utf-8"))
return
def run(
server_class=HTTPServer, handler_class=RequestHandler, host="0.0.0.0", port=8000
):
server_address = (host, port)
httpd = server_class(server_address, handler_class)
print(f"Starting HTTP server on {host}:{port}...")
httpd.serve_forever()
if __name__ == "__main__":
HOST = "0.0.0.0"
PORT = 8000
print(f"Starting server at http://{HOST}:{PORT}")
server = HTTPServer((HOST, PORT), RequestHandler)
server.serve_forever()
Step 3: Configure the bootstrap file¶
A file named bootstrap is used to start the function runtime and execute the function code.
The following is the code to be added in the bootstrap file for Python runtime. It starts the Python runtime and executes the index.py file.
/opt/function/runtime/[PYTHON_RUNTIME]/rtsp/python/bin/python $RUNTIME_CODE_ROOT/[FUNCTION_FILENAME]
where
[PYTHON_RUNTIME] is the Python runtime to use (see Supported Python Runtimes).
$RUNTIME_CODE_ROOT is the environment variable that points to the root directory of your function code (/opt/function/code).
[FUNCTION_FILENAME] is the name of the file that contains your function code (e.g., index.py).
In the code editor, replace the default code for file bootstrap with the following code, and click Deploy to save the code.
/opt/function/runtime/python3.10/rtsp/python/bin/python3 $RUNTIME_CODE_ROOT/src/index.py
Step 4: Create a test event¶
Click on Test tab, and click Configure Test Event to create test events with the following parameters:
(For HTTP functions only “API Gateway (Dedicated)” event template is supported.)
For POST /
{
"body": "eyJtZXNzYWdlIjogIkhlbGxvLCBXb3JsZCEifQ==",
"requestContext": {
"apiId": "bc1dcffd-aa35-474d-897c-d53425a4c08e",
"requestId": "11cdcdcf33949dc6d722640a13091c77",
"stage": "RELEASE"
},
"queryStringParameters": {
"responseType": "html"
},
"httpMethod": "POST",
"pathParameters": {},
"headers": {
"content-type": "application/json",
"accept-language": "q=0.5,en-US;q=0.3,en;q=0.2",
"accept-encoding": "gzip, deflate, br",
"x-forwarded-port": "443",
"x-forwarded-for": "103.218.216.98",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"upgrade-insecure-requests": "1",
"host": "host",
"x-forwarded-proto": "https",
"pragma": "no-cache",
"cache-control": "no-cache",
"x-real-ip": "103.218.216.98",
"user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0"
},
"path": "/",
"isBase64Encoded": true
}
For GET /
{
"body": "",
"requestContext": {
"apiId": "bc1dcffd-aa35-474d-897c-d53425a4c08e",
"requestId": "11cdcdcf33949dc6d722640a13091c77",
"stage": "RELEASE"
},
"queryStringParameters": {
"responseType": "html",
"name": "John"
},
"httpMethod": "GET",
"pathParameters": {},
"headers": {
"accept-language": "q=0.5,en-US;q=0.3,en;q=0.2",
"accept-encoding": "gzip, deflate, br",
"x-forwarded-port": "443",
"x-forwarded-for": "103.218.216.98",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"upgrade-insecure-requests": "1",
"host": "host",
"x-forwarded-proto": "https",
"pragma": "no-cache",
"cache-control": "no-cache",
"x-real-ip": "103.218.216.98",
"user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0"
},
"path": "/",
"isBase64Encoded": true
}
Step 5: Test the function¶
Click Test to execute the function with the test events created in the previous step,
and you should see the following output in the Execution Result section
For POST event:
{
"body": "eyJtZXNzYWdlIjogIkhlbGxvLCBXb3JsZCEifQ==",
"headers": {
"Date": [
"Fri, 03 Jul 2026 09:16:00 GMT"
],
"Server": [
"BaseHTTP/0.6 Python/3.10.0"
]
},
"statusCode": 200,
"isBase64Encoded": true
}
The body in the output is base64 encoded. After decoding, you should see the following content:
{"message": "Hello, World!"}
For GET event:
{
"body": "eyJtZXNzYWdlIjogIkhlbGxvLCBKb2huISJ9",
"headers": {
"Content-Type": [
"application/json"
],
"Date": [
"Fri, 03 Jul 2026 09:17:28 GMT"
],
"Server": [
"BaseHTTP/0.6 Python/3.10.0"
]
},
"statusCode": 200,
"isBase64Encoded": true
}
The body in the output is base64 encoded. After decoding, you should see the following content:
{"message": "Hello, John!"}