Explore Alibaba Cloud Function Compute for DevOps using Python 3.0

In this article, we will explore ** Alibaba Cloud Function Compute for DevOps ** using a sample program using ** Python 3.0 **.

Alibaba Cloud Tech Share Author, John Hanley. Tech Share is an Alibaba Cloud incentive program that encourages sharing of technical knowledge and best practices within the cloud community.

Alibaba Cloud Function Compute (https://www.alibabacloud.com/product/function-compute?spm=a2c65.11461447.0.0.78f37ef6H54oV8) is an event-driven serverless computing platform that allows developers to build and deploy services without having to manage their infrastructure. It seamlessly handles resource management, autoscaling, and load balancing, allowing you to focus on your business logic and speed up development. You can also set various event sources from other Alibaba services to trigger the code to execute automatically. The main advantage is that you only have to pay the resources that your code actually consumes in 100ms.

API Gateway is a managed service that makes it easy to expose secure APIs on a large scale. API Gateway provides interfaces with many services such as ECS, Function Compute, and web applications. API Gateway also integrates with DNS services to provide domain name-based APIs.

In today's article, I would like to explore Alibaba Cloud Function Compute for DevOps using a sample program using Python 3. The ultimate goal is to combine API Gateway, Function Compute and Direct Mail to provide a suitable contact form for static websites hosted on OSS.

Function Compute interface

There are several ways to execute code in Function Compute. You can "invoke" a function via the SDK, via API Gateway, or through Triggers. The definition of a function depends on which service calls your function. This article covers two different calling styles. The first is the HTTP trigger method and the second is the API Gateway method. The function definition is for Python. See here for Python functions.

In the function definition of an HTTP trigger, you need to know what an HTTP trigger is. An HTTP trigger is a URL that you assign to a function in the Function Compute console, and you can call the function. The URL looks like this:

https://1234567891234567.ap-southeast-1.fc.aliyuncs.com/2016-08-15/proxy/service_name/function_name/

Function definition when called by HTTP trigger

def my_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

    # do something here

    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return ["Hello World"]
item Description and usage
Function name my_handler is the function of the created function"Handler "Must correspond to the field. For example, when creating a function, Handler is main.my_If set to handler, Function Compute will automatically main.my defined in py_Load the handler function.
environ The environ parameter holds all client related informationPythonItisadictionary.DetailisenvironparameterPlease refer to the page.
start_response start_response parameterIs callable. Details start_See the response parameters page. It is provided by the FC runtime. Accepts the two required positional parameters and optional parameters.
Return value When the function returns, it must return the result to the calling server. The HTTP response must include the HTTP status, HTTP headers, and HTTP body. So before the function returns the HTML body as the return value, start_response()You need to call to return the HTTP status and the contents of the HTTP headers to the server. This function returns an HTML body.

Function definition when called from Invoke API or API Gateway

def my_handler(event, context):
    body = 'hello world'
    res = {
        'isBase64Encoded': False,
        'statusCode': 200,
        'headers': {
            'content-type' : 'text/plain'
        },
        'body': body
    }

    return json.dumps(res)
item Description and usage
Function name my_handler is the function of the created function"Handler "Must correspond to the field. For example, when creating a function, Handler is main.my_If set to handler, Function Compute will automatically main.my defined in py_Load the handler function.
Event parameters Event parametersは、関数呼び出しに渡されるデータです。Function Computeは変換を行わず、ユーザ関数に値を渡すだけです。パラメータの型はPython2.7 is str, Python 3 is bytes.
Context parameters Context parametersには、関数の操作情報(リクエストIDや一時的なAccesskeyなど)が含まれています。パラメータはFCContext型です。Pythonガイドの項では、コンテキストの構造や使い方を説明しています。
Return value 関数のReturn valueは、関数を呼び出した結果として返されます。どのような型であっても構いません。単純な型の場合、Function Computeは結果を返す前に文字列に変換します。複雑な型の場合、Function Computeは結果を返す前にJSON文字列に変換します。

Example program that returns the parameter "environ" in HTML

This example is an example of a function called by an HTTP trigger (HTTP URL).

Download the Sample Program for uploading to Function Compute.

Display the output produced by this program. Please note that some of the data is masked for security reasons.

############################################################
# Version 1.01
# Date Created: 2018-05-25
# Last Update:  2018-05-29
# https://www.neoprime.io
# Copyright (c) 2018, NeoPrime, LLC
############################################################

""" Alibaba Cloud Function Compute Example """
""" This program will return the environment back to the caller as an HTML table """
""" This is useful to learn about the running environment in Function Compute """
""" This code is designed to be called thru HTTP URL via an HTTP Trigger """

def handler(environ, start_response):
    body = '<!DOCTYPE html>\n<html lang="en"><head>\n'
    body = body + '<style>\n'
    body = body + 'table, th, td {border: 1px solid black;}\n'
    body = body + 'table {border-collapse: collapse;}\n'
    body = body + 'th, td {border: 1px solid #ddd; padding 8px;}\n'
    body = body + 'th {padding-top: 12px; padding-bottom: 12px;\n'
    body = body + 'text-align: left; background-color: #4CAF50;color: white;}\n'
    body = body + 'tr:nth-child(even){background-color: #f2f2f2;}\n'
    body = body + 'tr:hover {background-color: #ddd;}\n'
    body = body + '</style>\n'
    body = body + '</head>\n<body><table width="%100%">\n'
    body = body + "<thead>\n<tr><th>Name</th><th>Type</th><th>Value</th></tr>\n</thead>\n"
    body = body + "<tbody>\n"

    for k, v in environ.items():
      body = body + "<tr>"
      body = body + "<td>" + k + "</td>"
      body = body + "<td>" + type(v).__name__ + "</td>"
      if isinstance(v, bool):
        body = body + "<td>" + str(v) + "</td>"
      if isinstance(v, str):
        body = body + "<td>" + v + "</td>"
      if isinstance(v, tuple):
        body = body + "<td>" + str(v) + "</td>"
      if isinstance(v, type):
        body = body + "<td>" + str(v) + "</td>"
      body = body + "</tr>\n"

    body = body + "</tbody>\n</table>\n</body></html>"
    status = '200 OK'
    response_headers = [('Content-type', 'text/html')]
    start_response(status, response_headers)
    return [bytes(body, "utf-8")]

Example program that returns the parameter "context" in HTML

This example is for a function called from API Gateway.

Download the Sample Program (https://alicloud-common.oss-ap-southeast-1.aliyuncs.com/fc_context.zip?spm=a2c65.11461447.0.0.78f37ef6H54oV8&file=fc_context.zip) and upload it to Function Compute.

Display the output produced by this program. Please note that some of the data is masked for security reasons.

############################################################
# Version 1.01
# Date Created: 2018-05-25
# Last Update:  2018-05-29
# https://www.neoprime.io
# Copyright (c) 2018, NeoPrime, LLC
############################################################

""" Alibaba Cloud Function Compute Example """
""" This program will return the environment back to the caller as an HTML table """
""" This is useful to learn about the running environment in Function Compute """
""" This code is designed to be called thru API Gateway using an HTTP URL """

import json

# Add a row to the HTML table
def add_row(body, name, value):
    """ body - the current HTML body string that we append to """
    """ name - the name of the item. Added to the first column """
    """ value - the value to add. The type is added to the second column, value to the third """
    """ returns body """

    # begin a new table row
    body = body + '<tr>\n'
    body = body + '<td>' + name + '</td>\n'
    body = body + '<td>' + type(value).__name__ + '</td>\n'

    if isinstance(value, str):
        # Keep the string length less than 85 characters
        v = (value[:85] + ' ...') if len(value) > 85 else value
        body = body + '<td>' + v + '</td>\n'
    else:
        body = body + '<td>' + str(value) + '</td>\n'

    return body + '</tr>\n'

# Add a "dict" item to the table by parsing thru each item in the dictionary
def add_dict(body, name, item):
    """ body - the current HTML body string that we append to """
    """ name - the name of the item. """
    """ item - The item to process """
    for k in item:
        if isinstance(item[k], dict):
            body = add_dict(body, name + "." + k, item[k])
        else:
            body = add_row(body, name + "." + k, item[k])
    return body

def add_event(body, event):
    j = json.loads(event.decode("utf-8"))
    return add_dict(body, "event", j)

def add_context(body, context):
    body = add_row(body, 'context.request_id', context.request_id)
    body = add_row(body, 'context.region', context.region)
    body = add_row(body, 'context.account_id', context.account_id)
    body = add_row(body, 'context.function.handler', context.function.handler)
    body = add_row(body, 'context.function.memory', context.function.memory)
    body = add_row(body, 'context.function.name', context.function.name)
    body = add_row(body, 'context.function.timeout', context.function.timeout)
    body = add_row(body, 'context.credentials.accessKeyId', context.credentials.accessKeyId)
    body = add_row(body, 'context.credentials.accessKeySecret', context.credentials.accessKeySecret)
    body = add_row(body, 'context.credentials.access_key_id', context.credentials.access_key_id)
    body = add_row(body, 'context.credentials.access_key_secret', context.credentials.access_key_secret)
    body = add_row(body, 'context.credentials.securityToken', context.credentials.securityToken)
    body = add_row(body, 'context.credentials.security_token', context.credentials.security_token)
    body = add_row(body, 'context.service.log_project', context.service.log_project)
    body = add_row(body, 'context.service.log_store', context.service.log_store)

    return body

def build_html(body, event, context):
    body = '<!DOCTYPE html>\n<html lang="en"><head>\n'
    body = body + '<style>\n'
    body = body + 'table, th, td {border: 1px solid black;}\n'
    body = body + 'table {border-collapse: collapse;}\n'
    body = body + 'th, td {border: 1px solid #ddd; padding 8px;}\n'
    body = body + 'th {padding-top: 12px; padding-bottom: 12px;\n'
    body = body + 'text-align: left; background-color: #4CAF50;color: white;}\n'
    body = body + 'tr:nth-child(even){background-color: #f2f2f2;}\n'
    body = body + 'tr:hover {background-color: #ddd;}\n'
    body = body + '</style>\n'
    body = body + '</head>\n<body><table width="100%">\n'
    body = body + '<thead>\n<tr><th>Name</th><th width="5%">Type</th><th>Value</th></tr>\n</thead>\n'
    body = body + '<tbody>\n'

    body = add_event(body, event)
    body = add_context(body, context)

    body = body + '</tbody>\n'
    body = body + '</table>\n</body></html>'

    return body

def handler(event, context):
    body = ""
    body = build_html(body, event, context)

    res = {
        'isBase64Encoded': False,
        'statusCode': 200,
        'headers': {
            'content-type' : 'text/html'
        },
        'body': body
    }

    return json.dumps(res)

In the sample program, you will be able to display the environment of the function and the parameters passed in the function call (either via HTTP or API Gateway).

In the next article, I'll write the DirectMail code using the signed REST API. In the next article, we will integrate HTML contact forms, API Gateway, Function Compute, and DirectMail into a serverless system to provide a website contact page. The website can be either a dynamic website on OSS or a static website.

Function Compute access key

This section describes how to securely manage Function Compute access keys. RAM roll. Roles allow you to create access keys through a role in Alibaba Console and assign that role to the Function Compute service. This will prevent you from needing the key in your source code. Role credentials are made available to the function via the context.credentials parameter.

In the Resource Access Management Console, create a role with the required permissions. Then assign this role to the Function Compute service. Each function located under this service is assigned this role.

Alibaba Documentation

Function Compute: Alibaba Function Compute Product Page Alibaba Function Compute Document Alibaba Function Compute Trigger

API Gateway: Alibaba API Gateway Product Page Alibaba API Gateway Documentation Install API Gateway SSL Certificate

Recommended Posts

Explore Alibaba Cloud Function Compute for DevOps using Python 3.0
Connect your SQL Server database to Alibaba Cloud Function Compute using Python
Installation of dependent libraries for Alibaba Cloud function calculation
Python #function 2 for super beginners
[Alibaba Cloud] Do something like SSI even with OSS / Function Compute
Build a game leaderboard on Alibaba cloud using Python and Redis
Using Cloud Storage from Python3 (Introduction)
[TouchDesigner] Tips for for statements using python
Python #len function for super beginners
Cloud DevOps Cookbook Part 4-Explore DevOps DirectMail in Python with REST API
[Python] Reasons for overriding using super ()
[Python] Multiplication table using for statement
Try using FireBase Cloud Firestore in Python for the time being
Notes for using OpenCV on Windows10 Python 3.8.3.
Python development environment for macOS using venv 2016
[50 counts] Key transmission using Python for Windows
[python, multiprocessing] Behavior for exceptions when using multiprocessing
Try using Python with Google Cloud Functions
Tips for using python + caffe with TSUBAME
Notes for using python (pydev) in eclipse
python function ①
[Python] function
python function ②
[Python] I tried substituting the function name for the function name
vprof --I tried using the profiler for Python
Python pandas: Search for DataFrame using regular expressions
Get note information using Evernote SDK for Python 3
Understand Python for Pepper development. -Python box self-made function-
Refined search for Pokemon race values using Python
Note for formatting numbers with python format function
Register / update / acquire using GAE (Python3) Cloud NDB.
Let's make a module for Python using SWIG