printing files in Google App Engine - python

I am trying to read and print a file in Google App Engine, but the code bellow seems unresponsive. I can upload the file, and my expectation was that it would just print the text, but it does nothing. I thought about adding a submit button, but I have no idea how to link submit with pythons printing. How can I get this to print on command?
I have seen the example provided by GAE here, but I would first like to keep it all on one page, and second I still don't understand how the submit calls that second page.
import webapp2
from google.appengine.ext.webapp import util
class MainPage(webapp2.RequestHandler):
#http://bukhantsov.org/2011/12/python-google-app-engine-calculator/
def get(self):
# build a list of operations
self.response.out.write("""<html>
<body>
<form action='/' method='get' autocomplete='off'>
<input type='file' name='file'/><br/>
#<input type='submit' name="test" value="submit">
</form>
</body>
</html>""")
file = self.request.get('file')
self.response.out.write(file)
app = webapp2.WSGIApplication([('/', MainPage)], debug=True)
def main():
util.run_wsgi_app(app)
if __name__ == '__main__':
main()

Your form is sent using the HTTP GET method, but for file uploads you need POST. Change it from:
method='get'
to:
method='post'
You will also need to handle POST requests in a different method. The POST body itself should be available as self.request.POST. So you end up with something like:
def post(self):
file = self.request.POST['file']
self.response.out.write(file)

Related

How is flask able to access login.html? [duplicate]

This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed 1 year ago.
I am trying to learn flask.
My login.html file-
<html>
<body>
<form action = "http://localhost:5000/login" method = "post">
<table>
<tr><td>Name</td>
<td><input type ="text" name ="uname"></td></tr>
<tr><td>Password</td>
<td><input type ="password" name ="pass"></td></tr>
<tr><td><input type = "submit"></td></tr>
</table>
</form>
</body>
</html>
And my main.py file has this-
#app.route('/login',methods = ['POST'])
def login():
uname=request.form['uname']
passwrd=request.form['pass']
if uname=="ayush" and passwrd=="google":
return "Welcome %s" %uname
I am not able to understand how is this able to access login.html without specifying. Also also please explain what is the code in main.py means.
You have to specify the 'html' in flask to access it, however, if you open the html file in browser this will still work since its action is aimed directly at your flask server.
the code of your main.py says that if the in the form sent the data 'uname' and 'pass' are respectively 'ayush' and 'google', the code sends back to the browser a text indicating: "Welcome ayush"
If you want to directly implement the html in your flask web server, you have to create the function and put your html code in templates folder.
from flask import render_template
...
#app.route('/', methods=['GET'])
def code():
return render_template('index.html', name='')
So you can access with http://localhost:5000/ now

How to get test input from an html form to another python script using flask?

I'm trying to get a simple web form up and running that only asks for a URL.
This is the HTML Code (index.html)
<!DOCTYPE html>
<html>
<body>
<form name = 'test' action = "." method = "post">
<form action="test.php" method="get">
URL <input type="text" link="link" name = "URL"/>
<input type="submit" />
</form>
</body>
</html>
I'm using Flask to run the simple web application this is the Flask Code: (app.py)
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def index():
return render_template('index.html')
#app.route("/", methods = ["POST"])
def get_value():
url = request.form["URL"]
return 'The url is ' + url
if __name__ == "__main__":
app.run(debug=True)
and I'm trying to get the inputted URL to another python script so I can do something with it, this is the other python script: (url.py)
from app import get_value
print(get_value())
However, whenever I run python3 url.py it gives me this error:
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem.
Any idea how to print get the URL over successfully? In a lot of detail preferably because I am very new to Flask.
The error occurs because you called a function that needs data from a request to get the user inputs. You should call the url handling function instead letting the handling function call the retrieval of the url.
Consider this answer https://stackoverflow.com/a/11566296/5368402 to make sure you pass the url correctly. Now that you have your url, simply pass it to your other script.
import url # your url.py module
#app.route("/", methods = ["POST"])
def get_value():
input_url = request.form["URL"]
url.handle_url(input_url) #call a function inside url.py

Taking data from drop-down menu using flask

