I am trying to create a very simple one-page Flask application for a python script that I have. The script requires multiple user inputs in a for-loop with the number of loops being user input as well.
Here is the code in my script to make it more clear:
def shared_books():
import requests as re
from bs4 import BeautifulSoup
import time
num_lists = int(input('Enter the number of lists you would like to search:'))
urls = []
page_counts = []
for i in range(num_lists):
urls.append(input(f'Enter the url for list {i + 1}:'))
page_counts.append(int(input(f'Enter the number of pages for list {i + 1}:')))
I want a simple HTML that will ask the user for the number of lists, then the URL and page count for each list as is shown in my function. Then it will run the entire function.
The HTML code I have right now is super simple and I don't want much else outside of the input parts:
<html>
<head>
<title>Goodreads-App</title>
</head>
<body>
<h1>Welcome to my app!</h1>
<<p>This app will allow you to see books that are
shared between multiple lists on goodreads</p>
</body>
</html>
Please let me know how I can set up this application!
Firstly, I suggest you take a look at the Flask docs. You are doing it right in terms of having a view function, but the input() python keyword doesn't work like that in Flask. Instead, you should render an html template which you can then put your form input field into. Here is an example:
from flask import Flask, render_template
#flask initialising stuff, read docs for info
#app.route("/home")
def home():
return render_template("home.html")
Flask runs on your computer's local server "localhost", which is not publicly accessible. It conventionally runs on port 5000, which gives the name "localhost:5000".
When someone visits "localhost:5000/home", flask will look for a file called "home.html" in a pre-designated templates folder – the default is a directory called "templates" which you should put your html files into.
So if this is your "home.html" file:
<html>
<head>
<title>Goodreads-App</title>
</head>
<body>
<h1>Welcome to my app!</h1>
<p>This app will allow you to see books that are
shared between multiple lists on goodreads</p>
</body>
</html>
When you load the page associated with a specific function, it will return a template which is rendered as html. The above should look something like this:
And that is how to start.
Thank you for the answers! I haven't quite solved the previous issue but have approached it from a different angle which is working now! I will potentially post again if I don't solve it.
I am using flask forms to do what I was trying.
I am in the process of creating a Django web application that reads a URL and outputs selected data from the page. I have written the code in Python that parses the web page and it currently returns the information that I need to display in the Django app as desired.
Before I dive in I just want to confirm what I have researched is correct as I only have a limited time to complete the project.
To summarise my python code, it is in the src folder in a class called "manage.py"
I have created print statements that print the information that I need to display (I did this to ensure it was returning the correct data)
print(variable1)
print("some text" + variable2)
Can I create the Django app code in the same file, "manage.py"? (The project has already been created as a Django app in Eclipse when I started building the project)
Would I build the Django code as I've estimated below if I'm using the variables defined from the Python code above?
<!DOCTYPE>
<html>
<head>
<title>{% block title %}Title of website{% endblock %}</title>
</head>
<body>
<h1>Web page report</h1>
<h2>Summary of web page</h2>
<h3>Title of document</h3>
<p>{{variable1}}</p>
<h3>The file size of the document</h3>
<p>{"Some text" + {variable2}}</p>
</body>
</html>
Django has strict rules about where to place which information. You can not write everything into manage.py. Answering requests from the browser is for example done using view functions.
I am currently writing a CGI python script. Once I have time I will rewrite this in web2py, but simply have no time ATM for this.
I have the whole logic built, except for one thing. I need to be able to:
1) Send a variable to start a process (got that it works)
2) Refresh the page until such process ends
3) display information once process is done.
I can't seem to be able to get passed the URL refresh part, and stripping the variable which started the original process.
I tried webbrowser (webbrowser.open('http://example.com?running=1')), however for some reason I am not being redirected at all on Mac.
if print_html.parse_url():
url_variable=print_html.parse_url()
IP=url_variable['IP'].value
Iterations=int(url_variable['quantity'].value)
start=url_variable['start'].value
refresh=url_variable['refresh'].value
if start == "1":
As you can see I read the variables from URL, and assign values. When start == '1' I want to start running the rest of the programs. While the program is running I want to change the URL variable to re-read the page until everything is finished processing
Some more clarification, perhaps this helps:
I need to refresh the page, or perhaps open the same page but with different variables.
For instance
1st instance: http://example.com/test.py?start=1
logic runs and then refresh spawning:
2st instance: http://example.com/test.py?running=1
Does that make sense?
You can refresh the page using the HTML meta http-equiv directive.
#!/usr/bin/python
import datetime
import time
print "Content-Type: text/html"
print ""
print '''
<html>
<head>
<meta http-equiv="refresh" content="15" />
</head>'''
now = datetime.datetime.now()
now = now.isoformat()
print '''
<body>
The time is now %s
</body>''' % now
I am from a non coding background so python, web2py is very new to me.
My app needs to export textarea content (using RTE redactor) to pdf. I get html content from textarea (redactor), can you please advice me on how to use pyfpdf to generate a pdf file on button click.
I don't know how to get the html content (images and text) on button click in view to generate pdf using appreport.
I was able to use app-report to generate a pdf (using PISA, PYPDF does not work) from an existing html file (without css) if html file has css it throws an error,
***<class 'sx.w3c.cssParser.CSSParseError'> Terminal function expression expected closing ')':: (u'Alpha(Opacity', u'=0); }\n\n\n\n.ui-state-')***
This might be due to a mistake in the controller code:
def myreport():
html = response.render('myreport.html', dict())
return plugin_appreport.REPORTPISA(html = html)
Another thing I tried was passing the html from my view to the controller using ajax post (in Javascript). Redactor is the textarea RTE I am using and alert gives me the desired html result.
View:
function getContent() {
var t= jQuery('#redactor_content').getCode();
alert(t);
jQuery.ajax({
type: "POST",
url: "http://127.0.0.1:8000/Test50/default/myreport2",
data: "{g : 'jQuery('#redactor_content').getCode()'}"
});
}
Controller:
def myreport2():
g = request.get_vars
html = response.render(g)
return plugin_appreport.REPORTPISA(html = html)
Due to my less knowledge in coding , I am not able to figure out and correct my mistake. I will be thankful if anybody can help me with this problem.
Regards,
Akash
Could it be this post request:
jQuery.ajax({
type: "POST",
url: "http://127.0.0.1:8000/Test50/default/myreport2",
data: "{g : 'jQuery('#redactor_content').getCode()'}"
});
}
I think you should have the 'data' parameter be a literal dictionary, not a string. Change this line like this (remove all but one set of quotes):
data: {g : jQuery('#redactor_content').getCode() }
This should properly send the request. The jQuery documentation says that the data parameter should be key-value pairs, not a string.
I am a behavorial scientist and usually collect data by letting participants do some tasks on a computer and record their responses (I write the programs using the pyglet wrapper PsychoPy). That is, the program runs locally and the data is stored locally.
Now I would like to know if there is a way to use Python to display a (local) website with html-forms to the user and collect the input (locally). The reason for this idea is that currently whenever I want to display checkboxes, radiobuttons, or input fields I use wxPython. This works quite well, but programming and layouting in wxPython is kind of cumbersome and I would prefer html with forms.
A requirement would be that it would need to rum without any borders, adress field, menu bar, ... The reason is that I need it in kind of fullscreen mode (I currently open a non-fullscreen pygflet window in the size of the screen to hide the desktop) so that participants can do nothing but work on the forms.
So I am looking for a way to (a) display html websites including html form above a pyglet window with no menu bar or whatsoever, (b) collect the input when clicking on the Ok button (i.e., the form is send), (c) control what is presented prior and after viewing this website, and (d) everything of this should happen locally!
My idea would be that the data is collected when participants hit the "Send away" button in the following example pic and the next page is displayed.
Update: I use windows (XP or 7).
This is a solution using Qt Webkit for rendering HTML. The default navigation request handler is wrapped by a function that checks for submitted form requests. The form uses the "get" method, so the data is included in the url of the request and can be retrieved that way. The original request is declined and you can change the content of the displayed web page as you wish.
from PyQt4 import QtGui, QtWebKit
app = QtGui.QApplication([])
view = QtWebKit.QWebView()
# intercept form submits
class MyWebPage(QtWebKit.QWebPage):
def acceptNavigationRequest(self, frame, req, nav_type):
if nav_type == QtWebKit.QWebPage.NavigationTypeFormSubmitted:
text = "<br/>\n".join(["%s: %s" % pair for pair in req.url().queryItems()])
view.setHtml(text)
return False
else:
return super(MyWebPage, self).acceptNavigationRequest(frame, req, nav_type)
view.setPage(MyWebPage())
# setup the html form
html = """
<form action="" method="get">
Like it?
<input type="radio" name="like" value="yes"/> Yes
<input type="radio" name="like" value="no" /> No
<br/><input type="text" name="text" value="Hello" />
<input type="submit" name="submit" value="Send"/>
</form>
"""
view.setHtml(html)
# run the application
view.show()
app.exec_()
As AdamKG mentioned, using a webframework would be a good choice. Since Django and similar might be an overkill here, using a micro webframework like 'flask' or 'bottle' would be a great choice.
This link demonstrates via step by step instruction how to make a simple form via a To-DO application. It assumes zero previous knowledge.
You can run it only locally also.
your want a simple solution, so just write a http server and run your simple page.
using python.BaseHTTPServer, coding a 15 line web server:
import BaseHTTPServer
class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/foo':
self.send_response(200)
self.do_something()
else:
self.send_error(404)
def do_something(self):
print 'hello world'
server = BaseHTTPServer.HTTPServer(('',80), WebRequestHandler)
server.serve_forever()
easy enough,but i suggest using some web frameworks. They are easy too.
for example, web.py. here is what u want in 50 line codes:
install web.py
make a dir with 2 files:
./
|-- app.py
`-- templates
`-- index.html
index.html
$def with (form, ret)
<html>
<head>
<title> another site </title>
</head>
<body>
<h1> hello, this is a web.py page </h1>
<form action="" method="post">
$:form.render()
</form>
<h2>$:ret</h2>
</body>
</html>
app.py logic file:
import web
### Url mappings
urls = (
'/', 'Index', )
### Templates
render = web.template.render('templates')
class Index:
form = web.form.Form(
web.form.Textbox('fav_name', web.form.notnull, description="Favorite Name:"),
web.form.Textbox('cur_name', web.form.notnull, description="Current Name:"),
web.form.Button('Send Away'),
)
def GET(self):
""" Show page """
form = self.form()
return render.index(form, "")
def POST(self):
""" handle button clicked """
form = self.form()
if not form.validates():
return render.index(form, "INPUT ERROR")
# save data by ur method, or do some task
#pyglet.save_data(form.d.fav_name, form.d.cur_name)
#pyglet.draw(some_pic)
#os.system(some_cmd)
form = self.form()
return render.index(form, "YOUR DATA SAVED")
app = web.application(urls, globals())
if __name__ == '__main__':
app.run()
run this server in your windows:
python app.py 9999
open browser: http://127.0.0.1:9999/
by the way, if ur data is only strings, u can save them in web.by by sqlite.
My suggestion would be:
Use some python server as, for example SimpleHTTPServer. It is needed because the submit button on forms sends the information to a server. There you should manage the received info some way;
Have your browser configured with one of those Kiosk extensions, which disallow even the use of Alt+F4. An example would be Open Kiosk extension for Firefox
Optionally, if you have affinity with scripts in general, you could create a script which, when executed, would at the same time run the python server AND open your html file in the browser. That would ease a lot your setup work for every subject in your group.
EDIT: I've read you need the pyglet over the browser window. That could be included in the script of step 3, using "always on top" option and absolute positioning of the pyglet (I can tell this would probably be simpler on Linux, which could be run from persistent LiveUSB - just a thought!)
EDIT (regarding the posted comment):
I think the most reliable option for output would be to disk (file or database) instead or RAM (running python object), then you read the info from file afterwards. Then, in case of a surprise (system hang, power failure), the already-entered data would be there.
The only (and most important) part I don't know HOW to do is to handle the content of the form's "submit" on the server-side. Probably some server-side script file (php, python) shoud be created and left on the server root, so the server would receive an http request containing the info, and send the info to the script, which then handles the processing and file/database storage activities.
This might be of your interest:
"The POST request method is used when the client needs to send data to the server as part of the request, such as when uploading a file or submitting a completed form." (from wikipedia on "POST(HTTP)" ENTRY)
In another link, some thoughts on using SimpleHTTPServer itself for handling POST requests:
http://islascruz.org/html/index.php/blog/show/Python%3A-Simple-HTTP-Server-on-python..html
Hope this helps.
The reason for this idea is that currently whenever I want to display
checkboxes, radiobuttons, or input fields I use wxPython. This works
quite well, but programming and layouting in wxPython is kind of
cumbersome and I would prefer html with forms.
You can combine the ease of HTML and still create native Windows applications using Flex with a Python backend.
If you are averse to Flex, a bit more - involved - but still native windows application generator is Camelot
Edit
Instead of typing it out again - I would suggest the django + flex + pyamf article on Adobe that explains it all with screenshots as well. You can replace django with flask or bottle as they are more lightweight, however the PyAMF library provides native support for django which is why it was used in the example.
PyAMF provides Action Message Format (a binary protocol to exchange object with the flash runtime) support for Python.