am I evil?
Hi All, I'm writing a SQLAlchemy SessionExtension based on this pattern: http://www.sqlalchemy.org/trac/browser/examples/versioning/history_meta.py?rev=7253:3ef75b251d06#L171 So, in the listener, I want to record the user that made the change. How should I get hold of the currently authenticated user? The only way I can think of is calling pyramid.threadlocal.get_current_request inside the before_flush method of the VersionedListener, but having read: http://docs.pylonsproject.org/projects/pyramid/1.0/narr/threadlocals.html#why-you-shouldn-t-abuse-thread-locals I'm worried that I'm being evil. Am I being evil? How else can I get hold of Pyramid's notion of the current user id inside a SessionExtension? cheers, Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
Tune in next week when some community member writes a post entitled "Chris Withers Considered Harmful" ! On Feb 27, 11:40 am, Chris Withers wrote: > Hi All, > > I'm writing a SQLAlchemy SessionExtension based on this pattern: > > http://www.sqlalchemy.org/trac/browser/examples/versioning/history_me... > > So, in the listener, I want to record the user that made the change. > How should I get hold of the currently authenticated user? > > The only way I can think of is calling > pyramid.threadlocal.get_current_request inside the before_flush method > of the VersionedListener, but having read: > > http://docs.pylonsproject.org/projects/pyramid/1.0/narr/threadlocals > > I'm worried that I'm being evil. Am I being evil? > How else can I get hold of Pyramid's notion of the current user id > inside a SessionExtension? > > cheers, > > Chris > > -- > Simplistix - Content Management, Batch Processing & Python Consulting > -http://www.simplistix.co.uk -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
On 28/02/2011 03:27, Eric Ongerth wrote: Tune in next week when some community member writes a post entitled "Chris Withers Considered Harmful" ! I'm pretty sure that's been done before... Chris ;-) -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/27/2011 02:40 PM, Chris Withers wrote: > Hi All, > > I'm writing a SQLAlchemy SessionExtension based on this pattern: > > http://www.sqlalchemy.org/trac/browser/examples/versioning/history_meta.py?rev=7253:3ef75b251d06#L171 > > So, in the listener, I want to record the user that made the change. > How should I get hold of the currently authenticated user? > > The only way I can think of is calling > pyramid.threadlocal.get_current_request inside the before_flush method > of the VersionedListener, but having read: > > http://docs.pylonsproject.org/projects/pyramid/1.0/narr/threadlocals.html#why-you-shouldn-t-abuse-thread-locals > > I'm worried that I'm being evil. Am I being evil? > How else can I get hold of Pyramid's notion of the current user id > inside a SessionExtension? The "approved" way to share request-specific information is to just pass the request: in this case, the obvious candidate is to make the request an attribute of the event. Reaching around to the thread-local should be seen as a workaround for not being change the event code, if that happens to be the case. Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software "Excellence by Design"http://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk1r1C8ACgkQ+gerLs4ltQ7msACgy4aAvKqy/qLuJN3mLhhn4xZm nmgAni4Z8Tt6sC1JxBh46dJ0p+GAnuEO =ClRq -END PGP SIGNATURE- -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
On 28/02/2011 16:58, Tres Seaver wrote: I'm worried that I'm being evil. Am I being evil? How else can I get hold of Pyramid's notion of the current user id inside a SessionExtension? The "approved" way to share request-specific information is to just pass the request: in this case, the obvious candidate is to make the request an attribute of the event. What event are you referring to? Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/28/2011 12:53 PM, Chris Withers wrote: > On 28/02/2011 16:58, Tres Seaver wrote: >>> I'm worried that I'm being evil. Am I being evil? >>> How else can I get hold of Pyramid's notion of the current user id >>> inside a SessionExtension? >> >> The "approved" way to share request-specific information is to just pass >> the request: in this case, the obvious candidate is to make the request >> an attribute of the event. > > What event are you referring to? The one published to your listener. Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software "Excellence by Design"http://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk1r7IgACgkQ+gerLs4ltQ6LWACghuSRHnabqLWQgTuZNv1tyRII p0AAnjxkSdCf12b0CRQVmqGINF4DSRm+ =wCD7 -END PGP SIGNATURE- -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
On 28/02/2011 18:42, Tres Seaver wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/28/2011 12:53 PM, Chris Withers wrote: On 28/02/2011 16:58, Tres Seaver wrote: I'm worried that I'm being evil. Am I being evil? How else can I get hold of Pyramid's notion of the current user id inside a SessionExtension? The "approved" way to share request-specific information is to just pass the request: in this case, the obvious candidate is to make the request an attribute of the event. What event are you referring to? The one published to your listener. What listener? I'm using a SessionExtension: http://www.sqlalchemy.org/docs/orm/interfaces.html#session-events The only way I can think to get request there would be to try and stick it on either the model object, or the session object, both of which feel even more hacky than getting it from a thread local... Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
On Tue, Mar 1, 2011 at 8:09 AM, Chris Withers wrote: > On 28/02/2011 18:42, Tres Seaver wrote: >> >> -BEGIN PGP SIGNED MESSAGE- >> Hash: SHA1 >> >> On 02/28/2011 12:53 PM, Chris Withers wrote: >>> >>> On 28/02/2011 16:58, Tres Seaver wrote: > > I'm worried that I'm being evil. Am I being evil? > How else can I get hold of Pyramid's notion of the current user id > inside a SessionExtension? The "approved" way to share request-specific information is to just pass the request: in this case, the obvious candidate is to make the request an attribute of the event. >>> >>> What event are you referring to? >> >> The one published to your listener. > > What listener? > > I'm using a SessionExtension: > > http://www.sqlalchemy.org/docs/orm/interfaces.html#session-events That probably qualifies for "not being able to change the event code". > The only way I can think to get request there would be to try and stick it > on either the model object, or the session object, both of which feel even > more hacky than getting it from a thread local... I have very similar code in Kotti that gets hold of the request to set the owner id: https://github.com/dnouri/Kotti/blob/master/kotti/events.py And I don't feel evil at all. Though testing it turned out to be indeed a bit tricky: https://github.com/dnouri/Kotti/blob/master/kotti/tests.py#L626 Maybe the docs should be changed to say it's OK if you're working with a third party API and you know what you're doing. Daniel -- Daniel Nouri http://danielnouri.org -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
Hello, On Feb 27, 2011, at 10:40 PM, Chris Withers wrote: > I'm writing a SQLAlchemy SessionExtension based on this pattern: > > http://www.sqlalchemy.org/trac/browser/examples/versioning/history_meta.py?rev=7253:3ef75b251d06#L171 > > So, in the listener, I want to record the user that made the change. > How should I get hold of the currently authenticated user? Maybe, you should consider another approach to this problem? I don't think that recipe you've mentioned is a good way of versioning content. I like more explicit approach here -- versioning logic be in application logic, but not inside persistence engine: some_obj = some_objects.get(123) user = request.user # mutate some_obj some_objects.store_revision(some_obj, user) -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
Another approach is using separate repositories for storing data and revision history, it can be implemented as events, I think Tres Seaver was talking about that in this thread: some_obj = some_objects.get(123) user = request.user # mutate some_obj event = SomeObjectChanged(some_obj, user) some_objects.store(some_obj) event_manager.fire(event) and then in the event listener: def handle_some_obj_changed(event): some_objects_versions.store_revision(event.some_obj, event.user) The event_manager could be ZCA event API. You could also move event-firing logic inside subclass of class of some_objects repository: class VersionedSomeObjectsRepository(object): def __init__(self, some_objects, user): self.user = user self.some_objects = some_objects def store(self, some_obj): self.some_objects.store(some_obj) event = SomeObjectChanged(some_obj, self.user) event_manager.fire(event) def __getattr__(self, name): return getattr(self.some_objects, name) So the above snippet could be simplified in: versioned_some_objects = VersionedSomeObjectsRepository(some_objects, request.user) some_obj = versioned_some_objects.get(123) # mutate some_obj versioned_some_objects.store(some_obj) You can also preconfigure versioned repositories in application middleware. -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
> The event_manager could be ZCA event API. You could also move event-firing > logic inside subclass of class of some_objects repository: Oh, sorry, I was thought of wrapping repository inside versioning repository proxy, not subclassing. :-) -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
Spurred by this discussion, I implemented a simple events system that's akin to Zope3's object events. >From the docs: To subscribe only to insert events of documents, do:: def document_insert_handler(event): print event.object, event.request kotti.events.objectevent_listeners[(kotti.events.ObjectInsert, kotti.resources.Document)].append( document_insert_handler) The actual insert, update, delete events are still coming from SQLAlchemy but turned into events that hide away calls to "get_current_request" and the necessity to deal with SQLAlchemy internals, that is, calls to "session.is_modified" on update. See https://github.com/dnouri/Kotti/blob/master/kotti/events.py -- Daniel Nouri http://danielnouri.org -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.
Re: am I evil?
On 01/03/2011 12:58, Daniel Nouri wrote: Spurred by this discussion, I implemented a simple events system that's akin to Zope3's object events. For a fuller version of this pattern, check out: http://pydispatcher.sourceforge.net/ cheers, Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk -- You received this message because you are subscribed to the Google Groups "pylons-devel" group. To post to this group, send email to pylons-devel@googlegroups.com. To unsubscribe from this group, send email to pylons-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/pylons-devel?hl=en.