Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 如何在AmazonLinux环境中安装Python模块_Python 3.x_Aws Lambda_Mariadb_Aws Lambda Layers_Mariadb Connector C - Fatal编程技术网

Python 3.x 如何在AmazonLinux环境中安装Python模块

Python 3.x 如何在AmazonLinux环境中安装Python模块,python-3.x,aws-lambda,mariadb,aws-lambda-layers,mariadb-connector-c,Python 3.x,Aws Lambda,Mariadb,Aws Lambda Layers,Mariadb Connector C,我的目标是构建一个AWS Lambda层,为运行python 3.8的AWS Lambda提供mariadb模块 接下来,我需要在与AWS Lambda平台兼容的实例上安装mariadb模块。像这样安装模块 python3 -m pip install mariadb --target lambda-layer/python/lib/python3.8/site-packages 。。。失败并显示错误消息 mariadb_config not found. Please make sure,

我的目标是构建一个AWS Lambda层,为运行python 3.8的AWS Lambda提供mariadb模块

接下来,我需要在与AWS Lambda平台兼容的实例上安装mariadb模块。像这样安装模块

python3 -m pip install mariadb --target lambda-layer/python/lib/python3.8/site-packages
。。。失败并显示错误消息

mariadb_config not found.
Please make sure, that MariaDB Connector/C is installed on your system, edit the
configuration file 'site.cfg' and set the 'mariadb_config'
noption, which should point to the mariadb_config utility.
我需要什么来解决这个问题? 我假设安装“MariaDB连接器/C”是一项先决条件?但你是如何做到这一点的?如何将其打包成一个zip,用于定义AWS Lambda层

一些背景 我在一个Amazon实例上运行了这个,我相信它与Lamba主机相同,即“Amazon Linux AMI 2018.03.0(HVM),SSD卷类型-AMI-02769748522663066”<代码>cat/etc/os版本返回

NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
对于打包python3.8 Lambda层,另一个实例AMI会更好吗

我用这个设置了python3(这个盒子的图库中没有python3.8):


更新和自我回答 因此,简而言之,目前这是不可能的。MariaDb连接器不支持linux的Amazon风格。但是,有一个替代的python库PyMySQL将连接到mariadb服务器

下面是python3.8 AWS Lambda函数的内容,该函数为Lambda制作AWS函数层

工厂(AWS Lambda)功能 在客户端,可以调用(再次调用python脚本),如下所示。。。 factory函数接受python pip冻结需求,并生成一个层来为指定模块服务。在我的例子中,requirements.txt将包括PyMySQL

import json
import boto3

# Config section. Adapt as required.
lambdaRegion = 'ap-southeast-2'
bucket = 'some-bucket'
key    = 'provisioning-workspace/layer-package.zip'
layerName = 'someLayerName'
filenm = 'some-path\\requirements.txt'
functionName = 'layer-factory-p38'
# End config section. 

parms = {}
if lambdaRegion is not None:
  parms['region_name'] = lambdaRegion

client = boto3.client( 'lambda', **parms)

def invoke( functionName, qualifier, inData):
  parms = {'FunctionName'  : functionName,
           'InvocationType': 'RequestResponse',
           'LogType'       : 'None',
           'Payload'       : str.encode( json.dumps( {'body': json.dumps( inData)}))}
  if qualifier is not None:
    parms['Qualifier'] = str( qualifier)
  response = client.invoke( **parms)
  response = json.loads( response['Payload'].read().decode('utf-8'))
  try:
    statusCode = int( response['statusCode'])
  except:
    statusCode = 0
  try:
    response = json.loads( response['body'])
  except:
    print( response)
    response = {}
  return statusCode, response

def buildLayer( factoryFunctionName, requirementsFN, layerName, bucket, key):
  with open( requirementsFN, 'r') as file: 
    lines = file.readlines()
  statusCode, response = invoke( factoryFunctionName, None, {
    'requirements': lines, 'bucket': bucket, 'key': key, 'layer-name': layerName})
  return response['layer']

layerArn = buildLayer( functionName, filenm, layerName, bucket, key)
print( layerArn)
import json, boto3
from pathlib import Path
import os, sys, subprocess, shutil
from zipfile import ZipFile

def run( commandLine, captures, workingDir):
  options = {}
  if workingDir is not None:
    options['cwd'] = workingDir
  if 'standard-output' in captures:
    options['stdout'] = subprocess.PIPE
  if 'error-output' in captures:
    options['stderr'] = subprocess.PIPE
  proc = subprocess.run( commandLine, **options)
  outputLines = None
  errorLines  = None
  if 'standard-output' in captures:
    outputLines = proc.stdout.decode('UTF-8').strip().split( os.linesep)
  if 'error-output' in captures:
    errorLines = proc.stderr.decode('UTF-8').strip().split( os.linesep)
  if outputLines == ['']:
    outputLines = None
  if errorLines == ['']:
    errorLines = None
  return proc.returncode, outputLines, errorLines


