How to send http request to flask installed on EC2 - amazon-web-services

I've tried to set up a flask restful api on EC2 and used postman to test a request, but it returned a method result not allowed after I started a debugging session. Here is my python file:
from flask import Flask
from flask_restful import Api, Resource, reqparse
app=Flask(__name__)
api=Api(app)
data={
#angle
"a":0,
#hasStarted
"hs":False
}
class Angle(Resource):
def put(self):
parser=reqparse.RequestParser()
parser.add_argument("a")
parser.add_argument("hs")
args=parser.parse_args()
data["a"]=int(args["a"])
data["hs"]=bool(args["hs"])
return 200
api.add_resource(Angle,"/")
app.run(debug=True)
this is the PUT request I sent via postman:
ec2-xx-xxx-xx-xxx.us-east-2.compute.amazonaws.com/?a=10&hs=True
Also, I opened http (port 80), so should I use api.add_resource(Angle,"/var/www/html") instead?

I solved it. The reason is that I've already run apache on port 80, I opened 443 and ran my flask app there and it worked

Related

Flask: Request works on browser but not on Postman

I'm creating a simple Flask app. My problem is that when I try to do a request from Postman, I alway get a 501 Not Implemented.
However, if I do the request directly from my browser, I got a successful response.
My code is:
from flask import Flask, request
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class Logs(Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(Logs, '/logs')
if __name__ == '__main__':
app.run(debug=True, load_dotenv=True)
I'm not sure what is causing Postman to not being able to communicate with the app.
I'm sure I'm sending a GET request from Postman.
I'm attaching my Postman request configuration as an image.
Did you make sure you put your request type to GET and not to POST on Postman? The error usually means that the server doesn't know the request type and maybe expects a POST request but a post request hasn't been implemented in the Resource in your flask endpoint.

How to stop double message send in Flask based Slack application

I'm currently working on a custom bot for a Slack workspace to send messages when specific entries are given on a Google Sheet. I'm using a simple Flask setup with the Slack SDK and pydrive. I'm running into an issue where each message that is sent "asynchronusly" (i.e. not triggered by a specific Slack event) gets sent twice when running the Flask application. If I disable the Flask app, I only get one instance of the "Restarting Money Bot" sent. If the server is running, I get two instances, back to back. If the server is running and I respond to a slash command (test_command()), I only get the single response as required. I've attempted to alter the send method (using a raw API call rather than the SDK method) to no avail; I'm not sure where else to go with this issue.
Here's the code that's causing the issues. slack_handle just has simple wrapper functions for the API calls so I can keep Slack tokens and signatures local to one file:
from flask import Flask, request, redirect, make_response, render_template, send_from_directory
import os
import logging
import threading
import time
import json
from flask.wrappers import Response
import slack_handle
import drive_handle
logging.basicConfig(level=logging.DEBUG)
bot = Flask(__name__)
drive_access = drive_handle.gdrive()
#bot.route('/slack/test', methods=["POST"])
def test_command():
if not slack_handle.verifier.is_valid_request(request.get_data(), request.headers):
return make_response("Invalid request", 403)
td_test = threading.Thread(target = test_command_thread)
td_test.start()
return Response(status=200)
def test_command_thread():
slack_handle.sendMoneyBot("Money Bot is active :heavy_dollar_sign:")
slack_handle.sendMoneyBot("Last refreshed " + str(drive_access.access_time) + " minute(s) ago")
slack_handle.sendMoneyBot("Good connection: (" + str(drive_access.access_status) + ")")
# To run prior to server start
slack_handle.sendTreasurer("Restarting Money Bot")
td = threading.Thread(target = drive_access.mainDaemon)
td.daemon = True
td.start()
# Local server debug
if __name__ == "__main__":
port = int(os.environ.get('PORT', 5000))
bot.run(host='0.0.0.0', port=port, debug=True)
Any help would be awesome

How to make a request to local URL as part of automated tests?

I'm writing an automated test in Django to check that a webhook is working on the application. The test sends a bunch of JSON to the webhook and will check that the call has been logged in the database. The problem I'm hitting however is that the test calls the http://localhost URL and the data is thus saved in my local dev database and not in the temporary database created by the test. So I now have no way to check the call has been received.
Whats the right solution for this?
from django.test import TestCase
import requests
from monzo.models import Transaction, RequestLog
class WebhookChecks(TestCase):
fixtures = ['db.json', ]
def test_simple_expense(self):
my_json = '{"type": "transaction.created", REMOVED FOR SECURITY }'
url = 'http://localhost/some_url/webhook/'
headers = {'Content-Type': 'application/json'}
r = requests.post(url, data=my_json, headers=headers)
if not "200" in str(r):
print("Something didn't work out. Error: "+str(r))
self.assertTrue("200" in str(r))
Use Djangos Client with which you can perform requests in your tests.
Example:
from django.test import Client
c = Client()
c.get('/some_url/..')
Another way is to use Djangos LiveServerTestCase.
You can use self.live_server_url instead of directly writing http://localhost.
This testcase sets up a live server which listens to localhost.

localhost is not loading while trying to send mail using flask-mail

The localhost is not running and I am getting an OS:Error of 'No route to host' error when I run the flask app.
I've tried adding this:
app.run(host='0.0.0.0')
but it does not work.Also I have tried changing the port from 5000 to 4996 and various other ports but still I am facing the same issue .
Here is my complete code:
from flask import Flask
from flask_mail import Mail,Message
app = Flask(__name__)
app.config['DEBUG']=True
app.config['TESTING']=False
app.config['MAIL_SERVER']='smtp.gmail.com'
app.config['MAIL_PORT']=456
app.config['MAIL_USE_SSL']=True
#app.config['MAIL_DEBUG']=
app.config['MAIL_USERNAME']='trvt1234#gmail.com'
app.config['MAIL_PASSWORD']='#insert password here'
app.config['MAIL_DEFAULT_SENDER']='trvt1234#gmail.com'
app.config['MAIL_MAX_EMAILS']=None
#app.config['MAIL_SUPRESS_SEND']=
app.config['MAIL_ASCII_ATTACHMENTS']=False
email = Mail(app)
#app.route('/')
def mail():
message = Message('Hello',recipients=['trvt1234#gmail.com'])
email.send(message)
return('message sent successfully')
if __name__ == '__main__':
app.run(host='0.0.0.0')
I am a newbie to Flask and was figuring out how should I go on about this problem.
I think you have the wrong MAIL_PORT - it should be 465 not 456.

Flask / Werkzeug run_simple not displaying Exception traces

I created two flask apps: frontend and restapi (with flask-restful). I created the following runserver.py to run them in development:
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple
from restapi import app as restapi_app
from frontend import app as frontend_app
application = DispatcherMiddleware(frontend_app, {
'/api': restapi_app,
})
if __name__ == "__main__":
run_simple(
'localhost',
5000,
application,
use_reloader=True,
use_debugger=True,
use_evalex=True)
Despite having use_debugger=True, whenever one of the flask-restful resources raises an error, I don't get a trace, just a 500 error
{"status": 500, "message": "Internal Server Error"}
Any ideas how to get the full trace to display? Let me know if you need more details/code.
use_debugger option of Werkzeug WSGI server only enables embedded debugger, the server is unaware of Flask app configuration values (DEBUG in this case). To propagate exceptions to the server, you need to enable debug mode for both Flask app objects yourself. Here's one way to do it:
if __name__ == '__main__':
restapi_app.debug = True
frontend_app.debug = True
run_simple(...)