I'm completely new to flask, and really am completely lost with how to approach this. I've looked into other SO questions but I can't seem to get this working regardless.
I have a form as such:
<form class="teamSelection" method="POST" action="/submitted">
<select class="teamForm" id="teamDropdownSelector" type="text" name="teamDropdown" placeholder="Select A Team">
<option disabled selected>Select a game</option>
<option id="WatfordVSManchester Utd" value="">Watford VS Manchester Utd</option>
</select>
<input class="btn" type="submit" value="submit">
</form>
and my flask as so:
from flask import Flask
app = Flask(__name__)
#app.route("/submitted")
def hello():
return "hello world"
The goal is to take the content of the selected/submitted dropdown item, pass this to the flask file where I then use the team names to scrape information about the match. However at the moment I can't even seem to get the POST of the form to work and am at a complete loss. I appreciate this is a pretty vague and open-ended question, but I seriously don't know how else to figure this out.
Should I instead use jquery to detect when the dropdown has changed and use AJAX to send a POST to somehow call the script and pass the values into it?
Any help would be greatly appreciated.
EDIT
I thought I put this in the original post, but must have forgot.
I am currently running an apache localhost server, and am working with flask via pycharm. All I've done at the moment is install the flask package in pycharm, and haven't set any of it up like I've seen in some tutorials do when running from the command line. I assumed this step wasn't necessary, as I already have a server up and running with apache?
When it comes to backend stuff like this I really have no idea, so apologies if that's a stupid assumption.
I've changed the flask to:
from flask import Flask
app = Flask(__name__)
#app.route("/submitted", methods=['POST'])
def hello():
with open("newTest.csv", mode="w+") as file:
fileWriter = csv.writer(file)
fileWriter.writerow(['Time', 'HomeTeam', 'AwayTeam'])
file.close()
The reason being as I can see if this script is actually being called, if it is it will make a new csv file called newTest. After running the webpage and submitting no new csv file appears, so this script isn't being run, meaning it's likely due to me not configuring flask correctly?/The assumption that apache was enough was incorrect?
You have just to tell the flask method to accept POST request and to read parameters from the request
Example:
from flask import Flask, request
app = Flask(__name__)
#app.route("/submitted", methods=['POST'])
def hello():
myvariable = request.form.get("teamDropdown")
... your code ...
return "hello world"
So, your question is not about flask, but about fopen - you have to add a full file path including directory path script_dir = path.dirname(path.abspath(__file__)).
Flask script (modified for launching in my local copy of project):
from flask import Flask, render_template, request
import csv
from os import path
app = Flask(__name__)
script_dir = path.dirname(path.abspath(__file__))
#app.route ("/")
def index():
return render_template("index.html")
#app.route("/submitted", methods=["GET", "POST"])
def hello():
if request.method == "GET":
return render_template("index.html")
filefullpath = script_dir + '//newTest.csv'
with open(filefullpath, mode="w+") as file:
fileWriter = csv.writer(file)
fileWriter.writerow(['Time', 'HomeTeam', 'AwayTeam'])
file.close()
return "hello world"
index.html (in folder "/templates")
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
Test
<br>
<form class="teamSelection" method="POST" action="/submitted">
<select class="teamForm" id="teamDropdownSelector" type="text" name="teamDropdown" placeholder="Select A Team">
<option disabled selected>Select a game</option>
<option id="WatfordVSManchester Utd" value="">Watford VS Manchester Utd</option>
</select>
<input class="btn" type="submit" value="submit">
</form>
</body>
</html>
Modify your code as:
from flask import Flask
app = Flask(__name__)
#app.route("/submitted", methods=['POST'])
def hello():
return request.form['teamDropdown']
Please let me know if that helps.

Can't get response using iron-form in google app engine python

I have implemented a form using iron-form and I am able to process it in the server, but then I can't figure out how to get the response out, I cannot redirect to another page or refresh. If I remove the 'is="iron-form' then it works fine. I'm using polymer 1.0, google app engine, and jinja2 for templating.
HTML:
<div class="c-form">
<h1>"Contact us"</h1>
<p> {{ sucess-message }} </p>
<form is="iron-form" id="contact-form" method="post" action="/formhandler">
<paper-input label="Name" name="name" required></paper-input>
<paper-textarea label="Message" name="msj" required></paper-textarea>
<paper-button raised class="colorful" onclick="submitForm()">Send</paper-button>
</form>
</div>
<script>
function submitForm() {
document.getElementById('contact-form').submit();
}
</script>
main.py:
class FormHandler(MainHandler):
def post(self):
self.name = self.request.get('name')
self.msj = self.request.get('msj')
mesj = MensajesDB.new_msj(self.name, self.msj)
mesj.put()
self.respose.out.write("SUCCESS") //Here I would like to render the template,
but I can't get it to render or redirect to
another page...
class MainPage(MainHandler):
def get(self):
self.render("home.html", route="home", title="Home")
app = webapp2.WSGIApplication([
('/', MainPage),
('/formhandler', FormHandler),
], debug=True)
It seems like you might be having trouble debugging where the failure is happening. I suggest familiarizing yourself with the Chrome DevTools -- specifically, the Network tab, which will allow you to monitor the requests from your JS to your server, and then the server responses.
From your server-side application, you can access the entire request body from within your FormHandler.post method using the self.request.POST variable, as documented here.
If you want to redirect after saving to the Datastore, you'll need to remove the self.response.out.write() line and use self.redirect() instead. Note that you cannot send a response body/string and redirect in a single response.

Storing a string from a textbox to the Google App Engine Datastore

Is it possible to create a textbox in HTML, type a string into it, click a "save" button, store that information onto a GAE datastore model and have the text stay displayed in the textbox and saved in the datastore?
The HTML is on a separate file, just rendered through my main.py file using
class MainPage(webapp.RequestHandler):
def get(self):
template_values = {}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
What I tried for my problem is this:
class equipmentBox(db.Model):
equipCode = db.StringProperty()
class equipmentBoxGet(webapp.RequestHandler):
def post(self):
I think this will help, i have modified default guestbook app for you. Usual way of doing is having html files separately and using templates to render it. Here everything is just embedded into the controller itself
import cgi
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
class EquipmentBox(db.Model):
equipCode = db.StringProperty()
class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write('<html><body>')
equips = db.GqlQuery("SELECT * FROM EquipmentBox")
for equip in equips:
self.response.out.write('<blockquote>%s</blockquote>' %
cgi.escape(equip.equipCode))
# Write the submission form and the footer of the page
self.response.out.write("""
<form action="/post" method="post">
<div><input type="text" name="equip_code" /></div>
<div><input type="submit" value="post equipcode"></div>
</form>
</body>
</html>""")
class EquipBox(webapp.RequestHandler):
def post(self):
equip = EquipmentBox()
equip.equipCode = self.request.get('equip_code')
equip.put()
self.redirect('/')
application = webapp.WSGIApplication(
[('/', MainPage),
('/post', EquipBox)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
The best way to build this sort of interface, where the user "saves" data on the page without the page changing, is to use AJAX calls.
While a full explanation of how AJAX works is probably beyond the scope of an answer here, the basic idea is that you have a Javascript onclick event attached to your Save button, which sends the contents of your textbox via a POST request to the server. See the link above for a tutorial.

Categories