{"id":15009230,"url":"https://github.com/python-ring-doorbell/python-ring-doorbell","last_synced_at":"2025-05-13T16:12:19.708Z","repository":{"id":37270589,"uuid":"81387888","full_name":"python-ring-doorbell/python-ring-doorbell","owner":"python-ring-doorbell","description":"Python Ring Door Bell is a library written in Python 3 that exposes the Ring.com devices as Python objects.","archived":false,"fork":false,"pushed_at":"2025-01-14T11:45:12.000Z","size":1566,"stargazers_count":610,"open_issues_count":21,"forks_count":181,"subscribers_count":47,"default_branch":"master","last_synced_at":"2025-05-08T14:50:07.022Z","etag":null,"topics":["doorbell","home-automation","python","python27","python3","ring-doorbell"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/python-ring-doorbell.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2017-02-08T23:43:05.000Z","updated_at":"2025-05-06T10:38:11.000Z","dependencies_parsed_at":"2023-12-12T18:23:39.897Z","dependency_job_id":"48a9806e-f86b-410f-b82a-7e8415d4c363","html_url":"https://github.com/python-ring-doorbell/python-ring-doorbell","commit_stats":{"total_commits":365,"total_committers":39,"mean_commits":9.35897435897436,"dds":0.589041095890411,"last_synced_commit":"0d612f6fc6444911e9f2fe8e380a3ccb3de76a26"},"previous_names":["python-ring-doorbell/python-ring-doorbell"],"tags_count":61,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/python-ring-doorbell%2Fpython-ring-doorbell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/python-ring-doorbell%2Fpython-ring-doorbell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/python-ring-doorbell%2Fpython-ring-doorbell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/python-ring-doorbell%2Fpython-ring-doorbell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/python-ring-doorbell","download_url":"https://codeload.github.com/python-ring-doorbell/python-ring-doorbell/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253980057,"owners_count":21994042,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["doorbell","home-automation","python","python27","python3","ring-doorbell"],"created_at":"2024-09-24T19:23:53.210Z","updated_at":"2025-05-13T16:12:19.627Z","avatar_url":"https://github.com/python-ring-doorbell.png","language":"Python","readme":"=====================\nPython Ring Door Bell\n=====================\n\n.. image:: https://badge.fury.io/py/ring-doorbell.svg\n    :alt: PyPI Version\n    :target: https://badge.fury.io/py/ring-doorbell\n\n.. image:: https://github.com/python-ring-doorbell/python-ring-doorbell/actions/workflows/ci.yml/badge.svg?branch=master\n    :alt: Build Status\n    :target: https://github.com/python-ring-doorbell/python-ring-doorbell/actions/workflows/ci.yml?branch=master\n\n.. image:: https://coveralls.io/repos/github/python-ring-doorbell/python-ring-doorbell/badge.svg?branch=master\n    :alt: Coverage\n    :target: https://coveralls.io/github/python-ring-doorbell/python-ring-doorbell?branch=master\n\n.. image:: https://readthedocs.org/projects/python-ring-doorbell/badge/?version=latest\n    :alt: Documentation Status\n    :target: https://python-ring-doorbell.readthedocs.io/?badge=latest\n\n.. image:: https://img.shields.io/pypi/pyversions/ring-doorbell.svg\n    :alt: Py Versions\n    :target: https://pypi.python.org/pypi/ring-doorbell\n\n\nPython Ring Door Bell is a library written for Python that exposes the Ring.com devices as Python objects.\n\nThere is also a command line interface that is work in progress. `Contributors welcome \u003chttps://python-ring-doorbell.readthedocs.io/latest/contributing.html\u003e`_.\n\n*Currently Ring.com does not provide an official API. The results of this project are merely from reverse engineering.*\n\nDocumentation: `http://python-ring-doorbell.readthedocs.io/ \u003chttp://python-ring-doorbell.readthedocs.io/\u003e`_\n\n\nInstallation\n------------\n\n.. code-block:: bash\n\n    # Installing from PyPi\n    $ pip install ring_doorbell\n\n    # Installing latest development\n    $ pip install \\\n        git+https://github.com/python-ring-doorbell/python-ring-doorbell@master\n\n\nUsing the CLI\n-------------\n\nThe CLI is work in progress and currently has the following commands:\n\n1.  Show your devices::\n\n    $ ring-doorbell\n\n    Or::\n\n    $ ring-doorbell show\n\n#.  List your device names (with device kind)::\n\n    $ ring-doorbell list\n\n#.  Either count or download your vidoes or both::\n\n    $ ring-doorbell videos --count --download-all\n\n#.  Enable disable motion detection::\n\n    $ ring-doorbell motion-detection --device-name \"DEVICENAME\" --on\n    $ ring-doorbell motion-detection --device-name \"DEVICENAME\" --off\n\n#.  Listen for push notifications like the ones sent to your phone::\n\n    $ ring-doorbell listen\n\n#.  List your ring groups::\n\n    $ ring-doorbell groups\n\n#.  Show your ding history::\n\n    $ ring-doorbell history --device-name \"Front Door\"\n\n#.  Show your currently active dings::\n\n    $ ring-doorbell dings\n\n#.  See or manage your doorbell in-home chime settings::\n\n    $ ring-doorbell in-home-chime --device-name \"Front Door\"\n    $ ring-doorbell in-home-chime --device-name \"Front Door\" type Mechanical\n    $ ring-doorbell in-home-chime --device-name \"Front Door\" enabled True\n    $ ring-doorbell in-home-chime --device-name \"Front Door\" duration 5\n\n#.  Query a ring api url directly::\n\n    $ ring-doorbell raw-query --url /clients_api/dings/active\n\n#.  Run ``ring-doorbell --help`` or ``ring-doorbell \u003ccommand\u003e --help`` for full options\n\nUsing the API\n-------------\n\nThe API has an async interface and a sync interface.  All api calls starting `async` are\nasynchronous.  This is the preferred method of interacting with the ring api and the sync\nversions are maintained for backwards compatability.\n\n*You cannot call sync api functions from inside a running event loop.*\n\nInitializing your Ring object\n+++++++++++++++++++++++++++++\n\nThis code example is in the `test.py \u003chttps://github.com/python-ring-doorbell/python-ring-doorbell/blob/master/test.py\u003e`_ file.\nFor the deprecated sync example see `test_sync.py \u003chttps://github.com/python-ring-doorbell/python-ring-doorbell/blob/master/test_sync.py\u003e`_.\n\n.. code-block:: python\n\n    import getpass\n    import asyncio\n    import json\n    from pathlib import Path\n\n    from ring_doorbell import Auth, AuthenticationError, Requires2FAError, Ring\n\n    user_agent = \"YourProjectName-1.0\"  # Change this\n    cache_file = Path(user_agent + \".token.cache\")\n\n\n    def token_updated(token):\n        cache_file.write_text(json.dumps(token))\n\n\n    def otp_callback():\n        auth_code = input(\"2FA code: \")\n        return auth_code\n\n\n    async def do_auth():\n        username = input(\"Username: \")\n        password = getpass.getpass(\"Password: \")\n        auth = Auth(user_agent, None, token_updated)\n        try:\n            await auth.async_fetch_token(username, password)\n        except Requires2FAError:\n            await auth.async_fetch_token(username, password, otp_callback())\n        return auth\n\n\n    async def main():\n        if cache_file.is_file():  # auth token is cached\n            auth = Auth(user_agent, json.loads(cache_file.read_text()), token_updated)\n            ring = Ring(auth)\n            try:\n                await ring.async_create_session()  # auth token still valid\n            except AuthenticationError:  # auth token has expired\n                auth = await do_auth()\n        else:\n            auth = await do_auth()  # Get new auth token\n            ring = Ring(auth)\n\n        await ring.async_update_data()\n\n        devices = ring.devices()\n        pprint(devices.devices_combined)\n        await auth.async_close()\n\n\n    if __name__ == \"__main__\":\n        asyncio.run(main())\n\nEvent Listener\n++++++++++++++\n\n.. code-block:: python\n\n    event_listener = RingEventListener(ring, credentials, credentials_updated_callback)\n    event_listener.add_notification_callback(_event_handler(ring).on_event)\n    await event_listener.start()\n\nListing devices linked to your account\n++++++++++++++++++++++++++++++++++++++\n.. code-block:: python\n\n    # All devices\n    devices = ring.devices()\n    {'chimes': [\u003cRingChime: Downstairs\u003e],\n    'doorbots': [\u003cRingDoorBell: Front Door\u003e]}\n\n    # All doorbells\n    doorbells = devices['doorbots']\n    [\u003cRingDoorBell: Front Door\u003e]\n\n    # All chimes\n    chimes = devices['chimes']\n    [\u003cRingChime: Downstairs\u003e]\n\n    # All stickup cams\n    stickup_cams = devices['stickup_cams']\n    [\u003cRingStickUpCam: Driveway\u003e]\n\nPlaying with the attributes and functions\n+++++++++++++++++++++++++++++++++++++++++\n.. code-block:: python\n\n    devices = ring.devices()\n    for dev in list(devices['stickup_cams'] + devices['chimes'] + devices['doorbots']):\n        await dev.async_update_health_data()\n        print('Address:    %s' % dev.address)\n        print('Family:     %s' % dev.family)\n        print('ID:         %s' % dev.id)\n        print('Name:       %s' % dev.name)\n        print('Timezone:   %s' % dev.timezone)\n        print('Wifi Name:  %s' % dev.wifi_name)\n        print('Wifi RSSI:  %s' % dev.wifi_signal_strength)\n\n        # setting dev volume\n        print('Volume:     %s' % dev.volume)\n        await dev.async_set_volume(5)\n        print('Volume:     %s' % dev.volume)\n\n        # play dev test shound\n        if dev.family == 'chimes':\n            await dev.async_test_sound(kind = 'ding')\n            await dev.async_test_sound(kind = 'motion')\n\n        # turn on lights on floodlight cam\n        if dev.family == 'stickup_cams' and dev.lights:\n            await dev.async_lights('on')\n\n\nShowing door bell events\n++++++++++++++++++++++++\n.. code-block:: python\n\n    devices = ring.devices()\n    for doorbell in devices['doorbots']:\n\n        # listing the last 15 events of any kind\n        for event in await doorbell.async_history(limit=15):\n            print('ID:       %s' % event['id'])\n            print('Kind:     %s' % event['kind'])\n            print('Answered: %s' % event['answered'])\n            print('When:     %s' % event['created_at'])\n            print('--' * 50)\n\n        # get a event list only the triggered by motion\n        events = await doorbell.async_history(kind='motion')\n\n\nDownloading the last video triggered by a ding or motion event\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n.. code-block:: python\n\n    devices = ring.devices()\n    doorbell = devices['doorbots'][0]\n    await doorbell.async_recording_download(\n        await doorbell.async_history(limit=100, kind='ding')[0]['id'],\n                         filename='last_ding.mp4',\n                         override=True)\n\n\nDisplaying the last video capture URL\n+++++++++++++++++++++++++++++++++++++\n.. code-block:: python\n\n    print(await doorbell.async_recording_url(await doorbell.async_last_recording_id()))\n    'https://ring-transcoded-videos.s3.amazonaws.com/99999999.mp4?X-Amz-Expires=3600\u0026X-Amz-Date=20170313T232537Z\u0026X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Credential=TOKEN_SECRET/us-east-1/s3/aws4_request\u0026X-Amz-SignedHeaders=host\u0026X-Amz-Signature=secret'\n\nControlling a Light Group\n+++++++++++++++++++++++++\n.. code-block:: python\n\n    groups = ring.groups()\n    group = groups['the-group-you-want']\n\n    print(group.lights)\n    # Prints True if lights are on, False if off\n\n    # Turn on lights indefinitely\n    await group.async_set_lights(True)\n\n    # Turn off lights\n    await group.async_set_lights(False)\n\n    # Turn on lights for 30 seconds\n    await group.async_set_lights(True, 30)\n\nHow to contribute\n-----------------\nSee our `Contributing Page \u003chttps://python-ring-doorbell.readthedocs.io/latest/contributing.html\u003e`_.\n\n\nCredits \u0026\u0026 Thanks\n-----------------\n\n* This project was inspired and based on https://github.com/jeroenmoors/php-ring-api. Many thanks @jeroenmoors.\n* A guy named MadBagger at Prism19 for his initial research (http://www.prism19.com/doorbot/second-pass-and-comm-reversing/)\n* The creators of mitmproxy (https://mitmproxy.org/) great http and https traffic inspector\n* @mfussenegger for his post on mitmproxy and virtualbox https://zignar.net/2015/12/31/sniffing-vbox-traffic-mitmproxy/\n* To the project http://www.android-x86.org/ which allowed me to install Android on KVM.\n* Many thanks to Carles Pina I Estany \u003ccarles@pina.cat\u003e for creating the python-ring-doorbell Debian Package (https://tracker.debian.org/pkg/python-ring-doorbell).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpython-ring-doorbell%2Fpython-ring-doorbell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpython-ring-doorbell%2Fpython-ring-doorbell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpython-ring-doorbell%2Fpython-ring-doorbell/lists"}