Communication between django and external script

Hi guys,

I don’t know if this is in the right place but I have a question. I have a script that reads nfc/frid tags on a raspberry pi and stores it in the database.
Now I need to create an application that allows me to graphically see who passed the tag etc so I’d like to hear opinions on how I’m going to communicate between the script and a django server or flask etc.

You mention that you’re already writing the values to the database. Django can read that database to retrieve the data.

What sort of communication do you need between the script and Django?

The database will be shared yes,
The use case is: When a user passes the tag we see on the screen who passed the tag. The django need to receive or know who tagged the reader. for example.

If the server receive the tag id, i can use websockets to push the data to the frontend, but the server needs to receive the data and know there is new data to show

Since you’re using websockets, you have at least two options.

  • You could set up a URL in Django that the Pi can access (perhaps using requests) to signal that new data has been written. (Depending upon what data you have and need, you could even send the data in the request.)

  • You could have the Pi open a websocket (as a client) with the server instance of Channels and pass the notification (and possibly the data) through a websocket frame.

The django server will live inside the Pi.

I can use the channels on the script? good to know, i will explore that

And use something like celery a rabbitmq?

For what purpose? (I don’t see where this fits into what you’ve described so far)

To clarify:

I’m assuming that this “script” is a separate Python program. If so, then it would be running a websocket client, not Channels. That websocket client would be opening a connection to your Django/Channels server.

yes it is a different program. i am exploring solutions. and mqtt instead of websokets?

<opinion>
Ick. If you’re running Django/Channels for websocket support, you’ll already be using redis. There’s no reason to add an additional process into the mix.

If you don’t want to create a websocket client and don’t want to use a standard URL as a “trigger”, a far better solution would be to create your script as an external Channels Worker process and allow your external script to send the message through redis directly to the consumer.

</opinion>

I´m not using anything so far. i have only the script reading data and store in the database. I´m searching and try to figure how to do this in a good way.

And if the script live inside Django? or its not a good idea?

Physically, it’s fine for the script to be placed within your Django directory structure. But since it needs to run independently of Django as an always-running task, it won’t be running in the same process as your Django process.

Im running windows and having a hard time finding a way to run a python script and push the data to my django app to offload some work. Im running the script every 15 seconds. Can you please point me in the right direction.

Welcome! Please open up a new topic for this discussion, and include more details about what sort of work you’re generating (what this “python script” does) and what you’re expecting Django to do.

I went for the approach to access the django channels consumer via websockets as a client. When doing so, my Django server rejects the connection . What do i wrong?

(code snippets:)

websockets client:

class Base(ABC):
"""Basic class, containing common functionality among all versions."""
    def __init__(self, serial_number: str, software: str, country: str, postcode: str) -> None:
        self.server_url = r'ws://localhost:8000/ws/update/'
        self.publish = True

    async def publish_state(self, interval: int = 2):
        """Coro: Periodically publishes instance state to websocket URL."""
        async with websockets.connect(self.server_url) as ws:
            print(f'connected to {self.server_url}')
            while self.publish:
                await ws.send('hello world')#str(f"Update from {self.serial_number}").encode('ascii'))
                await asyncio.sleep(interval)
                if interval == 0:
                    break

consumers.py

class ServerConsumer(AsyncWebsocketConsumer):
    groups = ["broadcast"]

    async def connect(self):
        # Called on connection.
        # To accept the connection call:
        await self.accept()

routing.py:

websocket_urlpatterns = [
    re_path("ws/update/", consumers.SolServerConsumer.as_asgi()),
]

server log:
WebSocket HANDSHAKING /ws/update/ [127.0.0.1:65507]
WebSocket REJECT /ws/update/ [127.0.0.1:65507]
WebSocket DISCONNECT /ws/update/ [127.0.0.1:65507

client log:

websockets.exceptions.InvalidStatusCode: server rejected WebSocket connection: HTTP 403

1 Like

Welcome @fungos34 !

Please open up a new topic for this discussion. In your new post, in addition to what you have posted here, include the complete server log from the time you started the server, including the command used to run the server. Also include your asgi.py file and the INSTALLED_APPS section of your settings.py file.

Side note: When posting code, error messages, templates, or other preformatted text in the forum, enclose the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then the text, then another line of ```. This forces the forum software to keep that text properly formatted.

1 Like

thank you, I opened a new topic here

Just want to say thanks for the example code. Can’t find anything googling. I’ma copy / paste it and then refactor it like a Rubik’s cube for my needs.

1 Like