Where would I receive http request in AWS - python

Am beginner to Amazon web services.
I have a below lambda python function
import sys
import logging
import pymysql
import json
rds_host=".amazonaws.com"
name="name"
password="123"
db_name="db"
port = 3306
def save_events(event):
result = []
conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name,
connect_timeout=30)
with conn.cursor(pymysql.cursors.DictCursor) as cur:
cur.execute("select * from bodyPart")
result = cur.fetchall()
cur.close()
print ("Data from RDS...")
print (result)
cur.close()
bodyparts = json.dumps(result)
bodyParts=(bodyparts.replace("\"", "'"))
def lambda_handler(event, context):
save_events(event)
return bodyParts
using an above function am sending json to the client using API gateway, now suppose user selects an item from the list and send it back, in form of json where will i get http request and how should i process that request

I just made an additional information for #Harsh Manvar.
The easiest way I think is you can use
api-gateway-proxy-integration-lambda
Currently API Gateway support AWS lambda very good, you can pass request body (json) by using event.body to your lambda function.
I used it everyday in my hobby project (a Slack command bot, it is harder because you need to map from application/x-www-form-urlencoded to json through mapping template)
And for you I think it is simple because you using only json as request and response. The key is you should to select Integratiton type to Lambda function
You can take some quick tutorials in Medium.com for more detail, I only link the docs from Amazon.
#mohith: Hi man, I just made a simple approach for you, you can see it here.
The first you need to create an API (see the docs above) then link it to your Lambda function, because you only use json, so you need to check the named Use Lambda Proxy integration like this:
Then you need to deploy it!
Then in your function, you can handle your code, in my case, I return all the event that is passed to my function like this:
Finally you can post to your endpoint, I used postman in my case:
I hope you get my idea, when you successfully deployed your API then you can do anything with it in your front end.
I suggest you research more about CloudWatch, when you work with API Gateway, Lambda, ... it is Swiss army knife, you can not live without it, it is very easy for tracing and debug your code.
Please do not hesitate to ask me anything.

you can use aws service called API-gateway it will give you endpoint for http api requests.
this api gateway make connection with your lambda and you can pass http request to lambda.
here sharing info about creating rest api on lambda you can check it out : https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html
aws also provide example for lambda GET, POST lambda example.you just have to edit code it will automatically make api-gateway.as reference you can check it.
From Lambda Console > create function > choose AWS serverless repository > in search bar type "get" and search > api-lambda-dynamodb > it will take value from user and process in lambda.
here sharing link you can direct check examples : https://console.aws.amazon.com/lambda/home?region=us-east-1#/create?tab=serverlessApps

Related

How to pass received (bearer) access token to generated REST Client in order to invoke secured API-Gateway Endpoint

Im fairly new to AWS and its Cognito and API-Gateway services.
I have created in AWS a Cognito-specific User Pool and an AWS-specific API-Gateway API with some API-Endpoints to be accessed via REST API calls. The API-Gateway "Authorizer" is set to "Cognito".
After that, I have exported the Swagger document/OpenAPI2.0 using the AWS-Console specific export function and generated with the Swagger Editor a Python REST Client API.
The generated REST Client SDK generated the Model-specific "GET" function, e. g.:
# create an instance of the API class
api_instance = swagger_client.DefaultApi()
user_id = 'user_id_example' # str |
try:
api_response = api_instance.user_get(user_id)
pprint(api_response)
except ApiException as e:
print("Exception when calling DefaultApi->user_get: %s\n" % e)
In order to get a correct result from the function call api_instance.user_get(user_id)
I need somehow pass the access token to that function.
The question is now, how do I pass the access token - which I have successfully obtained after the User signed-in - to the Python REST Client API in order to invoke an API-Endpoint function which has an "Cognito" authorizer set?
I saw many expamples how to realize this with Postman or CURL, but this is not what I'm looking for. I want to invoke my "Cognito" protected API-Endpoint in AWS API-Gateway with the generated REST API Client. I assume, there must be a way to put the received access token to the "Authorization" Header in the HTTP-Request call, before the generated REST Client function is invoked.
Any help is very appreciated.
I'm not sure if I've understood you correctly, but this might help you.
import requests
endpoint = ".../api/ip"
data = {"ip": "1.1.2.3"}
headers = {"Authorization": "Bearer MyBearerAuthTokenHere"}
print(requests.post(endpoint, data=data, headers=headers).json())
#Edit
You don't need to parse the response as json if it isn't. This is just an Sample.

