weaviate-cli 3.3.0__tar.gz → 3.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- weaviate_cli-3.4.0/.claude/skills/contributing-to-weaviate-cli/SKILL.md +279 -0
- weaviate_cli-3.4.0/.claude/skills/contributing-to-weaviate-cli/references/adding-commands.md +215 -0
- weaviate_cli-3.4.0/.claude/skills/contributing-to-weaviate-cli/references/architecture.md +146 -0
- weaviate_cli-3.4.0/.claude/skills/contributing-to-weaviate-cli/references/code-review.md +141 -0
- weaviate_cli-3.4.0/.claude/skills/contributing-to-weaviate-cli/references/issue-workflow.md +268 -0
- weaviate_cli-3.4.0/.claude/skills/contributing-to-weaviate-cli/references/testing.md +201 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/SKILL.md +423 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/references/backups.md +64 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/references/benchmark.md +86 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/references/cluster.md +91 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/references/collections.md +108 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/references/config-management.md +112 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/references/data.md +71 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/references/rbac.md +112 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/references/search.md +62 -0
- weaviate_cli-3.4.0/.claude/skills/operating-weaviate-cli/references/tenants.md +81 -0
- weaviate_cli-3.4.0/.github/ISSUE_TEMPLATE/bug.yml +86 -0
- weaviate_cli-3.4.0/.github/ISSUE_TEMPLATE/config.yml +1 -0
- weaviate_cli-3.4.0/.github/ISSUE_TEMPLATE/feature.yml +71 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/.github/workflows/main.yaml +4 -4
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/.gitignore +1 -0
- weaviate_cli-3.4.0/CLAUDE.md +51 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/PKG-INFO +2 -2
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/requirements-dev.txt +1 -1
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/setup.cfg +1 -1
- weaviate_cli-3.4.0/test/integration/test_create_data_return_collection.py +178 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/integration/test_data_integration.py +5 -4
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/unittests/test_managers/test_alias_manager.py +93 -0
- weaviate_cli-3.4.0/test/unittests/test_managers/test_backup_manager.py +594 -0
- weaviate_cli-3.4.0/test/unittests/test_managers/test_cluster_manager.py +518 -0
- weaviate_cli-3.4.0/test/unittests/test_managers/test_collection_manager.py +779 -0
- weaviate_cli-3.4.0/test/unittests/test_managers/test_data_manager.py +937 -0
- weaviate_cli-3.4.0/test/unittests/test_managers/test_role_manager.py +206 -0
- weaviate_cli-3.4.0/test/unittests/test_managers/test_tenant_manager.py +854 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/unittests/test_managers/test_user_manager.py +65 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/assign.py +19 -4
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/benchmark.py +6 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/cancel.py +26 -4
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/create.py +224 -22
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/delete.py +109 -21
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/get.py +147 -49
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/query.py +34 -11
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/restore.py +13 -1
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/revoke.py +19 -4
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/update.py +147 -14
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/defaults.py +20 -2
- weaviate_cli-3.4.0/weaviate_cli/managers/alias_manager.py +98 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/backup_manager.py +76 -12
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/benchmark_manager.py +17 -1
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/cluster_manager.py +64 -3
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/collection_manager.py +317 -65
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/data_manager.py +399 -148
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/node_manager.py +96 -5
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/role_manager.py +153 -6
- weaviate_cli-3.4.0/weaviate_cli/managers/shard_manager.py +190 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/tenant_manager.py +231 -118
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/user_manager.py +63 -7
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/utils.py +51 -8
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli.egg-info/PKG-INFO +2 -2
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli.egg-info/SOURCES.txt +25 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli.egg-info/requires.txt +1 -1
- weaviate_cli-3.3.0/test/unittests/test_managers/test_collection_manager.py +0 -200
- weaviate_cli-3.3.0/test/unittests/test_managers/test_data_manager.py +0 -65
- weaviate_cli-3.3.0/weaviate_cli/managers/alias_manager.py +0 -52
- weaviate_cli-3.3.0/weaviate_cli/managers/shard_manager.py +0 -104
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/.github/dependabot.yml +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/.github/workflows/release.yaml +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/.pre-commit-config.yaml +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/CONTRIBUTING.md +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/Dockerfile +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/LICENSE +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/MANIFEST.in +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/Makefile +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/README.md +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/cli.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/publish.md +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/pyproject.toml +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/setup.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/README.md +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/__init__.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/integration/test_auth_integration.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/integration/test_integration.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/unittests/conftest.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/unittests/test_cli.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/unittests/test_defaults.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/unittests/test_managers/test_config_manager.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/unittests/test_managers/test_node_manager.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/unittests/test_managers/test_shard_manager.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/test/unittests/test_utils.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/__init__.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/commands/__init__.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/completion/__init__.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/completion/complete.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/datasets/__init__.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/datasets/movies.json +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/__init__.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/managers/config_manager.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli/types/models.py +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli.egg-info/dependency_links.txt +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli.egg-info/entry_points.txt +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli.egg-info/not-zip-safe +0 -0
- {weaviate_cli-3.3.0 → weaviate_cli-3.4.0}/weaviate_cli.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contributing-to-weaviate-cli
|
|
3
|
+
description: >-
|
|
4
|
+
Develops, tests, and reviews weaviate-cli source code. Use this skill when
|
|
5
|
+
the task involves modifying the weaviate-cli codebase itself. Trigger if
|
|
6
|
+
the request: asks to add a new command or flag to weaviate-cli; needs to
|
|
7
|
+
fix a bug in the CLI source code (weaviate_cli/ Python files); involves
|
|
8
|
+
reviewing a PR that changes weaviate-cli; wants to write or update unit or
|
|
9
|
+
integration tests for the CLI; asks about the Click-based architecture,
|
|
10
|
+
command-to-manager pattern, or defaults system; or the working directory is
|
|
11
|
+
the weaviate-cli repository and Python source files need to be modified.
|
|
12
|
+
Do NOT use for running weaviate-cli commands against a Weaviate cluster —
|
|
13
|
+
use operating-weaviate-cli for that.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Contributing to weaviate-cli
|
|
17
|
+
|
|
18
|
+
Guide for developing, testing, and maintaining the `weaviate-cli` codebase.
|
|
19
|
+
|
|
20
|
+
## Development Setup
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python -m venv .venv
|
|
24
|
+
source .venv/bin/activate
|
|
25
|
+
make install-dev # pip install -r requirements-dev.txt + pre-commit install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Key development commands:
|
|
29
|
+
```bash
|
|
30
|
+
make format # Black formatter on cli.py, weaviate_cli/, test/
|
|
31
|
+
make lint # Black --check (CI-equivalent)
|
|
32
|
+
make test # pytest test/unittests
|
|
33
|
+
make build-all # python -m build + twine check
|
|
34
|
+
make all # format + lint + test + build-all
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Repository Architecture
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
weaviate-cli/
|
|
41
|
+
cli.py # Entry point: Click group, global options, command registration
|
|
42
|
+
weaviate_cli/
|
|
43
|
+
__init__.py # Package version
|
|
44
|
+
defaults.py # Dataclass defaults for all commands
|
|
45
|
+
utils.py # Shared helpers: get_client, pp_objects, parse_permission
|
|
46
|
+
commands/ # Click command definitions (one file per group)
|
|
47
|
+
create.py # create collection, tenants, data, backup, role, user, alias, replication
|
|
48
|
+
get.py # get collection, tenants, shards, backup, role, user, nodes, alias, replication
|
|
49
|
+
update.py # update collection, tenants, shards, data, user, alias
|
|
50
|
+
delete.py # delete collection, tenants, data, role, user, alias, replication
|
|
51
|
+
query.py # query data, replications, sharding-state
|
|
52
|
+
restore.py # restore backup
|
|
53
|
+
cancel.py # cancel backup, replication
|
|
54
|
+
assign.py # assign role, permission
|
|
55
|
+
revoke.py # revoke role, permission
|
|
56
|
+
benchmark.py # benchmark qps
|
|
57
|
+
managers/ # Business logic (one file per domain)
|
|
58
|
+
config_manager.py # ConfigManager: config loading, client creation
|
|
59
|
+
collection_manager.py # CollectionManager: CRUD collections
|
|
60
|
+
tenant_manager.py # TenantManager: CRUD tenants
|
|
61
|
+
data_manager.py # DataManager: ingest/update/delete data
|
|
62
|
+
backup_manager.py # BackupManager: backup/restore operations
|
|
63
|
+
role_manager.py # RoleManager: RBAC role operations
|
|
64
|
+
user_manager.py # UserManager: RBAC user operations
|
|
65
|
+
node_manager.py # NodeManager: node information
|
|
66
|
+
shard_manager.py # ShardManager: shard operations
|
|
67
|
+
cluster_manager.py # ClusterManager: replication operations
|
|
68
|
+
alias_manager.py # AliasManager: alias operations
|
|
69
|
+
benchmark_manager.py # BenchmarkManager: QPS benchmarks
|
|
70
|
+
completion/ # Shell completion helpers
|
|
71
|
+
datasets/ # Built-in datasets (Movies)
|
|
72
|
+
types/ # Type definitions
|
|
73
|
+
test/
|
|
74
|
+
unittests/
|
|
75
|
+
conftest.py # Fixtures: mock_client, mock_config, mock_click_context
|
|
76
|
+
test_cli.py # CliRunner tests for CLI entry point
|
|
77
|
+
test_defaults.py # Defaults dataclass tests
|
|
78
|
+
test_utils.py # Utility function tests
|
|
79
|
+
test_managers/ # Manager unit tests (one per manager)
|
|
80
|
+
integration/
|
|
81
|
+
test_integration.py # Integration tests (requires running cluster)
|
|
82
|
+
test_auth_integration.py # RBAC integration tests (requires cluster + RBAC)
|
|
83
|
+
test_data_integration.py # Data integration tests
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
See [references/architecture.md](references/architecture.md) for detailed class hierarchy and patterns.
|
|
87
|
+
|
|
88
|
+
## Architecture Pattern: Commands -> Managers
|
|
89
|
+
|
|
90
|
+
Every CLI operation follows this pattern:
|
|
91
|
+
|
|
92
|
+
1. **`cli.py`**: Top-level Click group registers command groups
|
|
93
|
+
2. **`commands/<group>.py`**: Click decorators define options, validate input, get client from context, call manager
|
|
94
|
+
3. **`managers/<domain>_manager.py`**: Business logic, Weaviate client calls, output formatting
|
|
95
|
+
4. **`defaults.py`**: Dataclass with default values for each command
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
cli.py (main group)
|
|
99
|
+
-> commands/create.py (create group)
|
|
100
|
+
-> @create.command("collection") (Click decorators + options)
|
|
101
|
+
-> CollectionManager(client).create_collection(...) (business logic)
|
|
102
|
+
-> defaults.py::CreateCollectionDefaults (default values)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The `ConfigManager` is stored in the Click context (`ctx.obj["config"]`). Commands extract the client via `get_client_from_context(ctx)` from `utils.py`.
|
|
106
|
+
|
|
107
|
+
## Defaults System
|
|
108
|
+
|
|
109
|
+
All command defaults live in `weaviate_cli/defaults.py` as dataclasses:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
@dataclass
|
|
113
|
+
class CreateCollectionDefaults:
|
|
114
|
+
collection: str = "Movies"
|
|
115
|
+
replication_factor: int = 3
|
|
116
|
+
vector_index: str = "hnsw"
|
|
117
|
+
multitenant: bool = False
|
|
118
|
+
# ... etc
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Click options reference these: `default=CreateCollectionDefaults.collection`. This keeps defaults centralized and testable.
|
|
122
|
+
|
|
123
|
+
When adding a new command, always create a corresponding defaults dataclass.
|
|
124
|
+
|
|
125
|
+
## Issue Tracking
|
|
126
|
+
|
|
127
|
+
By default, every non-trivial task (new feature, bug fix, improvement) should follow the
|
|
128
|
+
GitHub Issue workflow defined in `references/issue-workflow.md` (including any documented
|
|
129
|
+
exceptions, such as documentation-only or agent/Claude-specific changes). This provides:
|
|
130
|
+
- A record of what was added in each release
|
|
131
|
+
- A link between issues and PRs for code review
|
|
132
|
+
- Visibility into work in progress
|
|
133
|
+
|
|
134
|
+
**Default workflow for non-trivial changes:**
|
|
135
|
+
1. Create issue with `draft` label via `gh issue create --repo weaviate/weaviate-cli`
|
|
136
|
+
2. Plan and implement the change
|
|
137
|
+
3. Create a PR with `Closes #N` in the body
|
|
138
|
+
4. Remove `draft` label when PR is ready for review
|
|
139
|
+
|
|
140
|
+
See [references/issue-workflow.md](references/issue-workflow.md) for full details,
|
|
141
|
+
templates, examples, and the authoritative list of exceptions. If this section ever
|
|
142
|
+
conflicts with that reference, defer to `references/issue-workflow.md`.
|
|
143
|
+
|
|
144
|
+
## Adding a New Command
|
|
145
|
+
|
|
146
|
+
Step-by-step guide: see [references/adding-commands.md](references/adding-commands.md).
|
|
147
|
+
|
|
148
|
+
Summary:
|
|
149
|
+
1. Create a GitHub Issue to track the work (see Issue Tracking above)
|
|
150
|
+
2. Add a defaults dataclass in `defaults.py`
|
|
151
|
+
3. Add Click command in the appropriate `commands/<group>.py`
|
|
152
|
+
4. Add manager method in `managers/<domain>_manager.py`
|
|
153
|
+
5. Add `--json` flag (mandatory for all commands)
|
|
154
|
+
6. Add unit test in `test/unittests/test_managers/`
|
|
155
|
+
7. Update the operating skill documentation
|
|
156
|
+
8. Create a PR linked to the issue
|
|
157
|
+
|
|
158
|
+
## JSON Output Convention
|
|
159
|
+
|
|
160
|
+
Every command **must** support `--json`:
|
|
161
|
+
|
|
162
|
+
**In the Click command:**
|
|
163
|
+
```python
|
|
164
|
+
@click.option("--json", "json_output", is_flag=True, default=False, help="Output in JSON format.")
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Note: The parameter is named `json_output` (not `json`) to avoid shadowing Python's `json` module.
|
|
168
|
+
|
|
169
|
+
**In the manager**, use `print_json_or_text()` from `utils.py`:
|
|
170
|
+
```python
|
|
171
|
+
from weaviate_cli.utils import print_json_or_text
|
|
172
|
+
|
|
173
|
+
print_json_or_text(
|
|
174
|
+
data={"collections": collection_list, "total": len(collection_list)},
|
|
175
|
+
json_output=json_output,
|
|
176
|
+
text_fn=lambda: click.echo(formatted_text),
|
|
177
|
+
)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Success JSON shape:**
|
|
181
|
+
```json
|
|
182
|
+
{"status": "success", "message": "..."}
|
|
183
|
+
```
|
|
184
|
+
or structured data with domain-specific fields.
|
|
185
|
+
|
|
186
|
+
**Error output:** Always `click.echo(f"Error: {e}")` + `sys.exit(1)`.
|
|
187
|
+
|
|
188
|
+
## Testing
|
|
189
|
+
|
|
190
|
+
### Unit Tests
|
|
191
|
+
|
|
192
|
+
Use `CliRunner` for CLI-level tests and `MagicMock` for manager tests:
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
# CLI test (test/unittests/test_cli.py)
|
|
196
|
+
from click.testing import CliRunner
|
|
197
|
+
from cli import main
|
|
198
|
+
|
|
199
|
+
def test_create_collection(cli_runner):
|
|
200
|
+
result = cli_runner.invoke(main, ["create", "collection", "--json"])
|
|
201
|
+
assert result.exit_code == 0
|
|
202
|
+
|
|
203
|
+
# Manager test (test/unittests/test_managers/test_collection_manager.py)
|
|
204
|
+
def test_create_collection(mock_client):
|
|
205
|
+
mock_client.collections.exists.side_effect = [False, True]
|
|
206
|
+
manager = CollectionManager(mock_client)
|
|
207
|
+
manager.create_collection(collection="Test", replication_factor=3)
|
|
208
|
+
mock_client.collections.create.assert_called_once()
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Fixtures in `conftest.py` (shared across all unit tests):
|
|
212
|
+
- `mock_client` -- `MagicMock(spec=weaviate.WeaviateClient)`
|
|
213
|
+
- `mock_config` -- `MagicMock(spec=ConfigManager)`
|
|
214
|
+
- `mock_click_context` -- context with mock config in `ctx.obj`
|
|
215
|
+
|
|
216
|
+
Note: `cli_runner` is defined locally in `test/unittests/test_cli.py`, not in `conftest.py`.
|
|
217
|
+
|
|
218
|
+
### Integration Tests
|
|
219
|
+
|
|
220
|
+
Require a running Weaviate cluster (typically via `weaviate-local-k8s`):
|
|
221
|
+
```bash
|
|
222
|
+
pytest test/integration/test_integration.py
|
|
223
|
+
pytest test/integration/test_auth_integration.py # Requires RBAC-enabled cluster
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
See [references/testing.md](references/testing.md) for full patterns.
|
|
227
|
+
|
|
228
|
+
## CI Pipeline
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
lint-and-format (Black + build check)
|
|
232
|
+
-> unit-tests (Python 3.9-3.13, matrix)
|
|
233
|
+
-> integration-tests (latest Weaviate, weaviate-local-k8s, Python 3.9-3.13)
|
|
234
|
+
-> integration-auth-tests (RBAC-enabled cluster, Python 3.9-3.13)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
- Linting must pass before unit tests run
|
|
238
|
+
- Unit tests must pass before integration tests run
|
|
239
|
+
- Integration tests use `weaviate/weaviate-local-k8s@v2` GitHub Action
|
|
240
|
+
- Auth integration tests create a config with `admin-key` API key
|
|
241
|
+
|
|
242
|
+
## Code Review Checklist
|
|
243
|
+
|
|
244
|
+
1. GitHub Issue exists and is linked to the PR (`Closes #N`)
|
|
245
|
+
2. New command has `--json` support
|
|
246
|
+
3. Defaults dataclass added/updated in `defaults.py`
|
|
247
|
+
4. Unit test covers happy path and error cases
|
|
248
|
+
5. Black formatting passes (`make lint`)
|
|
249
|
+
6. No hardcoded paths or credentials
|
|
250
|
+
7. Error messages follow `Error: <description>` pattern
|
|
251
|
+
8. Client is properly closed in `finally` block
|
|
252
|
+
9. Manager method handles both JSON and text output
|
|
253
|
+
|
|
254
|
+
See [references/code-review.md](references/code-review.md) for detailed checklist.
|
|
255
|
+
|
|
256
|
+
## Maintaining Skills
|
|
257
|
+
|
|
258
|
+
When adding new commands or options to `weaviate-cli`, update the agent skills:
|
|
259
|
+
|
|
260
|
+
1. **Operating skill** (`.claude/skills/operating-weaviate-cli/`):
|
|
261
|
+
- Add the new command to the **Command Reference** section in `SKILL.md`
|
|
262
|
+
- Update or create the relevant reference file in `references/`
|
|
263
|
+
- Update the **Command Groups** table if a new group is added
|
|
264
|
+
- Update **Workflow Dependencies** if the command introduces new dependencies
|
|
265
|
+
|
|
266
|
+
2. **Contributing skill** (`.claude/skills/contributing-to-weaviate-cli/`):
|
|
267
|
+
- Update `references/architecture.md` if new files/modules are added
|
|
268
|
+
- Update `references/adding-commands.md` if patterns change
|
|
269
|
+
- Update `references/testing.md` if test infrastructure changes
|
|
270
|
+
|
|
271
|
+
3. **CLAUDE.md**: Update if development commands or conventions change
|
|
272
|
+
|
|
273
|
+
## References
|
|
274
|
+
|
|
275
|
+
- [references/architecture.md](references/architecture.md) -- File-by-file breakdown, class hierarchy, utils helpers
|
|
276
|
+
- [references/adding-commands.md](references/adding-commands.md) -- Complete worked example for new commands
|
|
277
|
+
- [references/testing.md](references/testing.md) -- Test fixtures, patterns, CI details
|
|
278
|
+
- [references/code-review.md](references/code-review.md) -- PR checklist, common pitfalls, conventions
|
|
279
|
+
- [references/issue-workflow.md](references/issue-workflow.md) -- GitHub Issue creation, tracking, and PR linking
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Adding Commands Reference
|
|
2
|
+
|
|
3
|
+
Complete worked example for adding a new command to weaviate-cli.
|
|
4
|
+
|
|
5
|
+
## Step 1: Add Defaults Dataclass
|
|
6
|
+
|
|
7
|
+
In `weaviate_cli/defaults.py`, add a dataclass with default values:
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
@dataclass
|
|
11
|
+
class CreateWidgetDefaults:
|
|
12
|
+
collection: str = "Movies"
|
|
13
|
+
widget_name: str = "default-widget"
|
|
14
|
+
size: int = 100
|
|
15
|
+
enabled: bool = False
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Step 2: Add Click Command
|
|
19
|
+
|
|
20
|
+
In the appropriate `weaviate_cli/commands/<group>.py` file, add the command:
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from weaviate_cli.defaults import CreateWidgetDefaults
|
|
24
|
+
|
|
25
|
+
@create.command("widget")
|
|
26
|
+
@click.option(
|
|
27
|
+
"--collection",
|
|
28
|
+
default=CreateWidgetDefaults.collection,
|
|
29
|
+
help="The collection to create the widget in.",
|
|
30
|
+
shell_complete=collection_name_complete,
|
|
31
|
+
)
|
|
32
|
+
@click.option(
|
|
33
|
+
"--widget_name",
|
|
34
|
+
default=CreateWidgetDefaults.widget_name,
|
|
35
|
+
help="Name of the widget.",
|
|
36
|
+
)
|
|
37
|
+
@click.option(
|
|
38
|
+
"--size",
|
|
39
|
+
default=CreateWidgetDefaults.size,
|
|
40
|
+
help=f"Widget size (default: {CreateWidgetDefaults.size}).",
|
|
41
|
+
type=int,
|
|
42
|
+
)
|
|
43
|
+
@click.option(
|
|
44
|
+
"--enabled",
|
|
45
|
+
is_flag=True,
|
|
46
|
+
help="Enable the widget (default: False).",
|
|
47
|
+
)
|
|
48
|
+
@click.option(
|
|
49
|
+
"--json", "json_output", is_flag=True, default=False, help="Output in JSON format."
|
|
50
|
+
)
|
|
51
|
+
@click.pass_context
|
|
52
|
+
def create_widget_cli(ctx, collection, widget_name, size, enabled, json_output):
|
|
53
|
+
"""Create a widget in Weaviate."""
|
|
54
|
+
client = None
|
|
55
|
+
try:
|
|
56
|
+
client = get_client_from_context(ctx)
|
|
57
|
+
manager = WidgetManager(client)
|
|
58
|
+
manager.create_widget(
|
|
59
|
+
collection=collection,
|
|
60
|
+
widget_name=widget_name,
|
|
61
|
+
size=size,
|
|
62
|
+
enabled=enabled,
|
|
63
|
+
json_output=json_output,
|
|
64
|
+
)
|
|
65
|
+
except Exception as e:
|
|
66
|
+
click.echo(f"Error: {e}")
|
|
67
|
+
if client:
|
|
68
|
+
client.close()
|
|
69
|
+
sys.exit(1)
|
|
70
|
+
finally:
|
|
71
|
+
if client:
|
|
72
|
+
client.close()
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Key patterns to follow:
|
|
76
|
+
|
|
77
|
+
- **Parameter naming:** `--json` is aliased to `json_output` to avoid shadowing Python's `json` module
|
|
78
|
+
- **Default references:** Always use `CreateWidgetDefaults.field_name`, never hardcode defaults
|
|
79
|
+
- **Client lifecycle:** Get client in try, close in finally, echo error and exit(1) in except
|
|
80
|
+
- **Shell completion:** Use `shell_complete=collection_name_complete` for collection options
|
|
81
|
+
- **Boolean flags:** Use `is_flag=True` for boolean options
|
|
82
|
+
- **Choice options:** Use `type=click.Choice([...])` for constrained values
|
|
83
|
+
- **Help text:** Include default value in help string
|
|
84
|
+
|
|
85
|
+
## Step 3: Add Manager
|
|
86
|
+
|
|
87
|
+
Create `weaviate_cli/managers/widget_manager.py` (or add to an existing manager):
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
import click
|
|
91
|
+
import json
|
|
92
|
+
from weaviate import WeaviateClient
|
|
93
|
+
from weaviate_cli.utils import print_json_or_text
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class WidgetManager:
|
|
97
|
+
def __init__(self, client: WeaviateClient):
|
|
98
|
+
self.client = client
|
|
99
|
+
|
|
100
|
+
def create_widget(
|
|
101
|
+
self,
|
|
102
|
+
collection: str,
|
|
103
|
+
widget_name: str,
|
|
104
|
+
size: int,
|
|
105
|
+
enabled: bool,
|
|
106
|
+
json_output: bool = False,
|
|
107
|
+
):
|
|
108
|
+
# Validation
|
|
109
|
+
if not self.client.collections.exists(collection):
|
|
110
|
+
raise Exception(f"Collection '{collection}' does not exist.")
|
|
111
|
+
|
|
112
|
+
# Business logic
|
|
113
|
+
result = self.client.collections.get(collection).do_something(
|
|
114
|
+
name=widget_name, size=size, enabled=enabled
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Output
|
|
118
|
+
data = {
|
|
119
|
+
"status": "success",
|
|
120
|
+
"message": f"Widget '{widget_name}' created in collection '{collection}'.",
|
|
121
|
+
"widget": {"name": widget_name, "size": size, "enabled": enabled},
|
|
122
|
+
}
|
|
123
|
+
print_json_or_text(
|
|
124
|
+
data=data,
|
|
125
|
+
json_output=json_output,
|
|
126
|
+
text_fn=lambda: click.echo(
|
|
127
|
+
f"Widget '{widget_name}' created successfully in '{collection}'."
|
|
128
|
+
),
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Manager patterns:
|
|
133
|
+
|
|
134
|
+
- Raise exceptions with descriptive messages (caught by command's except block)
|
|
135
|
+
- Use `print_json_or_text()` for dual output support
|
|
136
|
+
- Accept `json_output: bool = False` parameter
|
|
137
|
+
- Don't call `sys.exit()` from managers -- let the command handle it
|
|
138
|
+
|
|
139
|
+
## Step 4: Add Unit Test
|
|
140
|
+
|
|
141
|
+
Create `test/unittests/test_managers/test_widget_manager.py`:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
import pytest
|
|
145
|
+
from unittest.mock import MagicMock
|
|
146
|
+
from weaviate_cli.managers.widget_manager import WidgetManager
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def test_create_widget(mock_client):
|
|
150
|
+
# Setup mock chain
|
|
151
|
+
mock_collections = MagicMock()
|
|
152
|
+
mock_client.collections = mock_collections
|
|
153
|
+
mock_collections.exists.return_value = True
|
|
154
|
+
mock_collection = MagicMock()
|
|
155
|
+
mock_collections.get.return_value = mock_collection
|
|
156
|
+
|
|
157
|
+
manager = WidgetManager(mock_client)
|
|
158
|
+
manager.create_widget(
|
|
159
|
+
collection="TestCollection",
|
|
160
|
+
widget_name="test-widget",
|
|
161
|
+
size=50,
|
|
162
|
+
enabled=True,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
mock_collections.exists.assert_called_once_with("TestCollection")
|
|
166
|
+
mock_collections.get.assert_called_once_with("TestCollection")
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def test_create_widget_collection_not_found(mock_client):
|
|
170
|
+
mock_client.collections.exists.return_value = False
|
|
171
|
+
manager = WidgetManager(mock_client)
|
|
172
|
+
|
|
173
|
+
with pytest.raises(Exception) as exc_info:
|
|
174
|
+
manager.create_widget(
|
|
175
|
+
collection="NonExistent",
|
|
176
|
+
widget_name="test-widget",
|
|
177
|
+
size=50,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
assert "does not exist" in str(exc_info.value)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Test patterns:
|
|
184
|
+
|
|
185
|
+
- Use `mock_client` fixture from `conftest.py`
|
|
186
|
+
- Test happy path: verify correct calls were made
|
|
187
|
+
- Test error path: verify exception raised with correct message
|
|
188
|
+
- Mock chains: `mock_client.collections.get.return_value = mock_collection`
|
|
189
|
+
|
|
190
|
+
## Step 5: Add Import
|
|
191
|
+
|
|
192
|
+
If you created a new manager, import it in the command file:
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
from weaviate_cli.managers.widget_manager import WidgetManager
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Step 6: Update Documentation
|
|
199
|
+
|
|
200
|
+
1. Add the command to `.claude/skills/operating-weaviate-cli/SKILL.md` command reference
|
|
201
|
+
2. Update or create the relevant reference file in `.claude/skills/operating-weaviate-cli/references/`
|
|
202
|
+
3. Update `CLAUDE.md` if the command introduces new patterns
|
|
203
|
+
|
|
204
|
+
## Checklist
|
|
205
|
+
|
|
206
|
+
- [ ] GitHub Issue created on `weaviate/weaviate-cli` with `draft` label
|
|
207
|
+
- [ ] Defaults dataclass in `defaults.py`
|
|
208
|
+
- [ ] Click command with `--json` support
|
|
209
|
+
- [ ] Manager with `print_json_or_text()` output
|
|
210
|
+
- [ ] Unit test (happy path + error path)
|
|
211
|
+
- [ ] Import in command file
|
|
212
|
+
- [ ] Black formatting passes (`make format && make lint`)
|
|
213
|
+
- [ ] Skill documentation updated
|
|
214
|
+
- [ ] PR created with `Closes #N` linking to the issue
|
|
215
|
+
- [ ] `draft` label removed from issue
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Architecture Reference
|
|
2
|
+
|
|
3
|
+
Detailed breakdown of the weaviate-cli codebase structure and patterns.
|
|
4
|
+
|
|
5
|
+
## Entry Point: `cli.py`
|
|
6
|
+
|
|
7
|
+
The CLI entry point defines the top-level Click group with global options (`--config-file`, `--user`, `--version`) and registers all command groups:
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
@click.group()
|
|
11
|
+
@click.option("--config-file", ...)
|
|
12
|
+
@click.option("--user", ...)
|
|
13
|
+
@click.option("--version", is_flag=True, callback=print_version, is_eager=True, ...)
|
|
14
|
+
@click.pass_context
|
|
15
|
+
def main(ctx, config_file, user):
|
|
16
|
+
try:
|
|
17
|
+
ctx.obj = {"config": ConfigManager(config_file, user)}
|
|
18
|
+
except Exception as e:
|
|
19
|
+
click.echo(f"Fatal Error: {e}")
|
|
20
|
+
sys.exit(1)
|
|
21
|
+
|
|
22
|
+
main.add_command(create)
|
|
23
|
+
main.add_command(delete)
|
|
24
|
+
# ... etc
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Key points:
|
|
28
|
+
- `ConfigManager` is created once and stored in `ctx.obj["config"]`
|
|
29
|
+
- Config creation is wrapped in try/except -- uses `"Fatal Error:"` prefix (distinct from the `"Error:"` prefix used in commands)
|
|
30
|
+
- Commands extract the client via `get_client_from_context(ctx)` from `utils.py`
|
|
31
|
+
- The `--version` flag uses an eager callback to print and exit
|
|
32
|
+
|
|
33
|
+
## Command Files: `weaviate_cli/commands/`
|
|
34
|
+
|
|
35
|
+
Each file defines a Click group and its subcommands. Pattern:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
@click.group()
|
|
39
|
+
def create():
|
|
40
|
+
"""Create resources in Weaviate."""
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
@create.command("collection")
|
|
44
|
+
@click.option("--collection", default=CreateCollectionDefaults.collection, ...)
|
|
45
|
+
@click.option("--json", "json_output", is_flag=True, default=False, ...)
|
|
46
|
+
@click.pass_context
|
|
47
|
+
def create_collection_cli(ctx, collection, ..., json_output):
|
|
48
|
+
client = None
|
|
49
|
+
try:
|
|
50
|
+
client = get_client_from_context(ctx)
|
|
51
|
+
manager = CollectionManager(client)
|
|
52
|
+
manager.create_collection(collection=collection, ...)
|
|
53
|
+
except Exception as e:
|
|
54
|
+
click.echo(f"Error: {e}")
|
|
55
|
+
if client:
|
|
56
|
+
client.close()
|
|
57
|
+
sys.exit(1)
|
|
58
|
+
finally:
|
|
59
|
+
if client:
|
|
60
|
+
client.close()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Every command follows this structure:
|
|
64
|
+
1. Click decorators with options referencing defaults
|
|
65
|
+
2. `json_output` parameter (aliased from `--json`)
|
|
66
|
+
3. Try/except/finally with client cleanup
|
|
67
|
+
4. Delegate to manager for business logic
|
|
68
|
+
|
|
69
|
+
## Manager Files: `weaviate_cli/managers/`
|
|
70
|
+
|
|
71
|
+
Managers encapsulate business logic. Each takes a `WeaviateClient` in `__init__`:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
class CollectionManager:
|
|
75
|
+
def __init__(self, client: WeaviateClient):
|
|
76
|
+
self.client = client
|
|
77
|
+
|
|
78
|
+
def create_collection(self, collection, replication_factor, ...):
|
|
79
|
+
if self.client.collections.exists(collection):
|
|
80
|
+
raise Exception(f"Error: Collection '{collection}' already exists...")
|
|
81
|
+
self.client.collections.create(name=collection, ...)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Managers handle:
|
|
85
|
+
- Input validation and error messages
|
|
86
|
+
- Weaviate client API calls
|
|
87
|
+
- Output formatting (JSON vs text via `print_json_or_text`)
|
|
88
|
+
|
|
89
|
+
## ConfigManager: `weaviate_cli/managers/config_manager.py`
|
|
90
|
+
|
|
91
|
+
Handles configuration loading and client creation:
|
|
92
|
+
|
|
93
|
+
- Default config path: `~/.config/weaviate/config.json`
|
|
94
|
+
- If no config file exists and none specified, creates default (localhost) config
|
|
95
|
+
- Supports three connection modes: local, Weaviate Cloud, custom host
|
|
96
|
+
- `get_client()` returns sync client, `get_async_client()` returns async client
|
|
97
|
+
- Handles `SLOW_CONNECTION` env var for doubled timeouts
|
|
98
|
+
- For `auth.type == "user"`, requires `--user` flag to select API key
|
|
99
|
+
|
|
100
|
+
## Defaults: `weaviate_cli/defaults.py`
|
|
101
|
+
|
|
102
|
+
Centralized defaults as dataclasses. One dataclass per command:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
@dataclass
|
|
106
|
+
class CreateCollectionDefaults:
|
|
107
|
+
collection: str = "Movies"
|
|
108
|
+
replication_factor: int = 3
|
|
109
|
+
vector_index: str = "hnsw"
|
|
110
|
+
# ...
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Also contains:
|
|
114
|
+
- `PERMISSION_HELP_STRING` -- Multi-line help text for `-p` flag
|
|
115
|
+
- `QUERY_MAXIMUM_RESULTS` -- Hard limit for query results
|
|
116
|
+
- `MAX_OBJECTS_PER_BATCH` -- Batch size cap
|
|
117
|
+
- `MAX_WORKERS` -- Computed from CPU count (capped at 32)
|
|
118
|
+
|
|
119
|
+
## Utils: `weaviate_cli/utils.py`
|
|
120
|
+
|
|
121
|
+
Shared utility functions:
|
|
122
|
+
|
|
123
|
+
| Function | Purpose |
|
|
124
|
+
|----------|---------|
|
|
125
|
+
| `get_client_from_context(ctx)` | Extract sync client from Click context |
|
|
126
|
+
| `get_async_client_from_context(ctx)` | Extract async client from Click context |
|
|
127
|
+
| `print_json_or_text(data, json_output, text_fn)` | Output JSON or formatted text |
|
|
128
|
+
| `pp_objects(response, properties, json_output)` | Pretty-print query results |
|
|
129
|
+
| `parse_permission(perm)` | Parse permission string to RBAC objects |
|
|
130
|
+
| `older_than_version(client, version)` | Check if Weaviate server is older than given version |
|
|
131
|
+
| `is_version_older_than(version, check_version)` | Compare two semver strings |
|
|
132
|
+
| `get_random_string(length)` | Random string generator |
|
|
133
|
+
|
|
134
|
+
## Completion: `weaviate_cli/completion/`
|
|
135
|
+
|
|
136
|
+
Shell completion helpers for Click options:
|
|
137
|
+
- `collection_name_complete` -- Auto-complete collection names
|
|
138
|
+
- `role_name_complete` -- Auto-complete role names
|
|
139
|
+
|
|
140
|
+
## Types: `weaviate_cli/types/`
|
|
141
|
+
|
|
142
|
+
Type definitions used across the codebase.
|
|
143
|
+
|
|
144
|
+
## Datasets: `weaviate_cli/datasets/`
|
|
145
|
+
|
|
146
|
+
Built-in datasets (Movies) used for non-randomized data ingestion.
|