SlideShare a Scribd company logo
BEAKER - MAKING SESSIONS AND
CACHING ROOMMATES
Alessandro Molina
@__amol__
amol@turbogears.org
Who am I
● CTO @ AXANT.it, mostly Python company
(with some iOS and Android)
● TurboGears2 dev team member
● Took over Beaker maintenace in 2015
● Mostly contributed to web python libraries:
Formencode, MING MongoDB ODM, ToscaWidgets2
What’s Beaker
● Framework for handling Caching and
Sessions in web applications
● Used by many different frameworks:
TurboGears, Bottle, Pyramid, etc...
● Created by Pylons Author to solve the
dogpile effect.
DogPile!
The Good
● Handles the DogPile effect
● Provides many backends: Memcache, File,
MongoDB, Redis, SQLAlchemy
● A single tool to handle both caching and
sessions with common backends.
The Bad
● File based synchronization, what about
distributed solutions?
● Session as a big BLOB of data doesn’t
perform well in case of big BLOBs of data
● Updated for too long without breaking
backward compatibility: Too many APIs
Getting on project: PY3 Support
● Beaker supported Python3 using 2to3
● This lead to some bugs (not everything got
properly converted)
● Made really hard to run the test suite and
maintain the project.
So my first action as new
maintainer...
Rewriting for Py3 a project that
involves serializing/deserializing
Porting to PY3: #1 Snakes speak ?
Beaker uses BASE64 to encode pickled data
in sessions.
>>> import base64, pickle
>>> data = dict(key='value', otherkey='othervalue')
>>> base64.b64encode(pickle.dumps(data))
'KGRwMApTJ290aGVya2V5JwpwMQpTJ290aGVydmFsdWUnCnAyCnN
TJ2tleScKcDMKUyd2YWx1ZScKcDQKcy4='
BASE64: rfc4648
Here are a few requirements that
determine which alphabet should be
used:
o Handled by humans.
Human handle?
TEXT!
Human handle?
TEXT!
Human handle?
BYTES!
>>> import base64, pickle
>>> base64.b64encode(pickle.dumps(‘HELLO’))
b'gANYBQAAAEhFTExPcQAu'
Porting to PY3: #2 Session Cookies?
● Session ID is stored in cookies
● CookieSession stores even the whole
session in a cookie
○ Great idea, makes really simple to scale
○ HTTP Headers are plain text
○ We are pickling data and base64 so already ASCII
○ Just need to encrypt it to avoid people from
messing with them.
HTTP Cookies
HTTP has allowed field content with text
in the ISO-8859-1 charset [ISO-8859-1],
supporting other charsets only through
use of [RFC2047] encoding. In practice,
most HTTP header field values use only a
subset of the US-ASCII charset [USASCII].
Newly defined header fields SHOULD limit
their field values to US-ASCII octets
Encoding/Encripting data on Py3
● Beaker expected to be able to perform
text operations on the result of base64
● Relied on AES to encrypt cookies, pbkdf2
to generates keys and base64/binascii
to make it text.
● Reads the encrypt_key from config file
4 lines of code == 10 doubts
● Even Python has no clear idea of what is
text and what are bytes:
○ Both BASE64 and BINASCII work with ASCII
○ BINASCII accepts unicode (text)
○ BASE64 accepts bytes
○ Between Python3.2 and Python3.3 the binascii
changed behaviour of accepting unicode vs bytes
○ ConfigParser returns text on py3, bytes on py2
Now crying in a corner...
Let’s go for something simpler...
● Review patch to caching decorator
● To cache a function, just apply a decorator
that calls function and caches the result
● Caching decorator generates cache key
○ Cache Key from the function name
○ convert parameters to strings
○ add parameters to cache key
Getting the Cache Key
def cache(self, *args, **kwargs):
"""Decorate a function to cache itself with supplied parameters
:param args: Used to make the key unique for this function, as in region()
above.
:param kwargs: Parameters to be passed to get_cache(), will override defaults
Example::
# Assuming a cache object is available like:
cache = CacheManager(dict_of_config_options)
def populate_things():
@cache.cache('mycache', expire=15)
def load(search_term, limit, offset):
return load_the_data(search_term, limit, offset)
return load('rabbits', 20, 0)
"""
return _cache_decorate(args, self, kwargs, None)
Well, maybe...
Unknown parameters
● Decorator gets *args and **kwargs
● Makes sense... doesn’t know the real
function arguments
● Not so much in fact… func(1) and func
(a=1) end up with two different cache
keys
Avoid the doubt
● Beaker solved this by accepting only
positional arguments on cached functions
.. note::
The function being decorated must only be called with
positional arguments.
● Users not so happy, breaks people code
when they introduce caching:
○ https://github.com/bbangert/beaker/issues/62
What to do?
● Leave it as is… As been like that for years
● Add **kwargs and just document the issue
● Add **kwargs and try to be smart using
inspect.getargspec / inspect.
getcallargs but that would be slow
Leave it as is… at least isn’t broken
Has been a great trip!
● Making sessions and caching in a single
solution seemed simple, but has actually a
lot of corner case
● Beaker Co-Author thrown in the towel and
created dopgile.cache which is based on
beaker code but is much simpler and
doesn’t provide sessions
Still is incredibily convenient
● There are more shared features than
differences (especially in cookie based
marshalled sessions).
● It’s really convenient, write backends once
and have support for both sessions and
caching on them.
Questions?

More Related Content

PDF
PyConIT6 - Messing up with pymongo for fun and profit
PDF
MongoTorino 2013 - BSON Mad Science for fun and profit
PPT
Java Development with MongoDB (James Williams)
PPTX
Threads and Node.js
PDF
PyconIE 2016 - Kajiki, the fast and validated template engine your were looki...
PPTX
Java Development with MongoDB
PDF
From SQLAlchemy to Ming with TurboGears2
PDF
Introduction to using MongoDB with Ruby
PyConIT6 - Messing up with pymongo for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profit
Java Development with MongoDB (James Williams)
Threads and Node.js
PyconIE 2016 - Kajiki, the fast and validated template engine your were looki...
Java Development with MongoDB
From SQLAlchemy to Ming with TurboGears2
Introduction to using MongoDB with Ruby

What's hot (20)

PDF
Reactive & Realtime Web Applications with TurboGears2
PPTX
MongoDB Aug2010 SF Meetup
PPTX
Robust C++ Task Systems Through Compile-time Checks
ODP
This upload requires better support for ODP format
ODP
Stefano Maestri - Blockchain and smart contracts, what they are and why you s...
PDF
Node.js and How JavaScript is Changing Server Programming
PPTX
MongoDB: Easy Java Persistence with Morphia
PDF
Mongophilly shell-2011-04-26
PPTX
Intro to data oriented design
PPTX
MongoDB + Java - Everything you need to know
PDF
Libbitcoin slides
PPTX
Defcamp 2013 - SSL Ripper
PDF
Cryptography in PHP: use cases
PPT
iOS Development with Blocks
PDF
Shared memory and multithreading in Node.js - Timur Shemsedinov - JSFest'19
PDF
BreizhCamp 2013 - Pimp my backend
PDF
ENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQL
PDF
ENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQL
PDF
Objective-C Blocks and Grand Central Dispatch
Reactive & Realtime Web Applications with TurboGears2
MongoDB Aug2010 SF Meetup
Robust C++ Task Systems Through Compile-time Checks
This upload requires better support for ODP format
Stefano Maestri - Blockchain and smart contracts, what they are and why you s...
Node.js and How JavaScript is Changing Server Programming
MongoDB: Easy Java Persistence with Morphia
Mongophilly shell-2011-04-26
Intro to data oriented design
MongoDB + Java - Everything you need to know
Libbitcoin slides
Defcamp 2013 - SSL Ripper
Cryptography in PHP: use cases
iOS Development with Blocks
Shared memory and multithreading in Node.js - Timur Shemsedinov - JSFest'19
BreizhCamp 2013 - Pimp my backend
ENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQL
ENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQL
Objective-C Blocks and Grand Central Dispatch
Ad

Similar to PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES (20)

