全部产品
云市场

Python 运行环境

更新时间:2020-03-25 10:20:32

函数计算目前支持以下 Python 运行环境:

  • Python 2.7 ( runtime = python2.7 )
  • Python 3.6 ( runtime = python3 )

本文介绍了 Python 运行环境的以下内容:

打印日志

函数向 stdout 打印的内容会被收集到创建服务时指定的 Logstore 中,在这里有两种打印日志的方法:

  • 使用 logging 模块,这样在每条日志中都包含时间、requestId、日志级别等信息。

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

    执行上面的代码输出的日志内容如下所示。

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

    说明:在这里推荐使用 logging 模块打印日志,因为这样可以自动包含 requestId 信息,方便在出错的时候定位问题日志。

  • 直接使用print,把内容原样地输出到日志中。

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

    执行上面的代码输出的日志内容如下所示。

    1. message:hello world

错误处理

函数在执行过程如果抛出异常,那么函数计算会把异常捕获并将异常信息返回,示例如下所示。

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

调用函数时收到的响应如下所示。

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

发生异常时,函数调用的响应的 HTTP header 中会包含 X-Fc-Error-Type: UnhandledInvocationError。函数计算的错误类型的更多信息,请参见错误类型

使用内置模块

除了 Python 的标准模块,函数计算的 Python 运行环境中还包含了一些常用模块,您可以直接引用,目前包含的模块如下所示。

模块名称 模块介绍 相关链接
oss2 2.6.0 OSS SDK https://github.com/aliyun/aliyun-oss-python-sdk
tablestore 4.6.0 表格存储 SDK https://github.com/aliyun/aliyun-tablestore-python-sdk
aliyun-fc2 2.1.0 函数计算 SDK https://github.com/aliyun/fc-python-sdk
aliyun-python-sdk-ecs 4.10.1 云服务器 SDK https://github.com/aliyun/aliyun-openapi-python-sdk/tree/master/aliyun-python-sdk-ecs
aliyun-python-sdk-vpc 3.0.2 专用网络 SDK https://github.com/aliyun/aliyun-openapi-python-sdk/tree/master/aliyun-python-sdk-vpc
aliyun-python-sdk-rds 2.1.4 云数据库 SDK https://github.com/aliyun/aliyun-openapi-python-sdk/tree/master/aliyun-python-sdk-rds
aliyun-python-sdk-kms 2.5.0 密钥管理服务 SDK https://github.com/aliyun/aliyun-openapi-python-sdk/tree/master/aliyun-python-sdk-kms
pydatahub 2.11.2 DataHub SDK https://github.com/aliyun/aliyun-datahub-sdk-python
aliyun-mns 1.1.5 消息服务 https://github.com/gikoluo/aliyun-mns
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
aliyun-python-sdk-iot 7.8.0 物联网平台IOT https://github.com/aliyun/aliyun-openapi-python-sdk/tree/master/aliyun-python-sdk-iot
aliyun-log-python-sdk 0.6.38 日志服务 SLS https://github.com/aliyun/aliyun-log-python-sdk
wand 0.4.4 图片处理库 http://docs.wand-py.org/en/0.4.4/
opencv 3.3.0.10 计算机视觉库 http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_intro/py_intro.html
numpy 1.13.3 科学计算库 http://www.numpy.org/
scipy 1.0.0 科学计算库 https://www.scipy.org/
matplotlib 2.0.2 绘图库 https://matplotlib.org/
scrapy 1.4.0 数据抓取库 https://scrapy.org/

访问 OSS 的示例代码如下所示。

  1. 'use strict';
  2. var oss = require('ali-oss').Wrapper;
  3. module.exports.handler = function(event, context, callback) {
  4. var client = new oss({
  5. region: 'oss-cn-hangzhou',
  6. accessKeyId: 'xxx',
  7. accessKeySecret: 'xxx',
  8. bucket: 'Your-bucket-name'
  9. });
  10. client.list().then(function() {
  11. console.log('objects: %j', result.objects)
  12. callback()
  13. })
  14. }

注意:上文的函数直接使用 event 作为图片的二进制数据,并且直接把生成的图片作为二进制数据返回。

其他使用 Python 的第三方库的示例请参见 fc-python-demo

使用自定义模块

如果您需要使用自定义的模块,则需要将自定义模块与代码一起打包上传。您可以通过 pip 包管理器进行依赖管理,如果您使用 Fun 部署应用,可以使用 fun install 命令来安装依赖。

使用 pip 包管理器进行依赖管理

使用方法:

  • 通过 pip install -t . 命令安装依赖库至函数根目录下。
  • 上传代码库时将依赖库一同打包上传。

下文以安装 pymysql 库为例进行详细介绍。

1.建立一个目录,用于存放代码和依赖模块。

  1. mkdir /tmp/code

2.在 /tmp/code 目录下安装依赖。

  1. cd /tmp/code
  2. pip install -t . PyMySQL

3.新建代码文件,例如 /tmp/code/index.py,在代码中使用 pymysql

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

4.打包上传。

