annexremote


Nameannexremote JSON
Version 1.6.5 PyPI version JSON
download
home_pageNone
Summarygit annex special remotes made easy
upload_time2024-04-13 17:05:09
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseGPL-3.0-only
keywords git-annex remote
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ![Tests](https://github.com/Lykos153/AnnexRemote/actions/workflows/unittests.yml/badge.svg) [![PyPI version](https://badge.fury.io/py/annexremote.svg)](https://badge.fury.io/py/annexremote)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)


# AnnexRemote
Helper module to easily develop special remotes for [git annex](https://git-annex.branchable.com).
AnnexRemote handles all the protocol stuff for you, so you can focus on the remote itself.
It implements the complete [external special remote protocol](https://git-annex.branchable.com/design/external_special_remote_protocol)
and fulfils all specifications regarding whitespaces etc. This is ensured by an excessive test suite.

[Documentation](https://lykos153.github.io/AnnexRemote/annexremote/)

(Also have a look at the [examples](examples) and [git-annex-remote-googledrive](https://github.com/Lykos153/git-annex-remote-googledrive) which is based on AnnexRemote.)

## Getting started
### Prerequisites
You need python3 installed on your system.

### Installing
`pip3 install annexremote`

### Running the tests
If you want to run the tests, copy the content of the `tests` folder to the same location as `annexremote.py`.
Then use a test discovery like [pytest](https://github.com/pytest-dev/pytest) to run them.

### Usage

Import the necessary classes

```python
from annexremote import Master
from annexremote import SpecialRemote
from annexremote import RemoteError
```

Now create your special remote class. It must subtype ``SpecialRemote`` and implement at least the 6 basic methods:

```python
class MyRemote(SpecialRemote):
    def initremote(self):
        # initialize the remote, eg. create the folders
        # raise RemoteError if the remote couldn't be initialized

    def prepare(self):
        # prepare to be used, eg. open TCP connection, authenticate with the server etc.
        # raise RemoteError if not ready to use

    def transfer_store(self, key, filename):
        # store the file in `filename` to a unique location derived from `key`
        # raise RemoteError if the file couldn't be stored

    def transfer_retrieve(self, key, filename):
        # get the file identified by `key` and store it to `filename`
        # raise RemoteError if the file couldn't be retrieved

    def checkpresent(self, key):
        # return True if the key is present in the remote
        # return False if the key is not present
        # raise RemoteError if the presence of the key couldn't be determined, eg. in case of connection error
        
    def remove(self, key):
        # remove the key from the remote
        # raise RemoteError if it couldn't be removed
        # note that removing a not existing key isn't considered an error
```

In your ``main`` function, link your remote to the master class and initialize the protocol:

```python
def main():
    master = Master()
    remote = MyRemote(master)
    master.LinkRemote(remote)
    master.Listen()

if __name__ == "__main__":
    main()
```

Now save your program as ``git-annex-remote-$something`` and make it executable.

``chmod +x git-annex-remote-$something``
(You'll need the sheebang line ``#!/usr/bin/env python3``)

That's it. Now you've created your special remote.

#### Export remotes
Import and subtype `ExportRemote` instead of `SpecialRemote`:

```python
# ...
from annexremote import ExportRemote

class MyRemote(ExportRemote):
    # implement the remote methods just like in the above example and then additionally:
    
    def transferexport_store(self, key, local_file, remote_file):
        # store the file located at `local_file` to `remote_file` on the remote
        # raise RemoteError if the file couldn't be stored

    def transferexport_retrieve(self, key, local_file, remote_file):
        # get the file located at `remote_file` from the remote and store it to `local_file`
        # raise RemoteError if the file couldn't be retrieved

    def checkpresentexport(self, key, remote_file):
        # return True if the file `remote_file` is present in the remote
        # return False if not
        # raise RemoteError if the presence of the file couldn't be determined, eg. in case of connection error

    def removeexport(self, key, remote_file):
        # remove the file in `remote_file` from the remote
        # raise RemoteError if it couldn't be removed
        # note that removing a not existing key isn't considered an error

    def removeexportdirectory(self, remote_directory):
        # remove the directory `remote_directory` from the remote
        # raise RemoteError if it couldn't be removed
        # note that removing a not existing directory isn't considered an error

    def renameexport(self, key, filename, new_filename):
        # move the remote file in `name` to `new_name`
        # raise RemoteError if it couldn't be moved

```

#### Logging
This module includes a StreamHandler to send log records to git annex via the special remote protocol (using DEBUG). You can use it like this:

```python
...
import logging
...

def main():
    master = Master()
    remote = MyRemote(master)
    master.LinkRemote(remote)

    logger = logging.getLogger()
    logger.addHandler(master.LoggingHandler())

    master.Listen()

if __name__ == "__main__":
    main()
```


## License

This project is licensed under GPLv3 - see the [LICENSE](LICENSE) file for details


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "annexremote",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "git-annex, remote",
    "author": null,
    "author_email": "Silvio Ankermann <silvio@booq.org>",
    "download_url": "https://files.pythonhosted.org/packages/ae/a7/103ec87b5400583be13e861bec8fb1a9fdc237016aa372bc46cade987df0/annexremote-1.6.5.tar.gz",
    "platform": null,
    "description": "![Tests](https://github.com/Lykos153/AnnexRemote/actions/workflows/unittests.yml/badge.svg) [![PyPI version](https://badge.fury.io/py/annexremote.svg)](https://badge.fury.io/py/annexremote)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n\n# AnnexRemote\nHelper module to easily develop special remotes for [git annex](https://git-annex.branchable.com).\nAnnexRemote handles all the protocol stuff for you, so you can focus on the remote itself.\nIt implements the complete [external special remote protocol](https://git-annex.branchable.com/design/external_special_remote_protocol)\nand fulfils all specifications regarding whitespaces etc. This is ensured by an excessive test suite.\n\n[Documentation](https://lykos153.github.io/AnnexRemote/annexremote/)\n\n(Also have a look at the [examples](examples) and [git-annex-remote-googledrive](https://github.com/Lykos153/git-annex-remote-googledrive) which is based on AnnexRemote.)\n\n## Getting started\n### Prerequisites\nYou need python3 installed on your system.\n\n### Installing\n`pip3 install annexremote`\n\n### Running the tests\nIf you want to run the tests, copy the content of the `tests` folder to the same location as `annexremote.py`.\nThen use a test discovery like [pytest](https://github.com/pytest-dev/pytest) to run them.\n\n### Usage\n\nImport the necessary classes\n\n```python\nfrom annexremote import Master\nfrom annexremote import SpecialRemote\nfrom annexremote import RemoteError\n```\n\nNow create your special remote class. It must subtype ``SpecialRemote`` and implement at least the 6 basic methods:\n\n```python\nclass MyRemote(SpecialRemote):\n    def initremote(self):\n        # initialize the remote, eg. create the folders\n        # raise RemoteError if the remote couldn't be initialized\n\n    def prepare(self):\n        # prepare to be used, eg. open TCP connection, authenticate with the server etc.\n        # raise RemoteError if not ready to use\n\n    def transfer_store(self, key, filename):\n        # store the file in `filename` to a unique location derived from `key`\n        # raise RemoteError if the file couldn't be stored\n\n    def transfer_retrieve(self, key, filename):\n        # get the file identified by `key` and store it to `filename`\n        # raise RemoteError if the file couldn't be retrieved\n\n    def checkpresent(self, key):\n        # return True if the key is present in the remote\n        # return False if the key is not present\n        # raise RemoteError if the presence of the key couldn't be determined, eg. in case of connection error\n        \n    def remove(self, key):\n        # remove the key from the remote\n        # raise RemoteError if it couldn't be removed\n        # note that removing a not existing key isn't considered an error\n```\n\nIn your ``main`` function, link your remote to the master class and initialize the protocol:\n\n```python\ndef main():\n    master = Master()\n    remote = MyRemote(master)\n    master.LinkRemote(remote)\n    master.Listen()\n\nif __name__ == \"__main__\":\n    main()\n```\n\nNow save your program as ``git-annex-remote-$something`` and make it executable.\n\n``chmod +x git-annex-remote-$something``\n(You'll need the sheebang line ``#!/usr/bin/env python3``)\n\nThat's it. Now you've created your special remote.\n\n#### Export remotes\nImport and subtype `ExportRemote` instead of `SpecialRemote`:\n\n```python\n# ...\nfrom annexremote import ExportRemote\n\nclass MyRemote(ExportRemote):\n    # implement the remote methods just like in the above example and then additionally:\n    \n    def transferexport_store(self, key, local_file, remote_file):\n        # store the file located at `local_file` to `remote_file` on the remote\n        # raise RemoteError if the file couldn't be stored\n\n    def transferexport_retrieve(self, key, local_file, remote_file):\n        # get the file located at `remote_file` from the remote and store it to `local_file`\n        # raise RemoteError if the file couldn't be retrieved\n\n    def checkpresentexport(self, key, remote_file):\n        # return True if the file `remote_file` is present in the remote\n        # return False if not\n        # raise RemoteError if the presence of the file couldn't be determined, eg. in case of connection error\n\n    def removeexport(self, key, remote_file):\n        # remove the file in `remote_file` from the remote\n        # raise RemoteError if it couldn't be removed\n        # note that removing a not existing key isn't considered an error\n\n    def removeexportdirectory(self, remote_directory):\n        # remove the directory `remote_directory` from the remote\n        # raise RemoteError if it couldn't be removed\n        # note that removing a not existing directory isn't considered an error\n\n    def renameexport(self, key, filename, new_filename):\n        # move the remote file in `name` to `new_name`\n        # raise RemoteError if it couldn't be moved\n\n```\n\n#### Logging\nThis module includes a StreamHandler to send log records to git annex via the special remote protocol (using DEBUG). You can use it like this:\n\n```python\n...\nimport logging\n...\n\ndef main():\n    master = Master()\n    remote = MyRemote(master)\n    master.LinkRemote(remote)\n\n    logger = logging.getLogger()\n    logger.addHandler(master.LoggingHandler())\n\n    master.Listen()\n\nif __name__ == \"__main__\":\n    main()\n```\n\n\n## License\n\nThis project is licensed under GPLv3 - see the [LICENSE](LICENSE) file for details\n\n",
    "bugtrack_url": null,
    "license": "GPL-3.0-only",
    "summary": "git annex special remotes made easy",
    "version": "1.6.5",
    "project_urls": {
        "Documentation": "https://lykos153.github.io/AnnexRemote",
        "Source": "https://github.com/Lykos153/AnnexRemote"
    },
    "split_keywords": [
        "git-annex",
        " remote"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a2ea4d730273de09f75f16fa222fb6260900381849bbd70e0209fecf7407c065",
                "md5": "bfc21c187db3e50557238f0d09126573",
                "sha256": "17f6c9278c1c900bdacd11876d9c4caaf82a0172519052a86c6c4d9b829be08c"
            },
            "downloads": -1,
            "filename": "annexremote-1.6.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "bfc21c187db3e50557238f0d09126573",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 25866,
            "upload_time": "2024-04-13T17:05:07",
            "upload_time_iso_8601": "2024-04-13T17:05:07.909159Z",
            "url": "https://files.pythonhosted.org/packages/a2/ea/4d730273de09f75f16fa222fb6260900381849bbd70e0209fecf7407c065/annexremote-1.6.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "aea7103ec87b5400583be13e861bec8fb1a9fdc237016aa372bc46cade987df0",
                "md5": "987241a8daf10d84c964ee4e48aa38da",
                "sha256": "ad0ccdd84a8771ad58922d172ee68b225ece77bf464abe4d24ff91a4896a423e"
            },
            "downloads": -1,
            "filename": "annexremote-1.6.5.tar.gz",
            "has_sig": false,
            "md5_digest": "987241a8daf10d84c964ee4e48aa38da",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 62459,
            "upload_time": "2024-04-13T17:05:09",
            "upload_time_iso_8601": "2024-04-13T17:05:09.654441Z",
            "url": "https://files.pythonhosted.org/packages/ae/a7/103ec87b5400583be13e861bec8fb1a9fdc237016aa372bc46cade987df0/annexremote-1.6.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-13 17:05:09",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Lykos153",
    "github_project": "AnnexRemote",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "annexremote"
}
        
Elapsed time: 0.30213s