waitfor it and pylons debugger, WAS: Running a program without waiting for it to finish
Hi Ian, I didn't notice this thread first time around, but you might find WaitForIt (http://pythonpaste.org/waitforit/) helpful for cases like these; you could write the code as blocking and let WaitForIt deal with the long-running aspect. (Assuming it runs for a long time, but eventually finishes -- if you need to interact with it over time you should stuff the process object in a module global) Thanks, this does indeed look like just the ticket. However I'm struggling to get this to work with Pylons correctly, specifically it seems to interfere with the debugger in the way that I have it set up [which is probably wrong]. To set it up I came across a post (http://www.mail-archive.com/paste-us...@pythonpaste.org/msg00213.html) on the paste mailing list which contained the following info: --- so then I tried to use waitforit with pylons, so I made a new pylons app and added this to my test.ini file: [app:main] use = config:development.ini filter-with = slow [filter:slow] use=egg:waitforit time_limit=2 poll_time=1 --- I don't think I even use test.ini, so I modded my development.ini file to look like this: snip [app:main] use = egg:ark full_stack = true cache_dir = %(here)s/data beaker.session.key = ark beaker.session.secret = somesecret sqlalchemy.default.url = sqlite:///%(here)s/data/project.db *filter-with = slow *[filter:slow] *use=egg:waitforit *time_limit=2 *poll_time=1 /snip With the * lines being the new additions [minus the asterisk of course]. This does work, and I can use the wait for it message etc, however if the pylons debugger needs to kick in it's now broken, with the following errors: Traceback (most recent call last): File c:\python26\lib\site-packages\paste-1.7.2-py2.6.egg\paste\evalexception\mid dleware.py, line 82, in simplecatcher_app return application(environ, start_response) File c:\python26\lib\site-packages\paste-1.7.2-py2.6.egg\paste\httpexceptions.py , line 636, in __call__ return self.application(environ, start_response) File c:\python26\lib\site-packages\paste-1.7.2-py2.6.egg\paste\evalexception\mid dleware.py, line 117, in application res = func(*args, **form.mixed()) File c:\python26\lib\site-packages\paste-1.7.2-py2.6.egg\paste\evalexception\mid dleware.py, line 140, in debug_info_replacement debugcount = int(debugcount) TypeError: int() argument must be a string or a number, not 'list' Any help on how to stop this? Jules --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: session auto-save
Below is quick implementation of this proposal. First we need to patch up Beaker's Session object to record it's dirty state(has been modified), and to allow clients to check the accessed and dirty properties: beaker_patch.py === import beaker.session def __setitem__(self, key, value): self.__dict__['_dirty'] = True self._session()[key] = value def __delitem__(self, key): self.__dict__['_dirty'] = True self._session().__delitem__(key) def save(self): self._session().save() self.__dict__['_dirty'] = False def accessed(): return self.__dict__['_sess'] is not None def dirty(self): return self.__dict__.get('_dirty') is not None beaker.session.SessionObject.__setitem__ = __setitem__ beaker.session.SessionObject.__delitem__ = __delitem__ beaker.session.SessionObject.save = save beaker.session.SessionObject.accessed = accessed beaker.session.SessionObject.dirty = dirty Now we need to implement the autosave in a custom middleware, which checks the config file for a beaker.session.autosave setting (defaults to off). autosave_opt_val = ('off', 'if_accessed', 'on') class CustomMiddleware(object): def __init__(self, application, config): self.application = application self.opt_val = 0 opt_name = 'beaker.session.autosave' if opt_name in config: for idx, name in enumerate(autosave_opt_val): if config[opt_name] == name: self.opt_val = idx break; else: raise Exception('Invalid option %r for %r in config file' % (config[opt_name], opt_name)) def __call__(self, environ, start_response): content = self.application(environ, start_response) if (self.opt_val==2 and session.dirty()) or (self.opt_val==1 and session.accessed()): session.save() return content Now you can enable autosave in development.ini: beaker.session.autosave = on So you can now go ahead and remove all the session.save() calls in your controllers and templates. The seesion will be save if and only if it has been modified, that is if an attribute was assigned or deleted. On Jan 6, 8:35 pm, Tycon adie...@gmail.com wrote: The session object is a very useful feature of pylons and is core to any web application. In pylons the session objects acts like a dictionary that you can access and modify, as well as save it to a storage manager which can be memory, file, dbms, memcached, etc. Normally you want to save whatever changes you made to the session object, so you have to explictly call session.save(). The most logical place to do that is at the end of processing a request, but it's annoying to do that at the end of every request and other wrappers can't easily tell if the session was modified and needs to be saved. Since the session can be modified by different parts of your code during a request, and you are not always sure if those changes will be saved at the end, what ends up happening is that the session is saved multiple times during one request, which is wasteful. Therefore, I have a suggestion to have a session.autosave setting in the config file that will have the following options: off: don't autosave on: save the session object at the end of the request, if it was modified during the request if_accessed: saves the session object at the end of the request, if it was accessed during the request compat: saves the session object when it's first accessed during the request, updating the _accessed_time attribute. The difference between if_accessed and on options is that for if_accessed the session is saved at the end of the request if it was accessed or modified, but for on options it's only saved if it was modified. In either case this means you can remove all the explicit session.save() statements from your code. Applications that don't care about the _accessed_time attribute can use the on setting so the session will be saved only if you actually modified it (this will produce better performance). The last option (compat) sounds kind of silly, but it's actually the way the session object currently works: the first time you try to access the session object, it is loaded using the storage manager, the _accessed_time attribute is updated to now, and then the session is immediately saved back. So any subsequent changes you make to the session object need to be saved explicitly. The new option if accessed gives you almost the exact same behavior by making sure the session is saved if it was accessed, but since it saves at the end of the request - the session is only saved once (and you don't need to do it explicitly anymore). A related note to all those automatic _something_time attributes - there is a bug with creation_time that it gets set to now when you do a session.save(). It will be better to have a _modified_time
Re: session auto-save
W liście Tycon z dnia środa 07 stycznia 2009: Below is quick implementation of this proposal. First we need to patch up Beaker's Session object to record it's dirty state(has been modified), and to allow clients to check the accessed and dirty properties: Just note, that in case the dict is not modified directly, but an object inside is modified, you won't get notified of the change. Eg. suppose the restored session has: session['messages'] = [] Now i do: session['messages'].append(u'New flash message') You won't see that the session has changed. -- Paweł Stradomski --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: session auto-save
I put session.save() in the __after__ method of my base controller when I want to auto save sessions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Pylons, SQLAlchemy and deleting
Hi, This question is specific to Pylons and SQLAlchemy. Hi all, I have a mapped class (I am using SQLAlchemy's ORM), called Person. I have a method on a pylons controller to delete a Person record from the table that the Person class is mapped to. I am using the id column (int, primary key) of the person table to delete this person record. I find myself doing something like this: def deletePerson(self): person_id = int(request.GET[personId]) p = Session.query(Person).filter_by(id=person_id).first() if p: Session.delete(p) Session.commit() return redirect_to(action=list) Is it normal, when using sqlalchemy, to have to select the Person object first, then delete it? I would rather not hit the database for the select, and then again for the delete. I realize I could probably do this if I bypassed SQLAlchemy's ORM and used it's SQL expression language, but I would rather not. Thanks, goon12 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: Pylons, SQLAlchemy and deleting
Joe Riopel, środa 07 stycznia 2009 15:51: def deletePerson(self): person_id = int(request.GET[personId]) p = Session.query(Person).filter_by(id=person_id).first() if p: Session.delete(p) Session.commit() return redirect_to(action=list) Is it normal, when using sqlalchemy, to have to select the Person object first, then delete it? Of course not. Try: Session.query(Person).filter_by(...).delete() .pk. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: Pylons, SQLAlchemy and deleting
2009/1/7 Piotr Kęplicz kepl...@cmc.pl: Of course not. Try: Session.query(Person).filter_by(...).delete() Hi Piotr and thank you for the reply. Isn't that code still doing the select first, to get the object, and then deleting it? The code you posted is much cleaner though. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
A more concise way to do it?
Hello everyone, I need access to parsed form variables, and lo and behold, paste does hold those. But. The access to it is a bit convoluted, esp. for smth done over and over: if request.environ.has_key('paste.parsed_formvars'): for item in request.environ['paste.parsed_formvars'][0].items(): do_smth(item) Is there a shorter / proper way to do it? Regards, mk --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
global h variable
Hello everyone, I'm really new to Pylons, so could someone please help me clear some of the confusion with the following stuff? I'm trying to access global h variable in Pylons 0.9.7, mainly for sake of getting at url_for function. But h var seems to be available only in Mako templates and not the controller code (at least in 0.9.7). http://wiki.pylonshq.com/display/pylonscookbook/Routes+for+people+in+a+hurry contains example of using h variable without quoting the context, but it may look like controller code (or routing.py). So my question is, what is h variable mainly for? Should I use it in (mainly or only in) templates or are there uses for it in controller code? If so, how to access it there? Regards, mk --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: Pylons, SQLAlchemy and deleting
Joe Riopel, środa 07 stycznia 2009 17:45: Session.query(Person).filter_by(...).delete() Isn't that code still doing the select first, to get the object, and then deleting it? No. It's a Query object turned into a DELETE statement, just like first(), all() or one() would turn it into a SELECT statement. .pk. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: waitfor it and pylons debugger, WAS: Running a program without waiting for it to finish
Jules Stevenson wrote: Hi Ian, I didn't notice this thread first time around, but you might find WaitForIt (http://pythonpaste.org/waitforit/) helpful for cases like these; you could write the code as blocking and let WaitForIt deal with the long-running aspect. (Assuming it runs for a long time, but eventually finishes -- if you need to interact with it over time you should stuff the process object in a module global) Thanks, this does indeed look like just the ticket. However I'm struggling to get this to work with Pylons correctly, specifically it seems to interfere with the debugger in the way that I have it set up [which is probably wrong]. To set it up I came across a post (http://www.mail-archive.com/paste-us...@pythonpaste.org/msg00213.html) on the paste mailing list which contained the following info: --- so then I tried to use waitforit with pylons, so I made a new pylons app and added this to my test.ini file: [app:main] use = config:development.ini filter-with = slow [filter:slow] use=egg:waitforit time_limit=2 poll_time=1 --- I don't think I even use test.ini, so I modded my development.ini file to look like this: snip [app:main] use = egg:ark full_stack = true cache_dir = %(here)s/data beaker.session.key = ark beaker.session.secret = somesecret sqlalchemy.default.url = sqlite:///%(here)s/data/project.db *filter-with = slow *[filter:slow] *use=egg:waitforit *time_limit=2 *poll_time=1 /snip With the * lines being the new additions [minus the asterisk of course]. This does work, and I can use the wait for it message etc, however if the pylons debugger needs to kick in it's now broken, with the following errors: Traceback (most recent call last): File c:\python26\lib\site-packages\paste-1.7.2-py2.6.egg\paste\evalexception\mid dleware.py, line 82, in simplecatcher_app return application(environ, start_response) File c:\python26\lib\site-packages\paste-1.7.2-py2.6.egg\paste\httpexceptions.py , line 636, in __call__ return self.application(environ, start_response) File c:\python26\lib\site-packages\paste-1.7.2-py2.6.egg\paste\evalexception\mid dleware.py, line 117, in application res = func(*args, **form.mixed()) File c:\python26\lib\site-packages\paste-1.7.2-py2.6.egg\paste\evalexception\mid dleware.py, line 140, in debug_info_replacement debugcount = int(debugcount) TypeError: int() argument must be a string or a number, not 'list' Any help on how to stop this? Hmm... I haven't seen this error, though generally it's better if WaitForIt is wrapped only around those parts of your app that are slow. I don't think Pylons controllers have a clear WSGI interface. That's too bad, they should. Here's a WSGI wrapper on a controller: class MyController(BaseController): ... def app(environ, start_response): return MyController()(environ, start_response) MyController = WaitForIt(app) I believe that will work, and then you can wrap just the controller that is likely to be slow. -- Ian Bicking : i...@colorstudy.com : http://blog.ianbicking.org --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: A more concise way to do it?
if request.environ.has_key('paste.parsed_formvars'): for item in request.environ['paste.parsed_formvars'][0].items(): do_smth(item) Is there a shorter / proper way to do it? Learn FormEncode or ToscaWidgets. I use both but like plain FormEncode more. -- Dalius http://blog.sandbox.lt --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: session auto-save
I agree that it's better to let users set the dirty flag if they want. It would also be great if you can change the Session.load() method to NOT save the session immediately after loading it (not at the end of the request), as is the case today. This auto-saving upon first access is quite useless because subsequent changes to the session during the same request need to be saved separately afterwards. The Session.load () method can set the dirty flag if the autosave options is if_accessed. Together these changes can help avoiding the multiple save() that is happening today every time the session is used. On Jan 7, 10:16 am, Ben Bangert b...@groovie.org wrote: On Jan 7, 2009, at 4:59 AM, Paweł Stradomski wrote: Just note, that in case the dict is not modified directly, but an object inside is modified, you won't get notified of the change. Eg. suppose the restored session has: session['messages'] = [] Now i do: session['messages'].append(u'New flash message') You won't see that the session has changed. This is the exact reason we don't have a 'dirty' type flag like this set on setitem. However, I think it'd be useful to let a user set the 'dirty' flag themselves, in addition to letting sessions auto-save merely upon access (just to be sure), or something as Tycon suggests. Many people end up calling save() multiple times because they need to put stuff in the session in various places and ensures its saved, when really, they should be marking it 'to-be-saved' so its done just *once*. Tycon, I'll have some time later today to merge a patch to that effect in. Cheers, Ben smime.p7s 3KViewDownload --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Best unit testing module for pylons REST api calls
I have a controller that I want to build unit test for, the controller is a web-based REST api, and I would like to know what you guys would recommend for a module. Thanks in advance, Charles --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: Best unit testing module for pylons REST api calls
On Wed, Jan 7, 2009 at 2:51 PM, csismondo csismo...@roadrunner.com wrote: I have a controller that I want to build unit test for, the controller is a web-based REST api, and I would like to know what you guys would recommend for a module. http://pypi.python.org/pypi/WebTest/1.1 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: A more concise way to do it?
Dalius Dobravolskas wrote: if request.environ.has_key('paste.parsed_formvars'): for item in request.environ['paste.parsed_formvars'][0].items(): do_smth(item) Is there a shorter / proper way to do it? Learn FormEncode or ToscaWidgets. I use both but like plain FormEncode more. There are three problems with FormEncode: 1. From what I gather in the docs, it seems FormEncode is directed more at form value validation rather than form generation. Author plainly states in the docs that FormEncode has limitations in the area of form generation: At one time FormEncode included form generation in addition to validation. The form generation worked okay; it was reasonably attractive, and in many ways quite powerful. I might revisit it. But generation is limited. It works great at first, then you hit a wall – you want to make a change, and you just can’t, it doesn’t fit into the automatic generation. 2. In simple / naive usage mode it requires mixing HTML and code, which I abhor, on top of it being contrary to the principles of 'separation of layers' in MVC. Sure, one could theoretically think about parsing templates and getting form strings out and then passing them to FormEncode for validation and/or further generation, or do smth even fancier like storing form HTML in database and then passing it to FormEncode. But that's complicated and I'm just a beginner with all the components of Pylons. Maybe some day. 3. I don't mean to be ungrateful towards Ian or smth, but I find FormEncode's documentation to be rather limited to tell the truth. By all means I am willing to expend some effort to learn FormEncode, but correct me if I'm wrong in thinking that it's mostly useful for user input validation, not form generation -- which leaves me with the original dilemma. Practically speaking, I need to store things like user's SpamAssassin's settings in db, then set appropriate values / radio buttons / etc in the form and obviously allow editing saving those. How would you approach such a problem in Pylons? Should I just write the HTML forms in templates manually or what? Regards, mk --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: global h variable
On Wed, Jan 7, 2009 at 1:05 PM, mk mrk...@gmail.com wrote: Hello everyone, I'm really new to Pylons, so could someone please help me clear some of the confusion with the following stuff? I'm trying to access global h variable in Pylons 0.9.7, mainly for sake of getting at url_for function. But h var seems to be available only in Mako templates and not the controller code (at least in 0.9.7). http://wiki.pylonshq.com/display/pylonscookbook/Routes+for+people+in+a+hurry contains example of using h variable without quoting the context, but it may look like controller code (or routing.py). So my question is, what is h variable mainly for? Should I use it in (mainly or only in) templates or are there uses for it in controller code? If so, how to access it there? h stands for helpers, and it's a couple of functions provided by pylons, webhelpers and your own /lib/helpers.py file. as for using them (helpers, not h) on the controller what I do is simply import it, either from webhelpers or your lib/helpers.py As for url_for I think you are breaking MVC a little here, why will you want the URL for another part of your site in the controller? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: global h variable
On Jan 7, 9:05 am, mk mrk...@gmail.com wrote: Hello everyone, I'm really new to Pylons, so could someone please help me clear some of the confusion with the following stuff? I'm trying to access global h variable in Pylons 0.9.7, mainly for sake of getting at url_for function. But h var seems to be available only in Mako templates and not the controller code (at least in 0.9.7). http://wiki.pylonshq.com/display/pylonscookbook/Routes+for+people+in+... contains example of using h variable without quoting the context, but it may look like controller code (or routing.py). So my question is, what is h variable mainly for? Should I use it in (mainly or only in) templates or are there uses for it in controller code? If so, how to access it there? Regards, mk By default, Pylons injects `h` into the template context for you. To get access to `h` in a controller: from pylons import config h = config['pylons.h'] See config/environment.py for where `config['pylons.h']` is configured. By default, it points at the yourapp.lib.helpers module, so you could also get `h` in a controller like this: import yourapp.lib.helpers as h I'd say `h` is intended as a convenient namespace for your Web-related utilities (AKA helpers), which are mainly used in templates, but I can imagine cases where you might want to use those helpers in a controller. If you just need `url_for`, you could also import it directly from Routes: from routes import url_for Hope that helps a bit. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: global h variable
Jorge Vargas wrote: So my question is, what is h variable mainly for? Should I use it in (mainly or only in) templates or are there uses for it in controller code? If so, how to access it there? h stands for helpers, and it's a couple of functions provided by pylons, webhelpers and your own /lib/helpers.py file. as for using them (helpers, not h) on the controller what I do is simply import it, either from webhelpers or your lib/helpers.py And normally you would use helpers mostly in templates, right? As for url_for I think you are breaking MVC a little here, why will you want the URL for another part of your site in the controller? Just testing what it's good for. :-) Regards, mk --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: A more concise way to do it?
On Jan 7, 11:58 am, mk mrk...@gmail.com wrote: Dalius Dobravolskas wrote: if request.environ.has_key('paste.parsed_formvars'): for item in request.environ['paste.parsed_formvars'][0].items(): do_smth(item) Is there a shorter / proper way to do it? Learn FormEncode or ToscaWidgets. I use both but like plain FormEncode more. There are three problems with FormEncode: 1. From what I gather in the docs, it seems FormEncode is directed more at form value validation rather than form generation. Author plainly states in the docs that FormEncode has limitations in the area of form generation: At one time FormEncode included form generation in addition to validation. The form generation worked okay; it was reasonably attractive, and in many ways quite powerful. I might revisit it. But generation is limited. It works great at first, then you hit a wall – you want to make a change, and you just can’t, it doesn’t fit into the automatic generation. 2. In simple / naive usage mode it requires mixing HTML and code, which I abhor, on top of it being contrary to the principles of 'separation of layers' in MVC. Sure, one could theoretically think about parsing templates and getting form strings out and then passing them to FormEncode for validation and/or further generation, or do smth even fancier like storing form HTML in database and then passing it to FormEncode. But that's complicated and I'm just a beginner with all the components of Pylons. Maybe some day. 3. I don't mean to be ungrateful towards Ian or smth, but I find FormEncode's documentation to be rather limited to tell the truth. By all means I am willing to expend some effort to learn FormEncode, but correct me if I'm wrong in thinking that it's mostly useful for user input validation, not form generation -- which leaves me with the original dilemma. Practically speaking, I need to store things like user's SpamAssassin's settings in db, then set appropriate values / radio buttons / etc in the form and obviously allow editing saving those. How would you approach such a problem in Pylons? Should I just write the HTML forms in templates manually or what? Hard to say. Have you seen FormAlchemy or Formish? I haven't used them, but they look interesting. Formish has a nice demo site: http://ish.io:8891/ --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: global h variable
Wyatt Baldwin wrote: snip Thanks Wyatt, great response! Regards, mk --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: session auto-save
On Jan 7, 2009, at 11:14 AM, Tycon wrote: I agree that it's better to let users set the dirty flag if they want. It would also be great if you can change the Session.load() method to NOT save the session immediately after loading it (not at the end of the request), as is the case today. This auto-saving upon first access is quite useless because subsequent changes to the session during the same request need to be saved separately afterwards. The Session.load () method can set the dirty flag if the autosave options is if_accessed. Together these changes can help avoiding the multiple save() that is happening today every time the session is used. Definitely. I'd be happy to review a patch to the code if you'd like to add these features, right now I'm heavily focused on Pylons 0.9.7 release so it'll be a few weeks before I can get back to the Beaker code-base myself. Feel free to email me directly about any patches (with unit tests) to this and I can apply them. I'm sure your suggestion of not saving immediately upon load will also help session performance, which has been one of our goals for awhile too. Cheers, Ben smime.p7s Description: S/MIME cryptographic signature
Re: A more concise way to do it?
On Wed, Jan 7, 2009 at 11:58 AM, mk mrk...@gmail.com wrote: Dalius Dobravolskas wrote: if request.environ.has_key('paste.parsed_formvars'): for item in request.environ['paste.parsed_formvars'][0].items(): do_smth(item) Is there a shorter / proper way to do it? Learn FormEncode or ToscaWidgets. I use both but like plain FormEncode more. There are three problems with FormEncode: 1. From what I gather in the docs, it seems FormEncode is directed more at form value validation rather than form generation. Author plainly states in the docs that FormEncode has limitations in the area of form generation: At one time FormEncode included form generation in addition to validation. The form generation worked okay; it was reasonably attractive, and in many ways quite powerful. I might revisit it. But generation is limited. It works great at first, then you hit a wall – you want to make a change, and you just can't, it doesn't fit into the automatic generation. FormEncode does not do form generation, period. That paragraph must have been written in an early stage of FormEncode's development. The main Pylons solutions for form generation are: 1) A template with a manually-built form. 2) Same but with WebHelpers. 3) ToscaWidgets. 4) FormAlchemy. 2. In simple / naive usage mode it requires mixing HTML and code, which I abhor, on top of it being contrary to the principles of 'separation of layers' in MVC. I'm not sure what it means, unless you're objecting to building forms in templates. But a form is intrinsically a user interface object. In some cases the exact look is unimportant enough that a programmatically-generated form (ToscaWidgets) is acceptable. In other cases the form needs so many customizations that it's not worth creating a ToscaWidgets widget set for it. My client is prone to say put this text here next to this one field, and move these three fields in a row, no, wait, change it back. This is easier to manage with a template+WebHelpers form. Sure, one could theoretically think about parsing templates and getting form strings out and then passing them to FormEncode for validation and/or further generation, or do smth even fancier like storing form HTML in database and then passing it to FormEncode. But that's complicated and I'm just a beginner with all the components of Pylons. Maybe some day. I think FormEncode is easier than than you're making it out to be. The main problem with FormEncode in Pylons is that there's not a good structure for calling htmlfill on the initial form to eliminate the form:error tags, while also calling it in a different way if validation fails. @validate works but is not structured that well. So you just have to work around these annoyances if they affect your application. 3. I don't mean to be ungrateful towards Ian or smth, but I find FormEncode's documentation to be rather limited to tell the truth. The FormEncode manual is incomplete and was written to introduce FormEncode on the command line. That's not how it's used in Pylons, which is what makes it difficult to learn FormEncode from the manual. The manual does not address the new validators that have been added, how to choose between similar validators, and does not say enough about building your own validators. At the last PyCon, Ian and I brainstormed a list of things that should go into the manual, but nobody has had time to write it. http://wiki.pylonshq.com/display/pylonscookbook/The+other+FormEncode+manual+(UNFINISHED) I and other users may have developed some other techniques in the meantime which have not made it onto this page. If you're having trouble with particular aspects of FormEncode, ask here or on the FormEncode list. -- Mike Orr sluggos...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: Pylons, SQLAlchemy and deleting
On 08/01/2009, at 4:22 AM, Piotr Kęplicz wrote: Joe Riopel, środa 07 stycznia 2009 17:45: Session.query(Person).filter_by(...).delete() Isn't that code still doing the select first, to get the object, and then deleting it? No. It's a Query object turned into a DELETE statement, just like first(), all() or one() would turn it into a SELECT statement. In your Pylons config (development.ini) you can enable sqlalchemy.echo = true to see all the SQL statements in the logfile. That helps to get a good understanding of what SA is actually doing. Cheers, Chris Miles --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: Best unit testing module for pylons REST api calls
On 08/01/2009, at 5:51 AM, csismondo wrote: I have a controller that I want to build unit test for, the controller is a web-based REST api, and I would like to know what you guys would recommend for a module. I'm using the TestController that comes with a Pylons template project for RESTful HTTP controller testing. This uses webtest as mentioned by Jorge. In the tests you can just use calls like: response = self.app.post(url('/new_app_submit'), params=dict(app_name='testapp1', app_desc='Test app #1')) response = self.app.put(url('/app/testapp1/purchases/user1/ productA')) response = self.app.get(url('/app/testapp1/purchases')) and test the response object for each case. e.g: self.failUnlessEqual(response.status, '200 OK') If you need a more thorough example of code just call out. Cheers, Chris Miles --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: Best unit testing module for pylons REST api calls
Chris Miles wrote: On 08/01/2009, at 5:51 AM, csismondo wrote: I have a controller that I want to build unit test for, the controller is a web-based REST api, and I would like to know what you guys would recommend for a module. I'm using the TestController that comes with a Pylons template project for RESTful HTTP controller testing. This uses webtest as mentioned by Jorge. In the tests you can just use calls like: response = self.app.post(url('/new_app_submit'), params=dict(app_name='testapp1', app_desc='Test app #1')) response = self.app.put(url('/app/testapp1/purchases/user1/ productA')) response = self.app.get(url('/app/testapp1/purchases')) and test the response object for each case. e.g: self.failUnlessEqual(response.status, '200 OK') If you need a more thorough example of code just call out. Note that WebTest automatically tests for a response code of 2xx or 3xx -- 4xx or 5xx will raise an error. So you don't really need failUnlessEqual, and you can always assert the response code like: self.app.post(..., status=200) # e.g., 204 No Content would be an error self.app.post('/random', status=404) -- Ian Bicking : i...@colorstudy.com : http://blog.ianbicking.org --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: global h variable
On Wed, Jan 7, 2009 at 12:05 PM, Wyatt Baldwin wyatt.lee.bald...@gmail.com wrote: I'd say `h` is intended as a convenient namespace for your Web-related utilities (AKA helpers), which are mainly used in templates, but I can imagine cases where you might want to use those helpers in a controller. If you just need `url_for`, you could also import it directly from Routes: from routes import url_for Many of the tutorials on the wiki are old, and the best practices have evolved over time, so mk's confusion is understandable. By definition, a helper is a generic function that's useful in templates and/or controllers. 'h' is automatically available in templates. In controllers you have to do import myapp.lib.helpers as h. In Pylons 0.9.5, 'h' was automatically available in controllers via an import in the base controller module. This was eliminated because of dissastisfaction with import *. url_for has traditionally been in the helpers module following a Rails tradition. Pylons 0.9.7 introduces pylons.url ('url' in templates), as an eventual replacement for url_for. That does not need to be accessed via 'h'. Most helpers are not application specific, but some applications may wish to define application-specific helpers. For instance, I have a format_date() function so that all dates are displayed in a consistent way. Helpers can also be used to expand numeric identifiers to their string equivalents, or for latitude/longitude formatting, etc. If you use 'literal(br /)' a lot, you can define a BR constant in the helpers module. Things like that. -- Mike Orr sluggos...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: session auto-save
I prepared a patch that fixes the following bugs in beaker sessions: 1. Problem: The first time the session is accessed, the _access_time is updated and it is immediately saved back. Solution: Defer saving of the session to the end of the request. 2. Problem: If the session is accessed but not modified, it still gets saved to the storage manager. Solution: If the session was not modified, don't save it. Note: The solution is the new default behavior. To override it and revert to the old behavior of saving the session even if it was only accessed, you can use the setting: beaker.session.auto = True 3. Problem: Anytime someone calls session.save() the session is first loaded and then saved. Solution: Do not perform a redundant load before the saving the session object. 4. Problem: If session.save() is called multiple times during a request, then the session will be saved multiple times. Solution: Only save the session once at the end of the request, if necessary. So with this fix the following hypothetical action only loads and saves the session once instead of three times : class HelloController(BaseController): def index(self): x = session.get('x') session['item1']='val1' session.save() session['item2']='val2' session.save() return render('/hello.html') On Jan 7, 2:16 pm, Ben Bangert b...@groovie.org wrote: On Jan 7, 2009, at 11:14 AM, Tycon wrote: I agree that it's better to let users set the dirty flag if they want. It would also be great if you can change the Session.load() method to NOT save the session immediately after loading it (not at the end of the request), as is the case today. This auto-saving upon first access is quite useless because subsequent changes to the session during the same request need to be saved separately afterwards. The Session.load () method can set the dirty flag if the autosave options is if_accessed. Together these changes can help avoiding the multiple save() that is happening today every time the session is used. Definitely. I'd be happy to review a patch to the code if you'd like to add these features, right now I'm heavily focused on Pylons 0.9.7 release so it'll be a few weeks before I can get back to the Beaker code-base myself. Feel free to email me directly about any patches (with unit tests) to this and I can apply them. I'm sure your suggestion of not saving immediately upon load will also help session performance, which has been one of our goals for awhile too. Cheers, Ben smime.p7s 3KViewDownload --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: session auto-save
On Wed, Jan 7, 2009 at 10:16 AM, Ben Bangert b...@groovie.org wrote: On Jan 7, 2009, at 4:59 AM, Paweł Stradomski wrote: Just note, that in case the dict is not modified directly, but an object inside is modified, you won't get notified of the change. Eg. suppose the restored session has: session['messages'] = [] Now i do: session['messages'].append(u'New flash message') You won't see that the session has changed. This is the exact reason we don't have a 'dirty' type flag like this set on setitem. However, I think it'd be useful to let a user set the 'dirty' flag themselves, in addition to letting sessions auto-save merely upon access (just to be sure), or something as Tycon suggests. Many people end up calling save() multiple times because they need to put stuff in the session in various places and ensures its saved, when really, they should be marking it 'to-be-saved' so its done just *once*. Ideally session.save() should really mean mark-to-save, and the actual saving done at the end of the request. The issue is that a generic function may modify the session (as is the case with Flash), and it does not know whether the caller will call .save or not. Likewise, the caller may not even know that the function is using the session. I do like the session.save() step because it acts like a transaction commit, explicity confirming that the session is to be modified persistently. On the other hand, it's not truly like a transaction because there is only one session, and any call to .save() will cause all changes to be saved, even if they were made in functions that did not themselves call .save(). But in practice, nobody modifies the session and leaves undesired changes in it counting on them being rolled back, so it's more of a theoretical problem than an actual problem. -- Mike Orr sluggos...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: session auto-save
That's exactly what my fix does, it makes session.save() be deferred by setting a flag to perform the actual save at the end of the request in the session middleware. You still need to call session.save() at least once to make sure the session will be saved, so up upside of all this is that people don't need to modify their code to take advantage of this single deferred save design. And now you don't have to be afraid to add session.save() calls as they will not cause any unnecessary saves. On Jan 7, 10:25 pm, Mike Orr sluggos...@gmail.com wrote: On Wed, Jan 7, 2009 at 10:16 AM, Ben Bangert b...@groovie.org wrote: On Jan 7, 2009, at 4:59 AM, Paweł Stradomski wrote: Just note, that in case the dict is not modified directly, but an object inside is modified, you won't get notified of the change. Eg. suppose the restored session has: session['messages'] = [] Now i do: session['messages'].append(u'New flash message') You won't see that the session has changed. This is the exact reason we don't have a 'dirty' type flag like this set on setitem. However, I think it'd be useful to let a user set the 'dirty' flag themselves, in addition to letting sessions auto-save merely upon access (just to be sure), or something as Tycon suggests. Many people end up calling save() multiple times because they need to put stuff in the session in various places and ensures its saved, when really, they should be marking it 'to-be-saved' so its done just *once*. Ideally session.save() should really mean mark-to-save, and the actual saving done at the end of the request. The issue is that a generic function may modify the session (as is the case with Flash), and it does not know whether the caller will call .save or not. Likewise, the caller may not even know that the function is using the session. I do like the session.save() step because it acts like a transaction commit, explicity confirming that the session is to be modified persistently. On the other hand, it's not truly like a transaction because there is only one session, and any call to .save() will cause all changes to be saved, even if they were made in functions that did not themselves call .save(). But in practice, nobody modifies the session and leaves undesired changes in it counting on them being rolled back, so it's more of a theoretical problem than an actual problem. -- Mike Orr sluggos...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: session auto-save
Just to clarify, this fix is not really an auto-save like I initially suggested. The fix is basically a deferred-save, which means that any calls to session.save() are not executed immediately, and instead they are deferred to the end of the request. So if session.save() is called at least once, the session will be saved at the end of the request. This means that there is no harm in calling session.save() multiple times, so even existing applications that do that will now see an improvement in performance without having to change the application. This is on top of the other fixes that eliminate redundant loads (before every save) and saves (after first access). On Jan 7, 10:39 pm, Tycon adie...@gmail.com wrote: That's exactly what my fix does, it makes session.save() be deferred by setting a flag to perform the actual save at the end of the request in the session middleware. You still need to call session.save() at least once to make sure the session will be saved, so up upside of all this is that people don't need to modify their code to take advantage of this single deferred save design. And now you don't have to be afraid to add session.save() calls as they will not cause any unnecessary saves. On Jan 7, 10:25 pm, Mike Orr sluggos...@gmail.com wrote: On Wed, Jan 7, 2009 at 10:16 AM, Ben Bangert b...@groovie.org wrote: On Jan 7, 2009, at 4:59 AM, Paweł Stradomski wrote: Just note, that in case the dict is not modified directly, but an object inside is modified, you won't get notified of the change. Eg. suppose the restored session has: session['messages'] = [] Now i do: session['messages'].append(u'New flash message') You won't see that the session has changed. This is the exact reason we don't have a 'dirty' type flag like this set on setitem. However, I think it'd be useful to let a user set the 'dirty' flag themselves, in addition to letting sessions auto-save merely upon access (just to be sure), or something as Tycon suggests. Many people end up calling save() multiple times because they need to put stuff in the session in various places and ensures its saved, when really, they should be marking it 'to-be-saved' so its done just *once*. Ideally session.save() should really mean mark-to-save, and the actual saving done at the end of the request. The issue is that a generic function may modify the session (as is the case with Flash), and it does not know whether the caller will call .save or not. Likewise, the caller may not even know that the function is using the session. I do like the session.save() step because it acts like a transaction commit, explicity confirming that the session is to be modified persistently. On the other hand, it's not truly like a transaction because there is only one session, and any call to .save() will cause all changes to be saved, even if they were made in functions that did not themselves call .save(). But in practice, nobody modifies the session and leaves undesired changes in it counting on them being rolled back, so it's more of a theoretical problem than an actual problem. -- Mike Orr sluggos...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---
Re: Pylons, SQLAlchemy and deleting
Piotr Kęplicz pisze: Joe Riopel, środa 07 stycznia 2009 17:45: Session.query(Person).filter_by(...).delete() Isn't that code still doing the select first, to get the object, and then deleting it? No. It's a Query object turned into a DELETE statement, just like first(), all() or one() would turn it into a SELECT statement. pylons 0.9.7, sqlalchemy 0.5 This is copy paste from console: Pylons Interactive Shell Python 2.5 (release25-maint, Jul 20 2008, 20:47:25) [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] All objects from pyupo.lib.base are available Additional Objects: mapper - Routes mapper object wsgiapp- This project's WSGI App instance app- paste.fixture wrapped around wsgiapp from pyupo.model.meta import Session from pyupo.model.emailbag import EmailBag as e s = Session.query(e).filter(e.order_id == 1).filter(e.active == True).filter(e.dispatched == False) s.delete() 07:10:35,545 INFO [sqlalchemy.engine.base.Engine.0x...6acL] BEGIN 07:10:35,546 INFO [sqlalchemy.engine.base.Engine.0x...6acL] SELECT em ailbag.id AS emailbag_id FROM emailbag WHERE emailbag.order_id = %s AND emailbag.active = %s AND emailbag.dis patched = %s 07:10:35,546 INFO [sqlalchemy.engine.base.Engine.0x...6acL] [1, 1, 0] 07:10:35,547 DEBUG [sqlalchemy.engine.base.Engine.0x...6acL] Col ('emailbag_id',) 07:10:35,547 INFO [sqlalchemy.engine.base.Engine.0x...6acL] DELETE FROM emailbag WHERE emailbag.order_id = %s AND emailbag.active = %s AND emailbag.dispatched = %s 07:10:35,547 INFO [sqlalchemy.engine.base.Engine.0x...6acL] [1, 1, 0] 0L s.update({'active': False}) 07:12:15,965 INFO [sqlalchemy.engine.base.Engine.0x...6acL] SELECT emailbag.id AS emailbag_id FROM emailbag WHERE emailbag.order_id = %s AND emailbag.active = %s AND emailbag.dispatched = %s 07:12:15,965 INFO [sqlalchemy.engine.base.Engine.0x...6acL] [1, 1, 0] 07:12:15,965 DEBUG [sqlalchemy.engine.base.Engine.0x...6acL] Col ('emailbag_id',) 07:12:15,966 INFO [sqlalchemy.engine.base.Engine.0x...6acL] UPDATE emailbag SET active=%s, updated_at=CURRENT_DATE WHERE emailbag.order_id = %s AND emailbag.active = %s AND emailbag.dispatched = %s 07:12:15,966 INFO [sqlalchemy.engine.base.Engine.0x...6acL] [0, 1, 1, 0] 0L This examples say something else. What is wrong with this query? Best Regards, Tomek --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups pylons-discuss group. To post to this group, send email to pylons-discuss@googlegroups.com To unsubscribe from this group, send email to pylons-discuss+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en -~--~~~~--~~--~--~---