Name | borgapi JSON |
Version |
0.7.0
JSON |
| download |
home_page | None |
Summary | Wrapper for borgbackup to easily use in code |
upload_time | 2025-01-20 09:42:25 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.9 |
license | Copyright 2021 Sean Slater Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
keywords |
borgbackup
backup
api
|
VCS |
 |
bugtrack_url |
|
requirements |
borgbackup
python-dotenv
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# BorgAPI
A helpful wrapper for `borgbackup` to be able to easily use it in python scripts.
**This is not supported use case by the `borg` developers. They only intend for it's use via a CLI.**
Keeping parity with `borg` is the main goal of this api.
## Installation
```
pip install borgapi
```
Requires:
* `borgbackup`: 1.4.0
* `python-dotenv`: 1.0.1
Supports Python 3.9 to 3.13
## Usage
```python
import borgapi
api = borgapi.BorgAPI(defaults={}, options={})
# Initalize new repository
api.init("foo/bar", make_parent_dirs=True)
# Create backup
result = api.create("foo/bar::backup", "/home", "/mnt/baz", json=True)
print(result['archive']["name"]) # backup
print(result["repository"]["location"]) # foo/bar
```
### BorgAPI Init arguments
```python
class BorgAPI(
defaults: dict = None,
options: dict = None,
log_level: str = "warning",
log_json: bool = False,
environ: dict = None,
)
```
* __defaults__: dictionary that has command names as keys and value that is a dict of
command specific optional arguments
```python
{
"init": {
"encryption": "repokey-blake2",
"make_parent_dirs": True,
},
"create": {
"json": True,
},
}
```
* __options__: dictionary that contain the optional arguments (common, exclusion, filesystem, and
archive) used for every command (when valid). Options that aren't valid for a command will get
filterd out. For example, `strip_components` will be passed into the `extract` command but not
the `diff` command.
```python
{
"debug": True,
"log_json": True,
"exclue_from": "baz/spam.txt",
"strip_components": 2,
"sort": True,
"json_lines": True,
}
```
* __log_level__: default log level, can be overriden for a specific comand by passing in another
level as and keyword argument
* __log_json__: log lines written by logger are formatted as json lines, passed into the
logging setup
* __environ__: dictionary that contains environmental variables that should be set before running
any commands. Useful for setting the passphrase or passcommand for the repository or other
settings like that. See [Environment Variables](#Setting-Environment-Variables) section for
how to set environmental variables after initalization or what the defaults are.
```python
{
"BORG_CHECK_I_KNOW_WHAT_I_AM_DOING": "YES",
"BORG_PASSCOMMAND": "cat ~/.borg/password",
}
```
### Setting Environment Variables
You are able to manage the environment variables used by borg to be able to use different settings
for different repositories.
When initialzing the `BorgAPI` object, you can include a dictionary with the `environ` argument.
The following are the defaults that BorgAPI will always load so that user input does not hold up
the app from progressing.
```ini
BORG_EXIT_CODES=modern,
BORG_PASSPHRASE="",
BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=no,
BORG_RELOCATED_REPO_ACCESS_IS_OK=no,
BORG_CHECK_I_KNOW_WHAT_I_AM_DOING=NO,
BORG_DELETE_I_KNOW_WHAT_I_AM_DOING=NO,
```
There are 3 ways you can set the variables after initialization:
1. `filename`: Path to a file that contains the variables and their values. See the
[python-dotenv README](https://github.com/theskumar/python-dotenv/blob/master/README.md#file-format)
for more information.
2. `dictionary`: Dictionary that contains the variable names as keys with their corresponding
values set.
3. `**kwargs`: Argument names are the variable names and the values are what will be set.
```python
api.set_environ(filename="foo/bar/.env")
api.set_environ(dictionary={"FOO":"BAR", "SPAM":False})
api.set_environ(FOO="BAR", SPAM=False)
```
Only one value will be used if multiple set, `filename` has highest precedence,
followed by `dictionary`, and fallback to `**kwargs`.
If no values are given for any of the three things (ie. calling with no arguments), then the
default behavior for `load_dotenv` from [python-dotenv](https://github.com/theskumar/python-dotenv)
will be used, which is searching for a ".env" file somewhere above in the current file path.
[Environment Variables](https://borgbackup.readthedocs.io/en/stable/usage/general.html#environment-variables)
used by `borgbackup`.
### Removing Environment Variables
If you want to unset a variable so it doesn't get used for another command you can use the
`unset_environ` method. It'll remove any variables passed in from the current environment.
If no variables are passed in, it'll remove the variables set from the last call to `set_environ`.
```python
# Enironment = {}
api.set_environ(dictionary={"FOO":"BAR", "SPAM":False})
# Enironment = {"FOO": "BAR", "SPAM": "False"}
api.unset_environ("FOO")
# Enironment = {"SPAM": "False"}
api.set_environ(BAZ="HAM")
# Enironment = {"SPAM": "False", "BAZ": "HAM"}
api.unset_environ("OTHER")
# Enironment = {"SPAM": "False", "BAZ": "HAM"}
api.unset_environ()
# Enironment = {"SPAM": "False"}
```
## Borg Commands
When using a borg command any of the arguments can be set as keyword arguments.
The argument names are the long option names with dashes turned into underscores.
So the `--storage-quota` argument in `init` gets turned into the keyword argument `storage_quota`.
```python
api.init(
repository="foor/bar",
encryption="repokey",
append_only=True,
storage_quota="5G",
make_parent_dirs=True,
debug=True,
log_json=True,
)
diff_args = {
sort: True,
json_lines: True,
debug: True,
exclude_from: "./exclude_patterns.txt",
}
api.diff(
"foo/bar::tuesday",
"friday",
"foo/bar",
"/baz",
**diff_args,
)
```
### Available Borg Commands
* init
* create
* extract
* check
* rename
* list
* diff
* delete
* prune
* compact
* info
* mount
* umount
* key change-passphrase (key_change_passphrase)
* key export (key_export)
* key import (key_import)
* upgrade
* recreate
* immport-tar (immport_tar)
* export-tar (export_tar)
* serve
* config
* with-lock (with_lock)
* break-lock (break_lock)
* benchmark crud (benchmark_crud)
### Command Quirks
Things that were changed from the way the default borg commands work to make things a bit
more manageable.
* __init__
* `encryption` is an optional argument that defaults to `repokey`
* __config__
* `borg config` can only change one key at a time
* `*changes` can either be:
* `NAME` to get the current value of the key
* `(NAME, VALUE)` which will change they key
* Any single string `NAME` values passed to `*change` will be returned as a list with their
values in the order they were passed, tuple changes will not appear in that list
### Capturing Output
`borg` commands display information different depending on what is asked for.
For example, `create` with the `--list` option writes the file list to the logger.
When the `--log-json` common flag is included it writes it to stderr. The `--stats`
option writes to the logger, like the `--list` option does, but when `--json` is used,
which outputs the stats info as a json object, it gets written to stdout.
If either `json` or `log_json` is set, it'll try to convert the tuple output to json.
If it is unable and there is output that is captured it'll return the plaintext value.
If no output is captured, it returns `None` if expecting a string or `{}` (an empty
dictionary) if expection some kind of JSON output.
If multiple outputs are requested at the same time (like `--stats` and `--list`) the command
will return a dictionary with aptly named keys (`--list` key is "list"). If only one output
is requested than the bare value will be returned, not in a dictionary.
#### Command Returns
Commands not listed return no output (None)
- create
- list: `--list`, `--log-json`
- stats: `--stats`, `--json`
- extract
- list: `--list`, `--log-json`
- extract: `--stdout`
- list:
- list: always returns bare value
- `--log-json`, `--json`, `--json-lines`
- diff:
- diff: always returns bare value
- `--log-json`, `--json-lines`
- delete:
- stats: always returns bare value
- `--stats`
- prune:
- list: `--list`, `--log-json`
- stats: `--stats`, `--log-json`
- compact:
- returns bare value, when verbose or info is set
- verbose: `--verbose`, `-v`
- info: `--info`
- info
- always returns bare value
- recreate:
- list: `--list`, `--log-json`
- stats: `--stats`
- import tar
- list: `--list`
- stats: `--stats`, `--json`
- export tar
- list: `--list`, `--log-json`
- tar: filename == "-"
- config
- list: `--list`, `--log-json`
- changes: single values passed into `*changes`
- benchmark crud
- always returns bare value
## Roadmap
- Start work on Borg's beta branch again and keeping up with those
## Links
* [PyPi Project](https://pypi.org/project/borgapi)
* [Github](https://github.com/spslater/borgapi)
## Contributing
Help is greatly appreciated. First check if there are any issues open that relate to what you want
to help with. Also feel free to make a pull request with changes / fixes you make.
## License
[MIT License](https://opensource.org/licenses/MIT)
Raw data
{
"_id": null,
"home_page": null,
"name": "borgapi",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "borgbackup, backup, api",
"author": null,
"author_email": "Sean Slater <seanslater@whatno.io>",
"download_url": "https://files.pythonhosted.org/packages/af/0a/42d596a9bb855565be08f1b86e64e6495f0a6a19ca177bb77c925a84d536/borgapi-0.7.0.tar.gz",
"platform": null,
"description": "# BorgAPI\n\nA helpful wrapper for `borgbackup` to be able to easily use it in python scripts.\n\n**This is not supported use case by the `borg` developers. They only intend for it's use via a CLI.**\nKeeping parity with `borg` is the main goal of this api.\n\n## Installation\n```\npip install borgapi\n```\n\nRequires:\n* `borgbackup`: 1.4.0\n* `python-dotenv`: 1.0.1\n\nSupports Python 3.9 to 3.13\n\n## Usage\n```python\nimport borgapi\n\napi = borgapi.BorgAPI(defaults={}, options={})\n\n# Initalize new repository\napi.init(\"foo/bar\", make_parent_dirs=True)\n\n# Create backup \nresult = api.create(\"foo/bar::backup\", \"/home\", \"/mnt/baz\", json=True)\nprint(result['archive'][\"name\"]) # backup\nprint(result[\"repository\"][\"location\"]) # foo/bar\n```\n\n### BorgAPI Init arguments\n```python\nclass BorgAPI(\n defaults: dict = None,\n options: dict = None,\n log_level: str = \"warning\",\n log_json: bool = False,\n environ: dict = None,\n)\n```\n* __defaults__: dictionary that has command names as keys and value that is a dict of\n command specific optional arguments\n```python\n{\n \"init\": {\n \"encryption\": \"repokey-blake2\",\n \"make_parent_dirs\": True,\n },\n \"create\": {\n \"json\": True,\n },\n}\n```\n* __options__: dictionary that contain the optional arguments (common, exclusion, filesystem, and\n archive) used for every command (when valid). Options that aren't valid for a command will get\n filterd out. For example, `strip_components` will be passed into the `extract` command but not\n the `diff` command.\n```python\n{\n \"debug\": True,\n \"log_json\": True,\n \"exclue_from\": \"baz/spam.txt\",\n \"strip_components\": 2,\n \"sort\": True,\n \"json_lines\": True,\n}\n```\n* __log_level__: default log level, can be overriden for a specific comand by passing in another\n level as and keyword argument\n* __log_json__: log lines written by logger are formatted as json lines, passed into the\n logging setup\n* __environ__: dictionary that contains environmental variables that should be set before running\n any commands. Useful for setting the passphrase or passcommand for the repository or other\n settings like that. See [Environment Variables](#Setting-Environment-Variables) section for\n how to set environmental variables after initalization or what the defaults are.\n```python\n{\n \"BORG_CHECK_I_KNOW_WHAT_I_AM_DOING\": \"YES\",\n \"BORG_PASSCOMMAND\": \"cat ~/.borg/password\",\n}\n```\n\n### Setting Environment Variables\nYou are able to manage the environment variables used by borg to be able to use different settings\nfor different repositories.\n\nWhen initialzing the `BorgAPI` object, you can include a dictionary with the `environ` argument.\n\nThe following are the defaults that BorgAPI will always load so that user input does not hold up\nthe app from progressing.\n```ini\nBORG_EXIT_CODES=modern,\nBORG_PASSPHRASE=\"\",\nBORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=no,\nBORG_RELOCATED_REPO_ACCESS_IS_OK=no,\nBORG_CHECK_I_KNOW_WHAT_I_AM_DOING=NO,\nBORG_DELETE_I_KNOW_WHAT_I_AM_DOING=NO,\n```\n\nThere are 3 ways you can set the variables after initialization:\n1. `filename`: Path to a file that contains the variables and their values. See the\n [python-dotenv README](https://github.com/theskumar/python-dotenv/blob/master/README.md#file-format)\n for more information.\n2. `dictionary`: Dictionary that contains the variable names as keys with their corresponding\n values set.\n3. `**kwargs`: Argument names are the variable names and the values are what will be set.\n\n```python\napi.set_environ(filename=\"foo/bar/.env\")\napi.set_environ(dictionary={\"FOO\":\"BAR\", \"SPAM\":False})\napi.set_environ(FOO=\"BAR\", SPAM=False)\n```\nOnly one value will be used if multiple set, `filename` has highest precedence,\nfollowed by `dictionary`, and fallback to `**kwargs`.\n\nIf no values are given for any of the three things (ie. calling with no arguments), then the\ndefault behavior for `load_dotenv` from [python-dotenv](https://github.com/theskumar/python-dotenv)\nwill be used, which is searching for a \".env\" file somewhere above in the current file path.\n\n[Environment Variables](https://borgbackup.readthedocs.io/en/stable/usage/general.html#environment-variables)\nused by `borgbackup`.\n\n### Removing Environment Variables\nIf you want to unset a variable so it doesn't get used for another command you can use the\n`unset_environ` method. It'll remove any variables passed in from the current environment.\nIf no variables are passed in, it'll remove the variables set from the last call to `set_environ`.\n\n```python\n# Enironment = {}\napi.set_environ(dictionary={\"FOO\":\"BAR\", \"SPAM\":False})\n# Enironment = {\"FOO\": \"BAR\", \"SPAM\": \"False\"}\napi.unset_environ(\"FOO\")\n# Enironment = {\"SPAM\": \"False\"}\napi.set_environ(BAZ=\"HAM\")\n# Enironment = {\"SPAM\": \"False\", \"BAZ\": \"HAM\"}\napi.unset_environ(\"OTHER\")\n# Enironment = {\"SPAM\": \"False\", \"BAZ\": \"HAM\"}\napi.unset_environ()\n# Enironment = {\"SPAM\": \"False\"}\n```\n\n## Borg Commands\nWhen using a borg command any of the arguments can be set as keyword arguments.\nThe argument names are the long option names with dashes turned into underscores.\nSo the `--storage-quota` argument in `init` gets turned into the keyword argument `storage_quota`.\n\n```python\napi.init(\n repository=\"foor/bar\",\n encryption=\"repokey\",\n append_only=True,\n storage_quota=\"5G\",\n make_parent_dirs=True,\n debug=True,\n log_json=True,\n)\n\ndiff_args = {\n sort: True,\n json_lines: True,\n debug: True,\n exclude_from: \"./exclude_patterns.txt\",\n}\n\napi.diff(\n \"foo/bar::tuesday\",\n \"friday\",\n \"foo/bar\",\n \"/baz\",\n **diff_args,\n)\n```\n\n### Available Borg Commands\n* init\n* create\n* extract\n* check\n* rename\n* list\n* diff\n* delete\n* prune\n* compact\n* info\n* mount\n* umount\n* key change-passphrase (key_change_passphrase)\n* key export (key_export)\n* key import (key_import)\n* upgrade\n* recreate\n* immport-tar (immport_tar)\n* export-tar (export_tar)\n* serve\n* config\n* with-lock (with_lock)\n* break-lock (break_lock)\n* benchmark crud (benchmark_crud)\n\n### Command Quirks\nThings that were changed from the way the default borg commands work to make things a bit\nmore manageable.\n\n* __init__\n * `encryption` is an optional argument that defaults to `repokey`\n* __config__\n * `borg config` can only change one key at a time\n * `*changes` can either be:\n * `NAME` to get the current value of the key\n * `(NAME, VALUE)` which will change they key\n * Any single string `NAME` values passed to `*change` will be returned as a list with their\n values in the order they were passed, tuple changes will not appear in that list\n\n### Capturing Output\n`borg` commands display information different depending on what is asked for.\nFor example, `create` with the `--list` option writes the file list to the logger.\nWhen the `--log-json` common flag is included it writes it to stderr. The `--stats`\noption writes to the logger, like the `--list` option does, but when `--json` is used,\nwhich outputs the stats info as a json object, it gets written to stdout.\n\nIf either `json` or `log_json` is set, it'll try to convert the tuple output to json.\nIf it is unable and there is output that is captured it'll return the plaintext value.\nIf no output is captured, it returns `None` if expecting a string or `{}` (an empty\ndictionary) if expection some kind of JSON output.\n\nIf multiple outputs are requested at the same time (like `--stats` and `--list`) the command\nwill return a dictionary with aptly named keys (`--list` key is \"list\"). If only one output\nis requested than the bare value will be returned, not in a dictionary.\n\n#### Command Returns\nCommands not listed return no output (None)\n- create\n - list: `--list`, `--log-json`\n - stats: `--stats`, `--json`\n- extract\n - list: `--list`, `--log-json`\n - extract: `--stdout`\n- list:\n - list: always returns bare value\n - `--log-json`, `--json`, `--json-lines`\n- diff:\n - diff: always returns bare value\n - `--log-json`, `--json-lines`\n- delete:\n - stats: always returns bare value\n - `--stats`\n- prune:\n - list: `--list`, `--log-json`\n - stats: `--stats`, `--log-json`\n- compact:\n - returns bare value, when verbose or info is set\n - verbose: `--verbose`, `-v`\n - info: `--info`\n- info\n - always returns bare value\n- recreate:\n - list: `--list`, `--log-json`\n - stats: `--stats`\n- import tar\n - list: `--list`\n - stats: `--stats`, `--json`\n- export tar\n - list: `--list`, `--log-json`\n - tar: filename == \"-\"\n- config\n - list: `--list`, `--log-json`\n - changes: single values passed into `*changes`\n- benchmark crud\n - always returns bare value\n\n## Roadmap\n- Start work on Borg's beta branch again and keeping up with those\n\n## Links\n* [PyPi Project](https://pypi.org/project/borgapi)\n* [Github](https://github.com/spslater/borgapi)\n\n## Contributing\nHelp is greatly appreciated. First check if there are any issues open that relate to what you want\nto help with. Also feel free to make a pull request with changes / fixes you make.\n\n## License\n[MIT License](https://opensource.org/licenses/MIT)\n",
"bugtrack_url": null,
"license": "Copyright 2021 Sean Slater Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
"summary": "Wrapper for borgbackup to easily use in code",
"version": "0.7.0",
"project_urls": {
"changelog": "https://github.com/spslater/borgapi/blob/master/CHANGELOG.md",
"documentation": "https://github.com/spslater/borgapi/blob/master/README.md",
"homepage": "https://github.com/spslater/borgapi",
"issues": "https://github.com/spslater/borgapi/issues",
"repository": "https://github.com/spslater/borgapi.git"
},
"split_keywords": [
"borgbackup",
" backup",
" api"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e0d596618359bcab77e11245fa63f38498a9a38919f011b97deddcc7d76df0f7",
"md5": "640bc2f73e6bd46a3bb27ae45be89fa2",
"sha256": "5af3e2249e0ab2f5991015269164b1fa17081b9dfbf2c9a2b4e0cd7c829c3423"
},
"downloads": -1,
"filename": "borgapi-0.7.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "640bc2f73e6bd46a3bb27ae45be89fa2",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 6222,
"upload_time": "2025-01-20T09:42:24",
"upload_time_iso_8601": "2025-01-20T09:42:24.063721Z",
"url": "https://files.pythonhosted.org/packages/e0/d5/96618359bcab77e11245fa63f38498a9a38919f011b97deddcc7d76df0f7/borgapi-0.7.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "af0a42d596a9bb855565be08f1b86e64e6495f0a6a19ca177bb77c925a84d536",
"md5": "5227fb145cfd7edd936d7e4b9d2d19f5",
"sha256": "de1c0fc1e08720769572b0ebbe847c61217ab74eb8e46f837d3030a707fe64d9"
},
"downloads": -1,
"filename": "borgapi-0.7.0.tar.gz",
"has_sig": false,
"md5_digest": "5227fb145cfd7edd936d7e4b9d2d19f5",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 7202,
"upload_time": "2025-01-20T09:42:25",
"upload_time_iso_8601": "2025-01-20T09:42:25.054273Z",
"url": "https://files.pythonhosted.org/packages/af/0a/42d596a9bb855565be08f1b86e64e6495f0a6a19ca177bb77c925a84d536/borgapi-0.7.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-20 09:42:25",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "spslater",
"github_project": "borgapi",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "borgbackup",
"specs": [
[
"~=",
"1.4.0"
]
]
},
{
"name": "python-dotenv",
"specs": [
[
"~=",
"1.0.0"
]
]
}
],
"lcname": "borgapi"
}