{"library":"realtime","title":"Supabase Realtime Python Client","description":"The `realtime` library is the official Python client for Supabase Realtime, offering capabilities for real-time communication. It allows applications to send and receive ephemeral messages via Broadcast, track and synchronize shared state with Presence, and listen for database changes using Postgres Change Data Capture (CDC). The current version is 2.28.3, and it receives frequent updates as part of the broader Supabase ecosystem.","status":"active","version":"2.28.3","language":"en","source_language":"en","source_url":"https://github.com/supabase-community/realtime-py","tags":["supabase","realtime","websocket","async","pubsub","cdc","postgres","phoenix-channels"],"install":[{"cmd":"pip install realtime","lang":"bash","label":"Install `realtime`"}],"dependencies":[{"reason":"Required for establishing and maintaining WebSocket connections to the Realtime server.","package":"websockets"}],"imports":[{"symbol":"AsyncRealtimeClient","correct":"from realtime import AsyncRealtimeClient"},{"symbol":"RealtimeSubscribeStates","correct":"from realtime import RealtimeSubscribeStates"}],"quickstart":{"code":"import asyncio\nimport os\nfrom typing import Optional\nfrom realtime import AsyncRealtimeClient, RealtimeSubscribeStates\n\nasync def main():\n    REALTIME_URL = os.environ.get('REALTIME_URL', 'ws://localhost:4000/websocket')\n    API_KEY = os.environ.get('SUPABASE_ANON_KEY', 'YOUR_SUPABASE_ANON_KEY') # Or your service role key\n\n    print(f\"Connecting to {REALTIME_URL} with API Key: {API_KEY[:5]}...\")\n\n    socket = AsyncRealtimeClient(REALTIME_URL, API_KEY)\n    channel = socket.channel(\"my_test_channel\")\n\n    def _on_subscribe(status: RealtimeSubscribeStates, err: Optional[Exception]):\n        if status == RealtimeSubscribeStates.SUBSCRIBED:\n            print(\"Connected to channel!\")\n        elif status == RealtimeSubscribeStates.CHANNEL_ERROR:\n            print(f\"Error subscribing to channel: {err}\")\n        elif status == RealtimeSubscribeStates.TIMED_OUT:\n            print(\"Subscription timed out.\")\n        elif status == RealtimeSubscribeStates.CLOSED:\n            print(\"Channel unexpectedly closed.\")\n\n    # Listen for database changes (example: all changes in 'public' schema)\n    channel.on_postgres_changes(\n        \"*\",\n        schema=\"public\",\n        callback=lambda payload: print(\"Database change received:\", payload)\n    )\n\n    # Listen for broadcast messages\n    channel.on_broadcast(\"my-event\", lambda payload: print(\"Broadcast received:\", payload))\n\n    await channel.subscribe(_on_subscribe)\n    await asyncio.sleep(60) # Keep the client alive for 60 seconds\n    await socket.disconnect()\n\nif __name__ == \"__main__\":\n    # Set these environment variables or replace placeholders for a live connection\n    # os.environ['REALTIME_URL'] = 'wss://<project_ref>.supabase.co/realtime/v1'\n    # os.environ['SUPABASE_ANON_KEY'] = 'eyJ...'\n    asyncio.run(main())","lang":"python","description":"This quickstart demonstrates how to establish a connection to the Supabase Realtime server, subscribe to a channel, listen for PostgreSQL database changes, and receive broadcast messages. Remember to replace placeholder `REALTIME_URL` and `SUPABASE_ANON_KEY` with your actual Supabase project details, typically retrieved from your project settings. Ensure your API key has the necessary permissions (e.g., 'anon' key for public read access or a 'service_role' key for elevated privileges)."},"warnings":[{"fix":"Verify the `REALTIME_URL` against your Supabase project's Realtime connection string in the Supabase Dashboard, or the local Supabase CLI output.","message":"The `REALTIME_URL` format is crucial. For local development, it's typically `ws://localhost:4000/websocket`. For a deployed Supabase project, use `wss://<project_ref>.supabase.co/realtime/v1`. Using the incorrect URL can lead to connection failures.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Update your code to access the change data using `payload['event']` instead of `payload['events']`. This change was noted in `supabase-py`'s v2.27.1 release, which the `realtime` client aligns with.","message":"The protocol for `postgres_changes` has shifted from using the key 'events' to 'event' in the payload. Older clients expecting 'events' will fail to process real-time database changes correctly.","severity":"breaking","affected_versions":"Pre-2.27.1"},{"fix":"Implement robust error handling and reconnection logic. Ensure your `API_KEY` is valid and has the necessary JWT claims (e.g., `exp` and `role`). Monitor network conditions and Supabase service status. Review GitHub issues for known transient problems.","message":"Realtime connections can experience timeouts or failed subscriptions, often due to network instability, incorrect API keys, or server-side issues. Common errors include 'keepalive ping timeout' or 'join push timeout'.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your project uses Python 3.9 or higher. Regularly check the `realtime` PyPI page or GitHub repository for updated Python version requirements.","message":"Python 3.8 support might be deprecated in future releases, following the general trend of the Supabase Python ecosystem. The library currently requires Python 3.9+.","severity":"deprecated","affected_versions":"<=2.27.3"},{"fix":"When generating or using JWTs, ensure they are correctly signed, unexpired, and contain the appropriate `role` claim that matches your Row Level Security (RLS) policies in Supabase.","message":"The `API_KEY` used for connecting to the Realtime server, especially for private channels, must be a JWT that includes `exp` (expiration) and `role` (database role) claims. An invalid or expired JWT will result in authorization failures.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-05T00:00:00.000Z","next_check":"2026-07-04T00:00:00.000Z"}