How to call an external API webservice from Python in Amazon Lambda? - web-services

I am pretty new to AWS Lambda i have a python code which has a post method for making an external API call,
import requests
import json
url = "http://sample/project"
headers = {
'content-type': "application/json"
}
r = request.post(url,headers=headers)
I tried putting it into a AWS Lamda call i tried like this below but it didn't get worked out
import requests
import json
url = "http://sample/project"
headers = {
'content-type': "application/json"
}
def lambda_handler(event, context):
response = requests.request("POST", url, headers=headers)
return response
But i am not getting in any response if i am running from local machine i am getting the output.Please help me how can i make a post call from AWS Lamda

Related

Getting 400 Bad Request from Open AI API using Python Flask

I want to get response using Flask from OpenAI API. Whether I am getting Status 400 Bad Request from Browser through http://127.0.0.1:5000/chat
Bad Request
The browser (or proxy) sent a request that this server could not understand.
Also I am checking this from Postman
from flask import Flask, request, render_template
import requests
app = Flask(__name__)
#app.route('/')
def index():
return 'Welcome to ChatGPT app!'
#app.route('/chat', methods=['GET', 'POST'])
def chat():
user_input = request.form['text']
# Use OpenAI's API to generate a response from ChatGPT
response = generate_response_from_chatgpt(user_input)
return response
def generate_response_from_chatgpt(user_input):
api_key = "YOUR_API_KEY"
url = "https://api.openai.com/v1/engines/davinci/completions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
data = {
"prompt": user_input,
"engine": "davinci"
}
response = requests.post(url, headers=headers, json=data)
return response.json()["choices"][0]["text"]
if __name__ == '__main__':
app.run()
It would be best if you check the openai documentation to make sure you are using the correct endpoint and data format in your request.
Also, you should check your API key, if it is correct and if you have reached the limit of requests.
Also, it's worth noting that the code you provided is missing the import statement for Flask. You will need to add the following line at the top of your file:
from flask import Flask, request
Also, I see that you're using request.form['text'] but you should check if the request is a GET or POST request.
if request.method == 'POST':
user_input = request.form['text']
else:
user_input = request.args.get('text')
This is to avoid a KeyError being raised when the request is a GET request.

Using telethon with a django application

I want to watch updates on telegram messages in an django application and interact with django orm.
I found telethon library, it works with user api which is what I want.
Below code simply works on its own.
from telethon import TelegramClient
from telethon import events
api_id = 231232131
api_hash = '32131232312312312edwq'
client = TelegramClient('anon', api_id, api_hash)
#client.on(events.NewMessage)
async def my_event_handler(event):
if 'hello' in event.raw_text:
await event.reply('hi!')
client.start()
But telethon requires phone message verification and it needs to work in a seperate thread.
I couldn't find a way to put this code in a django application. And when django starts, I dont know how to bypass phone verification.
It should always work in an seperate loop and interact with django orm. Which is very confusing for me.
You can simply use django-telethon and use the API endpoints for signing bot and user session.
run the following command to start the server:
python manage.py runserver
run the following command to start telegram client:
python manage.py runtelegram
go to admin panel and telegram app section. create a new app. get data from the your Telegram account.
request code from telegram:
import requests
import json
url = "127.0.0.1:8000/telegram/send-code-request/"
payload = json.dumps({
"phone_number": "+12345678901",
"client_session_name": "name of the client session"
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
send this request for sign in:
import requests
import json
url = "127.0.0.1:8000/telegram/login-user-request/"
payload = json.dumps({
"phone_number": "+12345678901",
"client_session_name": "name of the client session",
"code": "1234",
"password": "1234"
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
It's not the answer I wanted initially.
But, I think this is better approach.
Instead of trying to put all of this in django application. It's better to run it seperately and let django application communicate this with rest framework.

upload videos to s3 via API Gateway

I'm trying to upload mp4 videos to a s3 bucket via an API Gateway but I don't know how to do that. Everything works fine when I send a pdf file with Content-Type:application/pdf using this lambda function:
import json
import base64
import boto3
def lambda_handler(event, context):
s3 = boto3.client("s3")
get_file_content = event["content"]
decode_content = base64.b64decode(get_file_content)
s3_upload = s3.put_object(Bucket="mybucket", Key="content.pdf", Body=decode_content)
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
but how can I upload mp4 videos ???
Many thanks for your help

Generate Signed URL in S3 using boto3

In Boto, I used to generate a signed URL using the below function.
import boto
conn = boto.connect_s3()
bucket = conn.get_bucket(bucket_name, validate=True)
key = bucket.get_key(key)
signed_url = key.generate_url(expires_in=3600)
How do I do the exact same thing in boto3?
I searched through boto3 GitHub codebase but could not find a single reference to generate_url.
Has the function name changed?
From Generating Presigned URLs:
import boto3
import requests
from botocore import client
# Get the service client.
s3 = boto3.client('s3', config=client.Config(signature_version='s3v4'))
# Generate the URL to get 'key-name' from 'bucket-name'
url = s3.generate_presigned_url(
ClientMethod='get_object',
Params={
'Bucket': 'bucket-name',
'Key': 'key-name'
},
ExpiresIn=3600 # one hour in seconds, increase if needed
)
# Use the URL to perform the GET operation. You can use any method you like
# to send the GET, but we will use requests here to keep things simple.
response = requests.get(url)
Function reference: generate_presigned_url()
I get error InvalidRequestThe authorization mechanism you have provided is not supported when trying to access the url generated in normal browser – Aseem Apr 30 '19 at 5:22
As there isn't much info i am assuming you are getting signature version issue, if not maybe it will help someone else ! :P
For this you can import Config from botocore:-
from botocore.client import Config
and then get the client using this config and providing signature version as 's3v4'
s3 = boto3.client('s3', config=Config(signature_version='s3v4'))

Unable to post to bitbucket using OAuth2Session and requests_oauthlib in python

I have a python script that auto refreshes and gets a new access token to access bitbucket end points.
My script works as long as it a 'GET' request. I am trying to do a post to create a private repository inside a private project. But I am getting a 400 status code which means my request is malformed.
For eg:
protected_url='https://bitbucket.org/api/2.0/repositories/<team>'
from requests_oauthlib import OAuth2Session
client = OAuth2Session(client_id, token=token, auto_refresh_url=refresh_url,auto_refresh_kwargs=extra, token_updater=token_saver)
token=client.refresh_token(refresh_url, **extra)
token_saver(token)
client = OAuth2Session(client_id, token=token)
r = client.get(protected_url)
print r.content
works and fetches the list of repositories in bitbucket but
data1={"scm": "git", "is_private": "true", "fork_policy": "no_public_forks", "project": {"key": "project_key"}}
data=json.dumps(data1)
headers = {'Accept': 'application/json'}
protected_url='https://bitbucket.org/api/2.0/repositories/<team>/<new_repo>'
from requests_oauthlib import OAuth2Session
client = OAuth2Session(client_id, token=token, auto_refresh_url=refresh_url,auto_refresh_kwargs=extra, token_updater=token_saver)
token=client.refresh_token(refresh_url, **extra)
token_saver(token)
client = OAuth2Session(client_id, token=token)
r=client.post(protected_url, data=data, headers=headers)
print r.content
gives a 400 status code(the request is malformed) with the error
'{"type": "error", "error": {"message": "Private projects cannot
contain public repositories"}}'
. I have the access token to authenticate, my URIs are correct, it is just the syntax of the post request that looks incorrect. Can anyone help me fix this?