edit-icon download-icon

Python

Last Updated: Aug 07, 2018

Currently, Function Compute supports the Python 2.7 (runtime version 2.7) and Python 3.6 (runtime version 3).

Contents

This topic describes the following features of Python runtime environments:

Use the logging module

We recommend that you use the logging module to print logs. Logs printed in this mode contain information such as request ID, for you to easily locate relevant log entries when an error occurs.

The data that the function outputs to stdout is collected to the Logstore that is specified when the service is created. Data can be logged using the following methods:

  1. Enter the print command. In this mode, information is logged without being changed.

    1. def my_handler(event, context):
    2. print 'hello world'
    3. return 'done'

    After the preceding commands are run, the following output is displayed:

    1. message:hello world
  2. Use the logging module.

    In this mode, each log entry contains information such as the time, request ID, and log level.

    1. import logging
    2. def my_handler(event, context):
    3. logger = logging.getLogger()
    4. logger.info('hello world')
    5. return 'done'

    After the preceding commands are run, the following output is displayed:

    1. message:2017-07-05T05:13:35.920Z a72df088-f738-cee3-e0fe-323ad89118e5 [INFO] hello world

Use built-in modules

In addition to the standard logging module, the Python runtime environments for Function Compute provide other modules that users can access. Currently, the modules detailed in the following table are available.

Module Description Reference
oss2 2.3.3 OSS https://github.com/aliyun/aliyun-oss-python-sdk
tablestore 4.3.4 Table Store https://github.com/aliyun/aliyun-tablestore-python-sdk
aliyun-fc2 2.0.4 Function Compute https://github.com/aliyun/fc-python-sdk
aliyun-mns 1.1.5 MNS https://github.com/bowenpay/mns-python-sdk
aliyun-python-sdk-cdn 2.6.2 CDN https://github.com/aliyun/aliyun-openapi-python-sdk/tree/master/aliyun-python-sdk-cdn
aliyun-python-sdk-ram 3.0.0 RAM https://github.com/aliyun/aliyun-openapi-python-sdk/tree/master/aliyun-python-sdk-ram
aliyun-python-sdk-sts 3.0.0 STS https://github.com/aliyun/aliyun-openapi-python-sdk/tree/master/aliyun-python-sdk-sts py
aliyun-log-python-sdk 0.6.24 Log Service https://github.com/aliyun/aliyun-log-python-sdk
wand 0.4.4 Image processing library http://docs.wand-py.org/en/0.4.4/
opencv 3.3.0.10 OpenCV http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_intro/py_intro.html
numpy 1.13.3 Scientific computing library http://www.numpy.org/
scipy 1.0.0 Scientific computing library https://www.scipy.org/
matplotlib 2.0.2 Drawing library https://matplotlib.org/
scrapy 1.4.0 Data capture library https://scrapy.org/

The following example uses wand to rotate an image:

  1. from wand.image import Image
  2. def my_handler(event, context):
  3. with Image(blob=event) as img:
  4. print img.size
  5. with img.clone() as i:
  6. i.rotate(180)
  7. return i.make_blob()

The event parameter in the preceding function is used as the binary data of an image. The image generated subsequently is also returned in the form of binary data. For demonstrations of other third-party libraries, see fc-python-demo.

Use custom modules

If you must use a custom module, the module must be packaged with your code. For example, to add a module PyMySQL to access MySQL using the command-line tool fcli, follow these steps:

  1. Create a directory for storing code and the dependent module.

    1. mkdir /tmp/code
  2. Create a code file named main.py and save it to the /tmp/code directory. Enter pymysql in the code.

    1. import pymysql.cursors
    2. # Connect to the database
    3. connection = pymysql.connect(host='localhost',
    4. user='user',
    5. password='passwd',
    6. db='db',
    7. charset='utf8mb4',
    8. cursorclass=pymysql.cursors.DictCursor)
    9. def my_handler(event, context):
    10. with connection.cursor() as cursor:
    11. # Read a single record
    12. sql = "SELECT count(*) FROM `users`"
    13. cursor.execute(sql)
    14. result = cursor.fetchone()
    15. print(result)
    16. return result
  3. Install the dependency in the /tmp/code directory.

    1. cd /tmp/code
    2. pip install --install-option="--install-lib=$(pwd)" PyMySQL

    With pip install -t, all Python libraries that PyMySQL depends on are downloaded regardless of whether these libraries are installed. If the module version is not specified, we recommend that you use the install-option method for the installation. This method downloads only the Python libraries that do not exist in the local environment, which helps reduce the size of local third-party packages. In the following figure, the libraries outlined in red are not downloaded.

    py-install

    After the dependency is installed, the following information is displayed in the /tmp/code directory:

    1. ls -l /tmp/code
    2. drwxr-xr-x 9 rockuw staff 306 Jul 5 16:48 PyMySQL-0.7.11.dist-info
    3. -rw-r--r-- 1 rockuw staff 74 Jul 5 16:02 main.py
    4. drwxr-xr-x 26 rockuw staff 884 Jul 5 16:48 pymysql
  4. Use fcli to create and call a function.

    1. ./fcli shell
    2. mkf my-func -h main.my_handler --runtime python2.7 -d /tmp/code
    3. invk my-func

