阿里云函数计算为了降低开发者使用难度,推出了大量实用的模板供给用户使用,每个模板都提供一段业务示例逻辑代码,能降低用户使用门槛。下面来详细讲解基于对象存储的几个常用模板的使用方法和内容,更多模板详见!
引用步骤,进入函数计算控制台后,选择新建函数,在搜索框里填写OSS会自动检索出跟OSS相关的模板,目前系统内置了8个跟OSS相关的模板。
关于函数计算和OSS操作的模板,目前系统内置提供了8个模板,分别解决的问题有:把OSS数据同步备份到其他地方、获取对象的meta信息,获取OSS文件的MD5值、爬虫系统、图像识别、对OSS上的文件打包压缩、以及获取对象的详细信息等。今天讲解其中3个常用业务模板。
模板概述
阿里云函数计算模板主要包含三部分内容,模板详情描述、模板引用资源授权(部分不使用其他产品资源不需要授权)、模板示例代码。操作流程如下:
新建函数-》引用模板创建-》给模板引用的资源授权(选填,有些模板不需要引用外置的资源)-》获取代码示例。
模板一:get-oss-md5-python27(获取对象存储文件的MD5值)
通过该模板的示例代码,可以计算出对象存储(OSS)文件的MD5值,本示例的代码通过流式方式读取对象文件,计算的效率较高。基于数据访问安全考虑,需要授权某bucket给函数计算来使用,通过函数计算的引导页面可以完成。
模板详情:通过模板详情可以获取到模板的详细情况,例如输入参数,输出参数等。详细引用查看这里。模板详情里会包括示例说明,输入参数,输出参数,以及需要哪些授权等,下面的模板同。
附录几张界面截图:
模板授权:基于数据访问安全考虑,需要授权某bucket给函数计算来使用。
授权页面设置,本示例只需要选择某个Bucket授权即可。
代码详解:采用流式方式来读取文件的MD5值,其中creds = context.credentials是获取系统生成的临时AK来作为执行的认证。
# coding=utf-8
import json
import logging
from hashlib import md5
import oss2
# 函数服务主函数
def handler(event, context):
logger = logging.getLogger()
logger.info('start worker')
evt = json.loads(event)
endpoint = 'oss-{}-internal.aliyuncs.com'.format(context.region)
creds = context.credentials #获取系统生成的临时AK
auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token)
bucket_name = evt['bucket']
bucket = oss2.Bucket(auth, endpoint, bucket_name)
object_name = evt['object']
r = bucket.get_object(object_name)
m = md5()
while 1:
data = r.read(4096)
if not data:
break
m.update(data)
return m.hexdigest()
模板二:copy-oss-object-python27(同步备份OSS增量数据)
通过该模板的示例代码,可以把指定某个Bucket下的文件备份到其他资源,示例代码是备份到七牛存储上,也可以修改示例代码,把文件存储到本地硬盘或者某个服务上。对于大文件同步本示例文档对大文件备份做了优化,授权方式跟模板一介绍的一致,需要授权使用。
# -*- coding: utf-8 -*-
from qiniu import Auth, put_file, etag, urlsafe_base64_encode
import qiniu.config
import oss2
import json
def handler(event, context):
"""
Replicate the object from OSS to qiniu.
event: The OSS event json string. Including oss object uri and other information.
context: The function context, including credential and runtime info.
For detail info, please refer to https://help.aliyun.com/document_detail/56316.html#using-context
"""
evt_list = json.loads(event)
creds = context.credentials
auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token)
# Parse the event to get the source object info.
evt = evt_list['events'][0]
bucket_name = evt['oss']['bucket']['name']
endpoint = 'oss-' + evt['region'] + '.aliyuncs.com'
bucket = oss2.Bucket(auth, endpoint, bucket_name)
object_name = evt['oss']['object']['key']
# Download the oss object.
remote_stream = bucket.get_object(object_name)
if not remote_stream:
raise RuntimeError('failed to get oss object. bucket: %s. object: %s' % (bucket_name, object_name))
print 'download object from oss success: %s' % object_name
# replicate to qiniu
qiniu_ak_id = 'XXXX'
qiniu_ak_secret = 'XXXX'
qiniu_bucket_name = 'XXX'
q = Auth(qiniu_ak_id, qiniu_ak_secret)
qiniu_token = q.upload_token(qiniu_bucket_name, object_name, 1200)
ret, info = qiniu.put_data(qiniu_token, object_name, remote_stream)
if ret is None:
print info
else:
print 'replicate to qiniu success: %s' % object_name
# TODO: Verify the checksum
# TODO: Handle the error
模板三:oss-download-zip-upload(下载OSS对象并打压缩包)
通过该模板示例,您可以完成从OSS某个Bucket中下载图片,对图片进行打包(ZIP),并把打包后的ZIP文件上传到某Bucket中操作。注意该函数对应的Service的角色访问策略需要读写OSS的权限。
import os
import oss2
import zipfile
import shutil
import time
def handler(event, context):
creds = context.credentials
auth = oss2.StsAuth(creds.accessKeyId, creds.accessKeySecret, creds.securityToken)
bucket = oss2.Bucket(auth, 'your endpoint', 'your buecket name')
#your source list
sourceFile = ['resource/1.jpg','resource/2.jpg']
#zip name
uid = 'ZIP123456'
tmpdir = '/tmp/download/'
os.system("rm -rf /tmp/*")
os.mkdir(tmpdir)
#download
for name in sourceFile :
millis = int(round(time.time() * 1000))
bucket.get_object_to_file(name , tmpdir + str(millis) + '.jpg')
#zip file
zipname = '/tmp/'+uid + '.zip'
make_zip(tmpdir , zipname)
#upload
total_size = os.path.getsize(zipname)
part_size = oss2.determine_part_size(total_size, preferred_size = 128 * 1024)
key = uid + '.zip'
upload_id = bucket.init_multipart_upload(key).upload_id
with open(zipname, 'rb') as fileobj:
parts = []
part_number = 1
offset = 0
while offset < total_size:
num_to_upload = min(part_size, total_size - offset)
result = bucket.upload_part(key, upload_id, part_number,oss2.SizedFileAdapter(fileobj, num_to_upload))
parts.append(oss2.models.PartInfo(part_number, result.etag))
offset += num_to_upload
part_number += 1
bucket.complete_multipart_upload(key, upload_id, parts)
return total_size
def make_zip(source_dir, output_filename):
zipf = zipfile.ZipFile(output_filename, 'w')
pre_len = len(os.path.dirname(source_dir))
for parent, dirnames, filenames in os.walk(source_dir):
for filename in filenames:
pathfile = os.path.join(parent, filename)
arcname = pathfile[pre_len:].strip(os.path.sep)
zipf.write(pathfile, arcname)
zipf.close()