miguelgrinberg / Flask-SocketIO

Socket.IO integration for Flask applications.
MIT License
5.37k stars 892 forks source link

AttributeError: 'Request' object has no attribute 'sid' #445

Closed polmp closed 7 years ago

polmp commented 7 years ago

I'm getting this error when I try to add the arg include_self

Full traceback File "../app/views.py", line 230, in emit_update emit('event',{'bar':'foo'},namespace='/example_namespace',broadcast=True,include_self=False) File "../flask/lib/python2.7/site-packages/flask_socketio/init.py", line 652, in emit include_self=include_self, callback=callback) File "../flask/lib/python2.7/site-packages/flask_socketio/init.py", line 343, in emit skip_sid = flask.request.sid File "../flask/lib/python2.7/site-packages/werkzeug/local.py", line 347, in getattr return getattr(self._get_current_object(), name) AttributeError: 'Request' object has no attribute 'sid'

I'm doing anything wrong? Without include_self works.

polmp commented 7 years ago

Edit: I think what causes the problem.

I emit a message and then I redirect to a webpage. I suppose the program doesn't find the user that sent because it was disconnected when I do the redirect. I close the issue :)

744216212 commented 7 years ago
@controller.route('/user_login', methods=['GET', 'POST'])
@socketio.on('getuser', namespace='/test')
def user_login():
    sid=request.sid
    global userinfo
    userinfo=eval(request.form.keys()[0])['Key']

File "D:\svn\trunk\server\controller\useraction.py", line 222, in user_login sid=request.sid File "E:\newflasky\venv\lib\site-packages\werkzeug\local.py", line 343, in getattr return getattr(self._get_current_object(), name) AttributeError: 'Request' object has no attribute 'sid'

when i add socketio in views,find this error how to solve this problem? thanks

@polmp i do not do the redirect

miguelgrinberg commented 7 years ago

you can't use request.sid in an HTTP view, because there is no Socket.IO context. That only works in a Socket.IO event handler.

744216212 commented 7 years ago

thank you very much! I know it I also have a problem about callbacks official website said SocketIO supports acknowledgement callbacks that confirm that a message was received by the client: this is my demo

def connect_event_callback(*args):
    print '#=> client called {0}'.format(inspect.stack()[0][-4:-2])
@io.on('connect')
def connect_event_handler():
    io.emit(
        'connect event',
        {'data': 'hello word!'},
        callback=message_event_callback
    )
<script type="text/javascript">
    var socket = io.connect(
        location.protocol+
        '//'+
        document.domain+
        ':'+
        location.port
    );
    socket.on('connect event', function(data, func){
      console.log('#=> recive server data', data.data);
      func();
    });
</script>

i can't understand func(),so I can't run it can you help me or give me a demo that i can run it thinks

miguelgrinberg commented 7 years ago

In your example, func() is a placeholder for your message_event_callback() function in the server. When the client calls func(), a similar call will be made on the server side to your function. If you pass arguments into func(), the same arguments will be passed into your server callback function. I don't think I have any examples of callbacks that go in that direction, I have use callbacks many times, but in the reverse direction, where the client requests acknowledgements from the server, sorry.

NoelCarlton commented 5 years ago

hi man, i meet the same issue but it is from here: i use postman to post data like: 192.168.31.34:8050/socket/send and the post body is a form-data which key-value is data:'these are some datas' ,and my code is

@app.route("/socket/send",methods=['post'])
# @socketio.on("json") #no matter i uncomment this or not
def sendsocket():
    data = request.form['data']
    emit('message',jsonify("i'm data from socket",data),json=True,namespace="/socket")
    return jsonify("finish!")

it gets this:

Traceback (most recent call last):
  File "D:\developsoftware\python\lib\site-packages\flask\app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "D:\developsoftware\python\lib\site-packages\flask\app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "D:\developsoftware\python\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "D:\developsoftware\python\lib\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "D:\developsoftware\python\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "D:\developsoftware\python\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "D:\developsoftware\python\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "D:\developsoftware\python\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "D:\developsoftware\python\lib\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "c:\Users\noel\Desktop\selfcss\webserver\message.py", line 39, in sendsocket
    emit('message',jsonify("i'm data from socket",data),json=True,namespace="/socket")
  File "D:\developsoftware\python\lib\site-packages\flask_socketio\__init__.py", line 693, in emit
    room = flask.request.sid
  File "D:\developsoftware\python\lib\site-packages\werkzeug\local.py", line 347, in __getattr__
    return getattr(self._get_current_object(), name)
AttributeError: 'Request' object has no attribute 'sid'
miguelgrinberg commented 5 years ago