Can't access 'event' properties when calling it in Lambda Function in AWS

I have a specific issue on my AWS lambda function that I have recently built (in python 3.8). It's supposed to support a post request and put an item from the body of the request into a table in DynamoDB.
My Lambda function looks like this:
When I test using API Gateway it works perfectly and I get what I expect.
and the item gets inserted into the table. This is the response on the API-Gateway Test:
Here's my API gateway post method set up:
However, when I use postman and try to post a JSON I get this Key Error: (Note the JSON body of the post is identical).
Any help I get here will be very much appreciated.
Edit: For those who have read the comments below. This is the code I'm using to return the event:
So I believe I solved the issue. I simply un-ticked the 'use lambda proxy integration' box when setting up the post method in API Gateway. Now I'm receiving the body as the event as I wanted. Thank you for your responses anyway.
def handler(event, context):
requestObject = ""
if "requestObject" in event:
requestObject = event["requestObject"]
else:
requestJson = json.loads(event["body"])
if "requestObject" in requestJson:
serialNumber = requestJson["requestObject"]

Redirect from a Python AWS Lambda with AWS Gateway API Proxy

Posting here because I just can't get a redirect working. Using AWS API Gateway linked to a Python Lambda function as a proxy just returns the response and header json. Here is the code
import json
def lambda_handler(event, context):
response = {}
response["statusCode"]=301
response["headers"]=[{"key": 'Location',"value":
'https://www.google.com'}]
data = {}
response["body"]=json.dumps(data)
return response
Any help will be appreciated?
Thanks
Mixed documentation on the web which was confusing. The syntax for specifying the redirect using Location needs to be the following when using Python:
import json
def lambda_handler(event, context):
response = {}
response["statusCode"]=302
response["headers"]={'Location': 'https://www.google.com'}
data = {}
response["body"]=json.dumps(data)
return response
I'll prefix this by saying that when I copied this code into a Lambda function, added an API Gateway to it using the settings that made sense to me, and tested from a browser and curl, I got the correct redirect. Which is expected, the code looks right and conforms to the specification in the documentation.
So I spent some time fiddling with settings in Lambda and in API Gateway to try to break it; plus searching the web to see how others have had it not work.
The general Internet consensus in 2021 (time of original post) is that there was a setting "Use Lambda proxy integration" in the API Gateway that needed to be turned on for API Gateway to interpret the returned JSON correctly, and this was not the default. I can't find that setting in the console today in that format, but when you create an API Gateway "API" you select integrations, the first one in the list is Lambda. Selecting that sets up the integration correctly for interpreting the JSON (in either v1 or v2 format).
If you are working in an older already-configured API Gateway endpoint, I'd suggest looking for the "Use Lambda proxy integration" setting, followed by setting up the API Gateway with the "Lambda" integration setting if it is the new-style interface.
a bit less line, with the same output
def handler(event, context):
response = {
"headers": {"Location": "https://www.google.com", },
"statusCode": 301,
}
return response

How to query AWS CloudSearch domain using Python boto3 library?

