Code Monkey home page Code Monkey logo

flask-lambda's Introduction

flask-lambda

Python module to make Flask compatible with AWS Lambda for creating RESTful applications.

Installation

pip install flask-lambda

Usage

This module works pretty much just like Flask. This allows you to run and develop this applicaiton locally just like you would in Flask. When ready deploy to Lambda, and configure the handler as:

my_python_file.app

Here is an example of what my_python_file.py would look like:

import json
from flask import request
from flask_lambda import FlaskLambda

app = FlaskLambda(__name__)


@app.route('/foo', methods=['GET', 'POST'])
def foo():
    data = {
        'form': request.form.copy(),
        'args': request.args.copy(),
        'json': request.json
    }
    return (
        json.dumps(data, indent=4, sort_keys=True),
        200,
        {'Content-Type': 'application/json'}
    )


if __name__ == '__main__':
    app.run(debug=True)

Flask-RESTful

Nothing special here, this module works without issue with Flask-RESTful as well.

API Gateway

Configure your API Gateway with a {proxy+} resource with an ANY method. Your "Method Response" should likely include an application/json "Response Body for 200" that uses the Empty model.

Deploying

Consider using python-mu.

Lambda Test Event

If you wish to use the "Test" functionality in Lambda for your function, you will need a "API Gateway AWS Proxy" event. Below is an event to test the above sample application:

{
  "body": "{\"test\":\"body\"}",
  "resource": "/{proxy+}",
  "requestContext": {
    "resourceId": "123456",
    "apiId": "1234567890",
    "resourcePath": "/{proxy+}",
    "httpMethod": "POST",
    "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
    "accountId": "123456789012",
    "identity": {
      "apiKey": null,
      "userArn": null,
      "cognitoAuthenticationType": null,
      "caller": null,
      "userAgent": "Custom User Agent String",
      "user": null,
      "cognitoIdentityPoolId": null,
      "cognitoIdentityId": null,
      "cognitoAuthenticationProvider": null,
      "sourceIp": "127.0.0.1",
      "accountId": null
    },
    "stage": "prod"
  },
  "queryStringParameters": {
    "foo": "bar"
  },
  "headers": {
    "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
    "Accept-Language": "en-US,en;q=0.8",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Mobile-Viewer": "false",
    "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
    "CloudFront-Viewer-Country": "US",
    "Accept": "application/json",
    "Upgrade-Insecure-Requests": "1",
    "X-Forwarded-Port": "443",
    "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
    "X-Forwarded-Proto": "https",
    "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
    "CloudFront-Is-Tablet-Viewer": "false",
    "Cache-Control": "max-age=0",
    "User-Agent": "Custom User Agent String",
    "CloudFront-Forwarded-Proto": "https",
    "Accept-Encoding": "gzip, deflate, sdch",
    "Content-Type": "application/json"
  },
  "pathParameters": {
    "proxy": "foo"
  },
  "httpMethod": "POST",
  "stageVariables": {
    "baz": "qux"
  },
  "path": "/foo"
}

To update your test event, click "Actions" -> "Configure test event".

flask-lambda's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

flask-lambda's Issues

werkzeug.BaseRequest Deprecated

I have discovered BaseRequest class removed from werkzeug later 2.1.0 version.

Related discussion here.

The package works fine in 2.0.3 version as well as tested. However, would be great if you can specify the exact dependent werkzeug version or fix the deprecated implementation.

Thanks

TypeError: can assign only bytes, buffers, or iterables of ints in range(0, 256) when processing request.json using werkzeug 2.2.3 and higher

When calling request.json in DELETE or POST calls I receive the following stack trace error:

Traceback (most recent call last):
File "/var/lang/lib/python3.8/site-packages/flask/app.py", line 2190, in wsgi_app
    response = self.full_dispatch_request()
File "/var/lang/lib/python3.8/site-packages/flask/app.py", line 1486, in full_dispatch_request
    rv = self.handle_user_exception(e)
File "/var/lang/lib/python3.8/site-packages/flask/app.py", line 1484, in full_dispatch_request
    rv = self.dispatch_request()
File "/var/lang/lib/python3.8/site-packages/flask/app.py", line 1469, in dispatch_request
    return self.ensure_sync(self.view_functions [rule.endpoint])(**view_args)
File "/var/task/app.py", line 105, in delete_queue_messages
    data = request.json
File "/var/lang/lib/python3.8/site-packages/werkzeug/wrappers/request.py", line 561, in json
    return self.get_json()
File "/var/lang/lib/python3.8/site-packages/werkzeug/wrappers/request.py", line 611, in get_json
    data = self.get_data(cache=cache)
File "/var/Lang/lib/python3.8/site-packages/werkzeug/wrappers/request.py", line 423, in get_data
    rv = self.stream.read()
File */var/lang/lib/python3.8/site-packages/werkzeug/wsgi.py',line 829, in readall
    data = self.read(1024 * 64)