Note: If the dependency uses executable files or library files compiled from C, C++, or Go code, see sbox.

Use external commands

Your function may use external tools that are not developed in Python. For example, your function may use shell scripts or executable files compiled from C++ or Go code. In this case, you can still pack them with the code and then use them by running external commands in the functions. The following example demonstrates how to run a shell script:

  1. import os
  2. import subprocess
  3. def my_handler(event, context):
  4. script_path = os.environ.get('FC_FUNC_CODE_PATH') + '/script.sh'
  5. ret = subprocess.check_output(['bash', script_path])
  6. return ret

Note: Executable files compiled from C, C++, or Go code must be compatible with the runtime environment of Function Compute. The following Python runtime environments are supported in Function Compute:
  • Linux kernel: Linux 4.4.24-2.al7.x86_64
  • Docker base image: Docker Pull Python: 2.7; Docker Pull Python: 3.6

We recommend that the sbox command be used on fcli. The following example installs mysql-python with .so files in the runtime environment Python 2.7:

  1. Enter the sbox -d code -t python2.7 command. In the command, -d indicates the directory where code is stored. In this example, the code is saved to the “/code” directory. The -t parameter specifies the language. Note that when this command is run for the first time, the PULL operation must be performed on images, which may extend the process time.

  2. Access the sandbox environment and enter the pip install -t . mysql-python command to install the dependent library.

  3. Enter the exit command to exit the sandbox environment. In this case, the mysql-python library containing the _mysql.so file has been installed in the /code directory.

Notes:

  1. To make the sbox command take effect, make sure that Docker has been installed. For more information about how to install Docker, see Docker installation.

  2. Images required for running the sbox command are stored in Docker’s official repositories. If the image download is slow, we recommend that you use Alibaba Cloud Container Service. For more information, see Related documents.

  3. Only root users can run Docker in the Linux operating system. Therefore, run the sudo fcli shell command to enable fcli. Alternatively, you can configure the Linux host according to related documents and manage Docker as a non-root user.

  4. We recommend that you use a sandbox environment to package third-party libraries, test functions, and troubleshoot. This prevents problems caused by inconsistencies between the development environment and runtime environment. In particular, when your functions depend on binary files, compile relevant dependencies in the sandbox environment.

    1. songluo@demo $ fcli shell
    2. Welcome to the Function Compute world. Have fun!
    3. >>> sbox -d code -t python2.7
    4. Entering the container. Your code is in the /code direcotry.
    5. root@c5adc6ffd861:/code# pip install -t . mysql-python
    6. Collecting mysql-python
    7. Downloading MySQL-python-1.2.5.zip (108kB)
    8. 100% |████████████████████████████████| 112kB 440kB/s
    9. Building wheels for collected packages: mysql-python
    10. Running setup.py bdist_wheel for mysql-python ... done
    11. Stored in directory: /root/.cache/pip/wheels/38/a3/89/ec87e092cfb38450fc91a62562055231deb0049a029054dc62
    12. Successfully built mysql-python
    13. Installing collected packages: mysql-python
    14. Successfully installed mysql-python-1.2.5
    15. root@c5adc6ffd861:/code# exit

If your dependencies include dynamic link library files, such as .so files, place these files in the lib folder. The runtime environment of Function Compute adds the lib directory to the path variable.

Handle exceptions

If an exception occurs when a function is executed, Function Compute captures the exception and returns the error message to the host. For example, if the following code is written:

  1. def my_handler(event, context):
  2. raise Exception('something is wrong')

The following response is returned:

  1. {
  2. "errorMessage": "something is wrong",
  3. "errorType": "Exception",
  4. "stackTrace": [
  5. [
  6. "File \"/code/main.py\"",
  7. "line 2",
  8. "in my_handler",
  9. "raise Exception('something is wrong')"
  10. ]
  11. ]
  12. }

If an exception occurs, the HTTP header of the response called by the function contains the X-Fc-Error-Type: UnhandledInvocationError information. For more information about error types in Function Compute, see Error message.

Thank you! We've received your feedback.