How to receive HTML form data in Python 3? - python

As part of a project, I am trying to have python receive a form sent by HTML. Upon getting the variables, I need python to print either "True" or "False" in the console. Here is my current HTML code for the form.
...
<form name = "input" action = "CheckLogin.py" method = "get">
<!-- This is the form. Here the user submits their username and password.
The words before the colon are the words that appear on the user's screen -->
Username: <input type = "text" name = "htmlUser">
<br>
Password: <input type = "password" name = "htmlPassword">
<input type = "submit" value = "Submit">
<br>
</form>
...
Once I have had them submit their username and password, I want to use this data to check if they can log into an email server (I have used Google's in this case, Microsoft Server 2003 doesn't play nicely.) Here is my Python 3 script to do so:
def login(username, password):
import poplib
try:
server = poplib.POP3_SSL('pop.gmail.com', 995)#Weird bug here. When I use the exeter server, I am informed that the SSL number is incorrect. How do I fix?
server.user(username)
server.pass_(password)
print ("True")
except:
print("False")
login (username, password)
My question is, how can I have python get the username and password variables from the HTML webform?

Just get those values in CheckLogin.py and pass them to login():
import cgi
# ...
i = cgi.FieldStorage()
username = i["htmlUser"]
password = i["htmlPassword"]
login(username, password)

Related

Redirect to the same page and display a message if user insert wrong data

I am building a web chat application with chat rooms.
I have a page where users can open a new room, inside the page, there is a form.
I want to display a message to the user if he submits the form with a room that already exists.
For example:
Room 456 already exists and the user tried to open 456 room.
so I want to pop up a message that the room already exists.
The server side
#app.route('/NewRoom')
def newRm():
return render_template('NewRoom.html')
#app.route('/chat',methods=['GET','POST'])
def CreateRm():
if(request.method=='POST'):
username = request.form['username'].lower()
room = request.form['room'].lower()
ExistRoom = DBManage.ExistRoom(room)
error = "YOU ENTERED ROOM THAT ALREADY EXISTS"
if not ExistRoom:
limit = request.form['limit']
if limit == '':
limit = 'UNLIMITED'
session['limit'] = limit
image = request.files['getFile']
newImgs = open("static/images/" + username + ".jpg","wb")
newImgs.write(image.read())
newImgs.close()
room = room[:5].strip()
DBManage.newRoom(room,limit)
DBManage.newPerson(username,room)
#sDBManage.RoomUsers(room)
#Store the data in session
session['username'] = username
session['room'] = room
return render_template('chat.html', session = session)
else:
flash(error)
return redirect(url_for('newRm',error=error))
Inside CreateRm function the else at the end didn't work for me well, it's refreshing the page but doesn't send the error message, not really know how to solve that.
Client side
{% if error %}
<p class=error><strong>Error:</strong> {{ error }}
{% endif %}
Thanks all.
The problem is that you are returning a redirect to another route as well as trying to pass a variable to a template in that route. One way you could do this is by simply re-rendering the template, passing the variable, error to it at the same time. Try replacing:
return redirect(url_for('newRm',error=error))
with
return render_template('NewRoom.html', error=error)
Another option would be configuring your newRm route to accept optional arguments. This could look something like this:
#app.route('/NewRoom', defaults={'error':''})
#app.route('/Newroom/<error>')
def newRm():
return render_template('NewRoom.html')
You then pass an error to this route exactly as you have been doing.
return redirect(url_for('newRm', error=error))
To completely solve your problem, you'll also have to add a return statement outside your if(request.method=='POST'): to catch any GET requests. It could be something like this:
return render_template('NewRoom.html')

Using flask to run SQL command & output results as CSV download

idea:
take id's from html input
use id's to run sql and return relevant usernames
download the output as a csv on the front end when the "download" button is clicked
html
Enter comma delimited ids <input type="text" id="text1" name="text1"><br><br>
download
python
#app.route("/getPlotCSV", methods=['GET','POST'])
def getPlotCSV():
text1 = request.form['text1']
result = {}
a = []
x = []
a.extend([str(x) for x in text1.split(",")])
format_strings = ','.join(['%s'] * len(a))
cursor = cnxn.cursor()
sql = "SELECT DisplayName FROM dbo.[Users] where id IN ({seq})".format(
seq=','.join(['?'] * len(a)))
cursor.execute(sql,a)
for row, in cursor:
x.append(row)
csv = x
return Response(
csv,
mimetype="text/csv",
headers={"Content-disposition":
"attachment; filename=myplot.csv"})
The sql and input works because i have tested it separately without the csv download and it returns the correct data. The error i get at the moment is "400 Bad Request: The browser (or proxy) sent a request that this server could not understand." KeyError: 'text1'
what am i missing here?
The KeyError is because you haven't actually passed the value of text1 to your getPlotCSV route. A link on an HTML page won't also transfer the data with it. Instead you need to use a form with an action page, like this:
<form action="/getPageCSV" method="post">
Enter comma delimited ids: <input type="text" id="text1" name="text1">
<input type="submit" name="Submit" id="submit">
</form>
This should then pass those values to the url in the form action attribute, in this case your getPageCSV. It doesn't have to be POST, I've just done that as an example.
Then, when your route receives the data:
#app.route('/getPageCSV')
def getPlotCSV():
if request.method == "POST": #in other words, if the form is being submitted
text1 = request.form.get('text1') #use dict.get in case it isn't there
# your code
csv = x
return redirect(url_for('getPlotCSV')) #this time a get method
return Response(
csv,
mimetype="text/csv",
headers={"Content-disposition":
"attachment; filename=myplot.csv"})
The above won't specifically work without you adding in your own way to move the POST process data/csv over to when the user is redirected. You could do it as a request header, store it in the session storage or even put it in the query string, it's up to you, but you have to be able to display the results of your POST process into a GET request when the user is redirected.

