DEV Community

Cover image for Flask + Serverless — API in AWS Lambda the Easy Way
ICCHA Technologies
ICCHA Technologies

Posted on • Edited on

Flask + Serverless — API in AWS Lambda the Easy Way

If you either need to quickly deploy a small API or just decided to migrate your codebase to leverage the advantages of AWS Lambda. There are of course other guides on how to accomplish that, like packing and uploading your app by yourself. The process gets a bit more tricky when you realize some dependencies are not compatible (because of Linux on lambda) and you need to handle that too.

Solution

Use a powerful combo of Flask and Serverless framework. Any WSGI application such as Django can work too. We will use a quotes service.

Recipe

  1. Download and install Python in your device, then install pip and virtualenv package.

      pip install virtualenv
    
  2. Install Serverless framework, see full instructions

      $ npm install -g serverless
    
  3. Create your main folder, can call it "quotes". Then create the python venv.

        mkdir quotes
        cd quotes
        virtualenv venv -p python3
        (venv) pip install Flask
        (venv) pip freeze > requirements.txt
    

    You will now have a venv folder, go to quotes/venv/Scripts and run "activate" to active the virtual environment.

  4. At the main folder /quotes create an app.py file to contain our quotes service,then add the information below.

        from collections import namedtuple
        from random import choice
    
        from flask import Flask, jsonify
    
        Quote = namedtuple("Quote", ("text", "author"))
    
        quotes = [
            Quote("Talk is cheap. Show me the code.", "Linus Torvalds"),
            Quote("Programs must be written for people to read, and only incidentally for machines to execute.", "Harold Abelson"),
            Quote("Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live",
                "John Woods"),
            Quote("Give a man a program, frustrate him for a day. Teach a man to program, frustrate him for a lifetime.", "Muhammad Waseem"),
            Quote("Progress is possible only if we train ourselves to think about programs without thinking of them as pieces of executable code. ",
                "Edsger W. Dijkstra")
        ]
    
        app = Flask(__name__)
    
        @app.route("/")
        def hello_from_root():
            return jsonify(message='Hello from root!')
    
        @app.route("/quote", methods=["GET"])
        def get_random_quote():
            return jsonify(choice(quotes)._asdict())
    
  5. Wire it with the Serverless framework. To do so we need to create a serverless.yml file (in our root) manually. The file will look like this:

        service: quotes #name this whatever you want
    
        provider:
        name: aws
        runtime: python3.6
        region: us-east-1
        memorySize: 128
    
  6. Install two Serverless plugins. The first thing we need is to make Lambda understand WSGI (protocol Flask/Django is using), second is to make Serverless pack our python requirements into our deployment package.

      $ sls plugin install -n serverless-wsgi
      $ sls plugin install -n serverless-python-requirements
    
  7. Update the serverless.yml file with the plugins and further information needed.

    service: quotes-serverless #name this whatever you want
    
    provider:
    name: aws
    runtime: python3.6
    region: us-east-1
    memorySize: 128
    
    plugins:
    - serverless-wsgi
    - serverless-python-requirements
    
    custom:
    wsgi:
    app: app.app
    packRequirements: false
    
    functions:
    app:
    handler: wsgi_handler.handler
    events:
        - httpApi: '*'
    
    deprecationNotificationMode: error #add this for debugging
    configValidationMode: error #add this for debugging
        `);
    
    

    You can see a new section (custom) which holds configuration for those plugins. The wsgi part is saying where your app is and turning off packing of requirements. The last part (functions) declares what our service contains. We can have more functions within one service and also require specific permissions. In this case, we are just saying that all requests will be served through a WSGI handler, which is provided by our installed plugin.

  8. Update requirements.txt

    Flask==1.1.4
    Werkzeug==1.0.1
    markupsafe==2.0.1
    

    Check 'Werkzeug' version, can cause error while deploying.

  9. Do a Local deployment to test the service, run:

        $ serverless wsgi serve
    

    You can open the server to the specific path, for example http://localhost:5000/

    use /quotes to see the random quotes.

  10. Before deployment our project to AWS you need to create an account.

    1. Login to your AWS account and go to the Identity & Access Management (IAM) page.
    2. Click on Users and then Add user. Enter a name in the first field to remind you this user is related to the Serverless Framework, like serverless-admin. Enable Programmatic access by clicking the checkbox. Click Next to go through to the Permissions page. Click on Attach existing policies directly. Search for and select AdministratorAccess then click Next: Review. Check to make sure everything looks good and click Create user.
    3. View and copy the API Key & Secret to a temporary place. These are your AWS access keys.

    see more instruction in here

  11. Add AWs credentials to the project, the easiest way is create an .env file in our root folder and add the information below.

  12. Edit the create a new file nodemon.json in the root of your project folder, that file will be used to store our environment variables. In case that you are not using nodemon , create an .env file.

        set AWS_ACCESS_KEY_ID=<your-key-here>
        set AWS_SECRET_ACCESS_KEY=<your-secret-key-here>
        # AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are now available for serverless to use
        serverless deploy
    
        # In Linux use 'export' instead of 'set'
    
  13. Deploy our project, run the below command.

        $ serverless deploy
    

    Now we can see the server in our endpoint, at AWS Cloudformation we now have our Stack of the deployed project.

If you get an internal error or want to see recent logs, open CloudWatch in your AWS console or just type: serverless logs -f app

Feel free to visit this repository with all what this blog contains.

Top comments (0)