AnnexRemote

raw JSON →
1.6.6 verified Fri May 01 auth: no python

A Python library to implement git-annex external special remotes. It provides a base class that handles the protocol between git-annex and the remote, making it easy to develop custom remotes. Current version: 1.6.6. Release cadence: irregular, latest release August 2024.

pip install annexremote
error ModuleNotFoundError: No module named 'annexremote'
cause annexremote is not installed or not in the Python environment.
fix
Run: pip install annexremote
error AttributeError: 'MyRemote' object has no attribute 'listen'
cause The custom remote class does not inherit from AnnexRemote or does not call `super().__init__()`.
fix
Ensure your class inherits from annexremote.AnnexRemote and does not override __init__ without calling super().__init__().
error ImportError: cannot import name 'RemoteError' from 'annexremote.exception'
cause Incorrect import path; RemoteError is exported from annexremote directly.
fix
Use: from annexremote import RemoteError
breaking Python 2 support dropped in v1.6.0. If you are using Python 2, pin to annexremote<1.6.0.
fix Upgrade to Python 3 or pin annexremote<1.6.0
gotcha Initializing the remote with `remote = MyRemote()` does not automatically set up the protocol; you must call `remote.listen()` after instantiation.
fix Always call `.listen()` on the remote object to start communicating with git-annex.
gotcha In `transfer_store` and `transfer_retrieve`, the `progress_callback` should be called with the number of bytes transferred, not the total size. Common mistake: calling `progress_callback(total)` instead of incremental bytes.
fix Use `progress_callback(bytes_transferred)` where bytes_transferred is the cumulative bytes processed so far.

Minimal custom remote that listens for git-annex commands.

import os
from annexremote import AnnexRemote

class MyRemote(AnnexRemote):
    def initremote(self, kwargs):
        pass
    def prepare(self, kwargs):
        pass
    def transfer_store(self, key, path, progress_callback=None):
        pass
    def transfer_retrieve(self, key, path, progress_callback=None):
        pass
    def checkpresent(self, key):
        return False
    def remove(self, key):
        pass

remote = MyRemote()
remote.listen()