Использование фильма, скучного и наглого в амазонке лямбда

Я хотел бы создать видео с помощью AWS Lambda особенность.

Я следовал инструкциям, найденным здесь и здесь.

И теперь у меня есть следующий процесс, чтобы построить мой Lambda функция:

Шаг 1

Огонь Amazon Linux EC2 экземпляр и запустите это как root на нем:

#! /usr/bin/env bash

# Install the SciPy stack on Amazon Linux and prepare it for AWS Lambda

yum -y update
yum -y groupinstall "Development Tools"
yum -y install blas --enablerepo=epel
yum -y install lapack --enablerepo=epel
yum -y install atlas-sse3-devel --enablerepo=epel
yum -y install Cython --enablerepo=epel
yum -y install python27
yum -y install python27-numpy.x86_64
yum -y install python27-numpy-f2py.x86_64
yum -y install python27-scipy.x86_64

/usr/local/bin/pip install --upgrade pip
mkdir -p /home/ec2-user/stack
/usr/local/bin/pip install moviepy -t /home/ec2-user/stack

cp -R /usr/lib64/python2.7/dist-packages/numpy /home/ec2-user/stack/numpy
cp -R /usr/lib64/python2.7/dist-packages/scipy /home/ec2-user/stack/scipy

tar -czvf stack.tgz /home/ec2-user/stack/*

Шаг 2

Я получаю полученный архив на свой ноутбук. А затем запустите этот скрипт, чтобы создать ZIP-архив.

#! /usr/bin/env bash

mkdir tmp
rm lambda.zip
tar -xzf stack.tgz -C tmp

zip -9 lambda.zip process_movie.py
zip -r9 lambda.zip *.ttf
cd tmp/home/ec2-user/stack/
zip -r9 ../../../../lambda.zip *

process_movie.py На данный момент скрипт является всего лишь тестом, чтобы проверить, работает ли стек:

def make_movie(event, context):
    import os
    print(os.listdir('.'))
    print(os.listdir('numpy'))
    try:
        import scipy
    except ImportError:
        print('can not import scipy')

    try:
        import numpy
    except ImportError:
        print('can not import numpy')

    try:
        import moviepy
    except ImportError:
        print('can not import moviepy')

Шаг 3

Затем я загружаю полученный архив на S3, чтобы стать источником моего lambda функция. Когда я проверяю функцию, я получаю следующее callstack:

START RequestId: 36c62b93-b94f-11e5-9da7-83f24fc4b7ca Version: $LATEST
['tqdm', 'imageio-1.4.egg-info', 'decorator.pyc', 'process_movie.py', 'decorator-4.0.6.dist-info', 'imageio', 'moviepy', 'tqdm-3.4.0.dist-info', 'scipy', 'numpy', 'OpenSans-Regular.ttf', 'decorator.py', 'moviepy-0.2.2.11.egg-info']
['add_newdocs.pyo', 'numarray', '__init__.py', '__config__.pyc', '_import_tools.py', 'setup.pyo', '_import_tools.pyc', 'doc', 'setupscons.py', '__init__.pyc', 'setup.py', 'version.py', 'add_newdocs.py', 'random', 'dual.pyo', 'version.pyo', 'ctypeslib.pyc', 'version.pyc', 'testing', 'dual.pyc', 'polynomial', '__config__.pyo', 'f2py', 'core', 'linalg', 'distutils', 'matlib.pyo', 'tests', 'matlib.pyc', 'setupscons.pyc', 'setup.pyc', 'ctypeslib.py', 'numpy', '__config__.py', 'matrixlib', 'dual.py', 'lib', 'ma', '_import_tools.pyo', 'ctypeslib.pyo', 'add_newdocs.pyc', 'fft', 'matlib.py', 'setupscons.pyo', '__init__.pyo', 'oldnumeric', 'compat']
can not import scipy
'module' object has no attribute 'core': AttributeError
Traceback (most recent call last):
  File "/var/task/process_movie.py", line 91, in make_movie
    import numpy
  File "/var/task/numpy/__init__.py", line 122, in <module>
    from numpy.__config__ import show as show_config
  File "/var/task/numpy/numpy/__init__.py", line 137, in <module>
    import add_newdocs
  File "/var/task/numpy/numpy/add_newdocs.py", line 9, in <module>
    from numpy.lib import add_newdoc
  File "/var/task/numpy/lib/__init__.py", line 13, in <module>
    from polynomial import *
  File "/var/task/numpy/lib/polynomial.py", line 11, in <module>
    import numpy.core.numeric as NX
AttributeError: 'module' object has no attribute 'core'

END RequestId: 36c62b93-b94f-11e5-9da7-83f24fc4b7ca
REPORT RequestId: 36c62b93-b94f-11e5-9da7-83f24fc4b7ca  Duration: 112.49 ms Billed Duration: 200 ms     Memory Size: 1536 MB    Max Memory Used: 14 MB

Я не могу понять, почему Python не нашел основной каталог, который присутствует в структуре папок.

РЕДАКТИРОВАТЬ:

Следуя совету @jarmod, я уменьшил lambdaфункция для:

def make_movie(event, context):
    print('running make movie')
    import numpy

Теперь у меня есть следующая ошибка:

START RequestId: 6abd7ef6-b9de-11e5-8aee-918ac0a06113 Version: $LATEST
running make movie
Error importing numpy: you should not try to import numpy from
        its source directory; please exit the numpy source tree, and relaunch
        your python intepreter from there.: ImportError
Traceback (most recent call last):
  File "/var/task/process_movie.py", line 3, in make_movie
    import numpy
  File "/var/task/numpy/__init__.py", line 127, in <module>
    raise ImportError(msg)
ImportError: Error importing numpy: you should not try to import numpy from
        its source directory; please exit the numpy source tree, and relaunch
        your python intepreter from there.

END RequestId: 6abd7ef6-b9de-11e5-8aee-918ac0a06113
REPORT RequestId: 6abd7ef6-b9de-11e5-8aee-918ac0a06113  Duration: 105.95 ms Billed Duration: 200 ms     Memory Size: 1536 MB    Max Memory Used: 14 MB

11 ответов

Решение

С помощью всех постов в этой теме вот решение для записей:

Чтобы это заработало, вам нужно:

  1. начать EC2 экземпляр с минимум 2GO RAM (чтобы иметь возможность компилировать NumPy & SciPy)

  2. Установите необходимые зависимости

    sudo yum -y update
    sudo yum -y upgrade
    sudo yum -y groupinstall "Development Tools"
    sudo yum -y install blas --enablerepo=epel
    sudo yum -y install lapack --enablerepo=epel
    sudo yum -y install Cython --enablerepo=epel
    sudo yum install python27-devel python27-pip gcc
    virtualenv ~/env
    source ~/env/bin/activate
    pip install scipy
    pip install numpy
    pip install moviepy
    
  3. Скопируйте на свой локальный компьютер все содержимое каталогов (кроме _markerlib, pip*, pkg_resources, setuptools* и easyinstall*) в виде stack папка:

    • home/ec2-user/env/lib/python2.7/dist-packages
    • home/ec2-user/env/lib64/python2.7/dist-packages
  4. получить все необходимые общие библиотеки от вас EC2пример:

    • libatlas.so.3
    • libf77blas.so.3
    • liblapack.so.3
    • libptf77blas.so.3
    • libcblas.so.3
    • libgfortran.so.3
    • libptcblas.so.3
    • libquadmath.so.0
  5. Поместите их в lib подпапка stack папка

  6. imageio это зависимость moviepyвам нужно скачать бинарную версию его зависимостей: libfreeimage и из ffmpeg; их можно найти здесь. Поместите их в корень вашей папки стека и переименуйте libfreeimage-3.16.0-linux64.soв libfreeimage.so

  7. Теперь вы должны иметь stack папка, содержащая:

    • все зависимости Python в корне
    • все общие библиотеки в lib вложенная
    • ffmpeg бинарный в корне
    • libfreeimage.so в корне
  8. Заархивируйте эту папку: zip -r9 stack.zip . -x ".*" -x "*/.*"

  9. Используйте следующее lambda_function.py в качестве точки входа для вашего lambda

    from __future__ import print_function
    
    import os
    import subprocess
    
    SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
    LIB_DIR = os.path.join(SCRIPT_DIR, 'lib')
    FFMPEG_BINARY = os.path.join(SCRIPT_DIR, 'ffmpeg')
    
    
    def lambda_handler(event, context):
        command = 'LD_LIBRARY_PATH={} IMAGEIO_FFMPEG_EXE={} python movie_maker.py'.format(
            LIB_DIR,
            FFMPEG_BINARY,
        )
        try:
            output = subprocess.check_output(command, shell=True)
            print(output)
        except subprocess.CalledProcessError as e:
            print(e.output)
    
  10. Напиши movie_maker.pyсценарий, который зависит от moviepy, numpy...

  11. добавьте их в скрипт в ваш файл stack.zip zip -r9 lambda.zip *.py

  12. загрузить почтовый индекс в S3 и использовать его в качестве источника для вашего lambda

