am I evil?

2011-02-27 Thread Chris Withers

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?

2011-02-27 Thread Eric Ongerth
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?

2011-02-27 Thread Chris Withers

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?

2011-02-28 Thread Tres Seaver
-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?

2011-02-28 Thread Chris Withers

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?

2011-02-28 Thread Tres Seaver
-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?

2011-02-28 Thread Chris Withers

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?

2011-03-01 Thread Daniel Nouri
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?

2011-03-01 Thread Andrey Popp
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?

2011-03-01 Thread Andrey Popp
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?

2011-03-01 Thread Andrey Popp
> 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?

2011-03-01 Thread Daniel Nouri
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?

2011-03-01 Thread Chris Withers

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.