Almacenar datos grandes o una conexión de servicio por sesión de Flask

Estoy escribiendo una pequeña aplicación de Flask y la estoy conectando a Rserve mediante pyRserve. Quiero que cada sesión inicie y luego mantenga su propia conexión Rserve.

Algo como esto:

session['my_connection'] = pyRserve.connect() 

no funciona porque el objeto de conexión no es serializable JSON. Por otro lado, algo como esto:

 flask.g.my_connection = pyRserve.connect() 

No funciona porque no persiste entre solicitudes. Para boost la dificultad, no parece que pyRserve proporcione ningún identificador para una conexión, por lo que no puedo almacenar una ID de conexión en la sesión y usarla para recuperar la conexión correcta antes de cada solicitud.

¿Hay alguna manera de lograr tener una conexión única por sesión?

Lo siguiente se aplica a los datos globales de Python que no desea recrear para cada solicitud, no solo a rserve, y no solo a los datos que son únicos para cada usuario.

Necesitamos una ubicación común para crear una conexión rserve para cada usuario. La forma más sencilla de hacer esto es ejecutar un multiprocessing.Manager como un proceso separado.

 import atexit from multiprocessing import Lock from multiprocessing.managers import BaseManager import pyRserve connections = {} lock = Lock() def get_connection(user_id): with lock: if user_id not in connections: connections[user_id] = pyRserve.connect() return connections[user_id] @atexit.register def close_connections(): for connection in connections.values(): connection.close() manager = BaseManager(('', 37844), b'password') manager.register('get_connection', get_connection) server = manager.get_server() server.serve_forever() 

Ejecútalo antes de iniciar tu aplicación, para que el administrador esté disponible:

 python rserve_manager.py 

Podemos acceder a este administrador desde la aplicación durante solicitudes utilizando una función simple. Esto supone que tiene un valor para “user_id” en la sesión (que es lo que haría Flask-Login, por ejemplo). Esto termina haciendo que la conexión rserve sea única por usuario, no por sesión.

 from multiprocessing.managers import BaseManager from flask import g, session def get_rserve(): if not hasattr(g, 'rserve'): manager = BaseManager(('', 37844), b'password') manager.register('get_connection') manager.connect() g.rserve = manager.get_connection(session['user_id']) return g.rserve 

Accede dentro de una vista:

 result = get_rserve().eval('3 + 5') 

Esto debería ayudarlo a comenzar, aunque hay muchas cosas que se pueden mejorar, como no codificar la dirección y la contraseña y no eliminar las conexiones con el administrador. Esto se escribió con Python 3, pero debería funcionar con Python 2.