Websocket error in my consumers

Hello, it’s me again (sorry) I think I managed to debug the websocket, but I have an error, which makes that I receive nothing.
I post all the details, so I followed a documentation that uses redis-server and daphne for the back

gunicorn.socket

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

gunicorn.service

Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=wahab
Group=www-data
WorkingDirectory=/home/wahab/apporder
ExecStart=/home/wahab/apporder/env/bin/gunicorn \
          --access-logfile - \
          -k uvicorn.workers.UvicornWorker \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          OrderLine1.asgi:application

[Install]
WantedBy=multi-user.target

redis-server

wahab@django411:~/apporder$ sudo netstat -lnp | grep redis
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      82375/redis-server
tcp6       0      0 ::1:6379                :::*                    LISTEN      82375/redis-server

nginx

server {
    listen 80;
    server_name ****;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /var/www/html;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }

    location /ws/ {
        proxy_pass http://127.0.0.1:8001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;
    }

}

daphne.service

[Unit]
Description=WebSocket Daphne Service
After=network.target

[Service]
Type=simple
User=wahab
WorkingDirectory=/home/wahab/apporder
ExecStart=/home/wahab/apporder/env/bin/python /home/wahab/apporder/env/bin/daphne -b 0.0.0.0 -p 8001 OrderLine1.asgi:application
Restart=on-failure

[Install]
WantedBy=multi-user.target

settings.py

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [('localhost', 6379)],
        },
    },
}

ALLOWED_HOSTS = ['my_server', 'localhost', '127.0.0.1']

Consumers.py

import logging


class HubriseOrderConsumer(ListModelMixin, GenericAsyncAPIConsumer):
    print(HubriseOrder.objects)       
    def get_queryset(self, **kwargs):
        logger = logging.getLogger('django')
        logger.info((type(HubriseOrder.objects)))
        return HubriseOrder.objects.filter(ascount=self.scope["user"]).exclude(status__in=['En attente', 'Rejeter', 'Compléter', 'new', 'Livraison échouer']).order_by('created_at')
    serializer_class = HubriseOrderSerializer
    permissions = (permissions.AllowAny,)

    async def connect(self, **kwargs):
        await self.model_change.subscribe()
        await super().connect()


    @model_observer(HubriseOrder)
    async def model_change(self, message, observer=None, **kwargs):
        await self.send_json(message)

    @model_change.serializer
    def model_serialize(self, instance, action, **kwargs):
        return dict(data=HubriseOrderSerializer(instance=instance).data, action=action.value)

sorry again for the inconvenience

here is the error

It’s showing the error as being associated with the HubriseOrder object, what is its definition?

That is to say the model? Sorry I did not understand the meaning of definition

Correct, we’ll need to see the model HubriseOrder.

class HubriseOrder(models.Model):
    ascount = models.ForeignKey(
        User, on_delete=models.CASCADE, null=True, blank=True)
    location_id = models.CharField(max_length=255, null=True, blank=True)
    id_order = models.CharField(max_length=255, null=True, blank=True)
    status = models.CharField(max_length=255, null=True, blank=True)
    service_type = models.CharField(max_length=255, null=True, blank=True)
    email = models.CharField(max_length=255, null=True, blank=True)
    first_name = models.CharField(max_length=255, null=True, blank=True)
    last_name = models.CharField(max_length=255, null=True, blank=True)
    phone = models.CharField(max_length=255, null=True, blank=True)
    address_1 = models.CharField(max_length=255, null=True, blank=True)
    address_2 = models.CharField(max_length=255, null=True, blank=True)
    postal_code = models.CharField(max_length=255, null=True, blank=True)
    city = models.CharField(max_length=255, null=True, blank=True)
    namePaiement = models.CharField(max_length=255, null=True, blank=True)
    amount = models.CharField(max_length=255, null=True, blank=True)
    created_at = models.DateTimeField(
        auto_now_add=True, auto_now=False, null=True, blank=True)
    created_by = models.CharField(max_length=255, blank=True)
    expected_time = models.DateTimeField(
        auto_now_add=True, auto_now=False, null=True, blank=True)
    pictureplatform = models.CharField(max_length=255, blank=True)
    statuscolor = models.CharField(max_length=255, blank=True)

