{"id":19589371,"url":"https://github.com/motioneye-project/motioneye-client","last_synced_at":"2025-10-07T09:32:01.938Z","repository":{"id":36968856,"uuid":"346239682","full_name":"motioneye-project/motioneye-client","owner":"motioneye-project","description":"Client library for motionEye","archived":false,"fork":false,"pushed_at":"2023-04-28T07:06:33.000Z","size":212,"stargazers_count":32,"open_issues_count":7,"forks_count":2,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-01-20T07:07:52.879Z","etag":null,"topics":["motioneye"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/motioneye-project.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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}},"created_at":"2021-03-10T05:13:49.000Z","updated_at":"2024-10-13T21:29:43.000Z","dependencies_parsed_at":"2024-06-21T02:29:05.254Z","dependency_job_id":null,"html_url":"https://github.com/motioneye-project/motioneye-client","commit_stats":null,"previous_names":["dermotduffy/motioneye-client"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motioneye-project%2Fmotioneye-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motioneye-project%2Fmotioneye-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motioneye-project%2Fmotioneye-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motioneye-project%2Fmotioneye-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/motioneye-project","download_url":"https://codeload.github.com/motioneye-project/motioneye-client/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235614133,"owners_count":19018403,"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":["motioneye"],"created_at":"2024-11-11T08:18:13.053Z","updated_at":"2025-10-07T09:31:56.656Z","avatar_url":"https://github.com/motioneye-project.png","language":"Python","funding_links":["https://www.buymeacoffee.com/dermotdu"],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://github.com/motioneye-project/motioneye-client/blob/main/images/motioneye.png?raw=true\"\n     alt=\"motionEye icon\"\n     width=\"15%\"\n     align=\"right\"\n     style=\"float: right; margin: 10px 0px 20px 20px;\" /\u003e\n\n\u003c!-- Code coverage is always 100% since tests fail otherwise. Static badge avoids use of an external 3rd party data provider --\u003e\n\n[![PyPi](https://img.shields.io/pypi/v/motioneye-client.svg?style=flat-square)](https://pypi.org/project/motioneye-client/)\n[![PyPi](https://img.shields.io/pypi/pyversions/motioneye-client.svg?style=flat-square)](https://pypi.org/project/motioneye-client/)\n[![Build Status](https://img.shields.io/github/actions/workflow/status/motioneye-project/motioneye-client/build.yaml?branch=main)](https://github.com/motioneye-project/motioneye-client/actions/workflows/build.yaml)\n[![Test Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/motioneye-project/motioneye-client/actions/workflows/build.yaml)\n[![License](https://img.shields.io/github/license/motioneye-project/motioneye-client.svg?style=flat-square)](LICENSE)\n[![BuyMeCoffee](https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?style=flat-square)](https://www.buymeacoffee.com/dermotdu)\n\n# motionEye Client\n\nA simple async API client for [motionEye](https://github.com/ccrisan/motioneye).\n\n## Constructor arguments\n\nThe following arguments may be passed to the `MotionEyeClient` constructor:\n\n| Argument              | Type                    | Default                     | Description                         |\n| --------------------- | ----------------------- | --------------------------- | ----------------------------------- |\n| url                   | `str`                   | URL of the motionEye server |\n| admin_username        | `str`                   | admin                       | The motionEye admin username        |\n| admin_password        | `str`                   | \"\"                          | The motionEye admin password        |\n| surveillance_username | `str`                   | user                        | The motionEye surveillance username |\n| surveillance_password | `str`                   | \"\"                          | The motionEye surveillance password |\n| session               | `aiohttp.ClientSession` | None                        | Optional aiohttp session to use     |\n\nThis client needs both `admin` and `surveillance` passwords in order to interact with\nthe API (which generally require the `admin` user), as well as prepare the URLs for\ndata streaming (which require the `surveillance` user).\n\n## Primary Client Methods\n\nAll async calls start with `async_`, and return the JSON response from the server (if any).\n\n### async_client_login\n\nLogin to the motionEye server. Not actually necessary, but useful for verifying credentials.\n### async_client_close\n\nClose the client session. Always returns True.\n\n### async_get_manifest\n\nGet the motionEye server manifest (e.g. server version number).\n\n### async_get_server_config\n\nGet the main motionEye server config.\n\n### async_get_cameras\n\nGet the listing of all cameras.\n\n### async_get_camera\n\nGet the configuration of a single camera. Takes an integer `camera_id` argument.\n\n### async_set_camera\n\nSet the configuration of a single camera. Takes an integer `camera_id` argument, and a\ndictionary of the same format as returned by `async_get_camera`.\n\n### async_action\n\nPerform a motionEye action on a camera. Takes an integer `camera_id` argument and an\naction string.\n\nCommon actions include `snapshot`, `record_start` and `record_stop`. motionEye also\nsupports other user configurable actions which may be called in this manner. See\n[Action Buttons](https://github.com/ccrisan/motioneye/wiki/Action-Buttons) for more details.\n\n### async_get_movies\n\nGet a list of recorded movies for a given `camera_id`. Accepts a `prefix` argument that\ngives a path prefix to list (does not recurse).\n\n### async_get_images\n\nGet a list of saved images for a given `camera_id`. Accepts a `prefix` argument that\ngives a path prefix to list (does not recurse).\n\n## Convenience Methods\n\n### is_camera_streaming\n\nConvenience method to take a camera dictionary (returned by `async_get_camera` or\n`async_get_cameras`) and return True if the camera has video stream enabled.\n\n### get_camera_stream_url\n\nConvenience method to take a camera dictionary (returned by `async_get_camera` or\n`async_get_cameras`) and return the string URL of the streamed content (which can be\nopened separately). This extracts the hostname out of the motionEye URL and attaches the\nstreaming port to it -- depending on the configuration this may not necessarily lead to\nan accessible URL (e.g. in the use of motionEye behind a reverse proxy).\n\nWill raise [MotionEyeClientURLParseError](#MotionEyeClientURLParseError) if the hostname\ncannot be extracted from the motionEye server URL.\n\n### get_camera_snapshot_url\n\nConvenience method to take a camera dictionary (returned by `async_get_camera` or\n`async_get_cameras`) and return the string URL of a single still frame.\n\n### get_movie_url\n\nConvenience method to take a camera id and the path to a saved movie, and return a link\nto playback the movie. Takes a `preview` argument that if `True` returns a URL to a thumbnail.\n\n### get_image_url\n\nConvenience method to take a camera id and the path to a saved image, and return a link\nto that image. Takes a `preview` argument that if `True` returns a URL to a thumbnail.\n\n### is_file_type_image / is_file_type_movie\n\nDetermine if a given file_type `int` (from a web hook callback) represents an image or a movie respectively.\n\n## Context Manager\n\nThe client may be used in as a context manager, which will automatically close the\nsession.\n\n```python\nasync with client.MotionEyeClient(\"http://localhost:8765\", ) as mec:\n    if not mec:\n        return\n    ...\n````\n\n## Exceptions / Errors\n\n### MotionEyeClientError\n\nA generic base class -- all motionEye client exceptions inherit from this.\n\n### MotionEyeClientInvalidAuthError\n\nInvalid authentication detected during a request.\n\n### MotionEyeClientConnectionError\n\nConnected failed to given URL.\n\n\u003ca name=\"MotionEyeClientURLParseError\"\u003e\u003c/a\u003e\n### MotionEyeClientURLParseError\n\nUnable to parse the required URL.\n\n\n### MotionEyeClientPathError\n\nUnable to parse a path.\n\n\n### MotionEyeClientRequestError\n\nA request failed in some other undefined way.\n\n## Simple Example\n\n```python\n#!/usr/bin/env python\n\"\"\"Client test for motionEye.\"\"\"\nimport asyncio\n\nfrom motioneye_client.client import MotionEyeClient\n\n\nasync def query_motioneye_server() -\u003e None:\n    \"\"\"Test the motionEye client.\"\"\"\n    async with MotionEyeClient(\"http://localhost:8765\") as client:\n        if not client:\n            return\n\n        manifest = await client.async_get_manifest()\n        print(f\"Manifest: {manifest}\")\n\n        camera_list = await client.async_get_cameras()\n        print(f\"Cameras: {camera_list}\")\n\n\nasyncio.get_event_loop().run_until_complete(query_motioneye_server())\n```\n\n## Building / Testing\n\nThis library is built using [Poetry](https://python-poetry.org/).\n\nBuilding:\n\n```bash\n$ poetry build\n```\n\nTesting:\n```bash\n$ poetry run pytest\n```\n\n## Updating Dependencies\n\nUpdating dependencies:\n\n```bash\n$ poetry update\n```\n\nExporting to `requirements.txt` and `requirements_dev.txt`:\n\n```bash\n$ poetry export --without-hashes -o requirements.txt\n$ poetry export --without-hashes --dev -o requirements_dev.txt\n```\n\n## Publishing\n\nPublish the package to the [Python Package Index](https://pypi.org/project/motioneye-client/).\n\n```bash\n$ poetry publish\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmotioneye-project%2Fmotioneye-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmotioneye-project%2Fmotioneye-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmotioneye-project%2Fmotioneye-client/lists"}