I have a virtual machine running on a google cloud project with Debian as is OS. it doesn't have its http or https ports open, but when I run the following code, I get a response.
import urllib
import requests
req = urllib.request.Request("https://google.com")
with urllib.request.urlopen(req) as resp:
message = resp.read()
print(message[:15])
I get a response, b'<!doctype html>'.
I have a flask web app that takes a long time to process a request (around 45 minutes).
from flask import Flask, requests
import os
app = Flask(__name__)
#app.route('/', methods=['POST'])
def index():
payload = json.loads(request.get_data(as_text=True))
# runs long running task
if something_went_wrong:
return "something went wrong", 500
return "the task ended successfully", 200
if __name__ == "__main__":
app.run(debug=False, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))
The issue that I am having is that when I run the following code, it hangs on urlopen and eventually times out. I've checked the logs on my flask app. it runs successfully and there's a post 200 in the logs.
import urllib
import request
import json
import google.auth.transport.requests
import google.oauth2.id_token
payload = json.dumps({"key1":"value1", "key2":"value2"}).encode()
req = urllib.request.Request("https://my-service-url.app")
auth_req = google.auth.transport.requests.Request()
id_token = google.oauth2.id_token.fetch_id_token(auth_req, "https://my-service-url.app")
req.add_header("Authorization", f"Bearer {id_token}")
with urllib.request.urlopen(url=req, data=payload, timeout=60*60) as resp:
print(resp.read())
Is the timeout too long and it stops listening somewhere else in the system?
is my flask app not responding properly?
is the time I am asking simply unreasonable?
Related
I'm using python requests in order to make an API call and change the HEAD of the repo on Gerrit but for some reason it doesn't work. I've tried to call it with Postman and works fine but from my code i can't.
from flask import Flask
import requests
app = Flask(__name__)
#app.route("/test", methods=["PUT"])
def hello_world():
headers = {"Content-Type":"application/json"}
password = "khOGam97z5hKR+zmONVOx23bvlFROANtzc5hTaCNQQ"
response = requests.put("http://localhost:8080/a/projects/myproject/HEAD", data={ "ref": "refs/heads/test"}, auth=("admin", password), headers=headers)
return response.reason
if __name__=="__main__":
app.run()
I am new to python and flask and I am encountering a problem with Flask. I am trying to use a local HTTP POST (webhook) to call a function from another file, but when I do nothing happens.
from flask import Flask
from BotSpeak import main
app = Flask(__name__)
#app.route('/', methods=['POST'])
def respond():
main('hello')
if __name__ == '__main__':
app.run()
This is my very basic Flask app. As you can see it is trying to call the main function from this file (BotSpeak):
from json import dumps
from httplib2 import Http
def main(botmsg):
url = 'PLACEHOLDER FOR GOOGLE CHAT WEBHOOK URL'
bot_message = {
'text' : botmsg}
message_headers = {'Content-Type': 'application/json; charset=UTF-8'}
http_obj = Http()
response = http_obj.request(
uri=url,
method='post',
headers=message_headers,
body=dumps(bot_message),
)
print(response)
if __name__ == '__main__':
main("TEST MESSAGE")
This is the code that shoots local HTTP POSTs to my flask app:
import json
import requests
webhook_url ='http://127.0.0.1:5000/'
data = {PLACE HOLDER FOR JSON DATA}
r = requests.post(webhook_url, data=json.dumps(data), headers={'Content-Type': 'application/json'})
I can call the main function from other files outside the flask app and it'll work but it just wont trigger in the app.route decorator like it should. I really appreciate anyone's help and I encourage you to throw these into VS Code and try it for yourself.
If you're using flask you don't have to manually construct an HTTP response using httplib2 unless you have some very specific use case.
In your case you can just return bot_message since if the return value of a Flask handler is a dict it will convert it to a JSON response (including the correct headers). See
https://flask.palletsprojects.com/en/2.0.x/quickstart/#about-responses
In other words, your entire route handler could be rewritten (based off your example at least):
#app.route('/', methods=['POST'])
def respond():
return {'text': 'hello'}
If you want to pass the handling off to some utility function you can do that too, just make sure it returns a value, and that you in turn return an appropriate value from your respond() function.
I am receiving a 11200 HTTPS retrieval error from the code below. Can someone please explain me how I can resolve this? (I am hosting this application on a local server and using the ngrok https 5000 URL for the twilio API)
from flask import Flask, Response, request
from twilio import twiml
import os
from twilio.http.http_client import TwilioHttpClient
import requests
from twilio.rest import Client
app = Flask(__name__)
port = int(os.environ.get('PORT', 5000))
account_sid = "xxx"
auth_token = "xxx"
# proxy_client = TwilioHttpClient(proxy={'http': os.environ['http_proxy'], 'https': os.environ['https_proxy']})
client = Client(account_sid, auth_token)
#app.route("/")
def check_app():
# returns a simple string stating the app is working
return Response("It works!"), 200
#app.route("/twilio", methods=["POST"])
def inbound_sms():
response = twiml.Response()
# we get the SMS message from the request. we could also get the
# "To" and the "From" phone number as well
inbound_message = request.form.get("Body")
print(inbound_message)
# we can now use the incoming message text in our Python application
if inbound_message == "Hello":
response.message("Hello back to you!")
else:
response.message("Hi! Not quite sure what you meant, but okay.")
# we return back the mimetype because Twilio needs an XML response
return Response(str(response), mimetype="application/xml"), 200
if __name__ == "__main__":
app.run(debug=True)
You mixed up your Flask response and Twilio response, your code is actually raising an AttributeError with the Twilio Python Helper Library version 6.45.1 under Python 3.6.9 because Twilio doesn't have a twiml.Response attribute.
Change your code to the following, please note the usage of MessagingResponse:
#app.route("/twilio", methods=["POST"])
def inbound_sms():
response = MessagingResponse()
inbound_message = request.form.get("Body")
if inbound_message == "Hello":
response.message("Hello back to you!")
else:
response.message("Hi! Not quite sure what you meant, but okay.")
return Response(str(response), mimetype="application/xml"), 200
Don't forget to add from twilio.twiml.messaging_response import MessagingResponse to your imports. See also the example in the Twilio documentation.
I've only tested it locally but then your /twilio endpoint returns correct TwiML when hitting it with HTTPie:
$ http --form POST http://127.0.0.1:5000/twilio Body=Hello
HTTP/1.0 200 OK
Content-Length: 96
Content-Type: application/xml; charset=utf-8
Date: Fri, 26 Feb 2021 12:15:30 GMT
Server: Werkzeug/1.0.1 Python/3.6.9
<?xml version="1.0" encoding="UTF-8"?><Response><Message>Hello back to you!</Message></Response>
I want to forward a GET request that I get from a client to a different site,
In my case- A m3u8 playlist request to a streaming site to handle.
Does anyone know how can it be done?
If you want to proxy, first install requests:
pip install requests
then, get the file in the server and serve the content, ej:
import requests
from flask import Flask, Response
app = Flask(__name__)
#app.route('/somefile.m3u')
def proxy():
url = 'https://www.example.com/somefile.m3u'
r = requests.get(url)
return Response(r.content, mimetype="text/csv")
app.run()
If you just want to redirect, do this (requests not needed):
from flask import Flask, redirect
app = Flask(__name__)
#app.route('/redir')
def redir():
url = 'https://www.example.com/somefile.m3u'
return redirect(url, code=302)
app.run()
I have a simple flask server
import pdb
from flask import Flask, jsonify, abort, make_response, request, send_from_directory
from flask_cors import CORS, cross_origin
from pprint import pprint
import argparse
from mylib.mylib_rest_api import ProcessRestApiRequest
DEBUG=True
app = Flask(__name__)
CORS(app)
parser = argparse.ArgumentParser(description='Run the server')
parser.add_argument('--ip-address', default='127.0.0.1', help='Server IP Address. Default: %(default)s')
parser.add_argument('--port', type=int, default=8081, help='Server port')
args = parser.parse_args()
#app.errorhandler(404)
def not_found(error):
return make_response(jsonify({'error': 'Not found'}), 404)
def do_pre_serve_actions():
if not request.json: abort(400)
# Extract the data
dictReq = request.get_json(force=True)
if DEBUG:
pprint('dictReq: '+str(dictReq))
return dictReq
def do_post_serve_actions(dictResp):
if DEBUG:
pprint("dictResp: "+str(dictResp))
dictJSONResp = jsonify(dictResp)
objRespADF = make_response(dictJSONResp)
return objRespADF
#app.route('/<target>', methods=['POST'])
def serve(target):
dictReq = do_pre_serve_actions()
dictResp = ProcessRestApiRequest(dictReq, target)
return do_post_serve_actions(dictResp)
if __name__ == '__main__':
app.run(debug=DEBUG, host=args.ip_address, port=args.port)
This is how a request looks like:
makeRequestAndSendData(xhr, dict) {
dict['Interface'] = this.getChipInterface();
var data = JSON.stringify(dict);
var url = this.server.getUrl();
console.log("url: "+url);
console.log("Request Dictionary:");
console.log(dict);
xhr.open("POST", url, true);
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.setRequestHeader("Access-Control-Allow-Headers","*");
xhr.setRequestHeader("Access-Control-Allow-Credentials", "true");
xhr.setRequestHeader("Content-type","application/json");
xhr.send(data);
}
Here is what I'm getting:
Failed to load http://192.168.0.132:8084/mychip: Response to preflight
request doesn't pass access control check: The
'Access-Control-Allow-Origin' header has a value 'null' that is not
equal to the supplied origin. Origin 'null' is therefore not allowed
access.
What am I doing wrong? I've looked everywhere online and it seems like it got everything I need. Am I missing something?
This can happen with Chrome and WebKit/Chrome based browsers (Opera, Brave, etc.) if you serve the page from the file system instead of the network. In that case there is no origin site (because it was served from file), and Chrome will send the header Origin: null in the preflight OPTIONS request. Your CORS enabled Flask server will reply with this origin in its preflight response, however, Chrome rejects it as an invalid origin, even though that is what Chrome sent in the first place.
Firefox also sends header Origin: null in the OPTIONS request, but it is OK with the response and so it does issue the actual POST request. I have also found that Chrome on Android does seem to work when loading from the file system.
As a work-around, serve your test file from a HTTP server. The easiest way (for testing purposes only) is to use Python's SimpleHTTPSever. Simply change to the directory containing your test HTML file and run this command:
$ python -m SimpleHTTPServer
It will start a HTTP server listening on port 8000 so you can load the file into your browser using URL http://localhost:8000/cors_test.html for example.
Also note that the Access-Control-Allow-* headers are meant to be sent in the preflight response, not the request. flask-cors will generally handle that for you and the client side XMLHttpRequest object should properly construct the request for you.