Python 3.x 如何在AmazonLinux环境中安装Python模块
我的目标是构建一个AWS Lambda层,为运行python 3.8的AWS Lambda提供mariadb模块 接下来,我需要在与AWS Lambda平台兼容的实例上安装mariadb模块。像这样安装模块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,
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)