realtime


Namerealtime JSON
Version 2.0.6 PyPI version JSON
download
home_pagehttps://github.com/supabase/realtime-py
SummaryNone
upload_time2024-10-18 07:10:10
maintainerNone
docs_urlNone
authorJoel Lee
requires_python<4.0,>=3.9
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <br />
<p align="center">
  <a href="https://supabase.io">
        <picture>
      <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/supabase/supabase/main/packages/common/assets/images/supabase-logo-wordmark--dark.svg">
      <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/supabase/supabase/main/packages/common/assets/images/supabase-logo-wordmark--light.svg">
      <img alt="Supabase Logo" width="300" src="https://raw.githubusercontent.com/supabase/supabase/main/packages/common/assets/images/logo-preview.jpg">
    </picture>
  </a>

  <h1 align="center">Supabase Realtime Client</h1>

  <h3 align="center">Send ephemeral messages with <b>Broadcast</b>, track and synchronize state with <b>Presence</b>, and listen to database changes with <b>Postgres Change Data Capture (CDC)</b>.</h3>

  <p align="center">
    <a href="https://supabase.com/docs/guides/realtime">Guides</a>
    ·
    <a href="https://supabase.com/docs/reference/python">Reference Docs</a>
    ·
    <a href="https://multiplayer.dev">Multiplayer Demo</a>
  </p>
</p>

# Overview

This client enables you to use the following Supabase Realtime's features:

- **Broadcast**: send ephemeral messages from client to clients with minimal latency. Use cases include sharing cursor positions between users.
- **Presence**: track and synchronize shared state across clients with the help of CRDTs. Use cases include tracking which users are currently viewing a specific webpage.
- **Postgres Change Data Capture (CDC)**: listen for changes in your PostgreSQL database and send them to clients.

# Usage

## Installing the Package

```bash
pip3 install realtime==2.0.0
```

## Creating a Channel

```python
import asyncio
from typing import Optional
from realtime.client import RealtimeClient
from realtime.channel import RealtimeSubscribeStates

client = RealtimeClient(REALTIME_URL, API_KEY)
channel = client.channel('test-channel')

def _on_subscribe(status: RealtimeSubscribeStates, err: Optional[Exception]):
    if status == RealtimeSubscribeStates.SUBSCRIBED:
        print('Connected!')
    elif status == RealtimeSubscribeStates.CHANNEL_ERROR:
        print(f'There was an error subscribing to channel: {err.message}')
    elif status == RealtimeSubscribeStates.TIMED_OUT:
        print('Realtime server did not respond in time.')
    elif status == RealtimeSubscribeStates.CLOSED:
        print('Realtime channel was unexpectedly closed.')

await channel.subscribe(_on_subscribe)

# Listen for all incoming events, often the last thing you want to do.
await client.listen()
```

### Notes:

- `REALTIME_URL` is `ws://localhost:4000/socket` when developing locally and `wss://<project_ref>.supabase.co/realtime/v1` when connecting to your Supabase project.
- `API_KEY` is a JWT whose claims must contain `exp` and `role` (existing database role).
- Channel name can be any `string`.

## Broadcast

Your client can send and receive messages based on the `event`.

```python
# Setup...

channel = client.channel(
    "broadcast-test", {"config": {"broadcast": {"ack": False, "self": False}}}
)

await channel.on_broadcast("some-event", lambda payload: print(payload)).subscribe()
await channel.send_broadcast("some-event", {"hello": "world"})
```

### Notes:

- Setting `ack` to `true` means that the `channel.send` promise will resolve once server replies with acknowledgement that it received the broadcast message request.
- Setting `self` to `true` means that the client will receive the broadcast message it sent out.
- Setting `private` to `true` means that the client will use RLS to determine if the user can connect or not to a given channel.

## Presence

Your client can track and sync state that's stored in the channel.

```python
# Setup...

channel = client.channel(
    "presence-test",
    {
        "config": {
            "presence": {
                "key": ""
            }
        }
    }
)

channel.on_presence_sync(lambda: print("Online users: ", channel.presence_state()))
channel.on_presence_join(lambda new_presences: print("New users have joined: ", new_presences))
channel.on_presence_leave(lambda left_presences: print("Users have left: ", left_presences))

await channel.track({ 'user_id': 1 })
```

## Postgres CDC

Receive database changes on the client.

```python
# Setup...

channel = client.channel("db-changes")

channel.on_postgres_changes(
    "*",
    schema="public",
    callback=lambda payload: print("All changes in public schema: ", payload),
)

channel.on_postgres_changes(
    "INSERT",
    schema="public",
    table="messages",
    callback=lambda payload: print("All inserts in messages table: ", payload),
)

channel.on_postgres_changes(
    "UPDATE",
    schema="public",
    table="users",
    filter="username=eq.Realtime",
    callback=lambda payload: print(
        "All updates on users table when username is Realtime: ", payload
    ),
)

channel.subscribe(
    lambda status, err: status == RealtimeSubscribeStates.SUBSCRIBED
    and print("Ready to receive database changes!")
)
```

