Pip установить Python пакет в AWS Лямбда? - PullRequest
0 голосов
/ 20 февраля 2020

Я пытаюсь установить пакет в функции AWS Lambda.

Метод, рекомендованный Amazon, заключается в создании сжатого пакета развертывания, который включает в себя все зависимости и функцию python вместе (как описано в AWS Lambda Deployment Package в Python) , Однако это приводит к невозможности редактировать лямбда-функцию с помощью встроенного редактирования кода в AWS Lambda GUI.

Так что вместо этого я хотел бы установить пакет pip в AWS Lambda функционировать сам. В AWS Lambda файловая система доступна только для чтения, кроме каталога / tmp /, поэтому я пытаюсь установить pip в каталог / tmp /. Функция вызывается только один раз в день, поэтому я не возражаю против нескольких дополнительных секунд, необходимых для повторной установки пакета при каждом запуске функции.

Моя попытка

def lambda_handler(event, context):
    # pip install dependencies
    print('begin lambda handler')
    import subprocess
    import sys
    subprocess.call('pip install cryptography -t /tmp/ --no-cache-dir'.split())
    from cryptography.fernet import Fernet
    pwd_encrypted = b'gAAAAABeTcT0OXH96ib7TD5-sTII6jMfUXPhMpwWRCF0315rWp4C0yav1XAPIn7prfkkA4tltYiWFAJ22bwuaj0z1CKaGl8vTgNd695SDl25HnLwu1xTzaQ='
    key = b'fP-7YR1hUeVW4KmFmly4JdgotD6qjR52g11RQms6Llo='
    cipher_suite = Fernet(key)
    result = cipher_suite.decrypt(pwd_encrypted).decode('utf-8')
    print(result)
    print('end lambda handler')

Однако это приводит к ошибке

[ОШИБКА] ModuleNotFoundError: Нет модуля с именем 'cryptography'

Я также пытался заменить подпроцесс вызов со следующим, как рекомендовано в этом ответе stackoverflow

    cmd = sys.executable+' -m pip install cryptography -t dependencies --no-cache-dir'
    subprocess.check_call(cmd.split())

Однако это приводит к ошибке

OSError : [Errno 30] Файловая система только для чтения: '/ var / task / dependencies'

1 Ответ

0 голосов
/ 21 февраля 2020

Я решил это с помощью однострочной корректировки исходной попытки. Вам просто нужно добавить / tmp / в sys.path, чтобы Python знал, что искать / tmp / для модуля. Все, что вам нужно сделать, это добавить строку sys.path.insert(1, '/tmp/').

Решение

import os
import sys
import subprocess

# pip install custom package to /tmp/ and add to path
subprocess.call('pip install cryptography -t /tmp/ --no-cache-dir'.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
sys.path.insert(1, '/tmp/')
from cryptography.fernet import Fernet

def lambda_handler(event, context):
    # pip install dependencies
    pwd_encrypted = b'gAAAAABeTcT0OXH96ib7TD5-sTII6jMfUXPhMpwWRCF0315rWp4C0yav1XAPIn7prfkkA4tltYiWFAJ22bwuaj0z1CKaGl8vTgNd695SDl25HnLwu1xTzaQ='
    key = b'fP-7YR1hUeVW4KmFmly4JdgotD6qjR52g11RQms6Llo='
    cipher_suite = Fernet(key)
    result = cipher_suite.decrypt(pwd_encrypted).decode('utf-8')
    print(result)

Выход

Hello stackoverflow!

Примечание. Как упоминалось в комментариях @JohnRotenstein, предпочтительным методом добавления пакетов Python является пакетирование зависимостей в AWS лямбда-слой . Мое решение просто показывает, что можно установить пакеты установки напрямую в AWS лямбда-функцию.

...