You can use HTTP handlers to efficiently process HTTP requests. When a function is invoked, Function Compute uses the handler that you specify to process the HTTP request. 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 an HTTP trigger that invokes a function with HTTP requests.
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 atreturn '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 thehandler
function asreturn app(environ, start_response)
.
Before you start
Procedure
Log on to the Function Compute console. In the left-side navigation pane, click Services & Functions.
In the top navigation bar, select a region. On the Services page, click the desired service.
On the Functions page, click Create Function.
Create an HTTP function whose runtime environment is Python 3. For more information, see Create a function.
On the Function Details page, click the Code tab and enter the preceding sample code in the code editor. Then, choose
pip install flask -t .
in the TERMINAL code editor. Install the Flask library in the current directory and click Deploy. . RunClick 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 address 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. |
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 sample 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 items describe the parameters:
Parameter | Type | Description |
status | String | The HTTP response status. |
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 8 KB.
400
InvalidArgument
path
The total size of the request path and query parameters cannot exceed 4 KB.
body
The total size of the body of a synchronous invocation request cannot exceed 32 MB. The total size of the body of an asynchronous invocation request cannot exceed 128 KB.
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 8 KB.
502
BadResponse