## Get All Channels

You can see all the channels that your client has instantiated.

```python
# Setup...

client.get_channels()
```

## Cleanup

It is highly recommended that you clean up your channels after you're done with them.

- Remove a single channel

```python
# Setup...

channel = client.channel('some-channel-to-remove')

channel.subscribe()

await client.remove_channel(channel)
```

- Remove all channels

```python
# Setup...

channel1 = client.channel('a-channel-to-remove')
channel2 = client.channel('another-channel-to-remove')

await channel1.subscribe()
await channel2.subscribe()

await client.remove_all_channels()
```

## Credits

This repo draws heavily from [phoenix-js](https://github.com/phoenixframework/phoenix/tree/master/assets/js/phoenix).

## License

MIT.


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/supabase/realtime-py",
    "name": "realtime",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.9",
    "maintainer_email": null,
    "keywords": null,
    "author": "Joel Lee",
    "author_email": "joel@joellee.org",
    "download_url": "https://files.pythonhosted.org/packages/fe/7d/07f006df098c5fc9e00488e5268bcd7af0ee30a65fd6dfdbcee17ffeaa3b/realtime-2.0.6.tar.gz",
    "platform": null,
    "description": "<br />\n<p align=\"center\">\n  <a href=\"https://supabase.io\">\n        <picture>\n      <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/supabase/supabase/main/packages/common/assets/images/supabase-logo-wordmark--dark.svg\">\n      <source media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/supabase/supabase/main/packages/common/assets/images/supabase-logo-wordmark--light.svg\">\n      <img alt=\"Supabase Logo\" width=\"300\" src=\"https://raw.githubusercontent.com/supabase/supabase/main/packages/common/assets/images/logo-preview.jpg\">\n    </picture>\n  </a>\n\n  <h1 align=\"center\">Supabase Realtime Client</h1>\n\n  <h3 align=\"center\">Send ephemeral messages with <b>Broadcast</b>, track and synchronize state with <b>Presence</b>, and listen to database changes with <b>Postgres Change Data Capture (CDC)</b>.</h3>\n\n  <p align=\"center\">\n    <a href=\"https://supabase.com/docs/guides/realtime\">Guides</a>\n    \u00b7\n    <a href=\"https://supabase.com/docs/reference/python\">Reference Docs</a>\n    \u00b7\n    <a href=\"https://multiplayer.dev\">Multiplayer Demo</a>\n  </p>\n</p>\n\n# Overview\n\nThis client enables you to use the following Supabase Realtime's features:\n\n- **Broadcast**: send ephemeral messages from client to clients with minimal latency. Use cases include sharing cursor positions between users.\n- **Presence**: track and synchronize shared state across clients with the help of CRDTs. Use cases include tracking which users are currently viewing a specific webpage.\n- **Postgres Change Data Capture (CDC)**: listen for changes in your PostgreSQL database and send them to clients.\n\n# Usage\n\n## Installing the Package\n\n```bash\npip3 install realtime==2.0.0\n```\n\n## Creating a Channel\n\n```python\nimport asyncio\nfrom typing import Optional\nfrom realtime.client import RealtimeClient\nfrom realtime.channel import RealtimeSubscribeStates\n\nclient = RealtimeClient(REALTIME_URL, API_KEY)\nchannel = client.channel('test-channel')\n\ndef _on_subscribe(status: RealtimeSubscribeStates, err: Optional[Exception]):\n    if status == RealtimeSubscribeStates.SUBSCRIBED:\n        print('Connected!')\n    elif status == RealtimeSubscribeStates.CHANNEL_ERROR:\n        print(f'There was an error subscribing to channel: {err.message}')\n    elif status == RealtimeSubscribeStates.TIMED_OUT:\n        print('Realtime server did not respond in time.')\n    elif status == RealtimeSubscribeStates.CLOSED:\n        print('Realtime channel was unexpectedly closed.')\n\nawait channel.subscribe(_on_subscribe)\n\n# Listen for all incoming events, often the last thing you want to do.\nawait client.listen()\n```\n\n### Notes:\n\n- `REALTIME_URL` is `ws://localhost:4000/socket` when developing locally and `wss://<project_ref>.supabase.co/realtime/v1` when connecting to your Supabase project.\n- `API_KEY` is a JWT whose claims must contain `exp` and `role` (existing database role).\n- Channel name can be any `string`.\n\n## Broadcast\n\nYour client can send and receive messages based on the `event`.\n\n```python\n# Setup...\n\nchannel = client.channel(\n    \"broadcast-test\", {\"config\": {\"broadcast\": {\"ack\": False, \"self\": False}}}\n)\n\nawait channel.on_broadcast(\"some-event\", lambda payload: print(payload)).subscribe()\nawait channel.send_broadcast(\"some-event\", {\"hello\": \"world\"})\n```\n\n### Notes:\n\n- Setting `ack` to `true` means that the `channel.send` promise will resolve once server replies with acknowledgement that it received the broadcast message request.\n- Setting `self` to `true` means that the client will receive the broadcast message it sent out.\n- Setting `private` to `true` means that the client will use RLS to determine if the user can connect or not to a given channel.\n\n## Presence\n\nYour client can track and sync state that's stored in the channel.\n\n```python\n# Setup...\n\nchannel = client.channel(\n    \"presence-test\",\n    {\n        \"config\": {\n            \"presence\": {\n                \"key\": \"\"\n            }\n        }\n    }\n)\n\nchannel.on_presence_sync(lambda: print(\"Online users: \", channel.presence_state()))\nchannel.on_presence_join(lambda new_presences: print(\"New users have joined: \", new_presences))\nchannel.on_presence_leave(lambda left_presences: print(\"Users have left: \", left_presences))\n\nawait channel.track({ 'user_id': 1 })\n```\n\n## Postgres CDC\n\nReceive database changes on the client.\n\n```python\n# Setup...\n\nchannel = client.channel(\"db-changes\")\n\nchannel.on_postgres_changes(\n    \"*\",\n    schema=\"public\",\n    callback=lambda payload: print(\"All changes in public schema: \", payload),\n)\n\nchannel.on_postgres_changes(\n    \"INSERT\",\n    schema=\"public\",\n    table=\"messages\",\n    callback=lambda payload: print(\"All inserts in messages table: \", payload),\n)\n\nchannel.on_postgres_changes(\n    \"UPDATE\",\n    schema=\"public\",\n    table=\"users\",\n    filter=\"username=eq.Realtime\",\n    callback=lambda payload: print(\n        \"All updates on users table when username is Realtime: \", payload\n    ),\n)\n\nchannel.subscribe(\n    lambda status, err: status == RealtimeSubscribeStates.SUBSCRIBED\n    and print(\"Ready to receive database changes!\")\n)\n```\n\n## Get All Channels\n\nYou can see all the channels that your client has instantiated.\n\n```python\n# Setup...\n\nclient.get_channels()\n```\n\n## Cleanup\n\nIt is highly recommended that you clean up your channels after you're done with them.\n\n- Remove a single channel\n\n```python\n# Setup...\n\nchannel = client.channel('some-channel-to-remove')\n\nchannel.subscribe()\n\nawait client.remove_channel(channel)\n```\n\n- Remove all channels\n\n```python\n# Setup...\n\nchannel1 = client.channel('a-channel-to-remove')\nchannel2 = client.channel('another-channel-to-remove')\n\nawait channel1.subscribe()\nawait channel2.subscribe()\n\nawait client.remove_all_channels()\n```\n\n## Credits\n\nThis repo draws heavily from [phoenix-js](https://github.com/phoenixframework/phoenix/tree/master/assets/js/phoenix).\n\n## License\n\nMIT.\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": null,
    "version": "2.0.6",
    "project_urls": {
        "Homepage": "https://github.com/supabase/realtime-py",
        "Repository": "https://github.com/supabase/realtime-py"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7efc47a6615db976d5417ad982a15983cb3750910e0672d2e7e2d620433cdb2f",
                "md5": "5c21d845ed3d1a36fd01cc9bfb4376e7",
                "sha256": "9aab6009c11883197386a0a9dc8c2b6939e62dddda734cfb77594727ac9ae0ce"
            },
            "downloads": -1,
            "filename": "realtime-2.0.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5c21d845ed3d1a36fd01cc9bfb4376e7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.9",
            "size": 20568,
            "upload_time": "2024-10-18T07:10:08",
            "upload_time_iso_8601": "2024-10-18T07:10:08.497901Z",
            "url": "https://files.pythonhosted.org/packages/7e/fc/47a6615db976d5417ad982a15983cb3750910e0672d2e7e2d620433cdb2f/realtime-2.0.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fe7d07f006df098c5fc9e00488e5268bcd7af0ee30a65fd6dfdbcee17ffeaa3b",
                "md5": "980244719889fca81536a5cb16f0c843",
                "sha256": "ced37686a77a546571029ecc74cfb31fff1404a5159d1198fa882af545843a6f"
            },
            "downloads": -1,
            "filename": "realtime-2.0.6.tar.gz",
            "has_sig": false,
            "md5_digest": "980244719889fca81536a5cb16f0c843",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.9",
            "size": 17463,
            "upload_time": "2024-10-18T07:10:10",
            "upload_time_iso_8601": "2024-10-18T07:10:10.122831Z",
            "url": "https://files.pythonhosted.org/packages/fe/7d/07f006df098c5fc9e00488e5268bcd7af0ee30a65fd6dfdbcee17ffeaa3b/realtime-2.0.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-18 07:10:10",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "supabase",
    "github_project": "realtime-py",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "realtime"
}
        
Elapsed time: 3.02465s