打包时,需要针对文件进行打包,而不是针对代码整体目录进行打包;打包完成后,入口函数文件需要位于包内的根目录。

  • 在 Windows 下打包时,可以进入函数代码目录,全选所有文件以后,单击鼠标右键,选择 压缩为 zip 包,生成代码包。

  • 在 Linux 下打包时,通过调用 zip 命令时,将源文件指定为代码目录下的所有文件,实现生成部署代码包,例如 zip code.zip /home/code/*

打包后,您通过函数计算控制台代码执行页面,您可以选择OSS 上传代码包上传方式上传代码包。

使用 fun install 安装依赖

如果您使用 Fun 部署应用,可以使用 fun install 命令来安装依赖。关于 fun install 的详细信息请参见 fun install 介绍

下文以安装 pymysql 库为例进行详细介绍。

  1. 在函数根目录下初始化 Funfile 文件。
  1. $ fun install init
  2. ? Select a runtime
  3. nodejs8
  4. nodejs10
  5. python2.7
  6. python3
  7. java8
  8. php7.2
  9. dotnetcore2.1
  10. (Move up and down to reveal more choices)

2.选择 python3 后,会在当前目录生成一个名为 Funfile 的文件,编辑文件内容。

  1. RUNTIME python3
  2. RUN fun-install pip install PyMySQL

3.新建 template.yml 文件,例如 /tmp/code/template.yml,内容如下。

  1. ROSTemplateFormatVersion: '2015-09-01'
  2. Transform: 'Aliyun::Serverless-2018-04-03'
  3. Resources:
  4. FunDemo:
  5. Type: 'Aliyun::Serverless::Service'
  6. pythondemo:
  7. Type: 'Aliyun::Serverless::Function'
  8. Properties:
  9. Handler: index.handler
  10. Runtime: python3
  11. CodeUri: './'

这个 template.yml 的含义如下:声明名为 FunDemo 的服务,在这个服务下,声明一个名为 pythondemo 的函数,配置函数入口为 index.handler ,函数的 runtime 为 python3,并指定 CodeUri 为当前目录。在部署时,Fun 会将 CodeUri 指定的目录打包上传。更多的配置规则请参见 Serverless Application Model

4.在函数根目录下执行 fun install 命令安装依赖。

  1. $ fun install
  2. using template: template.yml
  3. start installing function dependencies without docker
  4. building FunDemo/pythondemo
  5. Funfile exist, Fun will use container to build forcely
  6. Step 1/2 : FROM registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-python3.6:build-1.9.4
  7. ---> 702c91653452
  8. Step 2/2 : RUN fun-install pip install PyMySQL
  9. ---> Using cache
  10. ---> 8f59062f15bb
  11. sha256:8f59062f15bb7a86bd59b85e3b61bd0e4ed711c536fe0cd10fdefebc78eae152
  12. Successfully built 8f59062f15bb
  13. Successfully tagged fun-cache-a6f4221c-33c8-4050-93b8-015e42396475:latest
  14. copying function artifact to /Users/txd123/Desktop/express
  15. Install Success
  16. Tips for next step
  17. ======================
  18. * Invoke Event Function: fun local invoke
  19. * Invoke Http Function: fun local start
  20. * Build Http Function: fun build
  21. * Deploy Resources: fun deploy

5.使用 Fun 部署。

  1. fun deploy -y

执行成功时,会看到相关日志。

  1. $ fun deploy -y
  2. using template: template.yml
  3. using region: cn-hangzhou
  4. using accountId: ***********3743
  5. using accessKeyId: ***********Ptgk
  6. using timeout: 60
  7. Collecting your services information, in order to caculate devlopment changes...
  8. Resources Changes(Beta version! Only FC resources changes will be displayed):
  9. ┌────────────┬──────────────────────────────┬────────┬──────────┐
  10. Resource ResourceType Action Property
  11. ├────────────┼──────────────────────────────┼────────┼──────────┤
  12. Handler
  13. ├──────────┤
  14. pythondemo Aliyun::Serverless::Function Add Runtime
  15. ├──────────┤
  16. CodeUri
  17. └────────────┴──────────────────────────────┴────────┴──────────┘
  18. Waiting for service FunDemo to be deployed...
  19. Waiting for function pythondemo to be deployed...
  20. Waiting for packaging function pythondemo code...
  21. The function pythondemo has been packaged. A total of 51 files were compressed and the final size was 114.35 KB
  22. function pythondemo deploy success
  23. service FunDemo deploy success

登录函数计算控制台,即可看到相关的服务、函数被创建成功,且触发执行可以返回正确的结果。

调用外部命令

您的函数可能会用到一些工具,而这些工具并不是用 Python 写的(例如 Shell、C++ 、Go 编译出来的可执行文件)。您仍然可以将这些工具与代码一起打包,然后在函数中通过运行外部命令的方法来使用这些工具。

注意:使用 C 、 C++ 、Go 编译出来的可执行文件,需要与函数计算的运行环境兼容。函数计算的 Node.js 运行环境如下所示。

  • Linux 内核版本:Linux 4.4.24-2.al7.x86_64。-
  • Docker 基础镜像:docker pull python:2.7 ; docker pull python:3.6。

您可以使用 Fun 工具安装依赖,下文以 runtime 为 python2.7,安装 mysql-python (含有 .so 文件)为例。

可以直接在代码目录执行 fun install --runtime python2.7 --package-type pip mysql-python 命令 ,即可安装好依赖。

注意

  • 第一次执行这个命令由于要拉取镜像,可能要耗费不少时间,请耐心等待。

  • 依赖(含有 mysql.so)会被装在 .fun 目录下,只需要在 template.yml 中通过 CodeUri 属性配置将 .fun 以及代码包含进来就可以了。

下面的代码演示了如何运行一个 Shell 脚本。

  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