Search code examples
djangodjango-rest-frameworkdjango-channels

Django Channels ERROR: TypeError: object.__init__() takes exactly one argument (the instance to initialize)


I am using a custom JWT Authentication Middleware for verifying of JWT.

import jwt
from urllib.parse import parse_qs
from channels.db import database_sync_to_async
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from django.conf import settings
from rest_framework_simplejwt.tokens import AccessToken


@database_sync_to_async
def get_user(user_id):
    User = get_user_model()
    try:
        user = User.objects.get(id=user_id)
        return user
    except User.DoesNotExist:
        return AnonymousUser()


class TokenAuthMiddleware:
    """
    Custom middleware (insecure) that takes user IDs from the query string.
    """

    def __init__(self, inner):
        # Store the ASGI application we were passed
        self.inner = inner

    async def __call__(self, scope, receive, send):
        # Look up user from query string (you should also do things like
        # checking if it is a valid user ID, or if scope["user"] is already
        # populated).
        token = parse_qs(scope["query_string"].decode())["token"][0]
        AccessToken(token).verify()
        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256'])
        scope["user"] = await get_user(int(payload["user_id"]))
        return await self.inner(dict(scope), receive, send)

I am getting the error TypeError: object.__init__() takes exactly one argument (the instance to initialize)

I followed the official docs

Can anyone guide me where is exactly the issue?


Solution

  • For anyone facing the same issue, the problem is not actually in the Middleware. For my case, the issue was in asgi.py. I had forgot to call the .as_asgi() method on the consumer.

    application = ProtocolTypeRouter(
        {
            "http": get_asgi_application(),
            # Just HTTP for now. (We can add other protocols later.)
            "websocket": TokenAuthMiddlewareStack(
                URLRouter([
                    path("chat/", ChatConsumer.as_asgi()),
                ])
            )
        }
    )
    

    Note the as_asgi() method on ChatConsumer. I missed that which eventually led me to think that the issue was in my custom middleware.