@NoelCarlton the emit() function has a default of emitting to the sender of an originating event. This default only makes sense when you call the function from an event handler. You are calling it from a route, which does not have the Socket.IO context (in particular, request.sid).

Do you know to which user(s) you want to emit an event from this route? If you want to emit to all your connected clients, add broadcast=True. If you know the sid of the user you want to address, then add room=sid. You also need to specify the namespace, so add namespace='/' or use the proper namespace name.

JocoYo1 commented 4 years ago

I'm having similar issues with a login form.

Where my app is

`from flask import Flask, render_template, flash, request, url_for, redirect

app = Flask(name)

@app.route('/') def index(): title = "Cheam Squash Ladders" return render_template("index.html", title=title)

@app.route('/register', methods=["POST", 'GET']) def squash(): user = request.squash.get("user") email = request.squash.get("email") password = request.squash.get("password") confirm_email = request.squash.get("confirm") return render_template("register.html")

@app.route('/register') def register(): return render_template("register.html")`

my forms are in

`<!DOCTYPE html>

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous">

{{ title }}
Squash Racquetball
I agree to terms and conditions

`

and the error message

`AttributeError AttributeError: 'Request' object has no attribute 'squash'

Traceback (most recent call last) File "/Users/Jocoyo/MyNewFlaskApp/flask/lib/python2.7/site-packages/flask/app.py", line 2464, in call return self.wsgi_app(environ, start_response) File "/Users/Jocoyo/MyNewFlaskApp/flask/lib/python2.7/site-packages/flask/app.py", line 2450, in wsgi_app response = self.handle_exception(e) File "/Users/Jocoyo/MyNewFlaskApp/flask/lib/python2.7/site-packages/flask/app.py", line 1867, in handle_exception reraise(exc_type, exc_value, tb) File "/Users/Jocoyo/MyNewFlaskApp/flask/lib/python2.7/site-packages/flask/app.py", line 2447, in wsgi_app response = self.full_dispatch_request() File "/Users/Jocoyo/MyNewFlaskApp/flask/lib/python2.7/site-packages/flask/app.py", line 1952, in full_dispatch_request rv = self.handle_user_exception(e) File "/Users/Jocoyo/MyNewFlaskApp/flask/lib/python2.7/site-packages/flask/app.py", line 1821, in handle_user_exception reraise(exc_type, exc_value, tb) File "/Users/Jocoyo/MyNewFlaskApp/flask/lib/python2.7/site-packages/flask/app.py", line 1950, in full_dispatch_request rv = self.dispatch_request() File "/Users/Jocoyo/MyNewFlaskApp/flask/lib/python2.7/site-packages/flask/app.py", line 1936, in dispatch_request return self.view_functionsrule.endpoint File "/Users/Jocoyo/MyNewFlaskApp/app.py", line 12, in squash user = request.squash.get("user") File "/Users/Jocoyo/MyNewFlaskApp/flask/lib/python2.7/site-packages/werkzeug/local.py", line 347, in getattr return getattr(self._get_current_object(), name) AttributeError: 'Request' object has no attribute 'squash'`

could you help please?

miguelgrinberg commented 4 years ago

@JocoYo1 what is request.squash? That does not appear to be defined.

JocoYo1 commented 4 years ago

I thought the request needed to go to the form squash in the html that I named {name = "squash"} as my html has 2 forms I want to pull information from one called name="squash" and one called name = "register"

<div class="CSC">
        <div class="form-box">
            <div class="CSC-logo">
                <a href="https://www.cheamsquashclub.co.uk/"><img src="images/CSC.png"></a>
            </div>
            <div class="button-box">
                <div id="btn"></div>
                <button type="button" class="toggle-btn" onclick="Signin()">Sign In</button>
                <button type="button" class="toggle-btn" onclick="register()">Register</button>
            </div>
            <form id="Signin" class="input-group" name = "squash">
                <input id="username" type="text" class="input-field" placeholder="User Id" required>
                <input id="password" type="password" class="input-field" placeholder="Enter password" required>
                <input type="checkbox" class="check-box"><span>Remember password</span>
                <button type="submit" class="submit-btn" onclick="login()">Sign In</button>
            </form>
            <form id="register" class="input-group" name = "register">
                <input id="newUser" type="text" class="input-field" placeholder="User Id" required>
                <input id="newEmail" type="email" class="input-field" placeholder="Email" required>
                <input id="newPassword" type="password" class="input-field" placeholder="Enter password" required>
                <input id="passwordConfirm" type="password" class="input-field" placeholder="Confirm Password" required>
                <input type="checkbox" class="check-box"><span>I agree to terms and conditions</span>
                <button type="submit" class="submit-btn" onclick="registerUser()">Register here</button>
            </form>
            <div class="social-icons">
                <a href="https://www.facebook.com/cheamsquash/" target="_blank"><img class=social-img src="images/fb.png"></a>
                <a href="https://twitter.com/cheamsquash" target="_blank"><img class=social-img src="images/tw.png"></a>
                <a href="https://www.englandsquash.com/" target="_blank"><img class="social-img-es" src="images/es1.png"></a>
            </div>
        </div>
    </div>
    <script>
    var x = document.getElementById("Signin");
    var y = document.getElementById("register");
    var z = document.getElementById("btn");

    function register(){
        x.style.left = "-400px";
        y.style.left = "50px";
        z.style.left = "110px";
    }
    function Signin(){
        x.style.left = "50px";
        y.style.left = "450px";
        z.style.left = "0px";
    }
