I understand that the browser makes an HTTP request to the bin/app.py application and asks for the / URL, which is commonly the first URL on any website.
Inside bin/app.py I have a list of URLs and what classes they match.
The only ones I have are the '/' and 'index' mappings. It's given in Learn Python the Hard Way that:
This means that whenever someone goes to / with a browser, lpthw.web will find the class index and load it to handle the request.
I have the following code in app.py right now.
import web
urls = ('/','index')
app = web.application(urls,globals())
class whatever:
def GET(self):
a = "Hello World!"
return a
if __name__ == "__main__":
app.run()
In the above code, I named the class "whatever." Even then, when I go to the localhost page, the browser displays "Hello World!"
Why is this happening? Even if I rename one of the urls from "index" to something else, the code works. What am I missing?
By default, the server needs to be restarted after every code change. However, there is a workaround. From the web.py tutorial:
...On the last line add web.reloader so that it reads:
if __name__ == "__main__": web.run(urls, globals(), web.reloader)
This tells web.py to use the web.reloader "middleware" (middleware is a wrapper function to add some functionality to your web server) which reloads your files whenever you edit them, so that you can see the changes in your web browser right away. (For some serious changes, though, you'll still have to restart the server.) You'll probably want to take this out when you make your site public, but it's great while developing
Related
I am deploying Flask on CPanel, and basic configurations are working correctly,
up to the point that I can access home route, defined as:
#app.route("/home")
#app.route("/")
def home():
return "This is home page, blah blah blah"
The site can be thought of, as being accessed at
https://sub-domain.main-domain.com/base-url,
thus, home page is accessed as https://sub-domain.main-domain.com/base-url/ and that works perfectly.
Problem
So, the issue comes when I access any other route, other than the slash("/"),
in the above example, for instance, accessing
https://sub-domain.main-domain.com/base-url/home,
doesn't seem to work at all, and results in
The configuration file does not exist. error.
Any possible help would be kindly appreciated. my passenger_wsgi.py is configured as:
import sys
# add your project directory to the sys.path
base_dir = u'/home/cpaneusername/base-dir'
if base_dir not in sys.path:
sys.path = [base_dir] + sys.path
# import flask app but need to call it "application" for WSGI to work
from app import website as application
Nevertheless, thanks for the assistance.
What I can suggest resolving the issue is to change the base URL of your Python app and remove any sub-folders from it. For example, just keep it that way:
https://sub-domain.main-domain.com/
And try again.
Otherwise, you might want to change the /home route of your app to this one instead:
#app.route("/base-url/home")
If none of the above works, then make sure that you have the correct .htaccess rules in place to forward the requests properly to your app, but I assume you already have considering the fact that you are able to access the / of the app.
I tried moving the Python app and other supporting modules to /public folder, and in the wsgi file, I imported as
from public.app import website as application
There, it worked.
G'day,
I've written a piece of software in Python 3.x with PySide which dynamically displays images (as a slideshow) from a network directory. The software works as intended for local machines (i.e. the slideshow is displayed on the machine which is running the software).
I would like to run the software on a centralised server, which then serves each image of the slideshow temporarily on a local network web page. I've managed to serve static content in my code using the Flask library. Below is a snippet of my code:
def ServeImage(self, DisplayImage):
app = Flask(__name__)
#app.route("/")
def main():
return '''<img src='{}' />'''.format(url_for('static', filename=DisplayImage))
app.run(host='10.2.x.x', port=5000)
'DisplayImage' is the output image path from my current code. At present, the above will correctly display the image in the browser at the designated local address. However, I'm unsure how to return to the slideshow component of the software (where the DisplayImage is generated). It appears that once ServeImage() has been called, the code terminates. I believe it's due to the way this example Flask function was put together. What I'm hoping for is detailed in the pseudo-code below:
def ServeImage(self, DisplayImage):
app = Flask(__name__)
'''<img src='{}' />'''.format(url_for('static', filename=DisplayImage))
app.run(host='10.2.x.x', port=5000)
#Timer
self.ImageNumber += 1
self.SlideShow()
I don't know whether this is possible. As mentioned above, it appears that when app.run() is called, that particular address is served forever, so any code coming after app.run() will never be run. What I'd like is: once the image has been served (i.e. once app.run() has been called), the ImageNumber() variable is changed, and the main SlideShow() function is called, which in turn generates the next DisplayImage to be served on the web page.
Any clarification/suggestions here would be great!
Thanks!
Ok, so I want to catch all the URLs in my Flask app, with this piece of code
#app.route('/<path:path>')
def catch_all(path):
return path
Just a basic app with shows the relative path of each page. So this works fine for most of the paths (localhost/whatever/I/want for example prints whatever/I/want).
EXCEPT in one case. For example if I type localhost/foo/http://google.com/bar in the URL bar, what I expected to be shown is foo/http://google.com/bar, but what I actually get is only bar. So actually Flask finds the last valid URL and takes the path following this URL.
Is there anyway to catch the real path of our URL?
Edit: I'm running Flask 0.10 using the Google App Engine for Python.
I was able to reproduce your problem with the current Google App Engine SDK; this is caused by the way the bundled CherryPy server parses the request.
The problem applies only to your local dev server, when you deploy the app to Google, a different handler parses the URI and the http:// scheme is left unparsed.
See CherryPy issue #1284 as well as the corresponding appengine devserver ticket.
The work-around is to URI-encode the colon:
http://localhost:8000/foo/http%3A//google.com/bar
works.
I recently began a project to migrate our web app from apache + Mod_python to just cherry-py.
There is still a good deal of stuff I still need to do, but for now, it is CherryPy's sessions that are giving me a bit of a headache.
My first question is how do they work?
In Mod_python, we do something like this:
...
from mod_python import Session
sess = Session.Session(req, timeout = 60*60, lock=0)
#req is the request page object.
Judging from the CherryPy documentation, all I need to do to start a session is modify the config by adding something like the following:
cherrypy.config.update({
'tools.sessions.on': True,
'tools.sessions.storage_type': 'ram'})
The above defaults to a time of 60 minutes (though you can manually set your own), but what if I want to destroy that session and make a new one? Do, I call cherrypy.lib.sessions.expire() in any arbitrary file and then do the cherrypy.config.update thing again? Or, will CherryPy make a new session by itself? What if I want to make a new session with a different expiry time?
Note: When I say arbitrary file, I mean a file that is not running CherryPy (My "config" file imports and gets html back from our other pages much like the standard Publisher that comes with Mod_Python).
I tried making a quick little test file:
import cherrypy
from cherrypy.lib import sessions
def index(sid=0, secret=None, timeout=30, lock=1):
cherrypy.session['test'] = 'test'
cherrypy.lib.sessions.expire()
return cherrypy.session.get('test','None')
The end result is that 'test' is still displayed on the screen. Is this happening because the client side session is expired, but the local one still has data? In that case, how can I check if a session expired or not?
Sorry for the confusing question, but I am confused.
Thanks for all your help!
Try this to end a session.
sess = cherrypy.session
sess['_cp_username'] = None
and try this to create a session...
cherrypy.session.regenerate()
cherrypy.session['_cp_username'] = cherrypy.request.login
I used this example to handle most of my session activity.
http://tools.cherrypy.org/wiki/AuthenticationAndAccessRestrictions
Hope this helps,
Andrew
The web app I am working on needs to perform a first-time setup or initialization,
where is a good place to put that logic? I dont want to perform the check if a configuration/setup exists on each request to / or before any request as thats kind of not performant.
I was thinking of performing a check if there is a sane configuration when the app starts up, then change the default route of / to a settings/setup page, and change it back. But thats like self-changing code a bit.
This is required since the web app needs settings and then to index stuff based on those settings which take a bit of time. So after the settings have been made, I still need to wait a while until the indexing is done. So even after the settings/setup has been made, any requests following, will need to see a "wait indexing" message.
Im using flask, but this is relevant for django as well I think.
EDIT: Im thinking like this now;
When starting up, check the appconfig.py for MY_SETTINGS, if it is not there
add a default from config.py and put a status=firstrun object on the app.config, also
change the / route to setup view function.
The setup view function will then check for the app.config.status object and perform
The setup of settings as necessary after user input, when the settings are okay,
remove app.config.status or change it to "indexing", then I can have a before_request function to check for the app.config.status just to flash a message of it.
Or I could use the flask.g instead of app.config to store the status?
The proper way is creating a CLI script, preferably via Flask-Script if you use Flask (in Django it would be the default manage.py where you can easily add custom commands, too) and defining a function such as init or install:
from flaskext.script import Manager
from ... import app
manager = Manager(app)
#manager.command
def init():
"""Initialize the application"""
# your code here
Then you mention it in your documentation and can easily assume that it has been run when the web application itself is accessed.