本文介绍Python HTTP函数的函数入口及部署框架。

函数入口

Python Runtime中函数的签名遵循WSGI(Python Web Server Gateway Interface)规范。您可以使用WSGI规范对请求进行处理。

入口函数

Python HTTP函数提供两种入口函数:

说明 以下示例以Python 3为例进行说明。
  • 入口函数一
    # 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]
  • 入口函数二
    # Method 2: User provide the callable class object. FC call the object to process request and send back response.
    
    HELLO_WORLD = b"Hello world!\n"
    
    class AppClass:    
        """Produce the same output, but using a class    
        """    
    
        def __init__(self, environ, start_response):        
            self.environ = environ        
            self.start = start_response    
    
        def __iter__(self):        
            status = '200 OK'        
            response_headers = [('Content-type', 'text/plain')]        
            self.start(status, response_headers)        
            yield HELLO_WORLD
    
    def handler(environ, start_response):    
        return AppClass(environ, start_response)

参数解释

  • environ:是一个Python字典,里面存放了所有和客户端相关的信息,详情请参见environ参数。函数计算增加了两个自定义的键,分别是fc.contextfc.request_uri
    • fc.context:和Python事件函数中的context参数意义相同。
    • fc.request_uri:请求的URL,格式为String。
      说明 environ中的HTTP_Variables里包含请求头,例如某个请求头是'x-Custom-key':'value' , 在environ中会表现为environ['HTTP_X_CUSTOM_KEY']='value',在这里WSGI对请求头中的键做了处理,处理方式为key = "HTTP_" + k.upper().replace("-","_")
  • start_response:是一个可调用者(Callable),具体介绍请参见the-start-response-callable

    start_response参数是函数计算Runtime提供的,包含两个必要的位置参数和一个可选参数。为方便说明,可以将他们命名为statusresponse_headersexc_info,代码示例如下所示。

    # 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):    
    ...
    • status:一个字符串,表示HTTP响应状态。
    • response_headers:一个列表,包含(header_name, header_value)形式的元组,表示HTTP响应头。
    • exc_info:可选。出错时,服务端需要返回给浏览器的信息。

当应用对象根据environ参数的内容执行完业务逻辑后,就需要把结果返回给服务端。HTTP响应需要包含响应状态,响应头和响应体,因此在应用对象将body作为返回值之返回前,需要先调用start_response() ,将statusheaders的内容返回给服务端,告知服务端应用对象要开始返回body了。

获取请求体

您可以直接使用WSGI获取raw body

示例代码如下所示。

# 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)

更多信息

从上述的入口函数二中,您可以看出利用Flask、Django等基于WSGI协议的前端框架构建的工程可以运行在函数计算的Python Runtime中。详情请参见部署基于Python WSGI Web框架的工程到函数计算