Is it possible to make POST request in Flask?
Yes, to make a POST request you can use urllib
, see the documentation.
I would however recommend to use the requests module instead.
EDIT:
I suggest you refactor your code to extract the common functionality:
@app.route("/test", methods=["POST"])
def test():
return _test(request.form["test"])
@app.route("/index")
def index():
return _test("My Test Data")
def _test(argument):
return "TEST: %s" % argument
Flask: make POST requests to development server
You can't make request POST
using URL
in browser. It needs HTML
page which has
<form method="POST">
</form>
so your server would have send this page to you.
Instead of browser you can use Python modules like urllib
or simpler requests
which can run .get()
, .post(...)
, etc.
In example I use https://httpbin.org/post because it sends back all what yout get - headers, post data, cookies, etc. so you can see what you send.
import requests
#url = 'http://127.0.0.1:5000'
url = 'https://httpbin.org/post'
# POST/form data
payload = {
'search': 'hello world',
}
r = requests.post(url, data=payload)
print(r.text)
Result:
{
"args": {},
"data": "",
"files": {},
"form": {
"search": "hello world"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Content-Length": "18",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.26.0",
"X-Amzn-Trace-Id": "Root=1-61687ab9-7bae70cf5bfdcbb75524b71b"
},
"json": null,
"origin": "83.11.118.179",
"url": "https://httpbin.org/post"
}
Some people use GUI
tools like postman to test pages - and it can also send requests POST/GET/DELETE/OPTION/etc.
You may also try to use console programs like curl
curl https://httpbin.org/post -X POST -d "search=hello world"
{
"args": {},
"data": "",
"files": {},
"form": {
"search": "hello world"
},
"headers": {
"Accept": "*/*",
"Content-Length": "18",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "curl/7.68.0",
"X-Amzn-Trace-Id": "Root=1-61687da3-5eaaa4ff6419c36639a2cc5d"
},
"json": null,
"origin": "83.11.118.179",
"url": "https://httpbin.org/post"
}
BTW:
Some API uses curl in documentation as example to show how to use API.
There is page https://curl.trillworks.com which can convert from curl
to Python requests
(but sometimes has problem to do it correctly)
Executing a post request from a flask route to a remote service
You don't need to redirect user to the remote server. Just send POST request inside this route function and either wait for the response from that server and then render some template to user with received response or send POST request to the desired server in another thread if you know that response can take a lot of time (in this case you can render some page immediately where would be something like "Processing your request" message). In the second case (in case of sending POST request in a different thread) you can show result of the request after reloading page retrieving it from some shared object in main thread that can be modified from the thread you use to send POST request from.
1) Sending request in the route function:
@app.route('/test/', methods=['POST'])
def test():
url = 'http://exemple.com'
headers = {'Content-type': 'text/html; charset=UTF-8'}
response = requests.post(url, data=data, headers=headers)
# wait for the response. it should not be higher
# than keep alive time for TCP connection
# render template or redirect to some url:
# return redirect("some_url")
return render_template("some_page.html", message=str(response.text)) # or response.json()
2) Sending POST request in a different thread (you can use this option if you know that response time is much higher than TCP keep alive time):
from threading import Thread
from flask import Flask, redirect
app = Flask(__name__)
shared_var = None
req_counter = 0
def send_post_req(url, data):
global shared_var
headers = {'Content-type': 'text/html; charset=UTF-8'}
response = requests.post(url, data=data, headers=headers)
shared_var = response.text # or response.json() - it's up to you
@app.route('/test/', methods=['POST'])
def test():
global req_counter
url = 'http://exemple.com'
data = "some data"
if req_counter == 0:
t = Thread(target=send_post_req, args=(url, data))
t.setDaemon(True)
t.start()
req_counter = 1 # use req_counter if you want to send request only one time
if shared_var:
# render some page or redirect to desired url using:
# return redirect(url_for('some_route_name'))
# or
# return redirect("some_url")
return render_template("some_page.html", message=str(shared_var))
return render_template("some_page.html", message="Your request is being processed")
or something like that.
Hope my explanation is clear.
Also you can pay attention to asyncio and Sanic to use asynchronous approach.
How can I send a GET request from my flask app to another site?
Install the requests
module (much nicer than using urllib2
) and then define a route which makes the necessary request - something like:
import requests
from flask import Flask
app = Flask(__name__)
@app.route('/some-url')
def get_data():
return requests.get('http://example.com').content
Depending on your set up though, it'd be better to configure your webserver to reverse proxy to the target site under a certain URL.
Sending Post request to Flask restAPI using python give response Error 500
Seems like you forgot to add request parameter to predict
method
import json
@app.route("/predict", methods=["POST"])
def predict():
data = json.loads(request.get_data())
print(data)
Explanation:
In your client code you are not sending json, you are sending data. I cannot explain very well de difference but in order to receive json and have content in request.get_json()
you must update your client to:
data = {"A":123, "B":22, etc...}
url_path = 'http://127.0.0.1:5000/predict'
response = requests.post(url_path, json=json.dumps(data))
This post will give to you more detail about whats happens
sending post request in flask
First fix the error:
You need to change this:
res = requests.post('https://fcm.googleapis.com/fcm/send', json=json_string)
to this:
res = requests.post('https://fcm.googleapis.com/fcm/send', data=json_string)
The error you are getting states that requests.post
cannot accept an argument named json
, but it accepts a keyword argument named data
, which can be in json format.
Then add your headers:
If you want to send custom headers with the requests
module, you can do it as follows:
headers = {'your_header_title': 'your_header'}
# In you case: headers = {'content-type': 'application/json'}
r = requests.post("your_url", headers=headers, data=your_data)
To sum everything up:
You need to fix your json formatting up a bit. A full solution will be:
json_data = {
"data":{
'key': app.config['FCM_APP_TOKEN']
},
"notification":{
'title': 'Wyslalem cos z serwera',
'body': 'Me'
},
"to": User.query.filter_by(id=2).first().fcm_token
}
headers = {'content-type': 'application/json'}
r = requests.post(
'https://fcm.googleapis.com/fcm/send', headers=headers, data=json.dumps(json_data)
)
Related Topics
I Have a Problem with Sending Mail:Typeerror: _Init_() Got an Unexpected Keyword Argument 'Context'
Differencebetween Size and Count in Pandas
Dynamically Evaluate an Expression from a Formula in Pandas
How to Find All the Subclasses of a Class Given Its Name
What Is the Most Efficient Way to Loop Through Dataframes with Pandas
Open Document with Default Os Application in Python, Both in Windows and MAC Os
Python Module for Converting PDF to Text
How to Use Python Requests to Fake a Browser Visit A.K.A and Generate User Agent
How to Get the Pythonpath in Shell
List Comprehension Rebinds Names Even After Scope of Comprehension. Is This Right
Getting an "Invalid Syntax" When Trying to Perform String Interpolation
Proper Name for Python * Operator
Convert Pandas Column Containing Nans to Dtype 'Int'