CMIS Python client library and command-line shell
Project description
CMIS Shell (cmissh)
A Python-based CMIS (Content Management Interoperability Services) client library and interactive command-line shell for browsing and managing content on CMIS repositories.
Features
- CMIS Client Library: Python client supporting both AtomPub and Browser bindings
- Interactive Shell: Command-line interface similar to a Unix shell for CMIS repositories
- Multiple Execution Modes:
- Interactive mode with command history and tab completion
- Single command execution (
-eflag) - Batch script execution (
-bflag)
- Comprehensive Commands: Navigation, file operations, property management, and more
Installation
From Source
# Clone the repository
git clone <repository-url>
cd cmissh
# Install in development mode
pip install -e .
# Or install with development dependencies
pip install -e ".[dev]"
Using pip (once published)
pip install cmissh
Quick Start
Interactive Mode
Start the shell and connect to a CMIS repository:
# Start shell
cmissh
# Connect to repository
|:> connect admin:admin@http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
Or connect directly when starting:
cmissh -u admin -p admin http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
Single Command Mode
Execute a single command and exit:
cmissh -u admin -p admin -e "ls" http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
Batch Mode
Execute commands from a script file:
cmissh -u admin -p admin -b script.cmis http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
Available Commands
Connection
connect [user:pass@]<url>- Connect to a CMIS repositorydisconnect- Disconnect from current repository
Navigation
ls [path]- List contents of folder or available repositoriescd <path>- Change directory or select repositorypwd- Print working directorypushd <path>- Push directory to stack and change to new directorypopd- Pop directory from stack and return to ittree [path] [depth]- Display repository tree structure (alias:dump)
File Operations
mkdir <name>- Create a new foldermkfile <name>- Create a new empty document (alias:mkdoc)rm <name>- Remove an object (alias:del)get <doc> [local]- Download document content (alias:getstream)put <local> [remote]- Upload file as document (alias:setstream)cat <doc>- Display document content to console
Property Management
props [path]- Display all properties of an objectpropget <prop> [path]- Get specific property value (alias:getp)propset <prop> <value> [path]- Set property value (alias:setp)id [path]- Display object ID and type information
Local File System
lpwd- Print local working directorylcd <path>- Change local working directorylls [path]- List local directory contents (alias:ll)lpushd <path>- Push local directory to stacklpopd- Pop local directory from stack
Utility
help [command]- Show help for commandsexit/quit- Exit the shell
Usage Examples
Example Session
$ cmissh
CMIS Shell. Type 'help' for help, 'connect' to connect to a repository.
|:> connect admin:admin@http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
Connected to http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
|:> ls
Available repositories:
-default-
|:> cd -default-
Entered repository: -default-
|-default-> ls
Data Dictionary/
Guest Home/
Shared/
Sites/
User Homes/
|-default-> cd Sites
|-default-:Sites> ls
swsdp/
|-default-:Sites> cd swsdp
|-default-:swsdp> tree
swsdp/
documentLibrary/
Agency Files/
Meeting Notes/
wiki/
|-default-:swsdp> cd documentLibrary
|-default-:documentLibrary> mkdir TestFolder
Created folder: TestFolder
|-default-:documentLibrary> cd TestFolder
|-default-:TestFolder> put /tmp/test.txt
Created document: test.txt
|-default-:TestFolder> ls
test.txt
|-default-:TestFolder> cat test.txt
This is a test file.
|-default-:TestFolder> props test.txt
Properties of test.txt:
cmis:baseTypeId = cmis:document
cmis:contentStreamFileName = test.txt
cmis:contentStreamLength = 21
cmis:contentStreamMimeType = text/plain
cmis:createdBy = admin
cmis:name = test.txt
cmis:objectId = workspace://SpacesStore/abc123...
cmis:objectTypeId = cmis:document
...
|-default-:TestFolder> quit
Bye
Batch Script Example
Create a file setup.cmis:
# Connect and navigate
cd -default-
cd Sites/swsdp/documentLibrary
# Create folder structure
mkdir Projects
cd Projects
mkdir Documentation
mkdir Code
# Upload files
put /tmp/readme.md Documentation/README.md
put /tmp/code.py Code/main.py
Run it:
cmissh -u admin -p admin -b setup.cmis http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
Using the Library
You can also use cmissh as a library in your Python code:
from cmissh.model import CmisClient
# Connect to repository
client = CmisClient(
'http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom',
'admin',
'admin'
)
# Get default repository
repo = client.getDefaultRepository()
# Get root folder
root = repo.getRootFolder()
# List children
for child in root.getChildren():
print(child.getName())
# Create a folder
properties = {
'cmis:objectTypeId': 'cmis:folder',
'cmis:name': 'My New Folder'
}
new_folder = root.createFolder(properties)
# Create a document with content
with open('myfile.txt', 'rb') as f:
properties = {
'cmis:objectTypeId': 'cmis:document',
'cmis:name': 'MyDocument.txt'
}
doc = new_folder.createDocument(properties, contentFile=f)
# Get document by path
doc = repo.getObjectByPath('/My New Folder/MyDocument.txt')
# Download content
content = doc.getContentStream()
with open('downloaded.txt', 'wb') as f:
f.write(content.read())
CMIS Bindings
The library supports two CMIS protocol bindings:
- AtomPub Binding (XML-based) - Legacy but widely supported
- Browser Binding (JSON-based) - Modern and more efficient
The binding is automatically selected based on the repository URL.
Development
Setup Development Environment
# Clone repository
git clone <repository-url>
cd cmissh
# Install with development dependencies
pip install -e ".[dev]"
Running Tests
The project includes a comprehensive test suite with 430+ tests:
# Run all unit tests (no CMIS server required!)
pytest
# Or: make test
# Run with verbose output
pytest -v
# Run with coverage report
pytest --cov=cmissh --cov-report=term-missing
# Or: make test-coverage
# Run specific test categories
pytest -m unit # Fast unit tests
pytest -m integration # Integration tests (mocked)
pytest -m shell # Shell command tests
# Run server integration tests (requires CMIS server)
make test-server
# Or with custom server:
# CMIS_URL=http://myserver/cmis CMIS_USER=user CMIS_PASSWORD=pass make test-server
# Run ALL tests including server integration
make test-all
Unit tests (430+) use mocks - no external dependencies required! Server integration tests (29) validate against a real CMIS server (optional)
Test Coverage by Module
| Module | Coverage |
|---|---|
| Exceptions | 100% ✅ |
| Utilities | 87% ⭐ |
| CLI | 87% ⭐ |
| Model | 84% ⭐ |
| Shell | 75% 🟡 |
| Domain | 62% 🟡 |
| Bindings | 27-30% 🔴 |
See TEST_SUMMARY.md for detailed coverage information and tests/SERVER_INTEGRATION.md for server testing documentation.
Code Formatting
# Format code
black src/
# Lint code
ruff src/
Type Checking
mypy src/
Requirements
- Python 3.9 or higher
- Dependencies:
iso8601- Date/time parsingrequests- HTTP clientrequests-toolbelt- Multipart encoding
Compatibility
This library is compatible with CMIS 1.0 and 1.1 compliant repositories, including:
- Alfresco
- Apache Chemistry OpenCMIS (InMemory Server)
- Nuxeo
- Microsoft SharePoint
- IBM FileNet
- EMC Documentum
- And other CMIS-compliant systems
License
Apache License 2.0
Credits
This project builds upon:
- cmislib - Original Apache Chemistry CMIS Python client library
- cmissh - Original Java-based CMIS shell by Nuxeo
Contributing
Contributions are welcome! Please feel free to submit pull requests or open issues.
Resources
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 cmissh-2026.1.0.tar.gz.
File metadata
- Download URL: cmissh-2026.1.0.tar.gz
- Upload date:
- Size: 87.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4962fd05e7de87fc595f728ae4989c9da23d66d67b6451bd883b415069e68f1
|
|
| MD5 |
bdddda48884734f00455d67624e4f574
|
|
| BLAKE2b-256 |
dcc7a23d75d11487002a85baf6bc2e2d868fe5a8e22d4d6940032a7d8aa17993
|
File details
Details for the file cmissh-2026.1.0-py3-none-any.whl.
File metadata
- Download URL: cmissh-2026.1.0-py3-none-any.whl
- Upload date:
- Size: 101.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf81f78cc13f7efdc2df1d6898ebf9d6b9e0cbc755a9bcbf03d3a07438ab9f66
|
|
| MD5 |
88c4d0e427a381f60f294dcc0421f30c
|
|
| BLAKE2b-256 |
987404ee8a2572acde2a6a6d59c52d5402995fdcec69ca33f3e9b2c43653e0fb
|