Вы также можете скачать stack.zip здесь

Я также перешел по вашей первой ссылке и смог импортировать numpy и pandas в функцию Lambda следующим образом (в Windows):

  1. Запустил (бесплатный) экземпляр t2.micro EC2 с 64-разрядной версией Amazon Linux AMI 2015.09.1 ​​и использовал Putty для SSH в.
  2. Пробовал те же команды, которые вы использовали, и ту, которая рекомендована в статье Amazon:

    sudo yum -y update
    sudo yum -y upgrade
    sudo yum -y groupinstall "Development Tools"
    sudo yum -y install blas --enablerepo=epel
    sudo yum -y install lapack --enablerepo=epel
    sudo yum -y install Cython --enablerepo=epel
    sudo yum install python27-devel python27-pip gcc
    
  3. Создана виртуальная среда:

    virtualenv ~/env
    source ~/env/bin/activate
    
  4. Установлены пакеты:

    sudo ~/env/bin/pip2.7 install numpy
    sudo ~/env/bin/pip2.7 install pandas
    
  5. Затем, используя WinSCP, я вошел в систему и загрузил все (кроме _markerlib, pip*, pkg_resources, setuptools* и easyinstall*) из /home/ec2-user/env/lib/python2.7/dist-packages и все из /home/ec2-user/env/lib64/python2.7/site-packages из экземпляра EC2.

  6. Я положил все эти папки и файлы в один zip вместе с файлом.py, содержащим функцию Lambda. иллюстрация всех скопированных файлов

  7. Поскольку этот ZIP-файл больше 10 МБ, я создал корзину S3 для хранения файла. Я скопировал ссылку на файл оттуда и вставил в "Загрузить ZIP-файл из Amazon S3" в функции Lambda.

  8. Экземпляр EC2 можно отключить, он больше не нужен.

