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.
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"}
So, I am trying to understand the digest authentication implementation with Python- Flask.
I did a simple test, I took the below code from the documentation,
from flask import Flask
from flask_httpauth import HTTPDigestAuth
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key here'
auth = HTTPDigestAuth()
users = {
"john": "hello",
"susan": "bye"
}
#auth.get_password
def get_pw(username):
if username in users:
return users.get(username)
return None
#app.route('/', methods=['HEAD'])
#auth.login_required
def index():
return "Hello, %s!" % auth.username()
if __name__ == '__main__':
app.run()
The code runs.
I paste this URL(host:port) in same in POSTMAN(head method), it always returns 401.
I am lost and am trying to get it work.
What am I doing wrong here?
OK so here is what the problem is, the URL works fine in the browser but not in POSTMAN.
This is happening due to the name resolution in your case, e.g. 9mxlhm2
You need to make sure that it resolved that name, try and see if you can ping that name mentioned or else easiest fix just use **0.0.0.0**, if this is local.
Make sure the authorization info is mentioned when you are doing a HTTP request via postman. Under the request section there will be a Authorization section. See this image as an example.
To reproduce the problem i used localhost but it didn't work and it gives me an error with 401, as soon as i try 0.0.0.0 in the GET request via postman, it starts to work again. Hope this fixes your problem. Although the hostname for me works(as in my own hostname, e.g rajlocal)
I am trying to make an API that when a POST request is made, it will accept images and then save them, and if a GET request is made then it will send back a URL to where you'd be able to download that image. How would that be possible?
This is the Flask app running on localhost for testing:
from flask import Flask, send_file
app = Flask(__name__)
#app.route("/upload_image/<filename>", methods=["POST"])
def upload_image(filename):
# receive the image here
# ...
#app.route("/get_image", methods=["GET"])
def get_image():
filename = "encoded_image.png"
return send_file(filename, mimetype="image/png")
if __name__ == "__main__":
app.run(host="localhost", port=5000)
I think sending the image is easy but I don't know how to go about receiving it and using requests to send it.
This is the idea behind the main code:
import requests
option = input()
if option == "get image":
print("Download the image at: https://localhost:5000/get_image")
elif option == "upload image":
post = requests.post("https://localhost:5000/upload_image/encoded_image.png")
i don't want the images to change names. I always want to send the file encoded_image.png and receive it, because I want it to be overwritten when the POST is made. This is for a discord bot but that doesn't really affect anything, I just thought I'd mention it. Thanks in advance :)
I have a decently intermediate understanding of APIs, and am not trying to host information I've got from APIs onto the web.
This incredibly simple code:
from flask import Flask, request, render_template
import requests
app = Flask(__name__)
#app.route('/temperature', methods=['POST'])
def temperature():
zipcode = request.form['zip']
r = requests.get('http://api.openweathermap.org/data/2.5/weather?zip=' +zipcode+',us&appid=9b56b06ab4c7f06821ccf55e3e10fce5')
json_obj = r.text
return json_obj
#app.route('/')
def index():
return 'hi'
if __name__ == '__main__':
app.run(debug=True)
Is not giving me anything (except the 405 error).
Can someone please explain why my POST method is not working?
While I'm not entirely sure what you have done, here's what I think you did:
You accessed the /temperature page in your browser which is by default a GET-Request.
You then get returned a 405 Method Not Allowed Error, because your route explicitly requires that the page will be accessed via the HTTP-POST Method.
Modify #app.route('/temperature', methods=['POST']) to #app.route('/temperature', methods=['POST', 'GET']) and you should be fine.
I'll post my answer from /r/ flask here, just for posterity.
the line in your code: zipcode = request.form['zip'] implies that you are submitting data from an HTML form to the view via a POST.
If there is no form, then request.form['zip'] does nothing, and is most likely raising the error. Considering that I see no route in your logic there that points to any HTML, I'm guessing that's the issue.
If you have not built a form for the user to submit the zip code, then you could build it into the route logic. For example, you could do:
#app.route('/temperature/<zipcode>')
def temperature(zipcode):
# add some kind of validation here to make sure it's a valid zipcode
r = requests.get('http://api.openweathermap.org/data/2.5/weather?zip=' +zipcode+',us&appid=DONT_SHARE_YOUR_API_KEY')
json_obj = r.text
return json_obj
You could then use http://127.0.0.1:5000/temperature/20003 to see the data for that zip code.
(as a side note, it's often unwise to publicly share your API keys. you may want to generate a new key.)
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