json.loads() doesnt work – AttributeError: ‘str’ object has no attribute ‘read’

I using flask-websockets, and sending in a data from my html to my server(python).

I receive it as a json dict, so I get my data as a string. I need to convert it to a dict so I can use the values in my code. I looked it up and json.loads() should do the job, but I am getting this error.

This is my server code.

from flask_app import app
from flask import render_template, redirect, request, flash, session
from flask_socketio import SocketIO, send
from flask_app.controllers import users_controller
from flask_app.controllers import scores_controller
import json
socketio = SocketIO(app, cors_allowed_origins="*")
players_choices = []

@socketio.on('message')
def handle_message(message):
    
    print("nnnMESSAGE TYPE ")
    print(type(message))
    print("nnnCHOICEEEEEE END")

    if message != "User connected!":
        send(message, broadcast=True)
    
        test = message['json']
        print("nnnIM AM HERE***********")
        print(test)
        res = json.load(test)
        print("nnnPRINTING JSONED DIC")
        print(res)

        players_choices.append(message)
        print("nnnPLAYERS CHOICES")
        print(players_choices)


        if len(players_choices)>=4:
            session['main_user_choice'] = players_choices[1]
            session['opponent_user_choice'] = players_choices[3]
            return redirect('/result')

This is my html code that includes script

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
    
    <script type="text/javascript" src="{{ url_for('static', filename='js/script.js') }}" defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
    <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function(){
            var socket = io.connect("localhost:5001");

            socket.on('connect', function(){
                socket.send("User connected!");
            });

            $('#rock').on('click', function(){
                //console.log("******************DATA")
                //console.log($('#rock').data())
                socket.send($('#rock').data())
            });
            $('#paper').on('click', function(){
                socket.send($('#paper').data())
            });
            $('#scissor').on('click', function(){
                socket.send($('#scissor').data())                
            });

        });
        
    </script>    
    <title>Gameplay</title>
</head>

<body class="bg-color-lght-green">
    <div class="container border mt-5">
        <!-- Choose now header -->
        <h1 class="d-flex justify-content-center mt-5 display-5 animate__animated animate__fadeIn">CHOOSE NOW</h1>
        <!-- Hand images with link to the loading page -->
        <div class="d-flex flex-wrap justify-content-center gap-3 ">
            <a href="/waiting_for_opponent" id="paper" data-json="{'user_id': '{{logged_user.name}}', 'choice' : '2'}"><img onmouseover="addShake(this)" onmouseleave="removeShake(this)" src="{{RockPaperScissorsImages.paper}}" alt="paper"> </a>
            <a href="/waiting_for_opponent" id="rock" data-json="{'user_id': '{{logged_user.name}}', 'choice' : '1'}"><img onmouseover="addShake(this)" onmouseleave="removeShake(this)" src="{{RockPaperScissorsImages.rock}}" alt="rock"> </a>
            <a href="/waiting_for_opponent" id="scissor" data-json="{'user_id': '{{logged_user.name}}', 'choice' : '3'}"><img id="scissorsss" onmouseover="addShake(this)" onmouseleave="removeShake(this)" src="{{RockPaperScissorsImages.scissors}}" alt="scissors"> </a>
        </div>

        <!-- HomePage Button -->
        <div class="d-flex justify-content-center me-2 ms-2 mb-5">
            <button onclick="window.location.href='/dashboard'" class="btn btn-outline-dark mt-5  animate__animated animate__fadeIn" style="border: 1px solid white; color: white" > Home Page</button>
        </div>
    </div>
</body>
</html>

and this is the console prints and the error:

127.0.0.1 - - [01/Feb/2023 20:36:27] "GET /gameplay/player HTTP/1.1" 200 -
127.0.0.1 - - [01/Feb/2023 20:36:27] "GET /static/css/style.css HTTP/1.1" 304 -
127.0.0.1 - - [01/Feb/2023 20:36:27] "GET /static/js/script.js HTTP/1.1" 304 -
127.0.0.1 - - [01/Feb/2023 20:36:27] "GET /socket.io/?EIO=4&transport=polling&t=OOGQM8d HTTP/1.1" 200 -
127.0.0.1 - - [01/Feb/2023 20:36:27] "POST /socket.io/?EIO=4&transport=polling&t=OOGQM8i&sid=boa2GwFjNeX77TZQAAAA HTTP/1.1" 200 -
127.0.0.1 - - [01/Feb/2023 20:36:27] "GET /socket.io/?EIO=4&transport=polling&t=OOGQM8j&sid=boa2GwFjNeX77TZQAAAA HTTP/1.1" 200 -



MESSAGE TYPE 
<class 'str'>



CHOICEEEEEE END



MESSAGE TYPE 
127.0.0.1 - - [01/Feb/2023 20:36:29] "GET /socket.io/?EIO=4&transport=websocket&sid=boa2GwFjNeX77TZQAAAA HTTP/1.1" 200 -
<class 'dict'>



CHOICEEEEEE END



IM AM HERE***********
{
Exception in thread Thread-31 (_handle_event_internal):
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 975, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/coding-workspace/.local/share/virtualenvs/rps-GYIrbTZz/lib/python3.11/site-packages/socketio/server.py", line 731, in _handle_event_internal
    r = server._trigger_event(data[0], namespace, sid, *data[1:])
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/coding-workspace/.local/share/virtualenvs/rps-GYIrbTZz/lib/python3.11/site-packages/socketio/server.py", line 756, in _trigger_event
    return self.handlers[namespace][event](*args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/coding-workspace/.local/share/virtualenvs/rps-GYIrbTZz/lib/python3.11/site-packages/flask_socketio/__init__.py", line 282, in _handler
    return self._handle_event(handler, message, namespace, sid,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/coding-workspace/.local/share/virtualenvs/rps-GYIrbTZz/lib/python3.11/site-packages/flask_socketio/__init__.py", line 828, in _handle_event
    ret = handler(*args)
          ^^^^^^^^^^^^^^
  File "/Users/coding-workspace/Desktop/CodingDojo/Python/FinalProject/rps/server.py", line 24, in handle_message
    res = json.load(test)
          ^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/__init__.py", line 293, in load
    return loads(fp.read(),
                 ^^^^^^^
AttributeError: 'str' object has no attribute 'read'
Running Query: 
            SELECT *
            FROM users
            WHERE id = 1;
        
127.0.0.1 - - [01/Feb/2023 20:36:29] "GET /waiting_for_opponent HTTP/1.1" 200 -
127.0.0.1 - - [01/Feb/2023 20:36:29] "GET /static/css/style.css HTTP/1.1" 304 -


When i print the message that I get is this:
{'json': "{'user_id': 'Ashot Gharibyan', 'choice' : '1'}"}

I am taking out the data info by this
test = message['json']
So this gives me a string: {‘user_id’: ‘Ashot Gharibyan’, ‘choice’ : ‘1’}

and this line should convert it to dict, but this is where I get the errors:{'user_id': 'Ashot Gharibyan', 'choice' : '1'}