I'm trying to use boto3 to query my CloudSearch domain using the docs as a guide: http://boto3.readthedocs.io/en/latest/reference/services/cloudsearchdomain.html#client
import boto3
import json
boto3.setup_default_session(profile_name='myprofile')
cloudsearch = boto3.client('cloudsearchdomain')
response = cloudsearch.search(
query="(and name:'foobar')",
queryParser='structured',
returnFields='address',
size=10
)
print( json.dumps(response) )
...but it fails with:
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "https://cloudsearchdomain.eu-west-1.amazonaws.com/2013-01-01/search"
But how am I supposed to set or configure the endpoint or domain that I want to connect to? I tried adding an endpoint parameter to the request, thinking maybe it was an accidental omission from the docs, but I got this error response:
Unknown parameter in input: "endpoint", must be one of: cursor, expr, facet, filterQuery, highlight, partial, query, queryOptions, queryParser, return, size, sort, start, stats
The docs say:
The endpoint for submitting Search requests is domain-specific. You submit search requests to a domain's search endpoint. To get the search endpoint for your domain, use the Amazon CloudSearch configuration service DescribeDomains action. A domain's endpoints are also displayed on the domain dashboard in the Amazon CloudSearch console.
I know what my search endpoint is, but how do I supply it?
I found a post on a Google forum with the answer. You have to add the endpoint_url parameter into the client constructor e.g.
client = boto3.client('cloudsearchdomain', endpoint_url='http://...')
I hope those docs get updated, because I wasted a lot of time before I figured that out.
import boto3
client = boto3.client('cloudsearchdomain',
aws_access_key_id= 'access-key',
aws_secret_access_key= 'some-secret-key',
region_name = 'us-east-1', # your chosen region
endpoint_url= 'cloudsearch-url'
# endpoint_url is your Search Endpoint as defined in AWS console
)
response = client.search(
query='Foo', # your search string
size = 10
)
Reference response['hits'] for returned results.

How to modify API gateway integration request using Boto3

I have created an api gateway from my existing api using boto3 import command.
apiClient = boto3.client('apigateway', awsregion)
api_response=apiClient.import_rest_api
(
failOnWarnings=True,
body=open('apifileswagger.json', 'rb').read()
)
But i cant modify integration request. I tried with following Boto3 command.
apiClient = boto3.client('apigateway', awsregion)
api_response=apiClient.put_integration
(
restApiId=apiName,
resourceId='/api/v1/hub',
httpMethod='GET',
integrationHttpMethod='GET',
type='AWS',
uri='arn:aws:lambda:us-east-1:141697213513:function:test-lambda',
)
But I got error like this
Unexpected error: An error occurred () when calling the PutIntegration operation:
I need to change lambda function region & name using Boto3 command. is it possible? .
if it is possible what is the actual issue with this command?
In the put_integration() call listed above, your restApiId and resourceId look incorrect. Here's what you should do.
After importing your rest API, check to see if it is available by calling your apiClient's get_rest_apis(). If the API was imported correctly, you should see it listed in the response along with the API's ID (which is generated by AWS). Capture this ID for future operations.
Next, you'll need to look at all of the resources associated with this API by calling your apiClient's get_resources(). Capture the resource ID for the resource you wish to modify.
Using the API ID and resource ID, check to see if an integration config exists by calling your apiClient's get_integration(). If it does exist you can modify the integration request by calling update_integration(); if it does not exist, you need to create a new integration by calling put_integration() and passing the integration request as a parameter.
Here's an example of how that might look in code:
# Import API
api_response1 = apiClient.import_rest_api(failOnWarnings=True, body=open('apifileswagger.json', 'rb').read())
print(api_response1)
# Get API ID
api_response2 = apiClient.get_rest_apis()
for endpoint in api_response2['items']:
if endpoint['name'] == "YOUR_API_NAME":
api_ID = endpoint['id']
# Get Resource ID
api_response3 = apiClient.get_resources(restApiId=api_ID)
for resource in api_response3['items']:
if resource['path'] == "YOUR_PATH":
resource_ID = resource['id']
# Check for Existing Integrations
api_response4 = apiClient.get_integration(restApiId=api_ID, resourceId=resource_ID , httpMethod='GET')
print(api_response4)
# Create Integration with Request
integration_request = { 'application/json': '{\r\n "body" : $input.json(\'$\'),\r\n}' }
api_response5 = apiClient.put_integration(restApiId=api_ID, resourceId=resource_ID , httpMethod='GET', type='AWS',
integrationHttpMethod='GET', uri="YOUR_LAMBDA_URI", requestTemplates=integration_request)
print(api_response5)
All the methods listed above are explained in the Boto3 Documentation found here.
As with most API Gateway updates to API definitions, in order to update an integration request, you have to do a PATCH and pass a body with a patch document using the expected format. See documentation here

Categories

Resources