I am trying to deploy the python serverless application on AWS.
I follow pretty straightforward tutorial and I do following steps:
Install serverless
npm install -g serverless
Generate template project sls create --template aws-python3 --name sls-demo --path sls-demo
My handler.py file looks as follows:
import json
def hello(event, context):
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
And my serverless.yml configuration file looks as follows:
service: sls-demo
frameworkVersion: '2'
provider:
name: aws
runtime: python3.8
lambdaHashingVersion: 20201221
region: eu-central-1
functions:
hello:
handler: handler.hello
I have already installed aws cli on my machine, configured it with aws credentials and when I run the deployment command sls deploy it finishes successfully.
I test the lambda function with following command sls invoke --function hello and the result returns successfully:
{
"statusCode": 200,
"body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}}"
}
Now I want to introduce some extra dependencies in my lambda function, dockerize it and deploy using the serverless-python-requirements plugin.
For this I do following steps:
Create virtual environment python -m venv ./venv
Activate virtual environment source venv/bin/activate
Install numpy dependency pip install numpy
Freeze python dependencies pip freeze > requirements.txt
Install serverless-python-requirements plugin sls plugin install -n serverless-python-requirements
My updated handler.py file looks as follows:
import json
import numpy
def hello(event, context):
array = numpy.arange(15).reshape(3, 5)
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event,
"array": array
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
And my updated serverless.yml configuration file looks as follows:
service: sls-demo
frameworkVersion: '2'
provider:
name: aws
runtime: python3.8
lambdaHashingVersion: 20201221
region: eu-central-1
functions:
hello:
handler: handler.hello
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: non-linux
After these changes, when I run the deployment command sls deploy it fails with the following error:
Serverless: Recoverable error occurred (Inaccessible host: `sls-demo-dev-serverlessdeploymentbucket-xyz.s3.eu-central-1.amazonaws.com'. This service may not be available in the `eu-central-1' region.), sleeping for ~5 seconds. Try 1 of 4
I enabled debug logs for the serverless by exporting this flag export SLS_DEBUG=* and the exception stack trace looks as follows:
Serverless: Recoverable error occurred (UnknownEndpoint: Inaccessible host: `sls-demo-dev-serverlessdeploymentbucket-xyz.s3.eu-central-1.amazonaws.com'. This service may not be available in the `eu-central-1' region.
at Request.ENOTFOUND_ERROR (/Users/macbook/.nvm/versions/node/v14.16.0/lib/node_modules/serverless/node_modules/aws-sdk/lib/event_listeners.js:507:46)
at Request.callListeners (/Users/macbook/.nvm/versions/node/v14.16.0/lib/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/Users/macbook/.nvm/versions/node/v14.16.0/lib/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/Users/macbook/.nvm/versions/node/v14.16.0/lib/node_modules/serverless/node_modules/aws-sdk/lib/request.js:688:14)
at ClientRequest.error (/Users/macbook/.nvm/versions/node/v14.16.0/lib/node_modules/serverless/node_modules/aws-sdk/lib/event_listeners.js:339:22)
at ClientRequest.<anonymous> (/Users/macbook/.nvm/versions/node/v14.16.0/lib/node_modules/serverless/node_modules/aws-sdk/lib/http/node.js:96:19)
at ClientRequest.emit (events.js:315:20)
at ClientRequest.EventEmitter.emit (domain.js:467:12)
at TLSSocket.socketErrorListener (_http_client.js:469:9)
at TLSSocket.emit (events.js:315:20)
at TLSSocket.EventEmitter.emit (domain.js:467:12)
at emitErrorNT (internal/streams/destroy.js:106:8)
at emitErrorCloseNT (internal/streams/destroy.js:74:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
----------------------------------------------------------------------------------------------------), sleeping for ~7 seconds. Try 1 of 4
This error happens when serverless is trying to upload the build artifact to the s3 bucket:
Serverless: Uploading service sls-demo.zip file to S3 (33.14 MB)...
I suspect that this error happens due to the large size of the file, but I don't know how to resolve this problem, or if I miss something in the configuration.
I tried to upload the large file in the mentioned s3 bucket using the aws cli and it works without any problem:
aws s3 cp large_file.zip s3://sls-demo-dev-serverlessdeploymentbucket-xyz/large_file.zip
I don't know how to troubleshoot this problem, and I was unable to find any answer regarding this error in the internet. Any help appreciated.
Related
I am deploying a model on Azure Machine Learning studio using azure kubernetes service
env = Environment(name='ocr')
aks_name = 'ocr-compute-2'
# Create the cluster
aks_target = AksCompute(ws, aks_name)
env.python.conda_dependencies.add_pip_package('google-cloud-vision')
env.python.conda_dependencies.add_pip_package('Pillow')
env.python.conda_dependencies.add_pip_package('Flask == 2.2.2')
env.python.conda_dependencies.add_pip_package('azureml-defaults')
inference_config = InferenceConfig(environment=env, source_directory='./', entry_script='./run1.py')
deployment_config = AksWebservice.deploy_configuration(autoscale_enabled=True,
autoscale_target_utilization=20,
autoscale_min_replicas=1,
autoscale_max_replicas=4)
I am getting this error
"statusCode": 400,
"message": "Kubernetes Deployment failed",
"details": [
{
"code": "CrashLoopBackOff",
"message": "Your container application crashed as it does not have AzureML serving stack.
Make sure you have 'azureml-defaults>=1.0.45' package in your pip dependencies, it contains requirements for the AzureML serving stack."
}
Will be great if I can know what I am missing here.
When the packages which are required to run the pipeline are mentioned in the requirements.txt, we shouldn’t use the manual approach to update the pod with the libraries.
RUN pip install -r requirements.txt
When the pod failed to find the library which is required from the requirements.txt it throughs CrashLoopBackOff error based on the dependencies.
The dependencies must be available in the requirements.txt
azureml-defaults>=1.0.45 -> install the package at pod level and include that in the requirements.txt
I'm trying to use serverless framework with a python project.
I created a hello world example that I run in offline mode. It works well but when I try to import a python package I get ModuleNotFoundError.
Here is my serverless.yaml file:
service: my-test
frameworkVersion: "3"
provider:
name: aws
runtime: python3.8
functions:
hello:
handler: lambdas.hello.hello
events:
- http:
path: /hello
method: get
plugins:
- serverless-python-requirements
- serverless-offline
In lambdas.hello.py:
import json
import pandas
def hello(event, context):
body = {
"message": 'hello world',
}
response = {"statusCode": 200, "body": json.dumps(body)}
return response
In my Pipfile:
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
pandas = "*"
[requires]
python_version = "3.8"
To run it, I use the command $ sls offline start
Then When I query on postman http://localhost:3000/dev/hello I get the error ModuleNotFoundError.
If I remove the line import pandasin hello.py file, it works.
I don't understand why I get this error as serverless-python-requirements is supposed to check the pipfile and pandas is in my pipfile.
How can I use pandas (or any other python package) in my lambdas with serverless framework in offline mode ?
The serverless-python-requirements plugin is used to bundle your dependencies and package them for deployment. This only comes to effect when you run sls deploy.
From the plugin page -
The plugin will now bundle your python dependencies specified in your requirements.txt or Pipfile when you run sls deploy
Read more about python packaging here - https://www.serverless.com/blog/serverless-python-packaging
Since you are running your service locally, this plugin will not be used.
Your dependencies need to be installed locally.
perform the below steps to make it work -
Create a virtual environment in you serverless directory.
install the plugin serverless plugin install -n serverless-offline
install pandas using pip
run sls offline start
Your lambda function don't have the panda module installed
You need to use the serverless-python-requirements plugin : https://www.serverless.com/plugins/serverless-python-requirements. To use it you need docker on your machine and to create a requirement.txt file in your service with the packages you need in your lambda
Error:
Running "serverless" from node_modules
Deploying serverless-flask to stage dev (us-east-1)
✖ Stack serverless-flask-dev failed to deploy (0s)
Environment: darwin, node 16.0.0, framework 3.1.1 (local) 3.1.1v (global), plugin 6.0.0, SDK 4.3.1
Credentials: Local, "default" profile
Docs: docs.serverless.com
Support: forum.serverless.com
Bugs: github.com/serverless/serverless/issues
Error:
Error: spawn docker ENOENT
at Process.ChildProcess._handle.onexit (node:internal/child_process:282:19)
at onErrorNT (node:internal/child_process:480:16)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
I'm following these instructions (https://www.serverless.com/blog/flask-python-rest-api-serverless-lambda-dynamodb/) and can't seem to figure this out since the base app is in python and not javascript... most people who have solved this solved it using javascript.
To solve this issue you need to update your serverless.yml file with these changes in the custom block
custom:
pythonRequirements:
pythonBin: python3
dockerizePip: "false"
I also face the same issue my issue was with dockerizePip it was set to
dockerizePip: non-linux
either remove this entry from serverless.yml file or just set it to false
To be able to deploy your project with serverless-python-requirements you need to have docker on your machine (if you are on windows consider using docker desktop or a linux vm)
Why do I need Docker ?
When you do a sls deploy, serverless-python-requirements launch a docker container to install all the dependencies you've put in your requirements.txt file that will be used during the deployement process
You are getting this error because your container is not launch correctly
I created a simple Flask web app with CRUD operations and deployed in beanstalk with the below requirements.txt file
Flask==1.1.1
Flask-MySQLdb==0.2.0
Jinja2==2.11.1
mysql==0.0.2
mysqlclient==1.4.6
SQLAlchemy==1.3.15
Werkzeug==1.0.0
Flask-Cors==3.0.8
Flask-Mail==0.9.1
Flask-SocketIO==4.3.0
It worked fine, and then I wrote a below function
import tensorflow as tf
import keras
from keras.models import load_model
import cv2
import os
def face_shape_model():
classifier = load_model('face_shape_recog_model.h5')
image = cv2.imread('')
res = str(classifier.predict_classes(image, 1, verbose=0)[0])
return {"prediction": res}
with including below packages in to requirments.txt file
keras==2.3.1
tensorflow==1.14.0
opencv-python==4.2.0.32
whole flask application working fine in my local environment so I zipped and deploy into AWS elasticbeanstalk after deployment it logged below error
Unsuccessful command execution on instance id(s) 'i-0a2a8a4c5b3e56b81'. Aborting the operation.
Your requirements.txt is invalid. Snapshot your logs for details.
as mentioned above I checked my log and it shows below error
distutils.errors.CompileError: command 'gcc' failed with exit status 1
so I searched about the above error find below solution according to that and I created yml file and added it into .ebextension file as below
packages:
yum:
gcc-c++: []
but I still get the same error. how can I solve this or is there any wrong steps above
Thank you.
Finally solved with docker container, I created docker environment In AWS ElasticBeanstalk and deployed it, and now it works fine, below shows my config file and Dockerfile
Dockerfile
FROM python:3.6.8
RUN mkdir -p /usr/src/flask_app/
COPY src/requirements.txt /usr/src/flask_app/
WORKDIR /usr/src/flask_app/
RUN pip install -r requirements.txt
COPY . /usr/src/flask_app
ENTRYPOINT ["python", "src/app.py"]
EXPOSE 5000
Dockerrun.aws.json
{
"AWSEBDockerrunVersion": "1",
"Ports": [
{
"ContainerPort": "5000",
"HostPort": "80"
}
]
}
I have a Python Serverless project that uses a private Git (on Github) repo.
Requirements.txt file looks like this:
itsdangerous==0.24
boto3>=1.7
git+ssh://git#github.com/company/repo.git#egg=my_alias
Configurations of the project mainly looks like this
plugins:
- serverless-python-requirements
- serverless-wsgi
custom:
wsgi:
app: app.app
packRequirements: false
pythonRequirements:
dockerizePip: true
dockerSsh: true
When I deploy using this command:
sls deploy --aws-profile my_id --stage dev --region eu-west-1
I get this error:
Command "git clone -q ssh://git#github.com/company/repo.git /tmp/pip-install-a0_8bh5a/my_alias" failed with error code 128 in None
What am I doing wrong? I'm suspecting either the way I configured my SSH key for Github access or the configurations of the serverless package.
So the only way I managed to sort this issue was
Configure the SSH WITH NO PASSPHRASE. Following steps here.
In serverless.yml, I added the following:
custom:
wsgi:
app: app.app
packRequirements: false
pythonRequirements:
dockerizePip: true
dockerSsh: true
dockerSshSymlink: ~/.ssh
Notice I added dockerSshSymlink to report the location of the ssh files on my local machine; ~/.ssh.
In requirements.txt, I added my private dependency like this:
git+ssh://git#github.com/my_comp/my_repo.git#egg=MyRepo
All works.
Although not recommeneded. Have you tried using sudo sls deploy --aws-profile my_id --stage dev --region eu-west-1
This error can be also created by using the wrong password or ssh key.