I want to use a perfecely simple flask (v=1.0.2) app to subscribe to a PubSub hub, where the hub would send a GET request containing a challenge string, and my flask app is suppose to return the string and do nothing more. However, it keeps outputting a messy line at the end, which I assume to be info on the GET request itself, and I am having difficulty understanding how it comes about. Could anyone explain how I can get rid of it please? My codes and the output are below. Thanks a lot.
from flask import Flask, request
app = Flask(__name__)
#app.route('/', methods=["GET", "POST"])
def index():
# get request used to subscribe to webhook
if request.method == 'GET':
print(datetime.datetime.now())
challenge = request.args['hub.challenge']
return challenge
if __name__ == '__main__':
app.run(host='0.0.0.0', port="80")
The output lines are below, and I would like to get rid of the 2nd line please:
2020-06-08 15:38:30.135647
198.12.103.36 - - [08/Jun/2020 15:38:30] "[37mGET /?hub.mode=subscribe&hub.topic=https%3A%2F%2Fblog.xxx.com%2Ffeed&hub.challenge=u9bs6yja251eeraa714i&hub.lease_seconds=1296000 HTTP/1.1[0m" 200 -
Related
I'm trying to understand what is the best way a POST request can be redirected to a GET request.
for example -
POST /redirect HTTP/1.1
Host: www.example1.com
url=www.example2.com
and i've created the following flask to help me with that :
from flask import Flask,request, redirect
app = Flask(__name__)
#app.route('/redirect',methods=['POST'])
def redire():
url = request.form['url']
return redirect('https://www.example2.com', code=307)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888)
the "issue" in my case, is that the request that is being sent to
https://www.example2.com
is also a POST request which is not what i wanted.
Consider that I don't "care" about the body that needs to be sent to the
https://www.example2.com
endpoint, what is the best way to do so without any user intervention (meaning that I'm aiming for an auto redirect).
Note: I've tried to do it via PHP but I can't seem to figure it out.
Apologies if something is not clear.
In order to redirect a POST request to a GET request, you need to use code=303 because it requires the client to use the GET method to retrieve the requested resource.
#app.route('/redirect',methods=['POST'])
def redire():
url = request.form['url']
return redirect('https://www.example2.com', code=303)
the server
from flask import Flask, redirect
app = Flask(__name__)
#app.route('/redirect', methods=['POST'])
def redire():
return redirect('http://127.0.0.1:8888/get')
#app.route('/get', methods=['GET'])
def iam_get():
return {"code": "ok"}
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888)
the client
import requests
data = requests.get("http://127.0.0.1:8888/get")
print(data.text)
data = requests.post("http://127.0.0.1:8888/redirect")
print(data.text)
the result as follows
{"code":"ok"}
{"code":"ok"}
I'm trying to build a very simple API I will then fetch data from and my code looks like this:
from flask import Flask, request, jsonify
import backend as b
app = Flask(__name__)
#app.route('/api/data/', methods=['GET'])
def api():
d = {}
m = b.getMarks(b.login())
d['Marks'] = str(m)
return jsonify(d)
if __name__ == '__main__':
app.run()
When I run the app and open the web page it just says error 404 (even after typing /api/data/ in the url). Shouldn't my dictionary pop up? Sorry I'm very new to this so thanks in advance.
Also, I know for a fact that my dictionary (d) works, I printed it out.
Found the mistake: when running the API, this line
#app.route('/api/data/', methods=['GET'])
Should be replaced with this one:
#app.route('/api', methods=['GET'])
So you can just add '/api'to the url.
The code of the website
from flask import *
app = Flask(__name__)
#app.route("/<name>")
def user(name):
return f"Hello {name}!"
#app.route("/")
def home():
return render_template("index.html")
#app.route("/admin")
def admin():
return redirect(url_for("home"))
if __name__ == "__main__":
app.run()
If I go to http://127.0.0.1:5000/ there are not issues but when I go to https://127.0.0.1:5000/ (https not http this time) I get the following error
127.0.0.1 - - [17/Nov/2019 17:43:25] code 400, message Bad request version ('y\x03Ðã\x80¨R¾3\x8eܽ\x90Ïñ\x95®¢Ò\x97\x90<Ù¦\x00$\x13\x01\x13\x03\x13\x02À+À/̨̩À,À0À')
The error code 400, message Bad request version is basically what I expected since I have not set up SSL nor have I declared what the website should do when getting a https request. What I am curious to find out is what the weird symbols mean (y\x03Ð.... and so on). This goes out to multiple questions such as: Where do they come from? Have the python code attempted to access a random memory location with no specific data? Is the data just in a format that the console cannot handle? What does it mean? You get the idea.
You're missing the ssl_context in app.run() which configures Flask to run with HTTPS support.
See the this article about it
If this is just for testing, you can use adhoc mode.
if __name__ == "__main__":
app.run(ssl_context="adhoc")
I am starting to learn Flask, so I am a noob in this stuff, but I have ran out of ideas to implement, that is why I came here to ask. I have python script that makes a GET request to the API and it returns me a QRcode, after that I get the QRcode and add it to my html, everything works fine.
But I have this code checking for the JSON response that the API gives me, it haves three responses: "loading", "authenticated" & "got qr code".
req = requests.get('this is the link with my API token')
json_content = req.content
# parsed JSON content, ready to use
parsed_json = json.loads(json_content)
#app.route("/")
def index():
if parsed_json["accountStatus"] == "loading":
print(parsed_json["accountStatus"])
print(req.status_code)
return render_template("loading.html")
if parsed_json["accountStatus"] == "got qr code":
print(parsed_json["accountStatus"])
str_parsed_json = yaml.safe_load(parsed_json["qrCode"])
print(req.status_code)
return render_template("qrcodePage.html", str_parsed_json=str_parsed_json)
if parsed_json["accountStatus"] == "authenticated":
print(parsed_json["accountStatus"])
print(req.status_code)
return render_template("index.html")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
The response I am getting is a 200
I have searched all over the internet to see if someone else has the same issue as me, but I haven't found one person with this problem.
I have tried restarting the following
Restart my local server
Making True the debug thing in the app.run()
Check in PostMan the server response but it always return me the expected result, but changes are not seen in the page.
The only way it seems to work is when I make some changes to my code, and restart the server, that is when I can refresh the page and redirect me to the expected template file.
Thanks in advance.
Move your requests.get and all subsequent object based on that inside your index():
#app.route("/")
def index():
req = requests.get('this is the link with my API token')
json_content = req.content
# parsed JSON content, ready to use
parsed_json = json.loads(json_content)
if parsed_json["accountStatus"] == "loading":
print(parsed_json["accountStatus"])
return render_template("loading.html")
... rest of your code
Currently your requests is not being refreshed past the point of your server starting. But if you move it inside your #app.route("/") each time you visit the site's root page, it will do a new requests.get() to refresh your data.
I want to do a web API which consist only POST. Currently I need to run python script on the web, so I am building a python web server from flask in Heroku. However, my issue is, whenever I send POST request from POSTMAN, what I will receive is the return data which is actually from GET request. Below is my code:
from flask import Flask
from flask import request
import os
app = Flask(__name__)
#app.route("/", methods=['GET', 'POST'])
def api_grab_key():
if request.method == 'POST':
if request.headers['Content-Type'] == 'application/json':
return request.json["imgUrl"]
else:
return "Request must be in JSON"
if request.method == 'GET':
return "Hello World! GET request"
if __name__ == "__main__":
port = int(os.environ.get('PORT', 33507))
app.run(host='0.0.0.0', port=port)
It works when I run locally, but not on Heroku. On Heroku, the output is always "Hello World! GET request" Thanks!
Sorry, apparently my issue is in the URL. So in Heroku, it has xxx.heroku.com and xxx.herokuapp.com.
I don't know why, requests sent to xxx.heroku.com turns into GET request. So, I had to change it to xxx.herokuapp.com for POST request.
I don't see anything jumping out, have you tried enabling debugging mode in Flask?
app.run(debug=True)
Then:
heroku logs --tail