I would like to use my Django application as a relay for a session-based online service and share this session among all users. For this, I've configured a python-requests Session object.
I would like to initialise this Session when Django starts up and keep it alive forever. My idea is to have all requests to my Django application share the session object by allowing the view for the particular request access the session object.
In Flask setting this up (for experimental purposes) is fairly easy:
from flask import Flask, render_template, request, session
from requests import Session
app = Flask(__name__)
session = Session()
session.post() # Setup Session by logging in
@app.route("/")
def use_session():
reply = session.get() # Get resource from web service
return jsonify(reply)
Here session would be created when starting and can be accessed by use_session().
I struggle to set up the same in Django though. Where would be the preferred place to create the session?
The equivalent of your Flask code in Django would be to put the same logic in a views.py file:
# yourapp/views.py
from django.http import HttpResponse
from requests import Session
session = Session()
session.post('https://httpbin.org/post') # Setup Session by logging in
def use_session(request):
reply = session.get('https://example.com') # Get resource from web service
return HttpResponse(reply.content, status=reply.status_code)
# yourproject/urls.py
from django.urls import path
from yourapp.views import use_session
urlpatterns = [
path('', use_session)
]
The object will get created as you start the server.
One problem with this approach is that in a real-world deployment you normally run multiple copies of your app (doesn't matter if it's Flask or Django or any other framework) to avoid thread blocking, utilize multiple CPU cores on the same server or have multiple servers, each copy will end up with its own session, which might work fine, but might be problematic.
In a situation like this, you can share a Python object1 across multiple processes by serializing it using the pickle module and storing the byte data in a database. A good place for the data would be something like Redis or Memcached but Django's ORM can be used as well:
# yourapp/models.py
from django.db import models
class Session(models.Model):
pickled = models.BinaryField()
# yourapp/views.py
import pickle
from django.http import HttpResponse
from requests import Session
from . import models
def use_session(request):
# Load the pickled session from the database
session_db_obj = models.Session.objects.first()
if session_db_obj:
# Un-pickle the session
session = pickle.loads(session_db_obj.pickled)
else:
# Create a new session
session = Session()
session.post('https://httpbin.org/post') # Setup Session by logging in
# Create the database object, pickle the session and save it
session_db_obj = models.Session()
session_db_obj.pickled = pickle.dumps(session)
session_db_obj.save()
reply = session.get('https://example.com') # Get resource from web service
return HttpResponse(reply.content, status=reply.status_code)
1: Not any object can be pickled and unpickled reliably, be careful!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With