PPTX
Why learn Internals?
PPTX
Logs @ OVHcloud
PDF
High Performance With Java
PDF
Second Skin: Real-Time Retheming a Legacy Web Application with Diazo in the C...
PDF
Fluent Bit: Log Forwarding at Scale
PDF
How to use MongoDB with CakePHP
PDF
Mongo db3.0 wired_tiger_storage_engine
PPTX
Advanced MySql Data-at-Rest Encryption in Percona Server
PPTX
Mario on spark
PDF
Zend Server Data Caching
PDF
The State of containerd
PDF
When is Myrocks good? 2020 Webinar Series
PDF
Interview with Anatoliy Kuznetsov, the author of BitMagic C++ library
PDF
Massively Scaled High Performance Web Services with PHP
PDF
[AWS Builders] Effective AWS Glue
PDF
Time series denver an introduction to prometheus
PDF
Log forwarding at Scale
PDF
The Parquet Format and Performance Optimization Opportunities
PDF
The reasons why 64-bit programs require more stack memory
ODP
Caching and tuning fun for high scalability
Why learn Internals?
Logs @ OVHcloud
High Performance With Java
Second Skin: Real-Time Retheming a Legacy Web Application with Diazo in the C...
Fluent Bit: Log Forwarding at Scale
How to use MongoDB with CakePHP
Mongo db3.0 wired_tiger_storage_engine
Advanced MySql Data-at-Rest Encryption in Percona Server
Mario on spark
Zend Server Data Caching
The State of containerd
When is Myrocks good? 2020 Webinar Series
Interview with Anatoliy Kuznetsov, the author of BitMagic C++ library
Massively Scaled High Performance Web Services with PHP
[AWS Builders] Effective AWS Glue
Time series denver an introduction to prometheus
Log forwarding at Scale
The Parquet Format and Performance Optimization Opportunities
The reasons why 64-bit programs require more stack memory
Caching and tuning fun for high scalability
Ad

More from Alessandro Molina (12)

PDF
PyCon Ireland 2022 - PyArrow full stack.pdf
PDF
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
PDF
EuroPython 2015 - Storing files for the web is not as straightforward as you ...
PDF
PyConFR 2014 - DEPOT, Story of a file.write() gone wrong
PDF
PyConUK 2014 - PostMortem Debugging and Web Development Updated
PDF
Post-Mortem Debugging and Web Development
PDF
PyConUK2013 - Validated documents on MongoDB with Ming
PDF
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
PDF
EuroPython 2013 - Python3 TurboGears Training
PDF
PyGrunn2013 High Performance Web Applications with TurboGears
PDF
Rapid Prototyping with TurboGears2
PDF
TurboGears2 Pluggable Applications
PyCon Ireland 2022 - PyArrow full stack.pdf
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EuroPython 2015 - Storing files for the web is not as straightforward as you ...
PyConFR 2014 - DEPOT, Story of a file.write() gone wrong
PyConUK 2014 - PostMortem Debugging and Web Development Updated
Post-Mortem Debugging and Web Development
PyConUK2013 - Validated documents on MongoDB with Ming
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - Python3 TurboGears Training
PyGrunn2013 High Performance Web Applications with TurboGears
Rapid Prototyping with TurboGears2
TurboGears2 Pluggable Applications

Recently uploaded (20)

PPTX
1. Introduction to Computer Programming.pptx
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Empathic Computing: Creating Shared Understanding
PPTX
Machine Learning_overview_presentation.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Mushroom cultivation and it's methods.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Approach and Philosophy of On baking technology
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
A comparative study of natural language inference in Swahili using monolingua...
PPTX
cloud_computing_Infrastucture_as_cloud_p
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Encapsulation theory and applications.pdf
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Getting Started with Data Integration: FME Form 101
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
A Presentation on Artificial Intelligence
1. Introduction to Computer Programming.pptx
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
Empathic Computing: Creating Shared Understanding
Machine Learning_overview_presentation.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Mushroom cultivation and it's methods.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Approach and Philosophy of On baking technology
gpt5_lecture_notes_comprehensive_20250812015547.pdf
A comparative study of natural language inference in Swahili using monolingua...
cloud_computing_Infrastucture_as_cloud_p
Digital-Transformation-Roadmap-for-Companies.pptx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
A comparative analysis of optical character recognition models for extracting...
Encapsulation theory and applications.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Getting Started with Data Integration: FME Form 101
Advanced methodologies resolving dimensionality complications for autism neur...
A Presentation on Artificial Intelligence

PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES

  • 1. BEAKER - MAKING SESSIONS AND CACHING ROOMMATES Alessandro Molina @__amol__ amol@turbogears.org
  • 2. Who am I ● CTO @ AXANT.it, mostly Python company (with some iOS and Android) ● TurboGears2 dev team member ● Took over Beaker maintenace in 2015 ● Mostly contributed to web python libraries: Formencode, MING MongoDB ODM, ToscaWidgets2
  • 3. What’s Beaker ● Framework for handling Caching and Sessions in web applications ● Used by many different frameworks: TurboGears, Bottle, Pyramid, etc... ● Created by Pylons Author to solve the dogpile effect.
  • 5. The Good ● Handles the DogPile effect ● Provides many backends: Memcache, File, MongoDB, Redis, SQLAlchemy ● A single tool to handle both caching and sessions with common backends.
  • 6. The Bad ● File based synchronization, what about distributed solutions? ● Session as a big BLOB of data doesn’t perform well in case of big BLOBs of data ● Updated for too long without breaking backward compatibility: Too many APIs
  • 7. Getting on project: PY3 Support ● Beaker supported Python3 using 2to3 ● This lead to some bugs (not everything got properly converted) ● Made really hard to run the test suite and maintain the project.
  • 8. So my first action as new maintainer...
  • 9. Rewriting for Py3 a project that involves serializing/deserializing
  • 10. Porting to PY3: #1 Snakes speak ? Beaker uses BASE64 to encode pickled data in sessions. >>> import base64, pickle >>> data = dict(key='value', otherkey='othervalue') >>> base64.b64encode(pickle.dumps(data)) 'KGRwMApTJ290aGVya2V5JwpwMQpTJ290aGVydmFsdWUnCnAyCnN TJ2tleScKcDMKUyd2YWx1ZScKcDQKcy4='
  • 11. BASE64: rfc4648 Here are a few requirements that determine which alphabet should be used: o Handled by humans.
  • 14. Human handle? BYTES! >>> import base64, pickle >>> base64.b64encode(pickle.dumps(‘HELLO’)) b'gANYBQAAAEhFTExPcQAu'
  • 15. Porting to PY3: #2 Session Cookies? ● Session ID is stored in cookies ● CookieSession stores even the whole session in a cookie ○ Great idea, makes really simple to scale ○ HTTP Headers are plain text ○ We are pickling data and base64 so already ASCII ○ Just need to encrypt it to avoid people from messing with them.
  • 16. HTTP Cookies HTTP has allowed field content with text in the ISO-8859-1 charset [ISO-8859-1], supporting other charsets only through use of [RFC2047] encoding. In practice, most HTTP header field values use only a subset of the US-ASCII charset [USASCII]. Newly defined header fields SHOULD limit their field values to US-ASCII octets
  • 17. Encoding/Encripting data on Py3 ● Beaker expected to be able to perform text operations on the result of base64 ● Relied on AES to encrypt cookies, pbkdf2 to generates keys and base64/binascii to make it text. ● Reads the encrypt_key from config file
  • 18. 4 lines of code == 10 doubts ● Even Python has no clear idea of what is text and what are bytes: ○ Both BASE64 and BINASCII work with ASCII ○ BINASCII accepts unicode (text) ○ BASE64 accepts bytes ○ Between Python3.2 and Python3.3 the binascii changed behaviour of accepting unicode vs bytes ○ ConfigParser returns text on py3, bytes on py2
  • 19. Now crying in a corner...
  • 20. Let’s go for something simpler... ● Review patch to caching decorator ● To cache a function, just apply a decorator that calls function and caches the result ● Caching decorator generates cache key ○ Cache Key from the function name ○ convert parameters to strings ○ add parameters to cache key
  • 21. Getting the Cache Key def cache(self, *args, **kwargs): """Decorate a function to cache itself with supplied parameters :param args: Used to make the key unique for this function, as in region() above. :param kwargs: Parameters to be passed to get_cache(), will override defaults Example:: # Assuming a cache object is available like: cache = CacheManager(dict_of_config_options) def populate_things(): @cache.cache('mycache', expire=15) def load(search_term, limit, offset): return load_the_data(search_term, limit, offset) return load('rabbits', 20, 0) """ return _cache_decorate(args, self, kwargs, None)
  • 23. Unknown parameters ● Decorator gets *args and **kwargs ● Makes sense... doesn’t know the real function arguments ● Not so much in fact… func(1) and func (a=1) end up with two different cache keys
  • 24. Avoid the doubt ● Beaker solved this by accepting only positional arguments on cached functions .. note:: The function being decorated must only be called with positional arguments. ● Users not so happy, breaks people code when they introduce caching: ○ https://github.com/bbangert/beaker/issues/62
  • 25. What to do? ● Leave it as is… As been like that for years ● Add **kwargs and just document the issue ● Add **kwargs and try to be smart using inspect.getargspec / inspect. getcallargs but that would be slow
  • 26. Leave it as is… at least isn’t broken
  • 27. Has been a great trip! ● Making sessions and caching in a single solution seemed simple, but has actually a lot of corner case ● Beaker Co-Author thrown in the towel and created dopgile.cache which is based on beaker code but is much simpler and doesn’t provide sessions
  • 28. Still is incredibily convenient ● There are more shared features than differences (especially in cookie based marshalled sessions). ● It’s really convenient, write backends once and have support for both sessions and caching on them.