That’s the complete model? There are no model functions defined as well? No custom manager?

What is the rest of the consumers.py file? (What does the import statement look like for HubriseOrder?)

If you’re not using a custom manager, then this error is probably caused by the name HubriseOrder being rebound to a different class or object. That means we may need to see a lot of stray code to check out where this might be happening.

my consumers.py complete

from typing import Generic
from myapp.models import HubriseOrder
from .serializers import HubriseOrderSerializer
from djangochannelsrestframework import permissions
from djangochannelsrestframework.generics import GenericAsyncAPIConsumer
from djangochannelsrestframework.mixins import ListModelMixin
from djangochannelsrestframework.observer import model_observer
import logging


class HubriseOrderConsumer(ListModelMixin, GenericAsyncAPIConsumer):
    print(HubriseOrder.objects)       
    def get_queryset(self, **kwargs):
        logger = logging.getLogger('django')
        logger.info((type(HubriseOrder.objects)))
        return HubriseOrder.objects.filter(ascount=self.scope["user"]).exclude(status__in=['En attente', 'Rejeter', 'Compléter', 'new', 'Livraison échouer']).order_by('created_at')
    serializer_class = HubriseOrderSerializer
    permissions = (permissions.AllowAny,)

    async def connect(self, **kwargs):
        await self.model_change.subscribe()
        await super().connect()


    @model_observer(HubriseOrder)
    async def model_change(self, message, observer=None, **kwargs):
        await self.send_json(message)

    @model_change.serializer
    def model_serialize(self, instance, action, **kwargs):
        return dict(data=HubriseOrderSerializer(instance=instance).data, action=action.value)

and my model.py complete

class OrderLine1UserProfil(models.Model):
    ascount = models.OneToOneField(
        User, on_delete=models.CASCADE, null=True, blank=True)
    phone = models.CharField(max_length=255, blank=True)
    date = models.DateTimeField(auto_now_add=True, blank=True)
    namefastfood = models.CharField(max_length=255, blank=True)
    imgClient = models.ImageField(
        null=True, blank=True, upload_to="images/")
    address = models.CharField(max_length=255, blank=True)
    zipcode = models.CharField(max_length=255, blank=True)
    city = models.CharField(max_length=255, blank=True)


class HubriseData(models.Model):
    ascount = models.OneToOneField(
        User, on_delete=models.CASCADE, null=True, blank=True)
    auth_token = models.CharField(max_length=255, null=True, blank=True)
    catalog = models.CharField(max_length=255, null=True, blank=True)
    location = models.CharField(max_length=255, null=True, blank=True)
    customer_list = models.CharField(max_length=255, null=True, blank=True)


class HubriseOrder(models.Model):
    ascount = models.ForeignKey(
        User, on_delete=models.CASCADE, null=True, blank=True)
    location_id = models.CharField(max_length=255, null=True, blank=True)
    id_order = models.CharField(max_length=255, null=True, blank=True)
    status = models.CharField(max_length=255, null=True, blank=True)
    service_type = models.CharField(max_length=255, null=True, blank=True)
    email = models.CharField(max_length=255, null=True, blank=True)
    first_name = models.CharField(max_length=255, null=True, blank=True)
    last_name = models.CharField(max_length=255, null=True, blank=True)
    phone = models.CharField(max_length=255, null=True, blank=True)
    address_1 = models.CharField(max_length=255, null=True, blank=True)
    address_2 = models.CharField(max_length=255, null=True, blank=True)
    postal_code = models.CharField(max_length=255, null=True, blank=True)
    city = models.CharField(max_length=255, null=True, blank=True)
    namePaiement = models.CharField(max_length=255, null=True, blank=True)
    amount = models.CharField(max_length=255, null=True, blank=True)
    created_at = models.DateTimeField(
        auto_now_add=True, auto_now=False, null=True, blank=True)
    created_by = models.CharField(max_length=255, blank=True)
    expected_time = models.DateTimeField(
        auto_now_add=True, auto_now=False, null=True, blank=True)
    pictureplatform = models.CharField(max_length=255, blank=True)
    statuscolor = models.CharField(max_length=255, blank=True)


