shorthair_[]
12/12/2022, 12:25 AMrp
12/12/2022, 5:05 AMKShivendu
12/12/2022, 5:09 AMshorthair_[]
12/12/2022, 3:08 PMKShivendu
12/13/2022, 4:10 AMshorthair_[]
12/13/2022, 1:18 PMrp
12/14/2022, 2:44 AMshorthair_[]
12/18/2022, 8:34 PMKShivendu
12/19/2022, 6:15 AMshorthair_[]
12/20/2022, 1:27 PMnew_session = Session(user_id=user_id, session_data=session_data)
new_session.save() # save the new session to the database
online_users = session.get_user_id()
online_users.save()
from supertokens_python.recipe.session import SessionContainer
importKShivendu
12/22/2022, 4:38 PMpython
# config.py
# This file comes along with Django boilerplate provided by supertokens cli
# Try `npx create-supertokens-app@latest` and choose Django as backend
from supertokens_python.recipe.session.recipe import RecipeImplementation as SessionRecipeImplementation
from functools import wraps
from django.http import HttpRequest
from asgiref.sync import sync_to_async
from typing import Any
from supertokens_python.recipe.session.syncio import get_session
def upsert_user_last_seen(user_id: str):
from .models import UserLastSeen
# This automatically sets the last seen time to now since it is a DateTimeField with auto_now=True
UserLastSeen.objects.update_or_create(user_id=user_id, defaults={"user_id": user_id})
def override_session_functions(oi: SessionRecipeImplementation):
oi_create_new_session = oi.create_new_session
async def create_new_session(request, user_id, access_token_payload, session_data, user_context):
new_session = await oi_create_new_session(request, user_id, access_token_payload, session_data, user_context)
await sync_to_async(upsert_user_last_seen)(user_id) # Note how that you need to pass the function to sync_to_async and pass the args later
return new_session
oi.create_new_session = create_new_session
return oi
def track_logged_user_wrapper(extra_args: Any = None):
def wrap(f):
from .models import UserLastSeen
@wraps(f)
def wrapped_function(request: HttpRequest, *args: Any, **kwargs: Any):
session = get_session(request, session_required=False)
if session is not None:
user_id = session.get_user_id()
upsert_user_last_seen(user_id)
return f(request, *args, **kwargs)
return wrapped_function
return wrap
python
# models.py
from django.db import models
class UserLastSeen(models.Model):
user_id = models.CharField(max_length=255, primary_key=True)
last_seen = models.DateTimeField(auto_now=True)
python
# views.py
@api_view(["GET"])
@track_logged_user_wrapper()
def get_users(
response = {}
last_seen_list = UserLastSeen.objects.all().order_by('-last_seen')
for user in last_seen_list:
response[user.user_id] = user.last_seen.strftime("%Y-%m-%d %H:%M:%S")
return JsonResponse({"users": response})
await sync_to_async(upsert_user_last_seen)(user_id)
was required otherwise Django wouldn't have allowed using models in async. I fixed it based on https://stackoverflow.com/questions/61926359/django-synchronousonlyoperation-you-cannot-call-this-from-an-async-context-ushorthair_[]
12/23/2022, 11:21 AMKShivendu
12/23/2022, 8:28 PMoi
as short form of original_implementation
. So you may change that accordingly.config.py
in our django boilerplate (generated with our CLI)
You'll also have to update recipe_list
as:
python
recipe_list = [
session.init(
override=session.InputOverrideConfig(
functions=override_session_functions
)
),
emailpassword.init()
]
shorthair_[]
12/25/2022, 11:58 AMKShivendu
12/26/2022, 5:46 AM