Interactive shell and CLI for exploring Plone REST API sites
Project description
Plone API Shell
Interactive command-line shell and CLI tool for exploring Plone REST API sites.
Most modern Plone 6.x sites expose their REST API at siteroot/++api++. This tool provides an interactive shell with filesystem-like navigation (ls, cd, pwd) plus direct API commands for exploring Plone content.
Installation
pip install ploneapi-shell
Or from source:
git clone <repo-url>
cd ploneapi-shell
pip install -r requirements.txt
pip install -e .
Quick Start
1. Configuration
First, configure the tool for your Plone site. Most Plone 6.x sites expose their API at siteroot/++api++.
For public sites (no authentication):
# Login will save the base URL (even without credentials, it sets up your config)
ploneapi-shell login --base https://yoursite.com/++api++/
# When prompted, just press Enter for username/password (or use --username "" --password "")
For authenticated sites:
# Login and save credentials + base URL
ploneapi-shell login --base https://yoursite.com/++api++/
# Enter your Plone username and password when prompted
After login, the base URL is saved and you can omit --base from subsequent commands.
2. Basic Usage
# Explore the API root (uses saved base URL)
ploneapi-shell get
# List available components
ploneapi-shell components
# Browse content items
ploneapi-shell items /news
# Get specific content
ploneapi-shell get /news/some-article
# View raw JSON
ploneapi-shell get /news --raw
3. Interactive Shell
Launch the interactive REPL (default when no command is given):
ploneapi-shell
# or explicitly:
ploneapi-shell repl
Inside the shell, use filesystem-like commands:
ls- List items with metadata (title, type, state, modified date)cd <path>- Navigate to content (supports relative paths and full URLs)cd images- Navigate to images foldercd https://demo.plone.org/images- Navigate using full URL
pwd- Show current pathget [path]- Fetch and display contentitems [path]- List items arrayraw [path]- Show raw JSONcomponents- List available API componentstags [path]- List all tags with frequencysimilar-tags [tag] [threshold]- Find similar tagssimilar-tags swimming- Find tags similar to "swimming" (default threshold: 70%)similar-tags swimming 80- Find similar tags with threshold 80similar-tags swimming -t 85- Use-tflag for thresholdsimilar-tags -t 75- Find all similar pairs with threshold 75
merge-tags <old> <new>- Merge two tagsrename-tag <old> <new>- Rename a tagremove-tag <tag>- Remove a tag from all itemshelp- Show all commandsexit- Exit shell
Tab completion: Press Tab to autocomplete:
- Commands (e.g., type
mer<Tab>to completemerge-tags) - Item names for navigation commands like
cd,get,items(shows clean names like "images" instead of full URLs) - Tag names for tag management commands like
merge-tags,rename-tag,remove-tag,similar-tags
Note: Tag autocompletion may be slow on the first use as it fetches all tags from the site. Subsequent completions are cached and much faster.
4. Web Interface
Launch a web-based interface with the same command functionality:
ploneapi-shell web
This opens a Streamlit web interface at http://localhost:8501 with:
- Command input box (same commands as REPL)
- Visual tables for
lsanditemsoutput - JSON viewer for
rawcommand - Sidebar with configuration and authentication
- Command history
The web interface provides the same functionality as the REPL but with a browser-based UI, making it easier to view and interact with Plone content.
5. Tag Management
Plone uses the Subject field for tagging content. This tool provides powerful commands for discovering, analyzing, and managing tags across your Plone site.
List All Tags
Get a comprehensive list of all tags with their frequency:
# List all tags in the entire site
ploneapi-shell tags
# List tags in a specific path
ploneapi-shell tags /news
# Enable debug mode to see diagnostic information
ploneapi-shell tags --debug
The command uses Plone's search endpoint for efficient tag discovery across large sites. If the search endpoint doesn't return tags, it falls back to recursive browsing (with a warning, as this is slower on large sites).
Find Similar Tags
Use fuzzy matching to find tags with similar names, useful for cleaning up duplicate or misspelled tags:
CLI Examples:
# Find tags similar to a specific tag (default threshold: 70%)
ploneapi-shell similar-tags "swimming"
# Use a custom threshold with --threshold flag
ploneapi-shell similar-tags "swimming" --threshold 80
# Use short -t flag for threshold
ploneapi-shell similar-tags "swimming" -t 85
# Find all similar tag pairs across the site (no query tag)
ploneapi-shell similar-tags --threshold 75
# Find all similar pairs with default threshold (70%)
ploneapi-shell similar-tags
REPL Examples:
ploneapi-shell repl
# Find similar tags with default threshold
> similar-tags swimming
# Use threshold as first argument (finds all pairs with that threshold)
> similar-tags 80
# Use -t flag for threshold
> similar-tags swimming -t 80
# Use --threshold flag
> similar-tags swimming --threshold 85
# Find all similar pairs with custom threshold
> similar-tags -t 75
# Tab completion for tag names
> similar-tags sw<Tab> # Autocompletes tag names starting with "sw"
Understanding the output:
- When you provide a tag: Shows tags similar to that tag with similarity scores
- When you don't provide a tag: Shows all pairs of similar tags above the threshold
- Similarity scores range from 0-100% (higher = more similar)
The similarity score uses fuzzy string matching (0-100%), showing tags that might be duplicates or variations.
Finding misspellings: Misspelled tags typically have very high similarity scores (98% or higher). To find potential misspellings, use a high threshold:
# Find likely misspellings (98%+ similarity)
ploneapi-shell similar-tags --threshold 98
# Find misspellings of a specific tag
ploneapi-shell similar-tags "swimming" --threshold 98
Tip: In the REPL, use Tab to autocomplete tag names when providing a query tag. The first autocomplete may be slow as it fetches all tags; subsequent completions are cached.
Merge Tags
Merge one or more tags into a target tag across all items. The target tag can be an existing tag or a new tag:
# Merge one tag into another
ploneapi-shell merge-tags swimming swim
# Merge multiple tags into one (consolidate tags)
ploneapi-shell merge-tags swimming diving water-polo water-sports
# Merge into an existing tag (both tags will be merged)
ploneapi-shell merge-tags "swimming" "water-sports"
# In REPL (with tab completion for tags)
> merge-tags sw<Tab> # Autocompletes tag names starting with "sw"
> merge-tags swimming diving water-sports
This finds all items with any of the source tags and replaces them with the target tag (or adds the target tag if the item doesn't already have it). The target tag can be an existing tag (to consolidate tags) or a new tag name.
Tip: In the REPL, use Tab to autocomplete tag names when typing tag management commands. Note that the first autocomplete may be slow as it fetches all tags from the site; subsequent completions are cached and faster.
Rename Tags
Rename a tag across all items. The new name can be an existing tag (which will merge them) or a new tag:
# Rename to a new tag name
ploneapi-shell rename-tag old-name new-name
# Rename to an existing tag (merges them)
ploneapi-shell rename-tag "swimming" "water-sports"
# In REPL (with tab completion)
> rename-tag <Tab> # Shows all available tags
> rename-tag swimming water-sports
Tip: In the REPL, use Tab to autocomplete tag names. The first autocomplete may be slow as it fetches all tags; subsequent completions are cached.
Remove Tags
Remove a tag from all items:
ploneapi-shell remove-tag unwanted-tag
# In REPL (with tab completion)
> remove-tag <Tab> # Shows all available tags
> remove-tag unwanted-tag
Tip: In the REPL, use Tab to autocomplete tag names. The first autocomplete may be slow as it fetches all tags; subsequent completions are cached.
Note: Tag management commands require authentication. Make sure you're logged in with appropriate permissions.
Advanced: Using Different Sites
To work with multiple sites or override the saved base URL:
# Use a different site for one command
ploneapi-shell get --base https://othersite.com/++api++/
# Skip saved auth for a specific request
ploneapi-shell get /public --no-auth
# Logout (removes saved credentials)
ploneapi-shell logout
Examples
Exploring a Public Site
# Get site root
ploneapi-shell get --base https://yoursite.com/++api++/
# List news items
ploneapi-shell items /news --base https://yoursite.com/++api++/
# Get specific content
ploneapi-shell get /news/some-article --base https://yoursite.com/++api++/
# View raw JSON
ploneapi-shell get /news --raw --base https://yoursite.com/++api++/
Working with Authenticated Sites
# Login once
ploneapi-shell login --base https://yoursite.com/++api++/
# Enter username and password when prompted
# Now browse authenticated content
ploneapi-shell get /members-only
ploneapi-shell items /private-folder
# Use interactive shell for easier navigation
ploneapi-shell repl
# > ls
# > cd private-folder
# > get
Custom Headers and Parameters
# Add custom headers
ploneapi-shell get /content --header "Accept:application/json" --header "X-Custom:value"
# Add query parameters
ploneapi-shell get /search --param "q:swimming" --param "limit:10"
Configuration
Credentials and base URL are stored in ~/.config/ploneapi_shell/config.json (or override with PLONEAPI_SHELL_CONFIG environment variable).
The config file stores:
base- Default API base URLauth- Authentication token (fromlogincommand)
Publishing to PyPI
The default setuptools metadata currently adds fields (license-file, license-expression) that PyPI rejects. Run the helper script so the build artifacts are fixed automatically:
# Build wheel + sdist and scrub the metadata
python fix_metadata.py
# Only rebuild the sdist, if needed
python fix_metadata.py -- --sdist
# Skip building (only clean existing artifacts)
python fix_metadata.py --skip-build
After running the script, upload as usual:
twine check dist/*
twine upload dist/*
Commands
get [PATH]
Fetch any API path. Shows summary by default, use --raw for full JSON.
items [PATH]
List the items array from a container endpoint in a formatted table.
components
List all available @components endpoints from the API root.
login
Authenticate with a Plone site and save the token. Prompts for username/password.
logout
Remove saved credentials.
repl
Launch interactive shell with tab completion and filesystem-like navigation. This is the default when no command is provided.
web
Launch web-based interface using Streamlit. Opens at http://localhost:8501 by default.
--port, -p- Port to run on (default: 8501)--host, -h- Host to bind to (default: localhost)
tags [PATH]
List all tags (subjects) with their frequency across the site or a specific path.
--path- Limit search to items in this path--base- Override the API base URL--no-auth- Skip saved auth headers--debug- Show debug information about tag collection
similar-tags [TAG] [THRESHOLD]
Find tags similar to the given tag using fuzzy matching. If no tag is provided, finds all pairs of similar tags.
Arguments:
TAG(optional) - Tag to find similar matches for. If omitted, finds all similar tag pairs.THRESHOLD(optional) - Minimum similarity score (0-100, default: 70). Can be provided as:- Positional argument:
similar-tags swimming 80orsimilar-tags 80(for all pairs) - Flag:
--threshold 80or-t 80
- Positional argument:
Options:
--threshold, -t- Minimum similarity score (0-100, default: 70)--path- Limit search to items in this path--base- Override the API base URL--no-auth- Skip saved auth headers
CLI Examples:
# Find tags similar to "swimming" (default threshold: 70%)
ploneapi-shell similar-tags swimming
# Find similar tags with custom threshold (positional)
ploneapi-shell similar-tags swimming 80
# Find similar tags with custom threshold (flag)
ploneapi-shell similar-tags swimming --threshold 80
ploneapi-shell similar-tags swimming -t 85
# Find all similar tag pairs (no query tag)
ploneapi-shell similar-tags --threshold 75
ploneapi-shell similar-tags -t 80
REPL Examples:
> similar-tags swimming # Default threshold (70%)
> similar-tags swimming 80 # Positional threshold
> similar-tags swimming -t 85 # Flag threshold
> similar-tags -t 75 # All pairs with threshold 75
> similar-tags 80 # All pairs with threshold 80 (positional)
> similar-tags -t 98 # Find likely misspellings (98%+ similarity)
> similar-tags swimming -t 98 # Find misspellings of "swimming"
Finding misspellings: Misspelled tags typically have very high similarity scores (98% or higher). Use a high threshold to find potential misspellings:
# Find all likely misspellings across the site
ploneapi-shell similar-tags --threshold 98
# Find misspellings of a specific tag
ploneapi-shell similar-tags "swimming" --threshold 98
merge-tags <SOURCE_TAG>... <TARGET_TAG>
Merge one or more tags into a target tag across all items. Finds all items with any of the source tags and replaces them with the target tag. The target tag can be an existing tag (to consolidate tags) or a new tag name.
Examples:
# Merge one tag
ploneapi-shell merge-tags swimming swim
# Merge multiple tags
ploneapi-shell merge-tags swimming diving water-polo water-sports
REPL Tip: Use Tab to autocomplete tag names when typing source tags.
rename-tag <OLD_NAME> <NEW_NAME>
Rename a tag across all items. The new name can be an existing tag (which will merge them) or a new tag name.
remove-tag <TAG>
Remove a tag from all items that have it.
API Endpoints
Plone REST API typically exposes:
@login- Authentication endpoint@types- Available content types@navigation- Site navigation structure@breadcrumbs- Breadcrumb navigation@workflow- Workflow information@actions- Available actions
Most content items are accessible at their URL path under ++api++, and containers expose an items array with child content.
License
MIT License - see LICENSE file for details.
Copyright (c) 2025 David Bain
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Acknowledgments
This tool is built on top of the Plone REST API (plone.restapi), which provides the foundation for all API interactions. We are grateful to the Plone REST API team and the broader Plone community for their incredible work.
Plone REST API
The Plone REST API was originally authored by Timo Stollenwerk and has been developed and maintained by the Plone community with significant contributions from:
Key Contributors:
- Timo Stollenwerk (original author)
- Thomas Buchberger
- Lukas Graf
- Víctor Fernández de Alba
- Paul Roeland
- Mikel Larreategi
- Eric Brehault
- Andreas Zeidler
- Carsten Senger
- Tom Gross
- Roel Bruggink
- Yann Fouillat (Gagaro)
- Sune Brøndum Wøller
- Philippe Gross
- Andrea Cecchi
- Luca Bellenghi
- Giacomo Monari
- Alin Voinea
- Rodrigo Ferreira de Souza
Organizations:
- kitconcept GmbH (Germany)
- 4teamwork (Switzerland)
- CodeSyntax (Spain)
And many other contributors from the global Plone community.
Plone
Plone itself was initiated in 1999 by Alexander Limi, Alan Runyan, and Vidar Andersen, and has been developed and maintained by a dedicated global community of developers, designers, and advocates.
For more information about the Plone community and contributors, visit:
Author
David Bain (@pigeonflight on X)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ploneapi_shell-0.1.8.tar.gz.
File metadata
- Download URL: ploneapi_shell-0.1.8.tar.gz
- Upload date:
- Size: 38.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f944c007fde3319bbbcc0e2f6358aeaf564fdf9259f857e4bf3c18fa91a55660
|
|
| MD5 |
1c8621aaee7fe7306c63a19cba93383b
|
|
| BLAKE2b-256 |
bc3552a743bfd56f8a588b3f0eada51b5e7700c818fd9f1e821bdf0515f412f0
|
File details
Details for the file ploneapi_shell-0.1.8-py3-none-any.whl.
File metadata
- Download URL: ploneapi_shell-0.1.8-py3-none-any.whl
- Upload date:
- Size: 34.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b6944cfaea7468f7ad5fd6762014bdc3949c34582d5df3551e07d65bdb2ba5a
|
|
| MD5 |
991ab90e013288671f39dd7e3a4bfc00
|
|
| BLAKE2b-256 |
7096302a7fb94dbdc1da2921e5c6832da687adf6fad3383670c585a196ffb40d
|