def lambda_handler(event, context):
    request = json.loads( event['body'])
    sitePackages = '/tmp/aws-lambda-layer/lambda-layer/python/lib/python3.8/site-packages'
    Path( sitePackages).mkdir(parents=True, exist_ok=True)
    lines = request['requirements']
    print( lines)
    bucket      = request['bucket']
    packageKey  = request['key']
    ExtraArgs   = request.get('ExtraArgs')
    layerName   = request['layer-name']
    licenceInfo = request.get('license-info')
    requiresFN  = '/tmp/aws-lambda-layer/requirements.txt'
    origin      = os.environ.get( 'ORIGIN', '*')
    with open( requiresFN, 'w') as file: 
      file.writelines( lines)
    returncode, outputLines, errorLines = run(
      [sys.executable, '-m', 'pip', 'install', '-r', requiresFN, '--target',  sitePackages],
      ['standard-output','error-output'], '/tmp/aws-lambda-layer')
    base  = '/tmp/aws-lambda-layer/lambda-layer'
    zipFN = '/tmp/aws-lambda-layer/package.zip'
    l = len( base) + 1
    with ZipFile( zipFN, 'w') as package:
      for folderName, subfolders, filenames in os.walk( base):
        for filename in filenames:
          filePath = os.path.join( folderName, filename)
          path = filePath[l:]
          if os.path.basename( filePath) != 'yum.log':
            package.write( filePath, path)
    if ExtraArgs is None:
      ExtraArgs = {}
    ExtraArgs['ContentType'] = 'application/zip'
    runtime_region = os.environ.get('AWS_REGION')
    parms = {}
    if runtime_region is not None:
      parms['region_name'] = runtime_region
    s3Client     = boto3.client( 's3'    , **parms)
    lambdaClient = boto3.client( 'lambda', **parms)
    s3Client.upload_file( zipFN, bucket, packageKey, ExtraArgs)
    try:
      shutil.rmtree( '/tmp/aws-lambda-layer', ignore_errors=True) 
    except:
      print( 'Errors in cleaning up /tmp/aws-lambda-layer')
    description = 'python 3.8 requirements:' + '\n'.join( lines)
    parms = {'LayerName'  : layerName,
             'Description': description,
             'Content': { 'S3Bucket': bucket, 'S3Key': packageKey},
             'CompatibleRuntimes': ['python3.8']}
    if licenceInfo is not None:
      parms['LicenseInfo'] = licenceInfo
    try:
      response = lambdaClient.publish_layer_version( **parms)
      response = response['layer']['LayerVersionArn']
    except:
      print('Error in publishing.')
      response = None
    try:
      lambdaClient.delete_object( Bucket=bucket, Key=packageKey)
    except:
      print( 'Failure to delete s3 staging package.')
    statusCode = 200
    response = {'pip-return-code': returncode, 'out': outputLines,
                'err': errorLines, 'layer': response}
    ret = {'statusCode': statusCode,
           'body': json.dumps( response),
           'headers': {
             'Content-Type': 'application/json',
             'Access-Control-Allow-Credentials': 'true',
             'Access-Control-Allow-Origin': origin}}
    return ret
import json
import boto3

# Config section. Adapt as required.
lambdaRegion = 'ap-southeast-2'
bucket = 'some-bucket'
key    = 'provisioning-workspace/layer-package.zip'
layerName = 'someLayerName'
filenm = 'some-path\\requirements.txt'
functionName = 'layer-factory-p38'
# End config section. 

parms = {}
if lambdaRegion is not None:
  parms['region_name'] = lambdaRegion

client = boto3.client( 'lambda', **parms)

def invoke( functionName, qualifier, inData):
  parms = {'FunctionName'  : functionName,
           'InvocationType': 'RequestResponse',
           'LogType'       : 'None',
           'Payload'       : str.encode( json.dumps( {'body': json.dumps( inData)}))}
  if qualifier is not None:
    parms['Qualifier'] = str( qualifier)
  response = client.invoke( **parms)
  response = json.loads( response['Payload'].read().decode('utf-8'))
  try:
    statusCode = int( response['statusCode'])
  except:
    statusCode = 0
  try:
    response = json.loads( response['body'])
  except:
    print( response)
    response = {}
  return statusCode, response

def buildLayer( factoryFunctionName, requirementsFN, layerName, bucket, key):
  with open( requirementsFN, 'r') as file: 
    lines = file.readlines()
  statusCode, response = invoke( factoryFunctionName, None, {
    'requirements': lines, 'bucket': bucket, 'key': key, 'layer-name': layerName})
  return response['layer']

layerArn = buildLayer( functionName, filenm, layerName, bucket, key)
print( layerArn)