My objective in this program is to store information in a database. My problem is that I'm trying to link a button from my HTML page by using a Python script. My instructor told us that it must be written in Python. Any Libraries that support Python 2.7 would work for me.
from google.appengine.api import images
from google.appengine.ext import ndb
from models import Note
import webapp2
import jinja2
import os
jinja_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class MainHandler(webapp2.RequestHandler):
def get(self):
template = jinja_env.get_template('./main.html')
self.response.out.write(template.render())
class InfoHandler(webapp2.RequestHandler):
def get(self):
note = Note(img = images.Image(photo.usr_img))
class Note(ndb.Model):
def get(self):
usr_img = ndb.BlobProperty()
desc = ndb.StringProperty()
app = webapp2.WSGIApplication([
('/', MainHandler),
], debug=True)
<html>
<head lang = "en">
<meta charset = "UTF-8">
<title>Title</title>
</head>
<body>
<div class = "container">
<h1>If this is an emergency, upload a photo and provide a short description.</h1>
<div id = "upload" >
<label for = "img">Upload image:</label>
<input type = "file" name = "pic" accept = "image/*"/>
<label for = "desc">Description:</label>
<input type = "text" />
<input type = "submit" href = "{{ submit_data }}"/>
</div>
</div>
</body>
</html>
I'm a noob in Python and I'm taking on a tough problem for class. Any suggestions or solutions?
Related
How can you use flask to make the text of your website blue? I only know how to display text on your website. My code :
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return '''Hello world'''
Despite the negative feedback from other user, this is not that bad of a question, besides apart of #go2nirvana no one answered your question.
Note
Despite this is more a Front-end question related to CSS or Javascript and not HTML (yes you can embed CSS inline within HTML but is not recommended) what you asked can be achieved in Flask in many ways.
Example 1 -Hard coding, not recommended buy you can do it-
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
my_html = '''
<body style="background-color: #e1eb34;">
<h1 style="color: #002aff;">Hello World</h1>
</body>
'''
return my_html
if __name__ == '__main__':
app.run(debug=True)
or
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return '''
<body style="background-color: #e1eb34;">
<h1 style="color: #002aff;">Hello World</h1>
</body>
'''
if __name__ == '__main__':
Example 2 -Using Jinja2 DOCS##
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def hello_world():
color = {
'blue': '002aff',
'yellow': 'e1eb34',
'green': '28fc03',
'red': 'fc1703',
'purple': 'b503fc'}
return render_template('index.html', color=color)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="background-color: #{{color['yellow']}};">
{% for hue in color.values() if hue != 'e1eb34'%}
<h1 style="color: #{{hue}};">Hello World</h1>
{% endfor %}
<h1></h1>
</body>
</html>
Example 3 -Adding request, session, redirect, url_for and more fun
from flask import Flask, render_template, redirect, url_for, request, session
import random
app = Flask(__name__)
app.config['SECRET_KEY'] = 'dev'
color = {
'blue': '002aff',
'yellow': 'e1eb34',
'green': '28fc03',
'red': 'fc1703',
'purple': 'b503fc',
'orange': 'FF9733 ',
'black' : 'FFFFFF',
'light-blue': '0AE5E3',
'pink': 'FF95AE',
'blue-green' : '95FFCA'}
#app.route('/', methods=['GET', 'POST'])
def index():
error = None
if 'color' not in session:
session['color'] = None
session['background'] = None
if request.method == 'POST':
choice = request.form['color'].lower()
if choice not in color:
error = 'Color not in list'
return render_template('index.html', color=session['color'], background=session['background'], error=error )
else:
session['color'] = color.get(choice)
session['background'] = random.choice(list(color.values()))
return redirect(url_for('index'))
return render_template('index.html', color=session['color'], background=session['background'], error=error )
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
{% if color%}
<style>
body {
color: #{{color}};
background-color: #{{background}};
}
</style>
{% endif %}
</head>
<body>
<h1>Hello World</h1>
{% if error%}
{{error}}
{% endif %}
<form action="{{url_for('index')}}" method="POST">
<label for="color">Choose a color</label>
<input type="text" name="color">
<input type="submit" value="PRESSS" name="i_talk-with_flask">
</form>
</body>
</html>
Variation with a Macro DOC
{% macro color_mix(color)%}
{% if color%}
<style>
body {color: #{{color}};}
body {background-color: #{{background_}};}
</style>
{% endif %}
{% endmacro%}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
{{color_mix(color)}}
</head>
<body>
<h1>Hello World</h1>
{% if error%}
{{error}}
{% endif %}
<form action="{{url_for('index')}}" method="POST">
<label for="color">Choose a color</label>
<input type="text" name="color">
<input type="submit" value="PRESSS" name="i_talk-with_flask">
</form>
</body>
</html>
Honestly this is only the tip of the iceberg of the option you can have. Now is this reccomended ? Probably not, because this it should be handle with CSS or then handle it with JavaScript.
However there may be planty of instances where you may want to use it from a Flask App, one of there are:
Testing Purposes.
Debugging.
Something related to a Database.
Fun
That's a CSS question, not Flask.
return '<span style="color: #00ccff;">Hello world</span>'
Answer to Question 2
I'm assuming that you mean taking an image from the web. Yes you can, but this is definitely a CSS/HTML related question. However following the same principle of my previous answer:
Picures taken from Unsplash
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
my_pic = 'https://images.unsplash.com/photo-1469980098053-382eb10ba017?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80'
return render_template('index.html', my_pic=my_pic)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="background-image: url(https://images.unsplash.com/photo-1600187734183-707cf1c0fd5a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1304&q=80);"
>
< <div>
<h1 style="color: white;">Picture from HTML</h1>
<img src="https://images.unsplash.com/photo-1600298881979-9b0c50d7abdf?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&q=60" alt="opps">
</div>
<div style="color: white;">
<h1>Picture from Flask</h1>
<img src="{{my_pic}}" alt="oops">
</div>
</body>
</html>
I suggest you to learn it from HTML and CSS related topic rather than Flask (first learn some CSS and HTML basic):
CSS
HTML
That been said I have a more interesting a USEFUL answer that however requires basic knowledge of the use of a Database, I assume you are a beginner and you may have not yet this knowledge but soon or later you will. So even if you dont understand completely the following keep it in mind and come back later.
I prepared a mini app that using flask, flask_sqlalchemy (with sqlite3), html and Bootstrap.
This app does the following and will teach you these principle:
.1 Upload a picture into a Database.
.2 How to download a picture from the Database.
.3 Render the picture from the Database into the WebBroser.
FULL CODE FROM GITHUB
Some Code from this mini app
Initiate the database, configs and Picture table for the databse
In class FileContent(db.Model):
data = file.read() It saves in database the Binary version of thefile
-render_file = render_picture(data). It saves the decode version, so that you can you see it for render it in the webpages.
# Built-in Imports
import os
from datetime import datetime
from base64 import b64encode
import base64
from io import BytesIO #Converts data from Database into bytes
# Flask
from flask import Flask, render_template, request, flash, redirect, url_for, send_file # Converst bytes into a file for downloads
# FLask SQLAlchemy, Database
from flask_sqlalchemy import SQLAlchemy
basedir = 'sqlite:///' + os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data.sqlite')
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = basedir
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'dev'
db = SQLAlchemy(app)
# Picture table. By default the table name is filecontent
class FileContent(db.Model):
"""
The first time the app runs you need to create the table. In Python
terminal import db, Then run db.create_all()
"""
""" ___tablename__ = 'yourchoice' """ # You can override the default table name
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(128), nullable=False)
data = db.Column(db.LargeBinary, nullable=False) #Actual data, needed for Download
rendered_data = db.Column(db.Text, nullable=False)#Data to render the pic in browser
text = db.Column(db.Text)
location = db.Column(db.String(64))
pic_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
def __repr__(self):
return f'Pic Name: {self.name} Data: {self.data} text: {self.text} created on: {self.pic_date} location: {self.location}'
Upload route, here is where the picture its sent to databse and processed with correct data
So here is what is going on in the app route:
def render_picture(data) --> Takes the bites raw version of the pic and return the decode version, so that it can be used to be display on the web.
data = file.read() : This is the raw data.This can be used for downloading the pic from database
render_file: decoded file so you can retrieve it and the render in the web page
#Render the pics, this Function converts the data from
request.files['inputFile'] so that in can be displayed
def render_picture(data):
render_pic = base64.b64encode(data).decode('ascii')
return render_pic
#app.route('/upload', methods=['POST'])
def upload():
file = request.files['inputFile']
data = file.read()
render_file = render_picture(data)
text = request.form['text']
location = request.form['location']
newFile = FileContent(name=file.filename, data=data,
rendered_data=render_file, text=text, location=location)
db.session.add(newFile)
db.session.commit()
flash(f'Pic {newFile.name} uploaded Text: {newFile.text} Location:
{newFile.location}')
return render_template('upload.html')
INDEX Route
# Index It routes to index.html where the upload forms is
#app.route('/index', methods=['GET', 'POST'])
#app.route('/')
def index():
return render_template('index.html')
INDEX HTML with the Form
<form method="POST" action="/upload" enctype="multipart/form-data">
<!-- File Upload-->
<div class="form-group">
<label for="inputFile">File input</label>
<input class="form-control-file" type="file" name="inputFile">
</div>
<!-- Location -->
<div class="form-group">
<label for="location">Location</label>
<input class="form-control" type="text" name="location">
</div>
<!-- Text -->
<div class="form-group">
<label for="text">Write Text</label>
<textarea class="form-control" name="text" id="text" rows="5" placeholder="Add a Description"></textarea>
</div>
<!-- Submit -->
<button type="submit" class="btn btn-primary">Submit</button>
</form>
How can I get data (html input) using python-tornado.
python code is this:
import tornado.web
import tornado.ioloop
import tornado.httpserver
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render("index.html")
def post(self):
title = self.get_argument("title")
self.render("second.html")
app = tornado.web.Application([
(r"/", MainHandler),
])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(8080)
tornado.ioloop.IOLoop.instance().start()
and html source code is this:
<!Doctype html>
<html>
<body>
<form method="post"></form>
<div style="margin-bottom:5px">
<input name="title" type="text"/>
</div>
<div>
<input type="submit"/>
</div>
</form>
</body>
</html>
Try something like this guy has Stack Overflow
class MyHandler(tornado.web.RequestHandler):
def post(self):
name = self.get_argument("Name", "")
index = self.get_argument("Index","")
.... code for updating MongoDB
Using Flask and SQLAlchemy on my localhost, I am looking to be able to submit a simple contact form and, using AJAX, pass the submitted data along to my Flask API and then insert it into my local database, named contact.db.
To set up my database, I put together a script named setup.py, which successfully creates a database in my working directory. Its contents look as follows:
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy import Column, Date, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref
engine = create_engine('sqlite:///contact.db', echo=True)
Base = declarative_base()
########################################################################
class Contact(Base):
""""""
__tablename__ = "contact"
id = Column(Integer, primary_key=True)
f_name = Column(String)
l_name = Column(String)
email = Column(String)
message = Column(String)
#----------------------------------------------------------------------
def __init__(self, f_name, l_name, email, message):
""""""
self.f_name = f_name
self.l_name = l_name
self.email = email
self.message = message
# create tables
Base.metadata.create_all(engine)
My simple contact page collects the data and submits it to my flask route /contact/request using AJAX (I have confirmed this to work via the console). For reference, however, here is the code I use in contact.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Contact</title>
<!-- Bootstrap -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://code.jquery.com/jquery.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
<script>
$(document).ready(function(){
$("#submitForm").click(function()
{
var firstName = $("#f_name").val();
var lastName = $("#l_name").val();
var email = $("#email").val();
var mess = $("#mess").val();
var nud = {
"f_name" : firstName,
"l_name" : lastName,
"email" : email,
"message" : mess
}
$.ajax({
type: "POST",
url: "/contact/request",
data: JSON.stringify(nud, null, '\t'),
contentType: 'application/json;charset=UTF-8',
success: function(result) {
console.log(result);
}
})
});
})
</script>
</head>
<body>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h1 style="text-align: center">Contact Me</h1>
</div>
<div class="panel-body">
<form role="form">
<div class="form-horizontal" class="form-group" style="width:50%">
<label for="name has-success">First Name</label>
<input class="form-control input-md" type="text" class="form-control" id="f_name" placeholder="Matthew">
</div><br />
<div class="form-horizontal" class="form-group" style="width:50%">
<label for="email">Last Name</label>
<input class="form-control input-md" type="text" class="form-control" id="l_name" placeholder="Gross">
</div><br />
<div class="form-horizontal" class="form-group" style="width:50%">
<label for="email">Email</label>
<input class="form-control input-md" type="email" class="form-control" id="email" placeholder="mattkgross#gmail.com">
</div><br />
<div class="form-group">
<label for="aboutMe">Message</label>
<textarea class="form-control" id="mess" placeholder="What's up?" rows="3" ></textarea>
</div>
<div>
<button type="button" input type "submit" class="btn btn-success" id="submitForm">Submit</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-3"></div>
</div>
</body>
</html>
Finally, I have my actual Flask API script that I run in order to start up my service on localhost. The /contact route works fine. However, when I send the data via my form submission, I get an internal server error. This is undoubtedly being caused by my incorrect attempt at inserting the parsed JSON into my contact database. Below is the code used in my api.py:
from flask import Flask
from flask import request
from flask import render_template
import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from setup import Contact
app = Flask(__name__)
#app.route('/contact')
def contact():
return render_template('contact.html')
#app.route('/contact/request', methods=["POST"])
def contact_request():
if request.method == "POST":
engine = create_engine('sqlite:///contact.db', echo=True)
# Create a Session
Session = sessionmaker(bind=engine)
session = Session()
new_contact = Contact(request.json['f_name'],
request.json['l_name'],
request.json['email'],
request.json['message'])
# Add the record to the session object
session.add(new_contact)
# commit the record the database
session.commit()
#return str(request.json)
app.debug = True
app.run()
If I comment out the two lines:
session.add(new_contact)
session.commit()
and replace them with return str(request.json), my console successfully returns the JSON I sent. I am just completely lost as to where I am going wrong in inserting my data into the database and why it is throwing an error at me for my attempt.
Any help you can give me would be very much appreciated - hopefully it's something simple I overlooked in being new to this whole thing. Thanks!
In flask you have to return something for your route otherwise it will lead to odd behavior. In your case you could return something as simple as an "OK" to let your AJAX know the function completed successfully.
I am executing the following code.
import webapp2
form="""
<form method = "post">
What is your birthday?
<p>
<label>
Day
<input type = "text" name = "day">
Month
<input type = "text" name = "month">
Year
<input type = "text" name = "year">
</p>
<input type = "submit">
</form>
"""
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.out.write(form)
def post(self):
self.response.out.write(form)
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
When I try opening the page localhost:8080, I do not see anything. The page is empty.
I am not familiar with webapp2 but:
after a quick look to tutorials I have seen them write:
self.response.write(...) instead of self.response.out.write()
your code is not correctly indented, you should have:
def get(self):
self.response.write(form)
the string "form" does not seem like a valid html page
maybe you could try
<!DOCTYPE html>
<html>
<head>
<title>Whatever</title>
</head>
<body>
<form method = "post">
What is your birthday?
<p>
<label>
Day
<input type = "text" name = "day">
Month
<input type = "text" name = "month">
Year
<input type = "text" name = "year">
</p>
<input type = "submit">
</form>
</body>
</html>
I have problem getting images displayed in the html template. I managed to store an image into the datastore. However, I don't know how to send it to an html file (or using an URL to display the image?). Please help and many thanks. The following is my code:
main.py
# -*- coding: utf-8 -*-
#!/usr/bin/env python2.7
import webapp2
import common
from google.appengine.ext import db
class Image(db.Model):
filename = db.StringProperty(required=True)
data = db.BlobProperty(required=True)
mimetype = db.StringProperty(required=True)
class Test(webapp2.RequestHandler):
def get(self):
common.render(self, 'test.html', {})
def post(self):
imgfile = self.request.POST['image']
img = Image(filename=imgfile.filename, data=imgfile.value, mimetype=imgfile.type)
img.put()
common.render(self, 'test.html', {'imgkey': img.key().id()})
app = webapp2.WSGIApplication([
("/.*", Test)],
debug=True)
test.html:
<htm>
<head>
<title>Test</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
<p></p>Upload image: </p>
<form method="post" action="/test" enctype="multipart/form-data">
<input type="file" name="image" /><br />
<input type="submit" name="確定" />
</form>
{% if imgkey %}
Display:<br />
<img src="http://.../disp?key={{imgkey}}" /><br />
{% endif %}
</body>
</html>
Try something like this:
class ImageHandler(webapp2.RequestHandler):
def get(self, image_id):
image = Image.get(image_id)
self.response.headers['Content-Type'] = 'image/jpeg'
self.response.out.write(image.data)
Then in your mapping, you should a create an url for image handling e.g:
(r'/images/(.*)', ImageHandler)
In your HTML code you need to create the image tags as follows:
<img src="/images/{{img1.key}}" /><br />
<img src="/images/{{img2.key}}" /><br />