Updated on 2023-07-06 GMT+08:00

Dependency Management

Introduction

Generally, the code of a function consists of public libraries and service logic. The public libraries can be packaged as a dependency and shared among functions, reducing the size of the function code package for easy deployment and update.

FunctionGraph also provides some public dependencies, which are cached internally for quick loading. These dependencies are recommended.

FunctionGraph enables you to manage dependencies in a unified manner. You can upload dependencies from a local path, or through OBS if they are too large, and specify names for them. Dependencies can be iterated. Each dependency can have multiple versions.

For details, see "How Do I Create Function Dependencies?"

  • The name of each file in the dependency package cannot end with a tilde (~).
  • A dependency package can contain up to 30,000 files.
  • If your function uses a large private dependency, increase the execution timeout by choosing Configuration > Basic Settings on the function details page.

Creating a Dependency

  1. Log in to the FunctionGraph console, and choose Functions > Dependencies in the navigation pane.
  2. Click Create Dependency.
  3. Set the following parameters:

    Table 1 Dependency configuration parameters

    Parameter

    Description

    Name

    Dependency name.

    Upload Mode

    Upload a ZIP file directly or upload a file from OBS.

    • Upload ZIP file: Click Select File to upload one.
    • Upload file from OBS: Specify an OBS link URL.

    Runtime

    Select a runtime.

    Description

    Description of the dependency. This parameter is optional.

  4. Click OK. By default, a new dependency is version 1.
  5. Click the dependency name, and view all versions and related information on the displayed page. Each dependency can have multiple versions.

    • To create a dependency version, click Create Version in the upper right corner of the page.
    • To view the address of a version, click the version.
    • To delete a version, click the delete icon in the same row.

Configuring Dependencies for a Function

  1. Log in to the FunctionGraph console, and choose Functions > Function List in the navigation pane.
  2. Click the name of the desired function.
  3. On the displayed function details page, click the Code tab, click Add in the Dependencies area.
  4. On the displayed Select Dependency dialog box, select dependencies and click OK.

    Table 2 Dependency configuration

    Parameter

    Description

    Runtime

    Runtime of this function. It cannot be changed.

    Type

    Add a Public or Private dependency.

    Name

    Select a dependency.

    Version

    Select a version to be added.

    • You can add a maximum of 20 dependencies for a function.
    • Except your private dependencies, FunctionGraph provides some public dependencies, which you can choose when creating a function.

Deleting a Dependency

To delete a dependency, just delete all of its versions.

  1. Log in to the FunctionGraph console, and choose Functions > Dependencies in the navigation pane.
  2. Click the name of the target dependency to go to the Versions page.
  3. Click the delete icon in the row of a version. Repeat this operation if the dependency has multiple versions.

    Figure 1 Deleting a dependency version

    Dependencies referenced by functions cannot be deleted.

Dependent Libraries

Supported Dependent Libraries

FunctionGraph supports both standard and third-party libraries.

  • Standard libraries

    When using standard libraries, you can import them to your inline code or package and upload them to FunctionGraph.

  • Supported non-standard libraries

    FunctionGraph provides built-in third-party components listed in Table 3 and Table 4. You can import these libraries to your inline code in the same way as you import standard libraries.

    Table 3 Third-party components integrated with the Node.js runtime

    Name

    Usage

    Version

    q

    Asynchronous method encapsulation

    1.5.1

    co

    Asynchronous process control

    4.6.0

    lodash

    Common tool and method library

    4.17.10

    esdk-obs-nodejs

    OBS SDK

    2.1.5

    express

    Simplified web-based application development framework

    4.16.4

    fgs-express

    Provides a Node.js application framework for FunctionGraph and API Gateway to run serverless applications and REST APIs. This component provides an example of using the Express framework to build serverless web applications or services and RESTful APIs.

    1.0.1

    request

    Simplifies HTTP invocation and supports HTTPS and redirection.

    2.88.0

    Table 4 Non-standard libraries supported by the Python runtime

    Module

    Usage

    Version

    dateutil

    Date and time processing

    2.6.0

    requests

    HTTP library

    2.7.0

    httplib2

    HTTP client

    0.10.3

    numpy

    Mathematical computing

    1.13.1

    redis

    Redis client

    2.10.5

    obsclient

    OBS client

    -

    smnsdk

    SMN access

    1.0.1

  • Other third-party libraries (FunctionGraph has no built-in non-standard third-party libraries except those listed in the preceding table.)

    Package the dependency third-party libraries and upload them to an OBS bucket or on the function details page. For details, see Creating a Dependency. These libraries will then be used in your function code.

Importing Dependent Libraries

The code for processing images is as follows:

