{"id":37741686,"url":"https://github.com/pymmcore-plus/pymmdevice","last_synced_at":"2026-01-16T14:10:48.505Z","repository":{"id":229033792,"uuid":"775586297","full_name":"pymmcore-plus/pymmdevice","owner":"pymmcore-plus","description":"Direct Python wrapper for MMDevice API","archived":false,"fork":false,"pushed_at":"2025-03-03T16:26:54.000Z","size":86,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-03T17:31:55.788Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pymmcore-plus.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":"2024-03-21T16:58:46.000Z","updated_at":"2025-01-16T21:10:09.000Z","dependencies_parsed_at":"2024-06-03T18:59:01.181Z","dependency_job_id":"636bf909-9f48-4cef-974c-196b80e40f54","html_url":"https://github.com/pymmcore-plus/pymmdevice","commit_stats":null,"previous_names":["pymmcore-plus/pymmdevice"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pymmcore-plus/pymmdevice","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pymmcore-plus%2Fpymmdevice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pymmcore-plus%2Fpymmdevice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pymmcore-plus%2Fpymmdevice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pymmcore-plus%2Fpymmdevice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pymmcore-plus","download_url":"https://codeload.github.com/pymmcore-plus/pymmdevice/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pymmcore-plus%2Fpymmdevice/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28479169,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: 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":[],"created_at":"2026-01-16T14:10:48.408Z","updated_at":"2026-01-16T14:10:48.497Z","avatar_url":"https://github.com/pymmcore-plus.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pymmdevice\n\n[![License](https://img.shields.io/pypi/l/pymmdevice.svg?color=green)](https://github.com/pymmcore-plus/pymmdevice/raw/main/LICENSE)\n[![PyPI](https://img.shields.io/pypi/v/pymmdevice.svg?color=green)](https://pypi.org/project/pymmdevice)\n[![Python Version](https://img.shields.io/pypi/pyversions/pymmdevice.svg?color=green)](https://python.org)\n[![CI](https://github.com/pymmcore-plus/pymmdevice/actions/workflows/ci.yml/badge.svg)](https://github.com/pymmcore-plus/pymmdevice/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/pymmcore-plus/pymmdevice/branch/main/graph/badge.svg)](https://codecov.io/gh/pymmcore-plus/pymmdevice)\n\nDirect, low-level control of Micro-Manager device adapters in Python.\n\nIf you want to use Micro-Manager devices directly in Python,\nyou should install [`pymmcore`](https://github.com/micro-manager/pymmcore)\n(or [`pymmcore-plus`](https://github.com/pymmcore-plus/pymmcore-plus))\nand instantiate an instance of `pymmcore.CMMCore` (or\n`pymmcore_plus.CMMCorePlus`).  Then, to load a specific device adapter, you\nwould call `loadDevice('MyLabel', 'ModuleName', 'DeviceName')`, and control\nit via the `CMMCore` instance.\n\nThis library is an **experimental** (read: broken) lower-level wrapper around\nthe MMDevice API that gives you *direct* control over device adapter libraries,\nas python wrappers around the various subclasses of\n[`MMCore/Devices/DeviceInstance.h`](https://github.com/micro-manager/mmCoreAndDevices/tree/4441b057e65fed8914c58c33e64123b17eeb6b25/MMCore/Devices).\nThis absolutely opens the possibility of using a device incorrectly, so an\nunderstanding of the MMDevice API is important, and caution is advised.  Here be\ndragons.\n\n## Installation\n\n```sh\npip install git+https://github.com/pymmcore-plus/pymmdevice.git\n```\n\n## Usage\n\n```python\nimport numpy as np\n\nimport pymmdevice as pmmd\n\npm = pmmd.PluginManager()\nlib_dir = (\n    \"/Users/talley/Library/Application Support/pymmcore-plus/mm/Micro-Manager-80d5ac1\"\n)\npm.SetSearchPaths([lib_dir])\nmodule = pm.GetDeviceAdapter(\"DemoCamera\")\nassert \"DCam\" in module.GetAvailableDeviceNames()\n\nwith module.load_camera(\"DCam\", \"MyCamera\") as cam:\n    cam.SetBinning(2)\n    cam.SnapImage()\n    img = cam.GetImageArray()\n    assert isinstance(img, np.ndarray)\n    assert img.shape == (256, 256)\n```\n\n## Development\n\n### Clone the repo and initialize the submodules\n\n```sh\ngit clone https://github.com/pymmcore-plus/pymmdevice.git --recurse-submodules\ncd pymmdevice\n```\n\n### Create a virtual environment\n\nYou can do this however you prefer:\n\n```sh\n# e.g\nmamba create -n pymmdevice python=3.11\nmamba activate pymmdevice\n\n# or\nuv venv\nsource .venv/bin/activate\n```\n\n### Install in editable mode *without* build isolation\n\nMeson-python is used to build the pybind11 extension, and editable installs in\nmeson-python currently require disabling build isolation.  See [meson-python\ndocs](https://meson-python.readthedocs.io/en/latest/how-to-guides/editable-installs.html)\nfor more information.\n\nThis means you must also install the build dependencies manually\nbefore running `pip install -e .`\n\n```sh\npip install meson-python meson ninja pybind11\npip install -e \".[dev]\" --no-build-isolation\n```\n\n#### Source the micro-manager libraries somewhere\n\nThe tests require a compiled `libmmgr_dal_DemoCamera` library from\nMicro-Manager.  I do this by using the build-dev command from\n[pymmcore-plus](https://github.com/pymmcore-plus/pymmcore-plus) (which will have\nbeen installed in the `[dev]` extra above.)\n\n```sh\nmmcore build-dev DemoCamera\n\n# or, to install all libraries from the latest release\nmmcore install\n```\n\nHowever, if you would like to point to a different location, you can set the\n`MM_LIB_DIR` environment variable to the directory containing the compiled\nlibraries. (This directory must minimally contain `libmmgr_dal_DemoCamera`\nfor tests to pass.)\n\n### Run tests\n\nThen you can run the tests:\n\n```sh\npytest\n```\n\nNote that compiled files end up in `build/` directory and are dynamically loaded\nat import time and test time.  This means you can make changes to the pybind11\nwrapper and simply re-run the tests without re-installing.\n\n### Troubleshooting\n\n- `ERROR: File  does not exist.` when building or running `pip install -e .`\n\n    You likely didn't initialize the submodules when you cloned the repo.  Run:\n\n    ```sh\n    git submodule update --init --recursive\n    ```\n\n- General Reset\n\n    After the initial install, one problem that can arise occasionally is a stale\n`build/` directory.  If you encounter errors during the build process, try\nremoving the `build/` directory and re-installing.\n\n    ```sh\n    rm -rf build \u0026\u0026 pip install -e . --no-build-isolation --force-reinstall\n    ```\n\n### Generating type stubs\n\n```sh\npybind11-stubgen pymmdevice._pymmdevice -o src\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpymmcore-plus%2Fpymmdevice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpymmcore-plus%2Fpymmdevice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpymmcore-plus%2Fpymmdevice/lists"}