You can use HTTP handlers to process HTTP requests in an efficient manner. When you invoke a function, Function Compute uses the handler that you specify to process HTTP requests. This topic describes the structure and characteristics of HTTP handlers in Python.

Usage notes

Before you use an HTTP handler, make sure that an HTTP trigger is configured for your HTTP function. For more information, see Configure and use an HTTP trigger.

Signatures for HTTP handlers

Signatures for HTTP handlers in Python follow the Python Web Server Gateway Interface (WSGI) specification.

The following sample code describes a signature for an HTTP handler:

def handler(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, world!</h1>']

In the preceding code:

  • handler: A function that is invoked to respond to HTTP requests and follows the WSGI specification. You can pass the following parameters:
    • environ: information about all HTTP requests.
    • start_response: the function that sends HTTP responses.
  • start_response('200 OK', [('Content-Type', 'text/html')]): the response of the function, which contains two parameters. The first parameter indicates the HTTP status code. The second parameter indicates HTTP headers that consist of a set of Python list objects. Each HTTP header is a Python tuple object that contains two Python strings.
  • return [b'<h1>Hello, world!</h1>']: the return value, which is returned by the server to the client as the HTTP response body.

Example: Implement a Flask application

Sample code

After you create an HTTP handler that follows the WSGI specification, applications that are built based on web frameworks such as Flask and Django can be quickly migrated to Function Compute. The following code shows how to run a Flask-based hello world application in the Python runtime of Function Compute.

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Web App with Python Flask!'

def handler(environ, start_response):
    return app(environ, start_response)
In the preceding sample code:
  • Part 1: the code of the Flask-based application. This part starts at from flask import Flask and ends at return 'Web App with Python Flask!'.
  • Part 2: the handler function. To run applications that are built on a web framework such as Flask or Django in the Python runtime of Function Compute, you need to only implement the handler function as return app(environ, start_response).

Prerequisites

Create a Service

Procedure

  1. Log on to the Function Compute console.
  2. In the left-side navigation pane, click Services and Functions.
  3. In the top navigation bar, select a region.
  4. On the Services page, click the desired service.
  5. On the Functions page, click Create Function.
    Create an HTTP function whose runtime environment is Python 3. For more information, see Create a function.
  6. Enter the preceding sample code in the editor on an on-premises machine, run pip install flask -t . on the client to install Flask, and then package your code as a ZIP file.
    Notice In the preceding sample code, the handler is the handler method in index.py. If the handler configurations of your function are different, use your actual handler configurations.
  7. On the Function Details page, click Upload Code and upload the ZIP file as prompted.
  8. Click Test Function.
    View the response. If the Web App with Python Flask! message appears, the function is executed.

HTTP request struct (environ)

The HTTP request struct is used to store information about HTTP requests. The request struct is of the Python dictionary structure. The following table describes the common parameters that are contained in the request struct. For more information about the request struct, see environ Variables.

Parameter Type Description
REQUEST_METHOD String The HTTP request method, such as GET or POST.
HTTP_Variables String The variables corresponding to the client-supplied HTTP request headers.
CONTENT_TYPE String The type of the HTTP request body.
CONTENT_LENGTH String The length of the HTTP request body.
REMOTE_ADDR String The IP addresses of the client.
wsgi.input BytesIO The HTTP request body.
fc.request_uri String The URL of the client request. The URL is defined by Function Compute.
fc.context FCContext The context. The context is defined by Function Compute.
Note The HTTP_Variables parameter in the request struct (environ) is an HTTP request header in which the key is processed as key="HTTP_"+k.upper().replace("-","_") based on the WSGI specification. For example, if the request header is 'x-Custom-key':'value', the HTTP_Variables parameter in the request struct is represented as environ['HTTP_X_CUSTOM_KEY']='value'.

The following sample code shows how to obtain the request struct of an HTTP handler.

# Method 1: User provide the function. FC call the function to process request and send back response.

HELLO_WORLD = b"Hello world!\n"

def handler(environ, start_response):
    context = environ['fc.context']
    request_uri = environ['fc.request_uri']
    for k, v in environ.items():
        if k.startswith("HTTP_"):
            # process custom request headers
            pass

    # get request_body
    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        request_body_size = 0
    request_body = environ['wsgi.input'].read(request_body_size)

    # get request_method
    request_method = environ['REQUEST_METHOD']

    # get path info
    path_info = environ['PATH_INFO']

    # get server_protocol
    server_protocol = environ['SERVER_PROTOCOL']

    # get content_type
    try:
        content_type = environ['CONTENT_TYPE']
    except (KeyError):
        content_type = " "

    # get query_string
    try:
        query_string = environ['QUERY_STRING']
    except (KeyError):
        query_string = " "

    print ('request_body: {}'.format(request_body))
    print ('method: {}\n path: {}\n  query_string: {}\n server_protocol: {}\n'.format(request_method, path_info,  query_string, server_protocol))
    # do something here

    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    # return value must be iterable
    return [HELLO_WORLD]

HTTP response struct

The response struct of an HTTP handler contains the response status, response header, and response body. Before the application returns the response body, you must invoke the start_response() function to return the values of status and headers to the server. The response body must be an iterative object.

start_response is a callable. The following code provides an example structure of start_response. For more information about start_response, see The start_response() Callable.

# Provided by FC runtime.
# status: a string like '200 OK' or '403 FORBIDDEN'
# return: must be a write(body_data) callable
def start_response(status, response_headers, exc_info=None):
...

The following table describes the parameters that are contained in the HTTP response struct.

Parameter Type Description
status String The HTTP response status code.
response_headers List The HTTP response headers.
exc_info List The exception information in the tuple format that the server needs to return to the client. This parameter is not used in Function Compute.

Limits

  • Request limits

    If a request exceeds one of the following limits, the system returns status code 400 and error InvalidArgument.

    Field Description HTTP status code Error code
    headers The total size of the keys and values in the request headers cannot exceed 4 KB. 400 InvalidArgument
    path The total size of the request path and query parameters cannot exceed 4 KB.
    body The size of the HTTP request body cannot exceed 16 MB.
  • Response limits

    If a response exceeds one of the following limits, the system returns status code 502 and error BadResponse.

    Field Description HTTP status code Error code
    headers The total size of the keys and values in the response headers cannot exceed 4 KB. 502 BadResponse