Tornado POST request not working - python

I've taken the below code from the Tornado server documentation and attempted to try it out but instead I keep getting the error
object has no attribute 'get_body_argument'
class MyFormHandler(RequestHandler):
def get(self):
self.write('<html><body><form action="/myform" method="POST">'
'<input type="text" name="message">'
'<input type="submit" value="Submit">'
'</form></body></html>')
def post(self):
self.set_header("Content-Type", "text/plain")
self.write("You wrote " + self.get_body_argument("message"))
Any help appreciated.

All it needed was my installation of Tornado had to be upgraded.

Related

500: Internal Server Error Spotify python Auth Code flow trying to redirect to login and get token

I am using this documentation to get the user to login and return me code and state. However, when I run my app It gives me a 500 error.
This is my app.py
import flask
import SpotifyOAuth
app = flask.Flask(__name__)
#app.route('/')
def index():
flask.render_template("index.html")
#app.route('/login')
def accessSpotify():
SpotifyOAuth.RedirectTologin(redirect_uri='https://localhost:7001/authorized')
#app.route('/authorized')
def SP_redirect_uri():
return "spotify connected"
def main():
print("nothin")
if __name__ == '__main__':
app.run(use_reloader=True,port=7001)
and this is my SpotifyOAuth.py
import requests
def RedirectTologin(redirect_uri="https://localhost:7001/authorized"):
token_uri="https://accounts.spotify.com/authorize"
method="GET"
params={
"client_id" : '<id>',
"response_type" : 'code',
"redirect_uri" : redirect_uri,
"scope" : 'user-read-email'
}
client_secret='<secret>'
r = requests.get(token_uri,params=params)
print(r)
if __name__=='__main__':
RedirectTologin()
I know my RedirectTLogin() is working because when I print r it gives me response code 200. Not sure where I am going wrong in app.py
Here is my index.html for reference
<html>
<body>
<div>
<div id="login">
<h1>First, log in to spotify</h1>
Log in
</div>
<div id="loggedin">
</div>
</div>
</body>
</html>
Does anyone see any issue? I don't have much experience working with APIs
Flask routes need to return something: a rendered template, a redirect, plain text with a status code, etc.
To fix your issue you need to add returns to index() and accessSpotify() as follows:
#app.route('/')
def index():
return flask.render_template("index.html")
#app.route('/login')
def accessSpotify():
SpotifyOAuth.RedirectTologin(redirect_uri='https://localhost:7001/authorized')
return flask.redirect(url_for('SP_redirect_uri'))

How to open a .html file and click submit button using python

