# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # Invoke Lambda in Request, Response Style, via SDK and API Gateway
#
# This article walks you through a minimal example of writing lambda function, and invoke this function via any programming language or API Gateway.

# First, let's install dependencies
# !pip install pip --upgrade -q
# !pip install boto3 -q
# !pip install requests -q

# ## Setup an Example Lambda Function
#
# Let's create a simple lambda function that take the data in ``event["data"]`` and return the sum of it.

# +
# content of func_sum_all.py

import json

def handler(event, context):
    print("Received event: " + json.dumps(event, indent=2))
    total = sum(event["data"])
    return {"total": total}


# -

# For request / response type of invoke, there are two common ways:
#
# 1. direct invoke via AWS SDK (Python / Ruby / Java ...)
# 2. http requests via API-Gateway
#
# **Let's see how to invoke lambda from your favorite programming language**.

# ## Invoke Lambda from any Programming Language
#
# Since **Lambda use binary json string as the interface**, so it doesn't matter of which programming language you use in either Lambda code, or invokation code. Let's use boto3 as example
#
# boto3 lambda invoke API reference: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/lambda.html#Lambda.Client.invoke

# +
# content of invoke_func_sum_all.py
import json
import boto3

# set up lambda client
aws_profile = "xxx" # replace it with your own aws profile
ses = boto3.Session(profile_name=aws_profile)
client = ses.client("lambda")

event = {"data": [1, 2, 3]}

response = client.invoke(
    FunctionName="test-int-with-api-gate",
    InvocationType="RequestResponse",
    Payload=json.dumps(event).encode("utf-8")
)

from pprint import pprint
pprint(response)
# -

payload = response["Payload"]
payload

binary = payload.read()
json_text = binary.decode("utf-8")
result = json.loads(json_text)
result

# ## Invoke Lambda Function via API Gateway
#
# API Gateway allows developer to isolate the lambda function from the api caller. It provides built-in access control, cache, and more useful feature
#
# Frist, let's set up your API gateway
#
# 1. Goto AWS API gateway console
# 2. Click Create API
# 3. Select **Protocol = Rest**, Create New API, pick a API name and click Create
# 4. Select your API in dashboard, choose **Resource menu**, create a post method, and link it to your lambda function.
# 5. Click **deploy api** in **Resource menu**, pick a stage name, let's say: "test"
# 6. Choose **Stage menu**, find your API endpoint url
#
#
# In python, requests is the community standard to make http request. Let's invoke the lambda function via http requests.
#
# Reference: https://2.python-requests.org/en/master/user/quickstart/#make-a-request

# +
import requests
import json

api_endpoint = "https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/test"
data = {"data": [1, 2, 3]}
response = requests.post(api_endpoint, data=json.dumps(data))
# -

response.text

type(response.text)

# ## Summary
#
# - The payload data in request and response are always binary json text.
# - The payload data in lambda function code input output are always json serializable object. In python, it usually a dict, rarely a list.

StarcoderdataJupyterScriptsDedupFiltered