I was trying to experiment with the loadhook function in web.py, however I am not quite able to make it work. Here is my code:
import web
render = web.template.render('templates/')
urls = (
'/(.*)', 'index'
)
class index:
def GET(self, name):
return render.base(name)
def test():
print "damn"
render.base("test")
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
app.add_processor(web.loadhook(test))
The base.html template is pretty simple which echoes back the "name" parameter.
What I understood from the documentation was that the loadhook function will be called before every request. But it doesn't seem to work. I have tried going to the homepage, another page etc. Neither do I see a print statement on my CMD, nor does the base template with the name test gets executed.
I tried running the same code with just the add_processor as well, but no luck.
Can anyone help me figure out how to run a function before a request happens on a page?
Also, I am assuming request only encompasses browser level requests. Is there any way to capture more via web.py? (such as call a function on keypress, mouse click etc.)
Any help is much appreciated!
loadhooks are called early in the processing and are used to either set configuration or intercept. For example, I implement a black list similar to the following:
def my_hook():
# If requester's IP is in my blacklist, redirect his browser.
if blacklist.in_blacklist(web.ctx.ip) and web.ctx.path != '/blacklist':
raise web.seeother('/blacklist')
....
app.add_processor(web.loadhook(my_hook))
In your example, your test hook calls render (I'm guessing you're trying to render the test page?) Problem is loadhooks don't return data to the browser, so calling render here doesn't do what you want.
Couple other issues: you need to call app.add_processor(web.loadhook(my_hook)) prior to calling app.run(), because the latter sets your polling loop & never returns.
As for your final question: to capture keypresses, etc. you need your javascript to send something to the server.... Everytime there's a keypress, do an ajax call to the server to log the action.
Python's powerful, but still can't read minds.
Related
In my app.py I added a python fuction (to track events) like this:
app = flask.Flask(__name__)
app.jinja_env.globals.update(track_event=track_event)
def track_event(category, label, action):
do="something"
In my HTML code I added it like this:
<a href="somewebsite.web"
class="button button-rounded tright button-large topmargin-sm"
onclick="{{ track_event(category='outbound',action='stackoverflow',
label='somewebsite.web') }}"
>
On this side I offer a listing and therefore add this kind of HTML snipped several times with different URLS (instead of somewebsite.web).
Here is my problem: Instead of being activated "onclick", everytime I load the website all of the onclick events are immediately activated once the browser finished loading.
The functions works as expected, but it shouldnt be called unless someone actually clicks on the . Did anyone have a similar experience?
Is my error in Python or HTML?
In a comment you mentioned that, in the rendered HTML, you had onclick="None". The problem is that your function
def track_event(category, label, action):
do="something"
doesn't return anything. Jinja is going to do what you tell it to do and put the return value of that function in the template. If you return None (which is implicit: if you never explicitly return, you return None by default).
I am working off of Safari's Pyramid tutorial
WEB APPLICATIONS WITH PYTHON AND THE PYRAMID FRAMEWORK
Inside of my views.py file I having a problem with the following code:
#property
def current(self):
todo_id = self.request.matchdict.get('id')
todo = sample_todos.get(todo_id)
if not todo:
raise HTTPNotFound()
return todo
particularly when the following view function calls this property
#view_config(route_name='view', renderer='templates/view.jinja2')
def view(self):
return dict(todo=self.current)
when I am running the application http://0.0.0.0:6543/5 will not trigger the anticipated HTTPNotFound(), see route below.
config.add_route('view', '/{id}')
the error logs return:
File "/Users/alex/zdev/t-oreilly/mysite/views.py", line 50, in view
return dict(todo=self.current)
File "/Users/alex/zdev/t-oreilly/mysite/views.py", line 25, in current
raise HTTPNotFound()
pyramid.httpexceptions.HTTPNotFound: The resource could not be found.
On the browser waitress returns a default server error.
What is the proper way to remove this error?
I have uploaded this work to github, commit aaf562e
the tutorial link is here, for those eager to help, it can be accessed with their 10 day trial. This problem is from video 17/48.
thank you, if you need additional information please let me know.
This is a different HTTPNotFound exception and it is raised at the route-matching step before your view is even executed. The reason is that you have config.add_route('view', '/{id}'). Note the /{id} NOT /{id}/. Pyramid considers these two different routes and thus the latter does not match. The simplest solution to this is to register all of our canonical routes with a / suffix such as /{id}/ and then pass append_slash=True to your notfound view configuration such as config.add_notfound_view(..., append_slash=True) or #notfound_view_config(append_slash=True). This will trigger a redirect when a user visits the version without the trailing slash.
In two of your Jinja templates you reference the #property view.current. However, since the property throws an HTTPNotFound() exception, your Jinja templates end up hitting that and explode, causing your problem.
Either remove the calls to view.current from your Jinja templates or modify your view.current function so that it doesn't throw.
I'm not sure if this is the solution you are looking for, but it doesn't deviate from the tutorial.
I'm trying to delay a part of my pipeline tool (which runs during the startup of Maya) to run after VRay has been registered.
I'm currently delaying the initialization of the tool in a userSetup.py like so:
def run_my_tool():
import my_tool
reload(my_tool)
mc.evalDeferred("run_my_tool()")
I've tried using evalDeferred within the tool to delay the execution of the render_settings script, but it keeps running before VRay has been registered. Any thoughts on how to create a listener for the VRay register event, or what event that is? Thanks!
EDIT:
Made a new topic to figure out how to correctly use theodox's condition/scriptJob commands suggestion here.
Uiron over at tech-artists.com showed me how to do this properly. Here's a link to the thread
Here's the post by uiron:
"don't pass the python code as string unless you have to. Wherever a python callback is accepted (that's not everywhere in Maya's api, but mostly everywhere), try one of these:
# notice that we're passing a function, not function call
mc.scriptJob(runOnce=True, e=["idle", myObject.myMethod], permanent=True)
mc.scriptJob(runOnce=True, e=["idle", myGlobalFunction], permanent=True)
# when in doubt, wrap into temporary function; remember that in Python you can
# declare functions anywhere in the code, even inside other functions
open_file_path = '...'
def idle_handler(*args):
# here's where you solve the 'how to pass the argument into the handler' problem -
# use variable from outer scope
file_manip_open_fn(open_file_path)
mc.scriptJob(runOnce=True, e=["idle", idle_handler], permanent=True)
"
New to python. I am using bottle.py as a web server.
I have a set of static HTML files that need to be rendered on different routes. I am using static_file() function for the same. I also want to set a session based cookie for the page. SO I am using response.set_cookie().
But it turns out that when I am returning a static_file the cookie is never set. However if I change the response to a simple string, set_cookie() works fine. Can anyone explain why? And how can I fix this?
#app.route("/index")
def landingPage():
response.set_cookie("bigUId", "uid12345")
# return "Hello there"
return static_file("/html/index.html", root=config.path_configs['webapp_path'])
Welcome to Bottle and to Python. :)
Looking at the Bottle source code, the problem is readily apparent. Look how static_file ends:
def static_file(...):
...
return HTTPResponse(body, **headers)
static_file creates a new HTTPResponse object--so any headers you've set before then will be discarded.
A very simple way around this is to set the cookies after you call static_file, like this:
#app.route("/index")
def landingPage():
resp = static_file("/html/index.html", root=config.path_configs["webapp_path"])
resp.set_cookie("bigUId", "uid12345")
return resp
I just tried it, and it works perfectly. Good luck!
Well, I just tried, indeed it's not working, I never tried to use cookie with a static_file() before ... However, you can do the following to return a static file as a template, and the cookie will be set :
Your routing function :
#route('/test')
def cookie_test():
response.set_cookie("test", "Yeah")
return template('template/test.html')
And for this to work, you'll need to define a route for /template this way :
#route('/template/<filepath:path>')
def server_static(filepath):
return static_file(filepath, root="./template")
(Obviously, change "/template" to whatever you need according to your project path !)
I'm doing it this way, and it's working fine ! I'm not sure why it doesn't work when you try to set a cookie with static_file(), it might come from the fact that IT IS a static file that you're serving, or whatever, I really don't know.
Also, using the template() function in order to server a "static" html page might not be the right way to do it, but I'm personnaly doing it since a while, and I've never had any issue with this.
Hope it helps !
I think this is quite an easy question to answer, I just haven't been able to find anywhere detailing how to do it.
I'm developing a GAE app.
In my main file I have a few request handlers, for example:
class Query(webapp.RequestHandler):
def post(self):
queryDOI = cgi.escape(self.request.get('doiortitle'))
import queryCosine
self.response.out.write(queryCosine.cosine(queryDOI))
In that handler there I'm importing from a queryCosine.py script which is doing all of the work. If something in the queryCosine script fails, I'd like to be able to print a message or do a redirect.
Inside queryCosine.py there is just a normal Python function, so obviously doing things like
self.response.out.write("Done")
doesn't work. What should I use instead of self or what do I need to include within my included file? I've tried using Query.self.response.out.write instead but that doesn't work.
A much better, more modular approach, is to have your queryCosine.cosine function throw an exception if something goes wrong. Then, your handler method can output the appropriate response depending on the return value or exception. This avoids unduly coupling the code that calculates whatever it is you're calculating to the webapp that hosts it.
Pass it to the function.
main file:
import second
...
second.somefunction(self.response.out.write)
second.py:
def somefunction(output):
output('Done')