I have a .html file where I am sending a value using the submit button as follows:
<HTML>
<HEAD>
<TITLE>XYZ Ltd.</TITLE>
</HEAD>
<BODY>
<FORM ACTION="http://192.168.2.2/cgi-bin/http_recv.cgi" METHOD="POST">
<TEXTAREA NAME="DATA_SEND" COLS='160' ROWS='40' WRAP='none'>
</TEXTAREA>
<INPUT TYPE="SUBMIT" VALUE="Send Data">
</FORM>
</BODY>
</HTML>
I did go through selenium and from my understanding it doesn't suit me. I would like to have a .html as above and maintain it, so it has to be opened and clicked. A cgi/python example did come into my notice but I would go for it only if there is no other alternative.
How can I use python to:
Open the .html file and
Press the "Send Data" button
Read any response given (assuming the response maybe displayed within a HTML page or a dialog box)
Python code for sending Data
`def hello():
Dict={'Title': 'This is title','Subtitle':'subtitle'}
return render_template('hello.html',Dict=Dict)`
Code for writing values which is passed from python as dictionary into HTML
`<form accept-charset="utf-8" class="simform" method="POST"
enctype=multipart/form-data>
Title <input type="text" name="Title" value="{{ Dict.get('Title')
}}" maxlength="36">
SubTitle <input type="text" name="SubTitle" value="{{
Dict.get('SubTitle') }}" maxlength="70">
<button type="submit" class="save btn btn-default">Submit</button>
</form>`
I believe this is exactly what you are looking for .Its a simple python server with the baseHttpHandler of Python.
class S(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
self._set_headers()
self.wfile.write("<html><body><h1>hi!</h1></body></html>")
def do_HEAD(self):
self._set_headers()
def do_POST(self):
# Doesn't do anything with posted data
self._set_headers()
self.wfile.write("<html><body><h1>POST!</h1></body></html>")
def run(server_class=HTTPServer, handler_class=S, port=80):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print 'Starting httpd...'
httpd.serve_forever()
You can run the code by passing an appropriate port of your choice to run method or the default 80 will be used. To test this or to do a get or post , you could run a curl as follows:
Send a GET request:: curl http://localhost
Send a HEAD request:: curl -I http://localhost
Send a POST request:: curl -d "foo=bar&bin=baz" http://localhost
You could also create a seperate file of index.html and read using the codecs in python. Since the input would be string , it could be tampered with , eventually displaying the desired page.
Use flask to host your HTML Page and use a POST request to send data to and from your python script.
This link should help you more :
https://www.tutorialspoint.com/flask/index.htm
"Clicking" a button is nothing more than a POST request with the form data in the body.
If you need something generic, you would have to parse the HTML, find what data the host accepts and POST it.
But if you just need this for this example, meaning, you already know the data the server accepts, you can just forget about the HTML and just use something like requests to post the data

Getting <response[200]> with Python http requests instead of INT

Im trying to create simple python code that would communicate with 9kw.eu captcha solving service through their api https://www.9kw.eu/api.html#apisubmit-tab. Basically I'm sending base64 encoded image with some keys:values and response from server should be number like: 58952554, but I'm only getting
<response[200]>
Which should mean that the server got my data, but im not getting anything else.
I'm able to get the right result with simple html form:
<form method="post" action="https://www.9kw.eu/index.cgi" enctype="multipart/form-data">
KEY:<br>
<input name="apikey" value="APIKEY"><br>
ACTION<br>
<input name="action" value="usercaptchaupload"><br>
FILE:<br>
<input name="file-upload-01" value="BASE64IMAGEDATAHERE"><br>
TOOL<br>
<input name="source" value="htmlskript"><br>
ROTATE<br>
<input name="rotate" value="1"><br>
Angle<br>
<input name="angle" value="40"><br>
BASE64
<input name="base64" value="1"><br>
Upload:<br>
<input type="submit" value="Upload and get ID">
</form>
This is the python code, which should do the same thing:
import requests
import time
#base64 image encoding
with open("funcaptcha1.png", "rb") as f:
data = f.read()
filekodovany = data.encode("base64")
#captcha uploader
udajepost = {'apikey':'APIKEY','action':'usercaptchaupload','file-upload-01':filekodovany,'source':'pythonator','rotate':'1','angle':'40','base64':'1'}
headers = {'Content-Type':'multipart/form-data'}
r = requests.post('https://www.9kw.eu/index.cgi', data = udajepost)
print(r)
Thanks for any help.
r = requests.post('https://www.9kw.eu/index.cgi', data = udajepost)
Here, r is the whole response object which has many attributes. I guess, you only need r.text. So, you can just use:
print(r.text)
You're looking for the response of the request:
print(r.text)
In this way you'll have the plain text response.
get json output by:
r.json()
and response_code by:
r.status_code

URL for Flask GET vs POST

I think this must be a really simple question or perhaps I'm overlooking something major, but I'm only getting started and there is something I just can't figure out.
I wrote a simple flask application:
from flask import Flask, request, jsonify
app = Flask(__name__)
#app.route("/")
def index():
return "Index!"
#app.route('/test', methods=['GET', 'POST'])
def test():
if request.method=='GET':
return "OK this is a get method"
elif request.method=='POST':
return "OK this is a post method"
else:
return("ok")
if __name__ == "__main__":
app.run()
When I open the following URL I get the GET method message as expected.
http://localhost:5000/test
But I can't switch it to a POST method.
What URL would I need to enter to see the POST method message?
Whenever you make a direct URL request via browser, it makes a GET call. It is not related to the URL, but the request type value that goes with the request to your server.
In order to make POST request (OR any other type of request) you may use any Rest Client Tool, refer: How do I manually fire HTTP POST requests with Firefox or Chrome?
Personally I use, Postman which comes as plugin for Chrome. Advance Rest Client is also a very nice alternative to achieve this.
If you want a geeky tool (some people consider command line to be geeky ;) ), you may use curl for transferring data with URLs. For making POST request, you have to call it as:
curl -i -X POST -H 'Content-Type: application/json' -d '{"param1": "value1", "param2": "value2"}' http://localhost:5000/test
HTML Forms are the primary way that you'd send a post request. Instead of your return "Index" you could instead do:
return '''
<form method="post" action="/test">
<input type="text" name="your field"/>
<button type="submit">Post to your /test!</button>
</form>
'''
In reality you'd have that form code in a whatever.html file within your template folder and render it with render_template to keep your code smart.

post a file to flask url using ajax

I have a javascript method that reads the input file submitted via a form and tries to post its data to a flask url, which is supposed to read the posted data and return it with some amendments.
The HTML part:
<form id="form_1">
<input type="file" name="file_1" id="file_1">
<input type="submit" value="submit" id="regan">
</form>
The JS part:
$("#form_1").submit(function(e){
e.preventDefault(e);
var reader = new FileReader();
var line_data = $('#file_1').get(0);
if (line_data.files.length) {
var input_file = line_data.files[0];
reader.readAsText(input_file);
$(reader).on('load', function(e){
data_line = e.target.result;
$.ajax({
url:'url/validate/',
type:'POST',
data:{akey: data_line},
success:function(returned_data){console.log(returned_data);},
error:function(){console.log('sorry...');}
});
});
}
});
The Flask/Python part:
#app.route('/validate_line/')
def validate_line_data():
try:
data = request.form['akey']
except:
data = 'bad'
data = str(data)
return data+'was_received'
So far, its reading the submitted text file successfully in javascript, but it seems like its not posting via the ajax post method and giving an error url/validate/ 405 (METHOD NOT ALLOWED).
Any help would be great. Thanks.
For Flask to accept POST requests, you need to specify so in the decorator:
#app.route('/validate_line/', methods=['POST'])
If you want it to accept GET requests as well, change to
['GET', 'POST']

Categories