danbooru-cli — specification (README.md)
Build a CLI for the Danbooru booru API.
Written in Python with Typer for command
handling and Rich for formatted output.
The package is scaffolded in src/danbooru_cli/. The binary is named
danbooru (see pyproject.toml). Use uv sync to install deps and the
entry point; uv run danbooru … to run.
Environment
The API base URL is controlled by DANBOORU_BASE (env) or a global
--base flag. Default: danbooru.donmai.us (implied scheme https).
Important: DANBOORU_BASE / --base may include a URL scheme.
If it starts with http:// or https://, use it verbatim. Otherwise
prefix https://. This lets the tool point at local test servers over
plain HTTP.
API endpoints
All endpoints return JSON. All GET requests.
GET /tags.json?search[name_matches]=Q&search[order]=count&limit=N
— returns an array of tag objects:
{ name, post_count, category, is_deprecated, ... }
Category codes: 0=general, 1=artist, 3=copyright, 4=character, 5=meta.
You may also passsearch[category]=Nto filter by category.GET /wiki_pages.json?search[title]=X&limit=1— returns an array
(may be empty); each page hastitle,body,other_names.GET /related_tag.json?query=X— returns an object:
{ tag: { name, post_count }, related_tags: [ { tag, jaccard_similarity } ], wiki_page_tags: [ { tag } ] }GET /tag_aliases.json?search[antecedent_name_matches]=X&search[status]=active&limit=N
— array of{ antecedent_name, consequent_name, ... }.GET /posts.json?tags=T&limit=N— array of post objects.GET /posts/{id}.json— a single post object.GET /posts/{id}.jsonfollowed by GET offile_url— download
image bytes.
Post shape (relevant fields)
On HTTP error: red message on stderr + exit 1.
Commands
All commands accept --raw to emit the API JSON on stdout (verbatim
where possible). Exit 0 on success or soft "nothing found"; exit 1 on
HTTP/parse errors.
danbooru tags <query> [-n LIMIT] [-c CATEGORY] [--raw]
Search tags by name pattern (* wildcards passed through to
search[name_matches]). -c filters by category. Ordered by post count
descending. Default LIMIT 20. --raw: the array of tag objects verbatim.
danbooru wiki <title> [--raw]
Fetch the wiki page for a tag name. Non-raw prints title, other names,
body. --raw: the first wiki page object (or empty output/null if not
found — either is acceptable; the command must exit 0).
danbooru related <tag> [-n LIMIT] [--raw]
Returns the raw related_tag.json response. Non-raw prints two sections
(wiki_page_tags, related_tags) each truncated to LIMIT. Default LIMIT 20.
--raw: the full response object (not truncated).
danbooru aliases <query> [-n LIMIT] [--raw]
Search active tag aliases where antecedent matches the pattern. Default
LIMIT 10. --raw: the array of alias objects verbatim.
danbooru post <id> [--raw]
Fetch a single post. Non-raw prints score/favs/rating + per-category
tag listings + image URL. --raw: the post object verbatim.
danbooru posts <tag_query> [-n LIMIT] [--raw]
Search posts by tags (space-separated, anonymous caps at 2). Default
LIMIT 10. --raw: the array of post objects verbatim.
danbooru download <id> [-o PATH] [--original]
Fetch the post by id, then GET the image URL. By default use
large_file_url (falls back to file_url); --original forces
file_url. Write bytes to PATH, falling back to
/tmp/danbooru_{id}.{ext} (ext derived from URL). Print the path as
the last stdout line. No --raw flag for this command.
What to deliver
A working implementation in src/danbooru_cli/ where uv sync installs
and uv run danbooru … works. Split across files as you like; keep
danbooru_cli.cli:app exported.
The grader invokes uv run danbooru … as a subprocess with
DANBOORU_BASE pointing at a local HTTP fixture server over plain HTTP.
The --raw shape is the hard contract.