</script>

How would I connect the app and the forms in this case?

JocoYo1 commented 4 years ago

Sorry the code for the html is

1. <div class="CSC">
2.         <div class="form-box">
3.             <div class="CSC-logo">
4.                 <a href="https://www.cheamsquashclub.co.uk/"><img src="images/CSC.png"></a>
5.             </div>
6.             <div class="button-box">
7.                 <div id="btn"></div>
8.                 <button type="button" class="toggle-btn" onclick="Signin()">Sign In</button>
9.                 <button type="button" class="toggle-btn" onclick="register()">Register</button>
10.             </div>
11.             <form id="Signin" class="input-group" name = "squash">
12.                 <input id="username" type="text" class="input-field" placeholder="User Id" required>
13.                 <input id="password" type="password" class="input-field" placeholder="Enter password" required>
14.                 <input type="checkbox" class="check-box"><span>Remember password</span>
15.                 <button type="submit" class="submit-btn" onclick="login()">Sign In</button>
16.             </form>
17.             <form id="register" class="input-group" name = "register">
18.                 <input id="newUser" type="text" class="input-field" placeholder="User Id" required>
19.                 <input id="newEmail" type="email" class="input-field" placeholder="Email" required>
20.                 <input id="newPassword" type="password" class="input-field" placeholder="Enter password" required>
21.                 <input id="passwordConfirm" type="password" class="input-field" placeholder="Confirm Password" required>
22.                 <input type="checkbox" class="check-box"><span>I agree to terms and conditions</span>
23.                 <button type="submit" class="submit-btn" onclick="registerUser()">Register here</button>
24.             </form>
25.             <div class="social-icons">
26.                 <a href="https://www.facebook.com/cheamsquash/" target="_blank"><img class=social-img src="images/fb.png"></a>
27.                 <a href="https://twitter.com/cheamsquash" target="_blank"><img class=social-img src="images/tw.png"></a>
28.                 <a href="https://www.englandsquash.com/" target="_blank"><img class="social-img-es" src="images/es1.png"></a>
29.             </div>
30.         </div>
31.     </div>
32.     <script>
33.     var x = document.getElementById("Signin");
34.     var y = document.getElementById("register");
35.     var z = document.getElementById("btn");
36.     
37.     function register(){
38.         x.style.left = "-400px";
39.         y.style.left = "50px";
40.         z.style.left = "110px";
41.     }
42.     function Signin(){
43.         x.style.left = "50px";
44.         y.style.left = "450px";
45.         z.style.left = "0px";
46.     }
47. </script> 
miguelgrinberg commented 4 years ago

Use request.form.get('form-field-name-here').

JocoYo1 commented 4 years ago

I don't really know if that is working ;P now it is showing me "Not Found the requested URL was not found on the server. if you entered the URL manually please check your spelling and try again". I have checked the spelling like 3000 times and it seem right as well as everything I can think of. The files are all in folder in the same place as the Index.html called templates in a folder called MyNewFlaskApp as per a tutorial in youtube (Is my first time programming :) ) . I'm not sure if the folder "templates" should be in the virtual environment within that folder "MyNewFlaskApp". I think this is a new topic but as I'm new here I don't even know how to open a new topic :P

miguelgrinberg commented 4 years ago

@JocoYo1 I don't really follow what you are saying. The "not found" error is the 404, it means that the browser is asking for a URL that the server does not know about. It has nothing to do with what you were asking before, it's a different bug that you have in your application.

JocoYo1 commented 4 years ago

Yeah sorry, the fact is that as soon as I have made the changes as per your advice, the next error appear. And even though I understand it should be published as a new topic, I have no idea how to do that. Sorry again for all the rumbling. I'm just running out of thing to check in order to debug it. ;P

miguelgrinberg commented 4 years ago

@JocoYo1 As I said above, your application is request a URL that the server hasn't implemented. This isn't an issue with this package.