class HubriseOrderItem(models.Model):
    id_order_item = models.CharField(max_length=255, null=True, blank=True)
    HubriseOrderId = models.ForeignKey(
        HubriseOrder, on_delete=models.CASCADE, related_name='entries')
    product_name = models.CharField(max_length=255, null=True, blank=True)
    priceProduct = models.CharField(max_length=255, null=True, blank=True)
    quantityProduct = models.CharField(max_length=255, null=True, blank=True)


class HubriseOrderItemOption(models.Model):
    id_order_item_option = models.CharField(
        max_length=255, null=True, blank=True)
    HubriseOrderItemId = models.ForeignKey(
        HubriseOrderItem, on_delete=models.CASCADE, related_name='entriesoption')
    nameOption = models.CharField(max_length=255, null=True, blank=True)
    priceOption = models.CharField(max_length=255, null=True, blank=True)
    quantityOption = models.CharField(max_length=255, null=True, blank=True)

maybe serializers.py

from rest_framework import serializers

from myapp.models import *


class HubriseOrderSerializer(serializers.ModelSerializer):

    class Meta:
        model = HubriseOrder
        fields = "__all__"

and my views i have this


class HubriseOrderViewSet(viewsets.ModelViewSet):

            serializers_class = HubriseOrderSerializer
            queryset = HubriseOrder.objects.all()

Something I’ve noticed from Observer — djangochannelsrestframework 1.2.0 documentation

They have:

from .models import User, Comment

But then they have:

@model_observer(Comments)

Notice the difference in names. I have no idea if this is intentional or just an error in their documentation.

This use of Comments appears in multiple locations (see: Search — djangochannelsrestframework 1.2.0 documentation) but always with reference to a class named Comment.
Also see Filtered model observer — djangochannelsrestframework 1.2.0 documentation as another example.

I think it’s possible that this may be intentional - that what is actually happening is that this decorator is creating a new class, and by you reusing the existing class name has changed the Type of that class. (But I haven’t examined the source code of that project to know this, it’s just a possibility.)

Sorry for the late reply but, I have tried in local and also then try in production on both, it does not work and send me this error (I think it is a mistake on their part)

Nov 17 23:13:18 django411]:   File "/home/wahab/apporder/myapp/consumers.py", line 26, in HubriseOrderConsumer
Nov 17 23:13:18 django411:     @model_observer(HubriseOrders)

Oh well, it was worth a shot.

By the way, what was logged for these two statements in that class?

@KenWhitesell So I set up a logging to see what type of HubriseOrder it was.

I already tested locally to see if it works, it sent me in my debug.log that it was a model.

Then I tested in production and it did not work, so I tried again but in another file to see if it was the consumers.py that had a problem and it was the case, because I wrote the same line in my views and it returned in my debug.log that it was a model.

We can conclude that it is indeed the consumers which has a problem or that I badly configured nginx or other

It’s definitely not nginx. Nginx is not running your application - your application is running as an independent process. The two communicate with each other through the socket file you have created.

If there’s a definite difference in how these work between your local install and production, then one of the first things to check is to compare everything between the two environments. Compare the versions of Python, Django, Channels, Gunicorn, and any other library your app is using. If you’re running the app differently in the two environments, try running it the same in both (at least temporarily.) The goal here is to identify what is different between the two environments to then identify the solution.

I already checked, I don’t think it’s that, but look

production

