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()
Related
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?
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 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 simplify my requirement to this simple code
from flask import Flask, request
import requests
app = Flask(__name__)
#app.route('/', methods=['POST'])
def root():
payload = {'Message': 'yo','Port':'123'}
r = requests.post("http://127.0.0.1:5000/test", data=payload)
return r.text
#app.route('/test', methods=['POST'])
def test():
return request.form['Message']+','+request.form['Port']
if __name__ == '__main__':
app.run(debug=True)
I've tested the url '127.0.0.1:5000/test' by google's Postman.
I send the data to the url, and It worked, can return the result I wanted.
And I created another .py to test the url, too. It also can show the result I wanted.
import requests
payload = {'Message':'yo','Port':'123'}
r = requests.post("http://127.0.0.1:5000/test", data=payload)
print r.text
Then I put the same code below
#app.route('/', methods=['POST'])
def root():
I want to use the url '127.0.0.1:5000/' to send data to the '127.0.0.1:5000/test' (I also Use google's Postman)
And it can't worked... it always show 'loading...'
Is there a better way to implement my requirement ?
I will thank you so so so much ~!!
Instead of sending a local POST request, which would take a lot longer time, just have them both route to the same function, and set defaults.
#app.route('/', methods=['GET'])
#app.route('/test', methods=['POST'])
def test():
return request.form.get('Message', 'yo') + ',' + request.form.get('Port', '123')
Which would respond normally to all POST requests on /test, and with a GET to /, it works the same as POSTing {'Message': 'yo', 'Port': '123'} to /test
I am having trouble reading a POST request with bottle.py.
The request sent has some text in its body. You can see how it's made here on line 29: https://github.com/kinetica/tries-on.js/blob/master/lib/game.js.
You can also see how it's read on a node-based client here on line 4: https://github.com/kinetica/tries-on.js/blob/master/masterClient.js.
However, I haven't been able to mimic this behavior on my bottle.py-based client. The docs say that I can read the raw body with a file-like object, but I can't get the data neither using a for loop on request.body, nor using request.body's readlines method.
I'm handling the request in a function decorated with #route('/', method='POST'), and requests arrive correctly.
Thanks in advance.
EDIT:
The complete script is:
from bottle import route, run, request
#route('/', method='POST')
def index():
for l in request.body:
print l
print request.body.readlines()
run(host='localhost', port=8080, debug=True)
Did you try simple postdata = request.body.read() ?
Following example shows reading posted data in raw format using request.body.read()
It also prints to the log file (not to the client) raw content of body.
To show accessing of form properties, I added returning "name" and "surname" to the client.
For testing, I used curl client from command line:
$ curl -X POST -F name=jan -F surname=vlcinsky http://localhost:8080
The code which works for me:
from bottle import run, request, post
#post('/')
def index():
postdata = request.body.read()
print postdata #this goes to log file only, not to client
name = request.forms.get("name")
surname = request.forms.get("surname")
return "Hi {name} {surname}".format(name=name, surname=surname)
run(host='localhost', port=8080, debug=True)
Simple script for processing POSTed data. POSTed data are written in a terminal and returned to the client:
from bottle import get, post, run, request
import sys
#get('/api')
def hello():
return "This is api page for processing POSTed messages"
#post('/api')
def api():
print(request.body.getvalue().decode('utf-8'), file=sys.stdout)
return request.body
run(host='localhost', port=8080, debug=True)
Script for POSTing json data to the script above:
import requests
payload = "{\"name\":\"John\",\"age\":30,\"cars\":[ \"Ford\", \"BMW\",\"Fiat\"]}"
url = "localhost:8080/api"
headers = {
'content-type': "application/json",
'cache-control': "no-cache"
}
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)