{"id":18891487,"url":"https://github.com/olirice/realtime","last_synced_at":"2026-05-16T18:33:10.891Z","repository":{"id":94799406,"uuid":"364716712","full_name":"olirice/realtime","owner":"olirice","description":"Realtime Subscription to PostgreSQL for Python","archived":false,"fork":false,"pushed_at":"2021-05-21T11:22:30.000Z","size":45,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-03T10:59:07.718Z","etag":null,"topics":["postgresql","python","sqlalchemy"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/olirice.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-05T22:03:59.000Z","updated_at":"2021-05-26T18:37:54.000Z","dependencies_parsed_at":"2023-03-31T03:49:14.133Z","dependency_job_id":null,"html_url":"https://github.com/olirice/realtime","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/olirice/realtime","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olirice%2Frealtime","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olirice%2Frealtime/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olirice%2Frealtime/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olirice%2Frealtime/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/olirice","download_url":"https://codeload.github.com/olirice/realtime/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olirice%2Frealtime/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33114223,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T04:41:52.686Z","status":"ssl_error","status_checked_at":"2026-05-16T04:41:52.009Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["postgresql","python","sqlalchemy"],"created_at":"2024-11-08T08:00:17.273Z","updated_at":"2026-05-16T18:33:10.868Z","avatar_url":"https://github.com/olirice.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Realtime\n\n\u003cp\u003e\n\n\u003ca href=\"https://github.com/olirice/realtime/actions\"\u003e\u003cimg src=\"https://github.com/olirice/realtime/workflows/tests/badge.svg\" alt=\"Tests\" height=\"18\"\u003e\u003c/a\u003e\n\u003ca href=\"https://realtime.readthedocs.io/en/latest/?badge=latest\"\u003e\u003cimg src=\"https://readthedocs.org/projects/realtime/badge/?version=latest\" alt=\"Tests\" height=\"18\"\u003e\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/olirice/realtime\"\u003e\u003cimg src=\"https://codecov.io/gh/olirice/realtime/branch/master/graph/badge.svg\" height=\"18\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/psf/black\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/code%20style-black-000000.svg\" alt=\"Codestyle Black\" height=\"18\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp\u003e\n    \u003ca href=\"https://www.python.org/downloads/\"\u003e\u003cimg src=\"https://img.shields.io/badge/python-3.8+-blue.svg\" alt=\"Python version\" height=\"18\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://badge.fury.io/py/realtime\"\u003e\u003cimg src=\"https://badge.fury.io/py/realtime.svg\" alt=\"PyPI version\" height=\"18\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/olirice/realtime/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/pypi/l/markdown-subtemplate.svg\" alt=\"License\" height=\"18\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/realtime/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/dm/realtime.svg\" alt=\"Download count\" height=\"18\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n**Documentation**: \u003ca href=\"https://realtime.readthedocs.io/en/latest/\" target=\"_blank\"\u003ehttps://realtime.readthedocs.io/en/latest/\u003c/a\u003e\n\n**Source Code**: \u003ca href=\"https://github.com/olirice/realtime\" target=\"_blank\"\u003ehttps://github.com/olirice/realtime\u003c/a\u003e\n\n---\n\nRealtime enables listening for changes in a PostgreSQL Database\n\nThis package is under active development and may change significantly. There is no stability guarentee. If you see something you like, please vendor it, or use at your own risk.\n\nThanks,\n\nOli\n\n\n## Setup\n\nRealtime relies on postgres using logical replication. Set it up using:\n\n```sql\n-- Ensure WAL replication is set to 'logical'\nALTER SYSTEM SET wal_level = logical;\n\n-- Allow a few replication slots\nALTER SYSTEM SET max_replication_slots = 5; -- any value \u003e 0\n\n/*\n-- Create a publication\nSpec:\n    CREATE PUBLICATION name\n        [ FOR TABLE [ ONLY ] table_name [ * ] [, ...]\n          | FOR ALL TABLES ]\n        [ WITH ( publication_parameter [= value] [, ... ] ) ]\n*/\nCREATE PUBLICATION realtime_py FOR ALL TABLES;\n```\n\nThen, restart your postgres instance.\n\n#### Notes\n\n##### Docker\nIf you're using docker, you can restart the postgres instance after issuing the commands above via\n```\ndocker restart \u003ccontainer_name\u003e\n```\n\n##### AWS - RDS\nAWS RDS does not grant superuser access to postgres instances. That level of access is required to issue `ALTER SYSTEM` commands. To enable logical replication on RDS, the value for `wal_level` can be set by creating a new parameter group and assigning it to the RDS instance.\n\nA reboot will still be required. That can also be done from the RDS UI.\n```\nRDS \u003e Databases \u003e \u003cyour database\u003e \u003e Configuration \u003e Parameter group\n```\n\n\n## Usage\n\n```python\nfrom realtime.subscribe import subscribe\nfrom sqlalchemy.ext.asyncio import create_async_engine\n\nconnection_string = \"postgresql+asyncpg://\u003cuser\u003e:\u003cpassword\u003e@\u003chost\u003e:\u003cport\u003e/\u003cdatabase\u003e\"\n\nengine = create_async_engine(connection_string)\n\nasync with engine.connect() as conn:\n\n    subscription = subscribe(con=conn, slot_name=\"realtime_example\")\n\n    async for message in subscription:\n        # Business Logic Goes Here\n        print(message)\n```\n\nwhere example outputs are:\n\n```python\nfrom realtime.message import TransactionMessage, CRUDMessage, Column\n\nTransactionMessage(command=\"COMMIT\", lsn=95)\n# OR\nCRUDMessage(\n    command=\"INSERT\",\n    schema=\"public\",\n    table=\"account\",\n    columns=[\n        Column(column=\"id\", data_type=\"integer\", value=5),\n        Column(column=\"email\", data_type=\"text\", value=\"example@example.com\"),\n    ]\n)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folirice%2Frealtime","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Folirice%2Frealtime","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folirice%2Frealtime/lists"}