Package                     Version
--------------------------- ------------------------------------
acme                        1.21.0
aioredis                    1.3.1
anyio                       3.6.2
asgiref                     3.2.10
async-timeout               4.0.2
attrs                       21.2.0
autobahn                    22.7.1
Automat                     20.2.0
Babel                       2.8.0
base58                      1.0.3
bcrypt                      3.2.0
blinker                     1.4
cbor                        1.0.0
certbot                     1.21.0
certbot-nginx               1.21.0
certifi                     2020.6.20
cffi                        1.15.0
channels                    3.0.5
channels-redis              2.4.2
chardet                     4.0.0
click                       8.0.3
cloud-init                  22.2
colorama                    0.4.4
command-not-found           0.3
ConfigArgParse              1.5.3
configobj                   5.0.6
constantly                  15.1.0
cryptography                3.4.8
Cython                      0.29.28
daphne                      3.0.2
dbus-python                 1.2.18
Deprecated                  1.2.13
distlib                     0.3.6
distro                      1.7.0
distro-info                 1.1build1
Django                      3.1
django-cors-headers         3.13.0
django-extensions           3.2.1
django-htmx                 1.13.0
djangochannelsrestframework 1.1.0
djangorestframework         3.14.0
ecdsa                       0.18.0b1
filelock                    3.8.0
flatbuffers                 1.12.1-git20200711.33e2d80-dfsg1-0.6
gevent                      21.8.0
greenlet                    1.1.2
gunicorn                    20.0.2
h11                         0.14.0
hiredis                     2.0.0
httplib2                    0.20.2
httptools                   0.5.0
hyperlink                   21.0.0
idna                        3.3
importlib-metadata          4.6.4
incremental                 21.3.0
jeepney                     0.7.1
Jinja2                      3.0.3
josepy                      1.10.0
jsonpatch                   1.32
jsonpointer                 2.0
jsonschema                  3.2.0
keyring                     23.5.0
launchpadlib                1.10.16
lazr.restfulclient          0.14.4
lazr.uri                    1.0.6
lz4                         3.1.3+dfsg
MarkupSafe                  2.0.1
mnemonic                    0.19
more-itertools              8.10.0
msgpack                     0.6.2
netifaces                   0.11.0
oauthlib                    3.2.0
packaging                   21.3
parsedatetime               2.6
passlib                     1.7.4
pexpect                     4.8.0
Pillow                      9.3.0
pip                         22.0.2
platformdirs                2.5.3
ply                         3.11
psycopg2                    2.9.2
ptyprocess                  0.7.0
py-ubjson                   0.16.1
pyasn1                      0.4.8
pyasn1-modules              0.2.1
pycparser                   2.21
PyGObject                   3.42.1
PyHamcrest                  2.0.2
PyICU                       2.8.1
PyJWT                       2.3.0
PyNaCl                      1.5.0
pyOpenSSL                   21.0.0
pyparsing                   2.4.7
pypng                       0.0.20
PyQRCode                    1.2.1
pyRFC3339                   1.1
pyrsistent                  0.18.1
pyserial                    3.5
python-apt                  2.3.0+ubuntu2.1
python-debian               0.1.43ubuntu1
python-dotenv               0.21.0
python-snappy               0.5.3
PyTrie                      0.4.0
pytz                        2022.1
PyYAML                      5.4.1
redis                       4.3.4
requests                    2.25.1
requests-toolbelt           0.9.1
SecretStorage               3.3.1
service-identity            18.1.0
setuptools                  59.6.0
six                         1.16.0
sniffio                     1.3.0
sortedcontainers            2.1.0
sos                         4.3
sqlparse                    0.4.2
ssh-import-id               5.11
systemd-python              234
Twisted                     22.1.0
txaio                       22.2.1
u-msgpack-python            2.3.0
ubuntu-advantage-tools      27.10
ufw                         0.36.1
ujson                       5.1.0
unattended-upgrades         0.1
urllib3                     1.26.5
uvicorn                     0.19.0
uvloop                      0.17.0
virtualenv                  20.16.6
wadllib                     1.3.6
watchfiles                  0.18.1
websockets                  10.4
wheel                       0.37.1
wrapt                       1.14.1
wsaccel                     0.6.3
zipp                        1.0.0
zope.component              4.3.0
zope.event                  4.4
zope.hookable               5.1.0
zope.interface              5.4.0

