From 098d5db426c59c802b2770d29e13f72a7786c084 Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Wed, 25 Feb 2026 09:29:06 -0800 Subject: [PATCH 01/12] support incremental backups --- requirements-dev.txt | 3 ++- weaviate_cli/defaults.py | 1 + weaviate_cli/managers/backup_manager.py | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 3646e43..e30eb84 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,5 @@ -weaviate-client>=4.16.7 +# weaviate-client>=4.16.7 +weaviate-client@git+https://github.com/weaviate/weaviate-python-client.git@incremental_backup_support click==8.1.7 twine pytest diff --git a/weaviate_cli/defaults.py b/weaviate_cli/defaults.py index 9e5e3d2..e9d4cb4 100644 --- a/weaviate_cli/defaults.py +++ b/weaviate_cli/defaults.py @@ -98,6 +98,7 @@ class CreateTenantsDefaults: class CreateBackupDefaults: backend: str = "s3" backup_id: str = "test-backup" + incremental_backup_base_id: Optional[str] = None include: Optional[str] = None exclude: Optional[str] = None wait: bool = False diff --git a/weaviate_cli/managers/backup_manager.py b/weaviate_cli/managers/backup_manager.py index 9909277..23b0d4a 100644 --- a/weaviate_cli/managers/backup_manager.py +++ b/weaviate_cli/managers/backup_manager.py @@ -25,6 +25,7 @@ def create_backup( wait: bool = CreateBackupDefaults.wait, cpu_for_backup: int = CreateBackupDefaults.cpu_for_backup, json_output: bool = False, + incremental_backup_base_id: Optional[str] = CreateBackupDefaults.incremental_backup_base_id, ) -> None: version = semver.Version.parse(self.client.get_meta()["version"]) @@ -44,6 +45,7 @@ def create_backup( result = self.client.backup.create( backup_id=backup_id, backend=backend, + incremental_backup_base_id=incremental_backup_base_id, include_collections=include.split(",") if include else None, exclude_collections=exclude.split(",") if exclude else None, wait_for_completion=wait, From 808b89b0fcbafd79c39b4e9bb34b71294cfaed09 Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Mon, 2 Mar 2026 07:45:30 -0800 Subject: [PATCH 02/12] parameter name update --- weaviate_cli/defaults.py | 2 +- weaviate_cli/managers/backup_manager.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/weaviate_cli/defaults.py b/weaviate_cli/defaults.py index e9d4cb4..7cdd044 100644 --- a/weaviate_cli/defaults.py +++ b/weaviate_cli/defaults.py @@ -98,7 +98,7 @@ class CreateTenantsDefaults: class CreateBackupDefaults: backend: str = "s3" backup_id: str = "test-backup" - incremental_backup_base_id: Optional[str] = None + incremental_base_backup_id: Optional[str] = None include: Optional[str] = None exclude: Optional[str] = None wait: bool = False diff --git a/weaviate_cli/managers/backup_manager.py b/weaviate_cli/managers/backup_manager.py index 23b0d4a..d71fc24 100644 --- a/weaviate_cli/managers/backup_manager.py +++ b/weaviate_cli/managers/backup_manager.py @@ -25,7 +25,7 @@ def create_backup( wait: bool = CreateBackupDefaults.wait, cpu_for_backup: int = CreateBackupDefaults.cpu_for_backup, json_output: bool = False, - incremental_backup_base_id: Optional[str] = CreateBackupDefaults.incremental_backup_base_id, + incremental_base_backup_id: Optional[str] = CreateBackupDefaults.incremental_base_backup_id, ) -> None: version = semver.Version.parse(self.client.get_meta()["version"]) @@ -45,7 +45,7 @@ def create_backup( result = self.client.backup.create( backup_id=backup_id, backend=backend, - incremental_backup_base_id=incremental_backup_base_id, + incremental_base_backup_id=incremental_base_backup_id, include_collections=include.split(",") if include else None, exclude_collections=exclude.split(",") if exclude else None, wait_for_completion=wait, From daeabf92e4e221aba3cc8d2929b7081e61f9d05d Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Thu, 5 Mar 2026 14:35:35 -0800 Subject: [PATCH 03/12] use real client version --- requirements-dev.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index e30eb84..1bf5c69 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,4 @@ -# weaviate-client>=4.16.7 -weaviate-client@git+https://github.com/weaviate/weaviate-python-client.git@incremental_backup_support +weaviate-client>=4.20.3 click==8.1.7 twine pytest From 0f8a91634c09704514d4f5f00d58b85380ae066a Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Fri, 6 Mar 2026 08:35:00 -0800 Subject: [PATCH 04/12] add blob data type --- weaviate_cli/managers/collection_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/weaviate_cli/managers/collection_manager.py b/weaviate_cli/managers/collection_manager.py index 92c7555..5458841 100644 --- a/weaviate_cli/managers/collection_manager.py +++ b/weaviate_cli/managers/collection_manager.py @@ -430,6 +430,7 @@ def create_collection( wvc.Property(name="releaseDate", data_type=wvc.DataType.DATE), wvc.Property(name="revenue", data_type=wvc.DataType.NUMBER), wvc.Property(name="status", data_type=wvc.DataType.TEXT), + wvc.Property(name="coverImage", data_type=wvc.DataType.BLOB), ] rds_map = { From 0abbbc75315bbcfa191598d43292a732ab2d14e2 Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Tue, 10 Mar 2026 10:11:21 -0700 Subject: [PATCH 05/12] update claude skills --- .claude/skills/operating-weaviate-cli/SKILL.md | 3 ++- .../operating-weaviate-cli/references/backups.md | 3 +++ weaviate_cli/commands/create.py | 16 +++++++++++++++- weaviate_cli/managers/backup_manager.py | 4 +++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/.claude/skills/operating-weaviate-cli/SKILL.md b/.claude/skills/operating-weaviate-cli/SKILL.md index 569097a..a631c46 100644 --- a/.claude/skills/operating-weaviate-cli/SKILL.md +++ b/.claude/skills/operating-weaviate-cli/SKILL.md @@ -209,13 +209,14 @@ See [references/tenants.md](references/tenants.md). ```bash weaviate-cli create backup --backend s3 --backup_id my-backup --wait --json weaviate-cli create backup --backend s3 --backup_id my-backup --include "Movies,Books" --wait --json +weaviate-cli create backup --backend s3 --backup_id my-incremental --incremental_base_backup_id my-backup --json weaviate-cli get backup --backend s3 --backup_id my-backup --json weaviate-cli get backup --backend s3 --backup_id my-backup --restore --json weaviate-cli restore backup --backend s3 --backup_id my-backup --wait --json weaviate-cli cancel backup --backend s3 --backup_id my-backup --json ``` -Backends: `s3`, `gcs`, `filesystem`. Options: `--include`, `--exclude`, `--wait`, `--cpu_for_backup N`, `--override-alias` +Backends: `s3`, `gcs`, `filesystem`. Options: `--include`, `--exclude`, `--wait`, `--cpu_for_backup N`, `--override-alias`, `--incremental_base_backup_id` See [references/backups.md](references/backups.md). diff --git a/.claude/skills/operating-weaviate-cli/references/backups.md b/.claude/skills/operating-weaviate-cli/references/backups.md index 0cd0b1c..2624f68 100644 --- a/.claude/skills/operating-weaviate-cli/references/backups.md +++ b/.claude/skills/operating-weaviate-cli/references/backups.md @@ -7,6 +7,7 @@ Create, inspect, restore, and cancel Weaviate backups. weaviate-cli create backup --backend s3 --backup_id my-backup --wait --json weaviate-cli create backup --backend s3 --backup_id my-backup --include "Movies,Books" --wait --json weaviate-cli create backup --backend gcs --backup_id my-backup --exclude "TempData" --cpu_for_backup 60 --json +weaviate-cli create backup --backend s3 --backup_id my-incremental-backup --incremental_base_backup_id my-backup --json ``` ## Check Backup Status @@ -40,6 +41,7 @@ weaviate-cli cancel backup --backend s3 --backup_id my-backup --json - `--exclude` -- Comma-separated collections to exclude - `--wait` -- Wait for completion - `--cpu_for_backup` -- CPU percentage for backup (default: 40) +- `--incremental_base_backup_id` -- Backup ID of a previous backup to create an incremental backup from. Requires Weaviate 1.25+. **Restore:** - `--backend`, `--backup_id` -- Same as create @@ -59,3 +61,4 @@ weaviate-cli cancel backup --backend s3 --backup_id my-backup --json - Without `--wait`, the command returns immediately and you must poll with `get backup` - `--cpu_for_backup` controls backup speed vs. resource consumption tradeoff - `--include` and `--exclude` are mutually exclusive +- Incremental backups require Weaviate 1.34+ and can only include collections that were part of the base backup diff --git a/weaviate_cli/commands/create.py b/weaviate_cli/commands/create.py index d47d60b..1ee4442 100644 --- a/weaviate_cli/commands/create.py +++ b/weaviate_cli/commands/create.py @@ -365,12 +365,25 @@ def create_tenants_cli( default=CreateBackupDefaults.cpu_for_backup, help="The percentage of CPU to use for the backup (default: 40). The larger, the faster it will occur, but it will also consume more memory.", ) +@click.option( + "--incremental_base_backup_id", + default=CreateBackupDefaults.incremental_base_backup_id, + help="The backup_id of the previous backup to create an incremental backup from.", +) @click.option( "--json", "json_output", is_flag=True, default=False, help="Output in JSON format." ) @click.pass_context def create_backup_cli( - ctx, backend, backup_id, include, exclude, wait, cpu_for_backup, json_output + ctx, + backend, + backup_id, + include, + exclude, + wait, + cpu_for_backup, + incremental_base_backup_id, + json_output, ): """Create a backup in Weaviate.""" @@ -385,6 +398,7 @@ def create_backup_cli( exclude=exclude, wait=wait, cpu_for_backup=cpu_for_backup, + incremental_base_backup_id=incremental_base_backup_id, json_output=json_output, ) except Exception as e: diff --git a/weaviate_cli/managers/backup_manager.py b/weaviate_cli/managers/backup_manager.py index d71fc24..6e88864 100644 --- a/weaviate_cli/managers/backup_manager.py +++ b/weaviate_cli/managers/backup_manager.py @@ -25,7 +25,9 @@ def create_backup( wait: bool = CreateBackupDefaults.wait, cpu_for_backup: int = CreateBackupDefaults.cpu_for_backup, json_output: bool = False, - incremental_base_backup_id: Optional[str] = CreateBackupDefaults.incremental_base_backup_id, + incremental_base_backup_id: Optional[ + str + ] = CreateBackupDefaults.incremental_base_backup_id, ) -> None: version = semver.Version.parse(self.client.get_meta()["version"]) From 637874c05a3bf42491c771a9a25983c3553e3811 Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Wed, 11 Mar 2026 07:31:37 -0700 Subject: [PATCH 06/12] fix version number --- .claude/skills/operating-weaviate-cli/references/backups.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/operating-weaviate-cli/references/backups.md b/.claude/skills/operating-weaviate-cli/references/backups.md index 2624f68..b6a12cb 100644 --- a/.claude/skills/operating-weaviate-cli/references/backups.md +++ b/.claude/skills/operating-weaviate-cli/references/backups.md @@ -41,7 +41,7 @@ weaviate-cli cancel backup --backend s3 --backup_id my-backup --json - `--exclude` -- Comma-separated collections to exclude - `--wait` -- Wait for completion - `--cpu_for_backup` -- CPU percentage for backup (default: 40) -- `--incremental_base_backup_id` -- Backup ID of a previous backup to create an incremental backup from. Requires Weaviate 1.25+. +- `--incremental_base_backup_id` -- Backup ID of a previous backup to create an incremental backup from. Requires Weaviate 1.34+. **Restore:** - `--backend`, `--backup_id` -- Same as create From 5f563f6104705ed7830011c02e4160eff8c4e8af Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Wed, 11 Mar 2026 09:30:38 -0700 Subject: [PATCH 07/12] add some default blob data --- weaviate_cli/managers/data_manager.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/weaviate_cli/managers/data_manager.py b/weaviate_cli/managers/data_manager.py index ff66e18..058150d 100644 --- a/weaviate_cli/managers/data_manager.py +++ b/weaviate_cli/managers/data_manager.py @@ -1,3 +1,4 @@ +import base64 import importlib.resources as resources import json import math @@ -203,6 +204,9 @@ def generate_movie_object(is_update: bool = False, seed: Optional[int] = None) - # Generate a movie title with proper capitalization title = fake.catch_phrase() + # Generate blob data to simulate an image + cover_image = base64.b64encode(fake.binary(100)).decode("utf-8") + # Prefix for update operations prefix = "updated-" if is_update else "" @@ -222,6 +226,7 @@ def generate_movie_object(is_update: bool = False, seed: Optional[int] = None) - "status": random.choice(STATUSES), "spokenLanguages": spoken_languages, "productionCountries": production_countries, + "coverImage": cover_image, } From 4b9ade762b4b0efd0a300e22993934ee59e2f31a Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Wed, 11 Mar 2026 09:38:11 -0700 Subject: [PATCH 08/12] format --- weaviate_cli/managers/data_manager.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/weaviate_cli/managers/data_manager.py b/weaviate_cli/managers/data_manager.py index 058150d..f5db175 100644 --- a/weaviate_cli/managers/data_manager.py +++ b/weaviate_cli/managers/data_manager.py @@ -205,7 +205,9 @@ def generate_movie_object(is_update: bool = False, seed: Optional[int] = None) - title = fake.catch_phrase() # Generate blob data to simulate an image - cover_image = base64.b64encode(fake.binary(100)).decode("utf-8") + cover_image = base64.b64encode( + fake.binary(100) + ).decode("utf-8") # Prefix for update operations prefix = "updated-" if is_update else "" From 14f9353a15ea76ae714400f3960d09cb5f1cdd98 Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Wed, 11 Mar 2026 09:44:45 -0700 Subject: [PATCH 09/12] lint --- weaviate_cli/managers/data_manager.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/weaviate_cli/managers/data_manager.py b/weaviate_cli/managers/data_manager.py index f5db175..33ed246 100644 --- a/weaviate_cli/managers/data_manager.py +++ b/weaviate_cli/managers/data_manager.py @@ -205,10 +205,8 @@ def generate_movie_object(is_update: bool = False, seed: Optional[int] = None) - title = fake.catch_phrase() # Generate blob data to simulate an image - cover_image = base64.b64encode( - fake.binary(100) - ).decode("utf-8") - + cover_image = base64.b64encode(fake.binary(100)).decode("utf-8") + # Prefix for update operations prefix = "updated-" if is_update else "" From f0002ffe75cf882debc203214bdb020ba60feeb0 Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Wed, 11 Mar 2026 11:56:42 -0700 Subject: [PATCH 10/12] lower blob data for performance --- weaviate_cli/managers/data_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaviate_cli/managers/data_manager.py b/weaviate_cli/managers/data_manager.py index 33ed246..15066ef 100644 --- a/weaviate_cli/managers/data_manager.py +++ b/weaviate_cli/managers/data_manager.py @@ -205,7 +205,7 @@ def generate_movie_object(is_update: bool = False, seed: Optional[int] = None) - title = fake.catch_phrase() # Generate blob data to simulate an image - cover_image = base64.b64encode(fake.binary(100)).decode("utf-8") + cover_image = base64.b64encode(fake.binary(10)).decode("utf-8") # Prefix for update operations prefix = "updated-" if is_update else "" From de323e9cf77cfc07f3ade949758fe13773088dcc Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Thu, 19 Mar 2026 10:43:59 -0700 Subject: [PATCH 11/12] change to coverimage --- weaviate_cli/managers/collection_manager.py | 2 +- weaviate_cli/managers/data_manager.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/weaviate_cli/managers/collection_manager.py b/weaviate_cli/managers/collection_manager.py index 5458841..bb33298 100644 --- a/weaviate_cli/managers/collection_manager.py +++ b/weaviate_cli/managers/collection_manager.py @@ -430,7 +430,7 @@ def create_collection( wvc.Property(name="releaseDate", data_type=wvc.DataType.DATE), wvc.Property(name="revenue", data_type=wvc.DataType.NUMBER), wvc.Property(name="status", data_type=wvc.DataType.TEXT), - wvc.Property(name="coverImage", data_type=wvc.DataType.BLOB), + wvc.Property(name="coverimage", data_type=wvc.DataType.BLOB), ] rds_map = { diff --git a/weaviate_cli/managers/data_manager.py b/weaviate_cli/managers/data_manager.py index 15066ef..33fa6b9 100644 --- a/weaviate_cli/managers/data_manager.py +++ b/weaviate_cli/managers/data_manager.py @@ -226,7 +226,7 @@ def generate_movie_object(is_update: bool = False, seed: Optional[int] = None) - "status": random.choice(STATUSES), "spokenLanguages": spoken_languages, "productionCountries": production_countries, - "coverImage": cover_image, + "coverimage": cover_image, } @@ -1083,6 +1083,8 @@ def __update_data( obj.properties[property] += 1.0 elif isinstance(value, datetime): obj.properties[property] = value + timedelta(days=1) + elif isinstance(value, bytes): + obj.properties[property] = value << 1 cl_collection.data.update( uuid=obj.uuid, From c24ecbd8375fddac78c0ed7e38e0fa48c6dea60e Mon Sep 17 00:00:00 2001 From: DanielJanicek Date: Fri, 20 Mar 2026 08:01:31 -0700 Subject: [PATCH 12/12] prop name update --- weaviate_cli/managers/collection_manager.py | 2 +- weaviate_cli/managers/data_manager.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/weaviate_cli/managers/collection_manager.py b/weaviate_cli/managers/collection_manager.py index bb33298..5458841 100644 --- a/weaviate_cli/managers/collection_manager.py +++ b/weaviate_cli/managers/collection_manager.py @@ -430,7 +430,7 @@ def create_collection( wvc.Property(name="releaseDate", data_type=wvc.DataType.DATE), wvc.Property(name="revenue", data_type=wvc.DataType.NUMBER), wvc.Property(name="status", data_type=wvc.DataType.TEXT), - wvc.Property(name="coverimage", data_type=wvc.DataType.BLOB), + wvc.Property(name="coverImage", data_type=wvc.DataType.BLOB), ] rds_map = { diff --git a/weaviate_cli/managers/data_manager.py b/weaviate_cli/managers/data_manager.py index 33fa6b9..8198803 100644 --- a/weaviate_cli/managers/data_manager.py +++ b/weaviate_cli/managers/data_manager.py @@ -226,7 +226,7 @@ def generate_movie_object(is_update: bool = False, seed: Optional[int] = None) - "status": random.choice(STATUSES), "spokenLanguages": spoken_languages, "productionCountries": production_countries, - "coverimage": cover_image, + "coverImage": cover_image, }