How do i signin to a database using PyQt and QtSql

I have a PyQt4 application that offers signup and sign in. The signup works well that is, the credentials are store in the database as intended. The problem is with sign-in where by it accepts any credentials including those that don't exist in the database.Below is the code am using.
self.database1 = QtSql.QSqlDatabase().addDatabase('QMYSQL')
self.database1.setHostName('localhost')
self.database1.setDatabaseName('database')
self.database1.setUserName('root')
self.database1.setPassword('')
if self.database1.open():
print('Successful')
else:
print(self.database1.lastError().text())
username = self.userName1.text()
password = self.passwordSlot.text()
query = QtSql.QSqlQuery(self.database1)
credentials = query.prepare("SELECT * FROM credentials WHERE username = ? and password = ?")
if credentials:
query.addBindValue(username)
query.addBindValue(password)
query.exec_()
self.database1.close()
print('Successfully logged in')
else:
print('Failed')
prepare() returns a boolean value that indicates whether the statement is correct or not, so it can not indicate if the credentials match, since the correct statement will always be true, what you should know if the information is in the database is that the order returns at least one element, and we can do that with first():
self.database1 = QtSql.QSqlDatabase().addDatabase('QMYSQL')
self.database1.setHostName('localhost')
self.database1.setDatabaseName('database')
self.database1.setUserName('root')
self.database1.setPassword('')
if self.database1.open():
print('Successful')
else:
print(self.database1.lastError().text())
username = self.userName1.text()
password = self.passwordSlot.text()
query = QtSql.QSqlQuery(self.database1)
is_valid_query = query.prepare("SELECT * FROM credentials WHERE username = ? and password = ?")
if is_valid_query:
query.addBindValue(username)
query.addBindValue(password)
if query.exec_():
if query.first():
print('Successfully logged in')
else:
print('Failed')
else:
print(query.lastError().text())
self.database1.close()

Have IP client address

I'm doing pages in html and python (I'm novice in python), I would like to have IP client address, but I don't know if it is possible. I saw it is possible with PHP language.
So, I execute my code in command line (with Linux) like that:
./code.py client_server app_name app_version
infos.py
def main( client_server, app_name, app_version):
template = open('infoHTML.py').read()
c = string.Template(template).substitute(
app_name = app_name,
app_version = app_version,
os = user,
user = login)
f = tempfile.NamedTemporaryFile(prefix='/tmp/info.html', mode='w', delete=False)
f.write(contenu)
f.close()
webbrowser.open(f.name)
if __name__ == "__main__":
client_server = sys.argv[1]
app_name = sys.argv[2]
app_version = sys.argv[3]
user = sys.platform
sys.argv.append(user)
login = getpass.getuser()
sys.argv.append(login)
main(client_server, app_name, app_version)
I have an html code into python code here: infoHTML.py
<html>
App: ${app_name}<br/><br/>
Version: ${app_version}<br/><br/>
User: ${user}<br/><br/>
<form name="sendData" method="get" action="http://localhost:8000/cgi/display.py">
Project: <input type="text" name="pro"><br/><br/>
Number: <input type="text" name="num"/><br/><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
It's possible. You need to do it either by rendering the address on the response body or by requesting it with ajax after the response has already been rendered.
It would be hard to give you a code solution without seeing what web server you are using, but here are a couple of pointers for the first approach. To obtain the address, on the server side (python handler):
import socket
ip = socket.gethostbyname(socket.gethostname())
or if you are using something like Google App Engine:
ip = self.request.remote_addr
you should then write the IP to the response. For example, if you are using a templating engine to render your HTML, your HTML can look like something similar to this:
<html>
<script>
var ip = {{ip}}
</script>
and on the python code that renders the template you should do something like that:
htmlContent = template.render(ip=ip)
self.response.write(htmlContent)

How to send mail using Python in Google App Engine (not working)

I have an app in Google app engine using jQuery and Python, it allows users to post things... I have an recover password handler in Python, I want this handler to deal with the query/data by send that user out an email. But it does not seem to work:
class RecoverHandler(webapp2.RequestHandler):
def get(self):
#email = self.request.get('#email')
usr = self.request.get('email')#or email
dob = self.request.get('dob')
name = self.request.get('maidenName')
callback = self.request.get('callback')
#get user from database
#user = User.get_by_id(#email)
user = User.get_by_id(usr)
#if user exists check for correct password
dobx = user.dob
namex = user.maidenName
if user:
if dobx == dob:
if namex == name:
self.response.write(callback + '({"response":"login Complete"})')
mail.send_mail(sender="Example.com Support <support#example.com>",
to="Albert Johnson <Albert.Johnson#example.com>",
subject="Your account has been approved",
body="""
Dear Albert:
Your example.com account has been approved. You can now visit
http://www.example.com/ and sign in using your Google Account to
access new features.Please let us know if you have any questions.The example.com Team""")
else:
self.response.write(callback + '({"response":"login incomplete"})')
else:
self.response.write(callback + '({"response":"login Password incorrect"})')
else:
self.response.write(callback + '({"response":"login not found"})')
user = User.get_by_id(usr) ?
is your entity's ID really their email address? Can you add some logging? user.dob and user.maidenName should throw NoneType errors if your ID is not the email address.
dobx = user.dob and namex = user.maidenName should go inside the if, so they don't throw an error if User not found.

Categories

Resources