С этим я мог импортировать numpy и панд. Я не знаком с moviepy, но scipy уже может быть хитрым, поскольку у Lambda есть ограничение на размер разархивированного пакета развертывания в 262 144 000 байт. Боюсь, что Numpy и Scipy вместе уже закончили.

Посты здесь помогают мне найти способ статической компиляции NumPy с файлами библиотек, которые могут быть включены в пакет AWS Lambda Deployment. Это решение не зависит от значения LD_LIBRARY_PATH, как в решении @rouk1.

Скомпилированную библиотеку NumPy можно скачать по https://github.com/vitolimandibhrata/aws-lambda-numpy

Вот шаги для пользовательской компиляции NumPy

Инструкция по компиляции этого пакета с нуля

Подготовьте свежий экземпляр AWS EC с AWS Linux.

Установить зависимости компилятора

sudo yum -y install python-devel
sudo yum -y install gcc-c++
sudo yum -y install gcc-gfortran
sudo yum -y install libgfortran

Установите зависимости NumPy

sudo yum -y install blas
sudo yum -y install lapack
sudo yum -y install atlas-sse3-devel

Создайте /var/task/lib для хранения библиотек времени выполнения

mkdir -p /var/task/lib

/ var / task - это корневой каталог, в котором ваш код будет находиться в AWS Lambda, поэтому нам необходимо статически связать необходимые библиотечные файлы в хорошо известной папке, которая в этом случае /var/task/lib

Скопируйте следующие файлы библиотеки в /var/task/lib

cp /usr/lib64/atlas-sse3/liblapack.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libptf77blas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libf77blas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libptcblas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libcblas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libatlas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libptf77blas.so.3 /var/task/lib/.
cp /usr/lib64/libgfortran.so.3 /var/task/lib/.
cp /usr/lib64/libquadmath.so.0 /var/task/lib/.

Получить последнюю версию исходного кода с сайта http://sourceforge.net/projects/numpy/files/NumPy/

Перейдите в папку с исходным кодом numpy, например, numpy-1.10.4. Создайте файл site.cfg со следующими записями

[atlas]
libraries=lapack,f77blas,cblas,atlas
search_static_first=true
runtime_library_dirs = /var/task/lib
extra_link_args = -lgfortran -lquadmath

-lgfortran -lquadmath flags необходимы для статической связи библиотек gfortran и quadmath с файлами, определенными в runtime_library_dirs

Построить NumPy

python setup.py build

Установить NumPy

python setup.py install

Проверьте, связаны ли библиотеки с файлами в /var/task/lib

ldd $PYTHON_HOME/lib64/python2.7/site-packages/numpy/linalg/lapack_lite.so

Тебе следует увидеть

linux-vdso.so.1 =>  (0x00007ffe0dd2d000)
liblapack.so.3 => /var/task/lib/liblapack.so.3 (0x00007ffad6be5000)
libptf77blas.so.3 => /var/task/lib/libptf77blas.so.3 (0x00007ffad69c7000)
libptcblas.so.3 => /var/task/lib/libptcblas.so.3 (0x00007ffad67a7000)
libatlas.so.3 => /var/task/lib/libatlas.so.3 (0x00007ffad6174000)
libf77blas.so.3 => /var/task/lib/libf77blas.so.3 (0x00007ffad5f56000)
libcblas.so.3 => /var/task/lib/libcblas.so.3 (0x00007ffad5d36000)
libpython2.7.so.1.0 => /usr/lib64/libpython2.7.so.1.0 (0x00007ffad596d000)
libgfortran.so.3 => /var/task/lib/libgfortran.so.3 (0x00007ffad5654000)
libm.so.6 => /lib64/libm.so.6 (0x00007ffad5352000)
libquadmath.so.0 => /var/task/lib/libquadmath.so.0 (0x00007ffad5117000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007ffad4f00000)
libc.so.6 => /lib64/libc.so.6 (0x00007ffad4b3e000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007ffad4922000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007ffad471d000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007ffad451a000)
/lib64/ld-linux-x86-64.so.2 (0x000055cfc3ab8000)

Начиная с 2017 года, NumPy и SciPy имеют диски, которые работают на Lambda (пакеты включают в себя предварительно скомпилированные libgfortran а также libopenblas). Насколько я знаю, MoviePy - это чистый модуль Python, так что в принципе вы могли бы сделать:

pip2 install -t lambda moviepy scipy

Затем скопируйте ваш обработчик в lambda каталог и почтовый индекс. За исключением того, что вы, скорее всего, превысите пределы размера 50/250 МБ. Есть несколько вещей, которые могут помочь:

  • удалить.pycs, документы, тесты и другие ненужные части;
  • оставить одну копию общих библиотек NumPy и SciPy;
  • убрать библиотеки несущественных частей, таких как символы отладки;
  • сжать архив, используя более высокие настройки.

Вот пример сценария, который автоматизирует вышеуказанные пункты.

Другой, очень простой метод, который возможен в наши дни, - это сборка с использованием потрясающих док-контейнеров, которые LambCI сделал для имитации Lambda: https://github.com/lambci/docker-lambda

lambci/lambda:build Контейнер напоминает AWS Lambda с добавлением практически полной среды сборки. Чтобы начать сессию оболочки в нем:

docker run -v "$PWD":/var/task -it lambci/lambda:build bash

Внутри сессии:

export share=/var/task
easy_install pip
pip install -t $share numpy

Или с помощью virtualenv:

export share=/var/task
export PS1="[\u@\h:\w]\$ " # required by virtualenv
easy_install pip
pip install virtualenv
# ... make the venv, install numpy, and copy it to $share

Позже вы можете использовать основной контейнер lambci / lambda для тестирования вашей сборки.

Начиная с 2018 года, шаги по установке внешних модулей в Python3 на AWS EC2:

  1. Запустите EC2 на Amazon Linux AMI 201709.

  2. SSH с замазкой с использованием закрытого и открытого ключа и стать суперпользователем.

  3. Установите Python 3 и создайте виртуальный env, затем сделайте его по умолчанию

    yum install python36 python36-virtualenv python36-pip
    
    virtualenv -p python3.6 /tmp/my_python_lib
    
    source /tmp/my_python_lib/bin/activate
    
    which python --to check which version s installed
    
    pip3 install  numpy
    
  4. Скопируйте файлы из пакетов сайта и пакетов dist в ваш локальный компьютер с помощью winscp.

    Чтобы найти фактическое местоположение, используйте команды grep ---

      grep -r dist-packages *. 
    

Эти пакеты могут быть как в lib, так и в lib64.

  1. Пакеты сайта и дистрибутива будут находиться по адресу:

    /tmp/my_python_lib/lib64/python3.6,
    /tmp/my_python_lib/lib/python3.6
    
  2. Заархивируйте эти пакеты вместе с вашим файлом сценария и загрузите на S3, к которому можно получить доступ в lambda. Вместо того, чтобы сжать корневую папку, вы должны выбрать все файлы и заархивировать их или отправить в сжатую папку.

Дополнительные советы:

  1. Если вы хотите установить все пакеты в одном каталоге, вы можете использовать команду:

     pip install --upgrade --target=/tmp/my_python_lib/lib/python3.6/dist-packages pandas
    

По состоянию на август 2018 года, вероятно, самый простой способ - запустить новую среду AWS Cloud9. Затем создайте лямбда-функцию внутри среды. Затем запустите это в командной строке Cloud9:

    cd YourApplicationName
    /venv/bin/pip install scipy -t .
    /venv/bin/pip install numpy -t .
    /venv/bin/pip install moviepy -t .

Теперь я могу импортировать модули в функцию lambda_handler.

Ноябрь 2018 Привет друзья, этот пост очень полезен для меня. Однако ответы до сих пор не очень автоматизированы. Я написал скрипт и учебник Python здесь https://gist.github.com/steinwaywhw/6a6a25d594cc07146c60af943f74c16f чтобы автоматизировать создание скомпилированных пакетов Python с использованием pip а также virtualenv на EC2. Все это Python (Boto3), нет скрипта bash, нет веб-консоли, нет awscli,

Есть еще одно изменение, помимо автоматизации, которое я считаю улучшением. Я загрузил всю виртуальную среду Python из EC2, сохранив структуру папок, вместо слияния lib а также lib64 пакеты все вместе. Я никогда не понимаю предполагаемого смысла слияния этих двух папок. Что если некоторые пакеты переопределяют другие, верно? Кроме того, подделка официальной виртуальной среды является, тем не менее, более безопасным путем, чем создание собственной.

Чтобы загруженная виртуальная среда работала, исходный код функции Lambda добавляет некоторый шаблонный код для обновления пути поиска Python с использованием sys.path, Предполагаемый sys.path виртуальной среды Python можно найти

  • На своей машине создайте виртуальную среду и активируйте ее.
  • Запустите скрипт Python в этой виртуальной среде и выполните print(sys.path) после import sys, Вы можете начать оттуда и изменять, как считаете нужным.

Фрагмент кода шаблона для добавления лямбда-функции для загрузки numpy и другие пакеты из моей упакованной виртуальной среды вставлены ниже. В моем случае я загрузил pandas_datareader который опирается на numpy,

import os
import sys 

# https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html
workdir = os.getenv('LAMBDA_TASK_ROOT')
version = f'{sys.version_info[0]}.{sys.version_info[1]}'
additionals = [f'{workdir}/venv/lib64/python{version}/site-packages',
               f'{workdir}/venv/lib64/python{version}/lib-dynload',
               f'{workdir}/venv/lib64/python{version}/dist-packages',
               f'{workdir}/venv/lib/python{version}/dist-packages',
               f'{workdir}/venv/lib/python{version}/site-packages']
sys.path = additionals + sys.path

import pandas_datareader as pdr

Я могу подтвердить, что шаги, опубликованные @attila-tanyi, работают правильно в Amazon Linux. Я только добавил бы, что нет необходимости использовать EC2, так как есть контейнер докера Amazon Linux, доступный из репозитория по умолчанию.

docker pull amazonlinux && docker run -it amazonlinux
# Follow @attila-tanyi steps
# Note - sudo is not necessary here

Я использую Dockerfile, встроенный в мое приложение, для сборки и развертывания в Lambda.

Мне нравится ответ @Vito Limandibhrata, но я думаю, что этого недостаточно для создания numpy с помощью runtime_library_dirs в numpy==1.11.1. Если кто-то думает, что site-cfg игнорируется, сделайте следующее:

cp /usr/lib64/atlas-sse3/*.a /var/task/lib/

*.a файлы в atlas-sse3 необходимы для сборки numpy. Также вам может потребоваться выполнить следующее:

python setup.py config

проверить конфигурацию NumPy. Если это требует чего-то большего, вы увидите следующее сообщение:

atlas_threads_info:
Setting PTATLAS=ATLAS   libraries ptf77blas,ptcblas,atlas not found in /root/Envs/skl/lib
    libraries lapack_atlas not found in /root/Envs/skl/lib
    libraries ptf77blas,ptcblas,atlas not found in /usr/local/lib64   
    libraries lapack_atlas not found in /usr/local/lib64
    libraries ptf77blas,ptcblas,atlas not found in /usr/local/lib         
    libraries lapack_atlas not found in /usr/local/lib
    libraries lapack_atlas not found in /usr/lib64/atlas-sse3
<class 'numpy.distutils.system_info.atlas_threads_info'>
Setting PTATLAS=ATLAS
Setting PTATLAS=ATLAS
Setting PTATLAS=ATLAS
Setting PTATLAS=ATLAS
    libraries lapack not found in ['/var/task/lib']
Runtime library lapack was not found. Ignoring
    libraries f77blas not found in ['/var/task/lib']
Runtime library f77blas was not found. Ignoring
    libraries cblas not found in ['/var/task/lib']
Runtime library cblas was not found. Ignoring
    libraries atlas not found in ['/var/task/lib']
Runtime library atlas was not found. Ignoring
    FOUND:
        extra_link_args = ['-lgfortran -lquadmath']
        define_macros = [('NO_ATLAS_INFO', -1)]
        language = f77
        libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas', 'lapack', 'f77blas', 'cblas', 'atlas']
        library_dirs = ['/usr/lib64/atlas-sse3']
        include_dirs = ['/usr/include']

тогда site-cfg будет игнорироваться.

Подсказка: если pip используется для построения numpy с runtime_library_dirs, вам лучше создать ~/.numpy-site.cfg и добавьте следующее:

[atlas]
libraries = lapack,f77blas,cblas,atlas
search_static_first = true
runtime_library_dirs = /var/task/lib
extra_link_args = -lgfortran -lquadmath

затем numpy распознает файл.numpy-site.cfg. Это довольно простой и легкий способ.

Вы можете создать zip-файл для лямбда с помощью scipy, numpy, moviepy и pandas в любой ОС.

https://pypi.org/project/scipy/#files

pypi имеет файлы колес для разных ОС, и вы можете скачать файл manylinux whl и разархивировать. После этого удалите файлы dist-info и pyc и заархивируйте все. Окончательный zip-файл может быть загружен в S3 и преобразован в лямбда-слой.

Этот учебник полезен для глубокого понимания этого.

Другие вопросы по тегам