local

Package                     Version
--------------------------- ---------
3-1                         1.0.0    
aioredis                    1.3.1    
amqp                        5.1.1    
asgiref                     3.2.10   
async-timeout               4.0.2    
attrs                       22.1.0   
autobahn                    22.7.1   
Automat                     20.2.0   
autopep8                    1.6.0    
billiard                    3.6.4.0  
certifi                     2022.6.15
cffi                        1.15.1   
chainer                     7.8.1    
channels                    3.0.5    
channels-redis              2.4.2    
charset-normalizer          2.1.0    
click                       8.1.3    
click-didyoumean            0.3.0    
click-plugins               1.1.1    
click-repl                  0.2.0    
colorama                    0.4.5    
constantly                  15.1.0   
cryptography                37.0.2   
cssbeautifier               1.14.7   
daphne                      3.0.2    
Deprecated                  1.2.13   
distlib                     0.3.4
dj-database-url             0.5.0
Django                      3.1
django-cors-headers         3.13.0
django-crontab              0.7.1
django-extensions           3.1.5
django-htmx                 1.12.2
django-jquery-js            3.1.1
django-replace              2020.12.3
djangochannelsrestframework 1.0.0
djangorestframework         3.13.1
djlint                      1.19.3
dnspython                   2.2.1
docopt                      0.6.2
EditorConfig                0.12.3
filelock                    3.7.1
gunicorn                    20.1.0
heroku                      0.1.4
hiredis                     2.0.0
html-tag-names              0.1.2
html-void-elements          0.1.0
hyperlink                   21.0.0
idna                        3.3
importlib-metadata          5.0.0
incremental                 22.10.0
jsbeautifier                1.14.7
kombu                       5.2.4
msgpack                     0.6.2
numpy                       1.23.4
oauthlib                    3.2.0
packaging                   21.3
pathspec                    0.10.1
Pillow                      9.2.0
pipreqs                     0.4.11
platformdirs                2.5.2
prompt-toolkit              3.0.31
protobuf                    4.21.9
psycopg2                    2.9.3
pyasn1                      0.4.8
pyasn1-modules              0.2.8
pycodestyle                 2.8.0
pycparser                   2.21
pymongo                     4.3.2
pyOpenSSL                   22.0.0
pypandoc                    1.10
pyparsing                   3.0.9
python-dateutil             1.5
pytz                        2022.1
PyYAML                      6.0
pyzmq                       24.0.1
redis                       4.3.4
regex                       2022.9.13
requests                    2.28.1
service-identity            21.1.0
six                         1.16.0
sqlparse                    0.4.2
toml                        0.10.2
tomli                       2.0.1
tornado                     6.2
tqdm                        4.64.1
Twisted                     22.8.0
twisted-iocpsupport         1.0.2
txaio                       22.2.1
typing_extensions           4.4.0
tzdata                      2022.1
urllib3                     1.26.10
vine                        5.0.0
virtualenv                  20.14.1
wcwidth                     0.2.5
Werkzeug                    2.1.2
whitenoise                  6.2.0
wrapt                       1.14.1
yarg                        0.1.9
zipp                        3.10.0
zope.interface              5.5.0

If it helps to identify the problem I have this on my network

So, you have quite a number of version differences - which ones do you think may be relevant?

(And, there’s still the question of which versions of Python you’re using.)

local Python 3.10.8
production Python 3.10.6

There is nothing coming over the network that would cause or be related to this issue. Something is changing the type of HubriseOrder.

It may also be worthwhile to change the print and log to identify the type of HubriseOrder instead of HubriseOrder.objects

I changed it to HubriseOrder, but the problem is that it does not return anything in my debug.log

That’s useful information in itself.

Something is stomping on that name in your module. Since that’s not happening in your local environment, that makes it clear to me that one of the differences in the libraries being used is causing this.