RyanovskY
@RyanovskY

Почему не работает проверка на пользователя django в fastapi?

так как в джанго вебсокеты работали в последний раз в 2017, а сейчас нивкакую не работают, я решил обьеденить fastapi и django.

таким образом запуская 2 сервака у меня на странице сайта нормально работает вебсокет.
протестировав вебсокет с передачей рандомных чисел, всё заработало, но потом я решил добавить проверку на пользователя джанго.
импортировав настройки джанго, я запустил приложение, но когда захожу на сайт то в сервере fasapi получаю ошибку:

ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\uvicorn\protocols\websockets\websockets_impl.py", line 247, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\uvicorn\middleware\proxy_headers.py", line 84, in __call__
    return await self.app(scope, receive, send)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\fastapi\applications.py", line 289, in __call__
    await super().__call__(scope, receive, send)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\starlette\applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\starlette\middleware\errors.py", line 149, in __call__
    await self.app(scope, receive, send)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\starlette\middleware\exceptions.py", line 79, in __call__
    raise exc
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\starlette\middleware\exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\fastapi\middleware\asyncexitstack.py", line 20, in __call__
    raise e
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\fastapi\middleware\asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\starlette\routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\starlette\routing.py", line 341, in handle
    await self.app(scope, receive, send)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\starlette\routing.py", line 82, in app
    await func(session)
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\fastapi\routing.py", line 324, in app
    await dependant.call(**values)
  File "G:\RyanovskY\scripts_for_work\virtuoz_project\virtuoz\fastserv.py", line 30, in websocket_endpoint
    user = websocket.user
  File "C:\Users\Ryan\AppData\Roaming\Python\Python39\site-packages\starlette\requests.py", line 161, in user
    assert (
AssertionError: AuthenticationMiddleware must be installed to access request.user


вот само приложение
#  fastserv.py
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "virtuoz.settings")
django.setup()
from django.db.models import Q
from main.models import Chat
import asyncio
import requests
import random

import uvicorn
from fastapi import FastAPI, Request
from fastapi import WebSocket
from fastapi.templating import Jinja2Templates

app = FastAPI()

templates = Jinja2Templates(directory="templates")


async def generate_random_numbers(websocket: WebSocket):
    while True:
        await asyncio.sleep(0.25)
        await websocket.send_text(str(random.randint(1, 1000)))


@app.websocket("/ws/random_numbers/")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    user = websocket.user
    if user and user.is_authenticated:
        print(user)
        unread_messages_count = 0
        user_chats = Chat.objects.filter(Q(user=user) | Q(with_user=user))
        for chat in user_chats:
            unread_messages_count += chat.messages.filter(~Q(sender=websocket.user.id), status='False').count()
        null = 0
        await generate_random_numbers(websocket)
    else:
        await websocket.close(code=1011)


def get_public_ip():
    response = requests.get('https://api.ipify.org?format=json')
    if response.status_code == 200:
        data = response.json()
        return data['ip']
    return None


app_str = "fastserv:app"
public_ip = get_public_ip()
host = '0.0.0.0'
port = 5010

if __name__ == '__main__':
    print(f"http://{public_ip}:{port}/")
    uvicorn.run(app_str, host=host, port=port, log_level="warning", workers=2)


не знаю как решить эту проблему, помогите пожалуйста.
кроме этой страницы fastapi ничего не делал.
  • Вопрос задан
  • 228 просмотров
Пригласить эксперта
Ответы на вопрос 2
@Everything_is_bad
Можно написать кастомный SessionStore, где вместе с session id, сохранить user id (в дефолтном SessionStore этого нет) После этого уже без проблем по session id доставать аутентифицированного юзера. И еще, у тебя проблема с пониманием async, ты Django ORM в синхронном стиле используешь (кстати и цикл лишний, нужно использовать annotate или aggregate), этим блокируешь event loop. Ну и fastapi тут скорее оверхед, для вебсокетов достаточно его основы, Starlette
Ответ написан
@chemdev
Причем тут джанго? У тебя приложение фастапи обрабатывает запрос, в нем должно быть middleware чтобы привязывало к вебсокету юзера. Можно написать свое и сразу привязывать юзера джанго.
Дока
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы