https://supertokens.com/ logo
Title
s

shorthair_[]

12/12/2022, 12:25 AM
is it possible for me to integrate my user data from supertokens to django’s user auth system
r

rp

12/12/2022, 5:05 AM
hey @shorthair_[]
@KShivendu will help here
k

KShivendu

12/12/2022, 5:09 AM
Yes it's possible. Will require some custom work depending on your usecase. But it's doable.
do you want a two way integration or just take a dump into django models?
s

shorthair_[]

12/12/2022, 3:08 PM
a two way integration
pls
how do i do it
k

KShivendu

12/13/2022, 4:10 AM
I see. Two integration will require more work. It will be based on https://docs.djangoproject.com/en/4.1/topics/auth/customizing/. It's not a priority at the moment but we plan to have it in the upcoming months. Feel free to try it on your own and ask for help wherever required.
s

shorthair_[]

12/13/2022, 1:18 PM
tnx a lot
i’ll look into it
hey @KShivendu , can you help me narrow my search on what i need?
just want to be able to get user data but with the User auth systems
so for example, i can log when a user comes online
and users make calls to be able to see who is online
r

rp

12/14/2022, 2:44 AM
Hey! That’s possible via overrides.
Override the create new session function to save that the userId was last seen online now
Create an api which is called on each page load which updates the last online time of a user
And then query that data to see who was last online in the last 1 min etc..
You will need to store that data in your own db.
s

shorthair_[]

12/18/2022, 8:34 PM
tnx for that rp!
the db would be made in my django models?
k

KShivendu

12/19/2022, 6:15 AM
Yes. you can use Django models to handle the custom DB part.
s

shorthair_[]

12/20/2022, 1:27 PM
thx so much guys
is there like a session module?
cuz im looking and trying to see a way to save so i came up with this
is there something that looks this?
should i replace
new_session = Session(user_id=user_id, session_data=session_data)
                new_session.save()  # save the new session to the database
with
online_users = session.get_user_id()
                online_users.save()
the session method is from the
from supertokens_python.recipe.session import SessionContainer
import
hey @rp
hey @KShivendu
k

KShivendu

12/22/2022, 4:38 PM
Hey @shorthair_[], try this:
python
# 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})
I'm really impressed by your efforts. Thanks a lot for trying it in the first place. Feel free to ask questions if stuck or if something doesn't make sense in this snippet. 😄
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-u
s

shorthair_[]

12/23/2022, 11:21 AM
🤩
this goes in the apps file right?
so methods and functions are undefined can you pls give me the imports to those
these are the app imports
k

KShivendu

12/23/2022, 8:28 PM
Actually, I used the django boilerplate generated by our CLI as a starting point. So I've kept the first snippet that I just shared in config.py (Haven't shared rest of the part since it's part of boilerplate)
But yeah, you may adjust it for apps.py
I use
oi
as short form of
original_implementation
. So you may change that accordingly.
Rest of the missing imports are defined/imported in the first snippet that I shared. I'm talking about this ^
If there's too much confusion, just start with our boilerplate and add these functions to
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()
]
And obviously update models.py and views.py as well..
s

shorthair_[]

12/25/2022, 11:58 AM
tnx for all this @KShivendu 🙂
the codes good now
k

KShivendu

12/26/2022, 5:46 AM
Great!