pallets-eco / flask-session

Server side session extension for Flask
https://flask-session.readthedocs.io
BSD 3-Clause "New" or "Revised" License
490 stars 236 forks source link

Can't pickle <function Session.post at 0x000002388BEE63A0> #180

Closed aukeschaap closed 1 year ago

aukeschaap commented 1 year ago

I am running into an issue when I am trying to cache an object in the session. Specifically, I'm trying to do the following:

def get_cca():
    cca = session.get("cca")
    if not cca:
        cca = _build_new_cca()
        session["cca"] = cca

    return cca

def _build_new_cca():
    cca = msal.ConfidentialClientApplication(
        os.environ.get("CLIENT_ID"),
        authority=f"https://login.microsoftonline.com/{os.environ.get('TENANT')}",
        client_credential=os.environ.get("CLIENT_SECRET"),
        token_cache=msal.SerializableTokenCache(),
    )
    return cca

In a different function I retrieve the object from the session, use/modify it, and store it in the session again.

I get the following errors in my log:

2023-06-25 14:33:32,467 - root:WARNING - An exception has been raised during a pickling operation: Can't pickle <function Session.post at 0x000002388BEA73A0>: it's not the same object as requests.sessions.Session.post
2023-06-25 14:33:32,471 - werkzeug:INFO - 127.0.0.1 - - [25/Jun/2023 14:33:32] "GET /login HTTP/1.1" 302 -
2023-06-25 14:33:32,811 - root:WARNING - Exception raised while handling cache file 'C:\Users\...\flask_session\f122c225eb3dc4d2e0866797d20ce736'
Traceback (most recent call last):
  File "C:\Users\...\venv\lib\site-packages\cachelib\file.py", line 210, in get
    return self.serializer.load(f)
  File "C:\Users\...\venv\lib\site-packages\cachelib\serializers.py", line 29, in load
    data = pickle.load(f)
EOFError: Ran out of input
2023-06-25 14:33:32,983 - root:WARNING - An exception has been raised during a pickling operation: Can't pickle <function Session.post at 0x000002388BEE63A0>: it's not the same object as requests.sessions.Session.post

I have not touched Session or requests.sessions.Session so I'm not sure what has happened to cause this. Do you have any idea?

ThiefMaster commented 1 year ago

msal's ConfidentialClientApplication is not something that belongs in a session... I'm not surprised that pickling this fails.

It's something you usually instantiate once during application startup, but maybe even creating it on demand is fine (I don't think it performs any network requests or other slow things during instantiation)

aukeschaap commented 1 year ago

Creating it on demand is not desirable, as it does perform network requests during instantiation. Creating it once is also not possible in a model with multiple workers. Hence my attempt to cache it in a server-side session. However, it seems the issue is not due to flask-session, as pickling the class in isolation fails as well. Therefore, consider this closed.