# -*- coding: utf-8 -*-
from PIL import Image, ImageEnhance

from com.obs.client.obs_client import ObsClient

import sys
import os

current_file_path = os.path.dirname(os.path.realpath(__file__))
# append current path to search paths, so that we can import some third party libraries.
sys.path.append(current_file_path)
region = 'your region'
obs_server = 'obs.xxxxxxcloud.com'
def newObsClient(context):
    ak = context.getAccessKey()
    sk = context.getSecretKey()
    return ObsClient(access_key_id=ak, secret_access_key=sk, server=obs_server,
                     path_style=True, region=region, ssl_verify=False, max_retry_count=5, timeout=20)
def downloadFile(obsClient, bucket, objName, localFile):
    resp = obsClient.getObject(bucket, objName, localFile)
    if resp.status < 300:
        print 'download file', file, 'succeed'
    else:
        print('download failed, errorCode: %s, errorMessage: %s, requestId: %s' % resp.errorCode, resp.errorMessage,
              resp.requestId)
def uploadFileToObs(client, bucket, objName, file):
    resp = client.putFile(bucket, objName, file)
    if resp.status < 300:
        print 'upload file', file, 'succeed'
    else:
        print('upload failed, errorCode: %s, errorMessage: %s, requestId: %s' % resp.errorCode, resp.errorMessage,
              resp.requestId)
def getObjInfoFromObsEvent(event):
    s3 = event['Records'][0]['s3']
    eventName = event['Records'][0]['eventName']
    bucket = s3['bucket']['name']
    objName = s3['object']['key']
    print "*** obsEventName: %s, srcBucketName: %s, objName: %s", eventName, bucket, objName
    return bucket, objName
def set_opacity(im, opacity):
    """Set the transparency."""
    if im.mode != "RGBA":
        im = im.convert('RGBA')
    else:
        im = im.copy()
    alpha = im.split()[3]
    alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
    im.putalpha(alpha)
    return im
def watermark(im, mark, opacity=0.6):
    """Add a watermark."""
    try:
        if opacity < 1:
            mark = set_opacity(mark, opacity)
        if im.mode != 'RGBA':
            im = im.convert('RGBA')
        if im.size[0] < mark.size[0] or im.size[1] < mark.size[1]:
            print "The mark image size is larger size than original image file."
            return False
        x = (im.size[0] - mark.size[0]) / 2
        y = (im.size[1] - mark.size[1]) / 2
        layer = Image.new('RGBA', im.size, )
        layer.paste(mark, (x, y))
        return Image.composite(layer, im, layer)
    except Exception as e:
        print ">>>>>>>>>>> WaterMark EXCEPTION:  " + str(e)
        return False
def watermark_image(localFile, fileName):
    im = Image.open(localFile)
    watermark_image_path = os.path.join(current_file_path, "watermark.png")
    mark = Image.open(watermark_image_path)
    out = watermark(im, mark)
    print "**********finish water mark"
    name = fileName.split('.')
    outFileName = name[0] + '-watermark.' + name[1]
    outFilePath = "/tmp/" + outFileName
    if out:
        out = out.convert('RGB')
        out.save(outFilePath)
    else:
        print "Sorry, Save watermarked file Failed."
    return outFileName, outFilePath
def handler(event, context):
    srcBucket, srcObjName = getObjInfoFromObsEvent(event)
    outputBucket = context.getUserData('obs_output_bucket')
    client = newObsClient(context)
    # download file uploaded by user from obs
    localFile = "/tmp/" + srcObjName
    downloadFile(client, srcBucket, srcObjName, localFile)
    outFileName, outFile = watermark_image(localFile, srcObjName)
    # Upload converted files to a new OBS bucket.
    uploadFileToObs(client, outputBucket, outFileName, outFile)
    return 'OK'

For standard libraries and supported non-standard libraries, you can directly use them in your function.

For non-standard third-party libraries that are not provided by FunctionGraph, you can use them by performing the following steps:

  1. Package the dependent libraries into a ZIP file, upload the ZIP file to an OBS bucket, and obtain the OBS link URL.
  2. Log in to the FunctionGraph console, and choose Functions > Dependencies in the navigation pane.
  3. Click Create Dependency.
  4. Set the dependency name and runtime, specify the OBS link URL, and click OK.
    Figure 2 Setting the dependency
  5. On the function details page, click the Code tab, click Add in the Dependencies area, select the dependency created in 4, and click OK.
    Figure 3 Selecting a dependency

    Each dependency package cannot contain a file with the same name as a code file. Otherwise, the two files may be incorrectly merged or overwritten. For example, if dependency package depends.zip contains a file named index.py, the handler of a function cannot be set to index.handler. Otherwise, a code file also named index.py will be generated.