Skip to main content

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 (-e flag)
    • Batch script execution (-b flag)
  • 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 repository
  • disconnect - Disconnect from current repository

Navigation

  • ls [path] - List contents of folder or available repositories
  • cd <path> - Change directory or select repository
  • pwd - Print working directory
  • pushd <path> - Push directory to stack and change to new directory
  • popd - Pop directory from stack and return to it
  • tree [path] [depth] - Display repository tree structure (alias: dump)

File Operations

  • mkdir <name> - Create a new folder
  • mkfile <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 object
  • propget <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 directory
  • lcd <path> - Change local working directory
  • lls [path] - List local directory contents (alias: ll)
  • lpushd <path> - Push local directory to stack
  • lpopd - Pop local directory from stack

Utility

  • help [command] - Show help for commands
  • exit / 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:

  1. AtomPub Binding (XML-based) - Legacy but widely supported
  2. 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 parsing
    • requests - HTTP client
    • requests-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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cmissh-2025.11.0.tar.gz (87.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cmissh-2025.11.0-py3-none-any.whl (101.1 kB view details)

Uploaded Python 3

File details

Details for the file cmissh-2025.11.0.tar.gz.

File metadata

  • Download URL: cmissh-2025.11.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.0

File hashes

Hashes for cmissh-2025.11.0.tar.gz
Algorithm Hash digest
SHA256 088b16e67a7793c4bc44400c85a725927a2b935b6bc16528ceb201101c931244
MD5 7fb6ee43a9737ee6d357e478bfb9f19c
BLAKE2b-256 9e8eed39fecfef77b305a61afc91f50b95a39faf43a1d08dc9b6104905705127

See more details on using hashes here.

File details

Details for the file cmissh-2025.11.0-py3-none-any.whl.

File metadata

  • Download URL: cmissh-2025.11.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.0

File hashes

Hashes for cmissh-2025.11.0-py3-none-any.whl
Algorithm Hash digest
SHA256 961f49d127439b5dcb6a19b83a114a25fff388becbcee1e07b16182ee2eeb053
MD5 1fab04c3dd460bd6449da7e57be81dc2
BLAKE2b-256 dd83ea486e10c50f9f1c1b4e154a47fb9189453deaf9e49001a1b3b3177df7e2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page