Skip to content

feat: add the searchlist and documents commands - #42

Merged
marevol merged 3 commits into
feat/add-general-plugin-storage-commandsfrom
feat/add-searchlist-documents-commands
Oct 16, 2026
Merged

marevol merged 3 commits into
feat/add-general-plugin-storage-commandsfrom
feat/add-searchlist-documents-commands

Conversation

@marevol

@marevol marevol commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds two commands for admin APIs fessctl did not wrap yet.

  • fessctl searchlist (/api/admin/searchlist): search, get, create, update, delete, delete-by-query (asks for confirmation unless --yes).
  • fessctl documents bulk (/api/admin/documents/bulk): index many documents from a file or stdin (-); the input may be a JSON array, {"documents": [...]} or NDJSON.

Notes on the API shape, all taken from the Fess source and checked live:

  • Documents are addressed by doc_id; the index _id (reported by bulk) is a different value.
  • The server validates url, title, role and boost on every create and update request, even though update merges into the stored document. update therefore fetches the document first and sends those four back unchanged together with the requested changes. Plain PUT semantics would otherwise force the caller to resend them.
  • search pages with --start (0-based offset) and --size; this API's SearchBody has no page. The server caps size at 100.
  • delete-by-query binds its query from a JSON body on a DELETE request, so send_request now sends a body on DELETE when json_data is given (other DELETE calls are unchanged).
  • Bulk partial failures (status 9) print every item and exit with that status.

Versions

Both APIs exist in Fess 14.19.2, 15.6.1, 15.7.0, 15.8.0 and 15.9.0. 14.x uses PUT for create and POST for edit and bulk; send_request already maps that (bulk goes through Action.EDIT). The request bodies are identical in all versions. Behaviour differences: 15.9.0 reports "not found" when delete matches nothing (earlier versions answer success); 15.8.0+ refuses content changes of chunked documents.

Verified live

Against Fess 15.9.0 (OpenSearch 3.9.0), by CLI: create (incl. validation errors, labels, extra fields), search (query, size, start, sort, lang, no-match, bad sort, offset beyond window), get (text/json/yaml, not found), update (title/boost/role/label/url moves the _id without duplicates, missing doc, no changes, bad value, document without a title), delete (found, unknown id), delete-by-query (confirmation declined/accepted, --yes, no match, blank query), bulk (array, wrapper, NDJSON, stdin, partial failure with exit code 9, validation failure, empty, unreadable input).

The new integration tests (13) were run against live stacks of 14.19.2, 15.6.1, 15.7.0, 15.8.0 and 15.9.0 through a throwaway conftest that points at those stacks (the repository fixture starts fixed-name containers): 12 passed and 1 skipped (the 15.9-only delete-not-found check) on each of the four older versions, 13 passed on 15.9.0. They use unique tokens and remove everything they create (delete-by-query plus a poll until the index refresh shows zero hits).

uv run pytest tests/unit: 208 passed.

Not verified

  • The full tests/commands suite through the repository compose fixture (to be run with the multi-version suite).
  • Chunked documents (content-chunk pipeline) and role-restricted searching were not exercised.
  • Very large bulk files (a single request with the client's 5 second timeout).

Stacked PRs (merge from the bottom; each PR's base is the branch below it, so no conflicts remain):
main ← #45 theme timeout (+ CI runs for stacked PRs) ← #46 typer ← #43 ops commands ← #44 dict ← #41 general/plugin/storage ← #42 searchlist/documents.
After a PR is squash-merged GitHub retargets the next one to main.

searchlist wraps the admin document browser API (/api/admin/searchlist):
search, get, create, update, delete and delete-by-query (confirms unless
--yes). update reads the stored document first and sends back the url,
title, role and boost the server requires on every update.

documents bulk wraps /api/admin/documents/bulk and reads a JSON array,
{"documents": [...]} or NDJSON from a file or stdin. A partial failure
prints every item and exits with the server status.

send_request now passes a JSON body on DELETE (delete-by-query binds its
query from the body). Both APIs exist in Fess 14.19.2 through 15.9.0.
…-searchlist-documents-commands

# Conflicts:
#	skills/fessctl/SKILL.md
#	src/fessctl/api/client.py
#	src/fessctl/cli.py
@marevol
marevol added this pull request to stack #47 October 16, 2026 13:50
@marevol marevol added this to the 0.4.0 milestone Oct 16, 2026
@marevol marevol self-assigned this Oct 16, 2026
@marevol
marevol merged commit 2986311 into main Oct 16, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant