Je voudrais configurer une fonction Python que j'ai écrite sur AWS Lambda, une fonction qui dépend d'un tas de bibliothèques Python que j'ai déjà collectées dans un environnement conda .
Pour configurer cela sur Lambda, je suis censé compresser cet environnement, mais les Lambda docs ne donnent que des instructions sur la façon de le faire en utilisant pip/VirtualEnv. Est-ce que quelqu'un a de l'expérience avec ça?
Vous devez utiliser framework serverless en combinaison avec plugin serverless-python-requirements . Vous avez juste besoin d'un requirements.txt
et le plugin compile automatiquement votre code et les dépendances dans un fichier Zip, télécharge tout sur s3 et déploie votre fonction. Bonus: Puisqu'il peut le faire, il est également en mesure de vous aider avec les packages qui nécessitent des dépendances binaires.
Jetez un oeil ici (https://serverless.com/blog/serverless-python-packaging/) pour un guide pratique.
Par expérience, je vous recommande fortement de vous pencher là-dessus. Chaque morceau de travail manuel pour le déploiement et tel est quelque chose qui vous empêche de développer votre logique.
Modifier le 17/12/2017:
Votre commentaire est logique @ eelco-hoogendoorn .
Cependant, dans mon esprit, un environnement conda est juste un endroit encapsulé où un tas de paquets python vivent. Donc, si vous mettiez toutes ces dépendances (de votre env conda) dans un requirements.txt
(et utiliser le plugin sans serveur +) qui résoudrait votre problème, non?
À mon humble avis, ce serait essentiellement la même chose que de compresser tous les packages que vous avez installés dans votre env dans votre package de déploiement. Cela étant dit, voici un extrait, qui fait essentiellement ceci:
conda env export --name Name_of_your_Conda_env | yq -r '.dependencies[] | .. | select(type == "string")' | sed -E "s/(^[^=]*)(=+)([0-9.]+)(=.*|$)/\1==\3/" > requirements.txt
Malheureusement conda env export
exporte uniquement l'environnement au format yaml. Le --json
L'indicateur ne fonctionne pas pour le moment, mais devrait être corrigé dans la prochaine version. C'est pourquoi j'ai dû utiliser yq au lieu de jq . Vous pouvez installer yq
en utilisant pip install yq
. C'est juste un wrapper autour de jq
pour lui permettre de fonctionner également avec les fichiers yaml.
RESTEZ À L'ESPRIT
Le code de déploiement Lambda ne peut avoir qu'une taille de 50 Mo. Votre environnement ne doit pas être trop grand.
Je n'ai pas essayé de déployer un lambda avec serverless
+ serverless-python-packaging
et un requirements.txt
créé comme ça et je ne sais pas si ça va marcher.
La principale raison pour laquelle j'utilise conda
est une option permettant de ne pas compiler différents packages binaires moi-même (comme numpy
, matplotlib
, pyqt
, etc.) ou de compiler les moins fréquemment. Lorsque vous devez compiler vous-même quelque chose pour la version spécifique de python
(comme uwsgi
), vous devez compiler les binaires avec la même version gcc
que la python
dans votre environnement conda
est compilé avec - ce n'est probablement pas le même gcc
que votre système d'exploitation utilise, puisque conda
utilise maintenant les dernières versions du gcc
qui devrait être installé avec conda install gxx_linux-64
.
Cela nous amène à deux situations:
Toutes vos dépendances sont en pur python et vous pouvez réellement enregistrer une liste de celles-ci en utilisant pip freeze
et regroupez-les comme indiqué pour virtualenv
.
Vous avez des extensions binaires. Dans ce cas, les binaires de votre environnement conda ne fonctionneront pas avec le python utilisé par AWS lambda. Malheureusement, vous devrez visiter le page décrivant l'exécution environnement (AMI: amzn-AMI-hvm-2017.03.1.20170812-x86_64-gp2), configurer l'environnement, créer les fichiers binaires pour la version spécifique de python dans un répertoire distinct (python $ === ainsi que de purs python packages), puis les regrouper dans une archive Zip.
Il s'agit d'une réponse générale à votre question, mais l'idée principale est que vous ne pouvez pas réutiliser vos packages binaires, seulement une liste d'entre eux.
Je pense que vous pouvez aller dans votre répertoire anaconda2/envs/
Ou anaconda3/envs/
Et copier/compresser le répertoire env que vous souhaitez télécharger. Conda n'est qu'une version optimisée d'un virtualenv, plus un gestionnaire de paquets différent et quelque peu facultatif. La grande raison pour laquelle je pense que c'est ok est que les environnements conda encapsulent toutes leurs dépendances dans leurs répertoires .../anaconda[2|3]/envs/$VIRTUAL_ENV_DIR/
Particuliers par défaut.
L'utilisation de l'expression virtualenv normale vous donne un peu plus de liberté, de la même manière que les hommes des cavernes avaient plus de liberté que les gens modernes. Personnellement, je préfère les voitures. Avec virtualenv, vous obtenez fondamentalement une variable $PYTHON_PATH
Semi-vide que vous pouvez remplir avec tout ce que vous voulez, plutôt que le plus robuste et pré-rempli env que Conda crache. Ce qui suit est un bon tableau de référence: https://conda.io/docs/commands.html#conda-vs-pip-vs-virtualenv-commands
~$ /path/to/$VIRTUAL_ENV_ROOT_DIR/bin/activate
En ~$ source activate $VIRTUAL_ENV_NAME
Supposons que vous souhaitiez créer un virtualenv
à l'ancienne. Vous choisiriez un répertoire (appelons-le $VIRTUAL_ENV_ROOT_DIR
,) & Nom (que nous appellerons $VIRTUAL_ENV_NAME
.) À ce stade, vous taperiez:
~$ cd $VIRTUAL_ENV_ROOT_DIR && virtualenv $VIRTUAL_ENV_NAME
python crée ensuite une copie de sa propre bibliothèque d'interpréteur (plus pip et setuptools je pense) et place un exécutable appelé activate
dans le répertoire bin/
de ce clone. Le script $VIRTUAL_ENV_ROOT_DIR/bin/activate
Fonctionne en changeant votre variable d'environnement $PYTHONPATH
Actuelle, qui détermine quel interprète python est appelé lorsque vous tapez ~$ python
Dans le shell , & aussi la liste des répertoires contenant tous les modules que l'interpréteur verra quand on lui dira import
quelque chose. C'est la principale raison pour laquelle vous verrez #!/usr/bin/env python
dans le code des gens au lieu de /usr/bin/python
.