Search code examples
pythonpyramidbeaker

Pyramid beaker - is there a way to create an endpoint that doesn't update the session timestamp?


In attempting to implement automatic logout on the browser-side after 30 seconds of inactivity, we thought of creating a /heartbeat endpoint:

  • when the user moves the mouse or types any key, a javascript callback is scheduled after 10 seconds, to call PUT /heartbeat.
  • if a callback is already scheduled, the previous one is cancelled - this is done to avoid an "avalanche" of PUT /heartbeat when the user types and/or moves the mouse continuously (while e.g. writing content).
  • then, every 60 seconds, a GET /heartbeat is issued - that checks how much time has passed since the last time this user's session was 'updated'. We can do this by checking the content of the beaker session table. If more than 30 minutes have passed, the endpoint returns an appropriate indication to Javascript, so the user is automatically logged out in the browser.

This would work fine, except for one minor flaw - the GET /heartbeat updates the beaker session timestamp...

So, the question is - under Pyramid/Beaker, is there a way to create an endpoint that DOESN'T update the session timestamp?


Solution

  • What I did end up doing is I created my own BeakerSessionFactoryConfig, as well as session_factory_from_settings (that instantiates BeakerSessionFactoryConfig).

    Then I modified what you can see here (a call to self.persist()) https://github.com/Pylons/pyramid_beaker/blob/6a62134bf99ff8d0836ccc0f6be557b816fa9987/pyramid_beaker/init.py#L32 to be a conditional operation based on if certain attribute is set on a request object.

    This works because as long as .persists() isn't called, the session "last accessed" timestamp isn't updated in the database (or whatever other storage you're using).