File * /var/lang/lib/python3.8/site-packages/werkzeug/wsgi.py*,Line 810, in readinto
    b[:out_size] = data
TypeError: can assign only bytes, buffers, or iterables of ints in range(0, 256)

As title suggests I am using main branch of flask-lambda, flask 2.3.2 and werkzeug 2.3.6.

When app is run locally as a regular Flask app the request.json call does not result in TypeError.

Using Sam when deploying to aws lambda i am facing this error when using flask-lambda package

[ERROR] KeyError: 'SERVER_NAME'Traceback (most recent call last):  File "/var/task/flask_lambda.py", line 97, in call    return super(FlaskLambda, self).call(event, context)  File "/var/task/flask/app.py", line 2464, in call    return self.wsgi_app(environ, start_response)  File "/var/task/flask/app.py", line 2442, in wsgi_app    ctx = self.request_context(environ)  File "/var/task/flask/app.py", line 2359, in request_context    return RequestContext(self, environ)  File "/var/task/flask/ctx.py", line 292, in init    self.url_adapter = app.create_url_adapter(self.request)  File "/var/task/flask/app.py", line 2171, in create_url_adapter    return self.url_map.bind_to_environ(  File "/var/task/werkzeug/routing.py", line 1594, in bind_to_environ    wsgi_server_name = get_host(environ).lower()  File "/var/task/werkzeug/wsgi.py", line 168, in get_host    rv = environ["SERVER_NAME"] [ERROR] KeyError: 'SERVER_NAME' Traceback (most recent call last):   File "/var/task/flask_lambda.py", line 97, in call     return super(FlaskLambda, self).call(event, context)   File "/var/task/flask/app.py", line 2464, in call     return self.wsgi_app(environ, start_response)   File "/var/task/flask/app.py", line 2442, in wsgi_app     ctx = self.request_context(environ)   File "/var/task/flask/app.py", line 2359, in request_context     return RequestContext(self, environ)   File "/var/task/flask/ctx.py", line 292, in init     self.url_adapter = app.create_url_adapter(self.request)   File "/var/task/flask/app.py", line 2171, in create_url_adapter     return self.url_map.bind_to_environ(   File "/var/task/werkzeug/routing.py", line 1594, in bind_to_environ     wsgi_server_name = get_host(environ).lower()   File "/var/task/werkzeug/wsgi.py", line 168, in get_host     rv = environ["SERVER_NAME"]

Issues with Python 3.6

As AWS Lambda announced their support for Python 3.6 a few days ago, I was testing flask-lambda with Python 3.6.

Under the FlaskLambda.__call__ method, there is this:

    body = next(self.wsgi_app(
        make_environ(event),
        response.start_response
    ))

However, the type of body always becomes bytes, and you ways end up getting the following error message when calling it via AWS Lambda.

An error occurred during JSON serialization of response: b'(your response)' is not JSON serializable

I know the following patch (body -> body.decode('utf-8')) will get my work done for now, but it is probably not a good general solution.

    return {
        'statusCode': response.status,
        'headers': response.response_headers,
        'body': body.decode('utf-8')
    }

What would be a good resolution for this issue?

handler file

hello,

Im very confused with the handler file.

I have a small flask web app. i have used the module flask-lambda , below is my app.my

from flask_lambda import FlaskLambda

app = FlaskLambda(__name__)

@app.route('/health_check')
def index():
    return "OK"

Now is my requirements.txt :

flask==2.1.3
flask-lambda==0.0.4
pytest
werkzeug==2.0.3

On my local when i add the app.run() in my code, the flask app works good.

 * Serving Flask app 'app' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 215-906-159

But i'm unable to dockerise this.

This is my entry file :

#!/bin/sh

if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
    exec /usr/bin/aws-lambda-rie /usr/bin/python3 -m awslambdaric $1
else
    exec /usr/bin/python3 -m awslambdaric $1
fi

This is my docker file :

ARG FUNCTION_DIR="/opt/myapp"

FROM ubuntu:22.04

RUN apt update && apt-get install -y python3 python3-dev python3-pip

RUN python3 -m pip --no-cache-dir install awslambdaric
ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie

ARG FUNCTION_DIR
RUN mkdir -p ${FUNCTION_DIR}
WORKDIR /opt
ADD myapp myapp
COPY ./requirements.txt requirements.txt 
RUN pip install -r requirements.txt
COPY entry.sh /opt/myapp/entry.sh
RUN chmod 755 /usr/bin/aws-lambda-rie /opt/myapp/entry.sh
WORKDIR /tmp
ENTRYPOINT [ "/opt/myapp/entry.sh" ]
CMD [ "/opt/myapp/app.handler" ]

First i have to dockerise this and test on local. which is not working at all. Do i need to create a file app.handler or the module flask-lambda does the event things automatically ?

Or do i have to add the app.run() part in the app.py ?

I know lambda needs a handler for events

Thanks for helping :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.