{"id":19745638,"url":"https://github.com/spslater/borgapi","last_synced_at":"2025-10-07T07:54:00.720Z","repository":{"id":47455995,"uuid":"366132501","full_name":"spslater/borgapi","owner":"spslater","description":"Wrapper for borgbackup to easily use in code","archived":false,"fork":false,"pushed_at":"2025-01-20T09:45:50.000Z","size":134,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T00:02:20.775Z","etag":null,"topics":["backup","borgbackup","python"],"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/spslater.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-10T17:59:23.000Z","updated_at":"2025-01-20T09:45:51.000Z","dependencies_parsed_at":"2022-08-21T03:00:59.742Z","dependency_job_id":null,"html_url":"https://github.com/spslater/borgapi","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spslater%2Fborgapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spslater%2Fborgapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spslater%2Fborgapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spslater%2Fborgapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spslater","download_url":"https://codeload.github.com/spslater/borgapi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251661115,"owners_count":21623383,"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":["backup","borgbackup","python"],"created_at":"2024-11-12T02:10:40.205Z","updated_at":"2025-10-07T07:53:55.679Z","avatar_url":"https://github.com/spslater.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 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","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspslater%2Fborgapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspslater%2Fborgapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspslater%2Fborgapi/lists"}