Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic realtime support (code included): #492

Open
earonesty opened this issue Jul 13, 2023 · 1 comment
Open

Basic realtime support (code included): #492

earonesty opened this issue Jul 13, 2023 · 1 comment
Labels
documentation Improvements or additions to documentation

Comments

@earonesty
Copy link

I use this for realtime support. It's not great, but it's fine for me.

  • one channel
  • uses threads
  • can be keyboard-interrupted (even on windows)
  • 5 second queue poll for interrupts

usage:

   mon = self.conn.monitor("work")
   
   for payload in mon:
       if payload.get("type") == "INSERT":
           log.error("hey, this table shouldn't have inserts")
           mon.send(False)
           break 

the class:

class AugmentedClient(Client):
    def monitor(self, tab):
        wss = self.realtime_url
        key = self.supabase_key

        wsv1 = f"{wss}/websocket?apikey={key}&vsn=1.0.0"

        q = queue.Queue()

        data = None
        def do_callback(payload):
            nonlocal data
            data = payload
            q.put(payload)

        s = Socket(wsv1, auto_reconnect=True)

        def thread_run():
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            s.connect()
            channel = s.set_channel(f"realtime:{self.schema}:{tab}")
            channel.join().on("*", do_callback)
            s.listen()

        thread = threading.Thread(target=thread_run, daemon=True)
        thread.start()

        prev_sig = signal.getsignal(signal.SIGINT)
        def signal_handler(signal, frame):
            q.put(None)
            if prev_sig is not None:
                prev_sig(signal, frame)
        signal.signal(signal.SIGINT, signal_handler)

        while True:
            try:
                ret = q.get(timeout=5)
            except queue.Empty:
                continue

            if ret is None:
                s.ws_connection.close()
                break

            # user can .send(False) to interrupt loop and close the channel
            ok = yield ret
            if ok is False:
                q.put(None)
                yield None
@J0 J0 added the documentation Improvements or additions to documentation label Sep 8, 2023
@snags141
Copy link

snags141 commented Sep 11, 2023

Any possibility this could be used with JWT's instead of the service_role API key? (Or even just a regular access_key after signing in a user with email & password?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

3 participants