# Python-Alfresco-API v1.1
**A Complete Python client package for developing python code and apps for Alfresco. Great for doing AI development
with Python based LangChain, LlamaIndex, neo4j-graphrag, etc. Also great for creating MCP servers (see [python-alfresco-mcp-server](https://github.com/stevereiner/python-alfresco-mcp-server)).**
Note this uses the remote Alfresco REST APIs. Not for in-process development in Alfresco.
A modern, type-safe Python client library for Alfresco Content Services REST APIs with dual model architecture (attrs + Pydantic) and async support.
[](https://pypi.org/project/python-alfresco-api/)
[](https://pypi.org/project/python-alfresco-api/)
[](https://www.python.org/downloads/)
[](https://pydantic.dev/)
[](LICENSE)
## ๐ Features
- **Complete API Coverage**: All 7 Alfresco REST APIs (Auth, Core, Discovery, Search, Workflow, Model, Search SQL)
- **328+ Complete Domain Models**: attrs-based raw client models with separate Pydantic models available for AI integration
- **Model Conversion Utilities**: Bridge utilities for attrs โ Pydantic transformation when needed
- **Async/Sync Support**: Both synchronous and asynchronous API calls
- **Modular Architecture**: Individual client design for scalability
- **AI/LLM Ready**: Pydantic models available for AI integration, MCP servers, and tool interfaces
- **Event System**: ActiveMQ and Event Gateway support for Python apps to handle change events
- **Docker Compatible**: Works with Alfresco running in separate Docker Compose setups
- **Comprehensive Testing**: Extensive unit and live Alfresco integration tests
## ๐ Documentation & Examples
- **[๐๏ธ Architecture Overview and Diagram](docs/ARCH_DIAGRAM_AND_OVERVIEW.md)** - V1.1 hierarchical architecture with visual diagram
- **[๐ Complete Documentation](docs/)** - Comprehensive guides and API documentation
- **[๐ฏ Working Examples](examples/)** - Live code examples and usage patterns
- **[๐งช Test Suite](tests/)** - Complete test coverage and integration examples
## ๐ค MCP Server / LLM Integration
### See [python-alfresco-mcp-server](https://github.com/stevereiner/python-alfresco-mcp-server)
This is a MCP Server that uses Python Alfresco API
## ๐ฆ Installation
### Quick Install from PyPI
[](https://pypi.org/project/python-alfresco-api/)
```bash
pip install python-alfresco-api
```
- **Requres**: Python: 3.10+
- **All features included** - No optional dependencies needed! Includes event system, async support, and all 7 Alfresco APIs.
### Virtual Environment Setup (Recommended)
**Best Practice**: Always use a virtual environment to avoid dependency conflicts
#### Windows
```powershell
# Clone the repository
git clone https://github.com/stevereiner/python-alfresco-api.git
cd python-alfresco-api
# Create virtual environment
python -m venv venv
# Activate virtual environment
venv\Scripts\activate
# Verify activation (should show venv path)
where python
# Install dependencies
pip install -r requirements.txt
# Deactivate when done
deactivate
```
#### Linux / MacOS
```bash
# Clone the repository
git clone https://github.com/stevereiner/python-alfresco-api.git
cd python-alfresco-api
# Create virtual environment
python3 -m venv venv
# Activate virtual environment
source venv/bin/activate
# Verify activation (should show venv path)
which python
# Install dependencies
pip install -r requirements.txt
# Deactivate when done
deactivate
```
### Package Installation
Install the package form PyPI use:
```bash
pip install python-alfresco-api
```
### Development with source
For development of your project using python-alfresco-api to have debugging with source:
```bash
# After setting up virtual environment above
git clone https://github.com/your-org/python-alfresco-api.git
cd python-alfresco-api
# Activate your virtual environment first
# Windows: venv\Scripts\activate
# Linux/macOS: source venv/bin/activate
# Install in development mode
pip install -e .
```
## Alfresco Installation
If you don't have an Alfresco server installed you can get a docker for the
Community version from Github
```bash
git clone https://github.com/Alfresco/acs-deployment.git
```
**Start Alfresco with Docker Compose**
```bash
cd acs-deployment/docker-compose
```
Note: you will likely need to comment out activemq ports other than 8161
in community-compose.yaml
```bash
ports:
- "8161:8161" # Web Console
#- "5672:5672" # AMQP
#- "61616:61616" # OpenWire
#- "61613:61613" # STOMP
docker-compose -f community-compose.yaml up
```
## ๐ฏ Environment Setup
### Environment Configuration (Recommended)
For easy configuration, copy the sample environment file:
```bash
cp sample-dot-env.txt .env
# Edit .env with your Alfresco settings
```
## Factory Pattern
The factory pattern provides shared authentication and centralized configuration:
```python
from python_alfresco_api import ClientFactory
# Automatic configuration (loads from .env file or environment variables)
factory = ClientFactory() # Uses ALFRESCO_URL, ALFRESCO_USERNAME, etc.
# Or explicit configuration
factory = ClientFactory(
base_url="http://localhost:8080",
username="admin",
password="admin"
)
# Create individual clients (all share same authentication session)
auth_client = factory.create_auth_client()
core_client = factory.create_core_client()
search_client = factory.create_search_client()
workflow_client = factory.create_workflow_client()
discovery_client = factory.create_discovery_client()
model_client = factory.create_model_client()
search_sql_client = factory.create_search_sql_client() # SOLR admin only
# Can also use a master client like setup with all clients initialized
master_client = factory.create_master_client()
```
### Authentication
For standard Alfresco authentication (recommended):
```python
from python_alfresco_api import AuthUtil, ClientFactory
# Primary authentication pattern - Basic Auth with Alfresco
auth_util = AuthUtil(
base_url="http://localhost:8080",
username="admin",
password="admin"
)
# Use with factory for shared authentication
factory = ClientFactory(auth_util=auth_util)
clients = factory.create_all_clients()
```
**Alternative Authentication:**
- `OAuth2AuthUtil` is available for enterprise OAuth2-based authentication but has not been live tested
### Sync and Async Usage
```python
import asyncio
from python_alfresco_api import ClientFactory
async def main():
factory = ClientFactory(
base_url="http://localhost:8080",
username="admin",
password="admin"
)
# Create core client for node operations
core_client = factory.create_core_client()
# Sync node operation
sync_node = core_client.get_node("-my-")
print(f"Sync: User folder '{sync_node.entry.name}'")
# Async node operation
async_node = await core_client.get_node_async("-my-")
print(f"Async: User folder '{async_node.entry.name}'")
# Run the async example
asyncio.run(main())
```
## ๐ฏ Key Operations & Examples
### Essential Operation Samples
Quick examples of the most common operations. **๐ For complete coverage, see [๐ Essential Operations Guide](docs/ESSENTIAL_OPERATIONS_GUIDE.md)**
#### Basic Setup
```python
from python_alfresco_api import ClientFactory
from python_alfresco_api.utils import content_utils_highlevel
factory = ClientFactory(base_url="http://localhost:8080", username="admin", password="admin")
core_client = factory.create_core_client()
```
#### Create Folder & Upload Document
```python
# Create folder (High-Level Utility)
folder_result = content_utils_highlevel.create_folder_highlevel(
core_client=core_client,
name="My Project Folder",
parent_id="-my-"
)
# Upload document with auto-versioning
document_result = content_utils_highlevel.create_and_upload_file_highlevel(
core_client=core_client,
file_path="/path/to/document.pdf",
parent_id=folder_result['id']
)
```
#### Search Content
```python
from python_alfresco_api.utils import search_utils
search_client = factory.create_search_client()
# Simple text search (already optimized!)
results = search_utils.simple_search(
search_client=search_client,
query_str="finance AND reports",
max_items=25
)
```
#### Download Document
```python
# Download document content
content_response = core_client.nodes.get_content(node_id=document_id)
# Save to file
with open("downloaded_document.pdf", "wb") as file:
file.write(content_response.content)
```
#### Get & Set Properties
```python
from python_alfresco_api.utils import content_utils_highlevel
# Get node properties and details
node_info = content_utils_highlevel.get_node_info_highlevel(
core_client=core_client,
node_id=document_id
)
print(f"Title: {node_info.get('properties', {}).get('cm:title', 'No title')}")
# Update node properties
update_request = {
"properties": {
"cm:title": "Updated Document Title",
"cm:description": "Updated via Python API"
}
}
updated_node = core_client.nodes.update(node_id=document_id, request=update_request)
```
#### Document Versioning - Checkout & Checkin
```python
from python_alfresco_api.utils import version_utils_highlevel
# Checkout document (lock for editing)
checkout_result = version_utils_highlevel.checkout_document_highlevel(
core_client=core_client,
node_id=document_id
)
# Later: Checkin with updated content (create new version)
checkin_result = version_utils_highlevel.checkin_document_highlevel(
core_client=core_client,
node_id=document_id,
content="Updated document content",
comment="Fixed formatting and added new section"
)
```
### ๐ Complete Documentation & Examples
| Resource | Purpose | What You'll Find |
|----------|---------|------------------|
| **[๐ Essential Operations Guide](docs/ESSENTIAL_OPERATIONS_GUIDE.md)** | **Complete operation coverage** | All operations with both high-level utilities and V1.1 APIs |
| **[๐ examples/operations/](examples/operations/)** | **Copy-paste examples** | Windows-compatible, production-ready code |
| **[๐งช tests/test_mcp_v11_true_high_level_apis_fixed.py](tests/test_mcp_v11_true_high_level_apis_fixed.py)** | **MCP Server patterns** | 15 operations with sync/async patterns |
| **[๐งช tests/test_highlevel_utils.py](tests/test_highlevel_utils.py)** | **High-level utilities testing** | Real Alfresco integration examples |
#### ๐ฏ Production-Ready Examples (examples/operations/)
| Example File | Key Operations |
|--------------|----------------|
| **[upload_document.py](examples/operations/upload_document.py)** | Document upload, automatic versioning, batch uploads |
| **[versioning_workflow.py](examples/operations/versioning_workflow.py)** | Checkout โ Edit โ Checkin workflow, version history |
| **[basic_operations.py](examples/operations/basic_operations.py)** | Folder creation, CRUD operations, browsing, deletion |
| **[search_operations.py](examples/operations/search_operations.py)** | Content search, metadata queries, advanced search |
### ๐ Model Architecture & Conversion (V1.1)
V1.1 implements a dual model system with conversion utilities:
| Component | Model Type | Purpose |
|-----------|------------|---------|
| **Raw Client Models** | `@_attrs_define` | Complete OpenAPI domain models (`RepositoryInfo`, `NodeEntry`, etc.) |
| **Pydantic Models** | `BaseModel` | AI/LLM integration, validation, type safety |
| **Conversion Utils** | Bridge utilities | Transformation between attrs โ Pydantic |
**For detailed guidance**, see **[๐ Pydantic Models Guide](docs/PYDANTIC_MODELS_GUIDE.md)** and **[๐ Conversion Utilities Design](docs/CONVERSION_UTILITIES_DESIGN.md)**.
```python
# โ
V1.1: Two model systems with conversion utilities
from python_alfresco_api.models.alfresco_core_models import NodeBodyCreate # Pydantic
from python_alfresco_api.raw_clients.alfresco_core_client.models import NodeBodyCreate as AttrsNodeBodyCreate # attrs
from python_alfresco_api.clients.conversion_utils import pydantic_to_attrs_dict
# 1. Use Pydantic for validation and AI integration
pydantic_model = NodeBodyCreate(name="document.pdf", nodeType="cm:content")
# 2. Convert for raw client usage
factory = ClientFactory()
core_client = factory.create_core_client()
# Option A: Manual conversion via model_dump()
result = core_client.create_node(pydantic_model.model_dump())
# Option B: Conversion utilities (V1.1)
attrs_dict = pydantic_to_attrs_dict(pydantic_model, target_class_name="NodeBodyCreate")
result = core_client.create_node(attrs_dict)
# 3. Raw clients return attrs-based domain models
repository_info = discovery_client.get_repository_information() # Returns attrs RepositoryInfo
# Convert to dict for further processing
repo_dict = repository_info.to_dict()
```
### V1.2 Roadmap: Unified Pydantic Architecture
V1.2 will migrate raw client models from attrs to Pydantic v2:
```python
# ๐ฏ V1.2 Target: Single Pydantic model system
from python_alfresco_api.raw_clients.alfresco_core_client.models import NodeBodyCreate # Will be Pydantic!
# No conversion needed - everything is Pydantic BaseModel
pydantic_model = NodeBodyCreate(name="document.pdf", nodeType="cm:content")
result = core_client.create_node(pydantic_model) # Direct usage!
```
**Notes**
- V1.1: Dual system with conversion utilities
- Pydantic models: Available for AI/LLM integration and validation
- Raw client models: attrs-based with 328+ complete domain models
- V1.2: Will unify to Pydantic v2 throughout
## ๐ Event System
### ActiveMQ Integration (Community Edition)
```python
from python_alfresco_api.activemq_events import AlfrescoActiveMQEventClient
# Create event client
event_client = AlfrescoActiveMQEventClient(
activemq_host="localhost",
activemq_port=61616,
username="admin",
password="admin"
)
# Register event handler
async def node_created_handler(notification):
print(f"Node created: {notification.nodeId}")
event_client.register_event_handler("alfresco.node.created", node_created_handler)
# Start listening
await event_client.connect()
await event_client.start_listening()
```
### Event Gateway (Enterprise Edition)
```python
from python_alfresco_api.event_client import AlfrescoEventClient
# Unified event client (auto-detects available systems)
event_client = AlfrescoEventClient()
# Works with both Community (ActiveMQ) and Enterprise (Event Gateway)
await event_client.create_subscription("node-events")
await event_client.start_listening()
```
## ๐ง For Developing the Python Alfresco API Package
For complete development documentation including the **3-step generation process** (Pydantic models โ HTTP clients โ High-level APIs), see **[๐ Package Developers Guide](docs/PACKAGE_DEVELOPERS_GUIDE.md)**.
## ๐งช Development and Testing
### Development Setup
For development, testing, and contributing:
```bash
pip install -r requirements-dev.txt
```
For most development work on python-alfresco-api, you can develop directly without regenerating code:
```bash
git clone https://github.com/stevereiner/python-alfresco-api.git
cd python-alfresco-api
# Install in development mode
pip install -e .
```
> **Note**: For proper pytest execution, work from the source directory with `pip install -e .` rather than testing from separate directories. This avoids import path conflicts.
### Run Tests
```bash
cd python-alfresco-api
# Simple - just run all tests pytest
pytest
# Run all tests with coverage
pytest --cov=python_alfresco_api --cov-report=html
# Custom test runner with additional features
python run_tests.py
# Features:
# - Environment validation (venv, dependencies)
# - Colored output with progress tracking
# - Test selection for 44%+ coverage baseline
# - Performance metrics (client creation speed)
# - Live Alfresco server detection
# - HTML coverage reports (htmlcov/index.html)
# - Test summary with next steps
```
### Live Integration Tests
To run tests against a live Alfresco server
(Note: This package was developed and tested with Community Edition)
```bash
# Run one test (test live with Alfresco)
pytest tests/test_mcp_v11_true_high_level_apis_fixed.py -v
```
## ๐ Project Structure
```
python-alfresco-api/
โโโ python_alfresco_api/
โ โโโ __init__.py # Main exports
โ โโโ auth_util.py # Authentication utility
โ โโโ client_factory.py # Client factory pattern
โ โโโ clients/ # Individual API clients + utilities
โ โ โโโ auth_client.py
โ โ โโโ core_client.py
โ โ โโโ discovery_client.py
โ โ โโโ search_client.py
โ โ โโโ workflow_client.py
โ โ โโโ model_client.py
โ โ โโโ search_sql_client.py
โ โ โโโ conversion_utils.py # Pydantic โ attrs conversion utilities
โ โโโ models/ # Pydantic v2 models (available for separate use)
โ โ โโโ alfresco_auth_models.py
โ โ โโโ alfresco_core_models.py
โ โ โโโ alfresco_discovery_models.py
โ โ โโโ alfresco_search_models.py
โ โ โโโ alfresco_workflow_models.py
โ โ โโโ alfresco_model_models.py
โ โ โโโ alfresco_search_sql_models.py
โ โโโ raw_clients/ # Generated HTTP clients
โ โโโ utils/ # Utility functions
โ โ โโโ content_utils.py
โ โ โโโ node_utils.py
โ โ โโโ search_utils.py
โ โ โโโ version_utils.py
โ โ โโโ mcp_formatters.py
โ โโโ events/ # Event system (Community + Enterprise)
โ โโโ __init__.py # Event exports
โ โโโ event_client.py # Unified event client (AlfrescoEventClient)
โ โโโ models.py # Event models (EventSubscription, EventNotification)
โโโ config/ # Code generation configurations
โ โโโ auth.yaml # Auth API config โ auth_client
โ โโโ core.yaml # Core API config โ core_client
โ โโโ discovery.yaml # Discovery API config โ discovery_client
โ โโโ search.yaml # Search API config โ search_client
โ โโโ workflow.yaml # Workflow API config โ workflow_client
โ โโโ model.yaml # Model API config โ model_client
โ โโโ search_sql.yaml # Search SQL API config โ search_sql_client
โ โโโ general.yaml # Unified config โ alfresco_client
โ โโโ README.md # Configuration documentation
โโโ openapi/ # OpenAPI specifications (checked in)
โ โโโ openapi2/ # Original OpenAPI 2.0 specs
โ โโโ openapi2-processed/ # Cleaned OpenAPI 2.0 specs
โ โโโ openapi3/ # Converted OpenAPI 3.0 specs
โโโ tests/ # Comprehensive test suite
โโโ scripts/ # Generation scripts
โโโ docs/ # Comprehensive documentation
โ โโโ PYDANTIC_MODELS_GUIDE.md # Complete Pydantic models guide
โ โโโ CLIENT_TYPES_GUIDE.md # Client architecture guide
โ โโโ CONVERSION_UTILITIES_DESIGN.md # Model conversion utilities
โ โโโ REQUEST_TYPES_GUIDE.md # Node & Search request documentation
โ โโโ API_DOCUMENTATION_INDEX.md # Complete API reference
โโโ examples/ # Working usage examples
โโโ requirements.txt # Runtime dependencies
โโโ requirements-dev.txt # Development dependencies
โโโ run_tests.py # Test runner with nice display
โโโ README.md # This file
```
## ๐ Requirements
### Runtime Requirements
- **Python**: 3.10+
- **pydantic**: >=2.0.0,<3.0.0
- **requests**: >=2.31.0
- **httpx**: >=0.24.0 (for async support)
- **aiohttp**: >=3.8.0 (for async HTTP)
### Optional Dependencies
- **stomp.py**: >=8.1.0 (for ActiveMQ events)
- **ujson**: >=5.7.0 (faster JSON parsing)
- **requests-oauthlib**: >=1.3.0 (OAuth support)
## ๐ ๏ธ Contributing
For development workflows, code generation, testing, and contribution guidelines, see **[๐ Package Developers Guide](docs/PACKAGE_DEVELOPERS_GUIDE.md)**.
## ๐ค Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run tests: `pytest`
5. Submit a pull request
## ๐ License
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
## ๐ Support
- **Issues**: [GitHub Issues](https://github.com/stevereiner/python-alfresco-api/issues)
- **Documentation**: [Project Documentation](docs/)
- **Examples**: [Usage Examples](examples/)
## ๐ Related Projects
- **Model Context Protocol (MCP)**: [MCP Documentation](https://modelcontextprotocol.io/docs) - Standard for AI-data source and function integration
- **Alfresco Community Edition**: [Community Documentation](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services-Community-Edition/25.1/Alfresco-Content-Services-Community-Edition/Introduction)
- **Alfresco Enterprise Edition**: [Enterprise Documentation](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/25.1/Alfresco-Content-Services/Introduction)
- **Pydantic**: [Type validation library](https://pydantic.dev/)
- **Datamodel-code-generator**: [Pydantic model generator](https://github.com/koxudaxi/datamodel-code-generator)
- **Openapi-python-client**: [HTTP client generator](https://github.com/openapi-generators/openapi-python-client)
- **MCP Server based on Python Alfresco API**: [python-alfresco-mcp-server](https://github.com/stevereiner/python-alfresco-mcp-server)
## โญ Star History
If this project helps you, please consider giving it a star! โญ
Raw data
{
"_id": null,
"home_page": null,
"name": "python-alfresco-api",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "alfresco, content-management, document-management, ecm, rest-api",
"author": null,
"author_email": "Steve Reiner <example@example.com>",
"download_url": "https://files.pythonhosted.org/packages/aa/ec/7e9014be61405867f191682ed9d89dbf8305d151d183831494177ce67502/python_alfresco_api-1.1.1.tar.gz",
"platform": null,
"description": "# Python-Alfresco-API v1.1\n\n**A Complete Python client package for developing python code and apps for Alfresco. Great for doing AI development \nwith Python based LangChain, LlamaIndex, neo4j-graphrag, etc. Also great for creating MCP servers (see [python-alfresco-mcp-server](https://github.com/stevereiner/python-alfresco-mcp-server)).**\n\nNote this uses the remote Alfresco REST APIs. Not for in-process development in Alfresco.\n\nA modern, type-safe Python client library for Alfresco Content Services REST APIs with dual model architecture (attrs + Pydantic) and async support.\n\n[](https://pypi.org/project/python-alfresco-api/)\n[](https://pypi.org/project/python-alfresco-api/)\n[](https://www.python.org/downloads/)\n[](https://pydantic.dev/)\n[](LICENSE)\n\n## \ud83d\ude80 Features\n\n- **Complete API Coverage**: All 7 Alfresco REST APIs (Auth, Core, Discovery, Search, Workflow, Model, Search SQL)\n- **328+ Complete Domain Models**: attrs-based raw client models with separate Pydantic models available for AI integration\n- **Model Conversion Utilities**: Bridge utilities for attrs \u2194 Pydantic transformation when needed\n- **Async/Sync Support**: Both synchronous and asynchronous API calls\n- **Modular Architecture**: Individual client design for scalability\n- **AI/LLM Ready**: Pydantic models available for AI integration, MCP servers, and tool interfaces\n- **Event System**: ActiveMQ and Event Gateway support for Python apps to handle change events \n- **Docker Compatible**: Works with Alfresco running in separate Docker Compose setups\n- **Comprehensive Testing**: Extensive unit and live Alfresco integration tests\n\n## \ud83d\udcda Documentation & Examples\n\n- **[\ud83c\udfd7\ufe0f Architecture Overview and Diagram](docs/ARCH_DIAGRAM_AND_OVERVIEW.md)** - V1.1 hierarchical architecture with visual diagram\n- **[\ud83d\udcd6 Complete Documentation](docs/)** - Comprehensive guides and API documentation\n- **[\ud83c\udfaf Working Examples](examples/)** - Live code examples and usage patterns\n- **[\ud83e\uddea Test Suite](tests/)** - Complete test coverage and integration examples\n\n## \ud83e\udd16 MCP Server / LLM Integration \n\n### See [python-alfresco-mcp-server](https://github.com/stevereiner/python-alfresco-mcp-server)\nThis is a MCP Server that uses Python Alfresco API\n\n## \ud83d\udce6 Installation\n\n### Quick Install from PyPI\n\n[](https://pypi.org/project/python-alfresco-api/)\n\n```bash\npip install python-alfresco-api\n```\n- **Requres**: Python: 3.10+\n- **All features included** - No optional dependencies needed! Includes event system, async support, and all 7 Alfresco APIs.\n\n### Virtual Environment Setup (Recommended)\n\n**Best Practice**: Always use a virtual environment to avoid dependency conflicts\n\n#### Windows\n\n```powershell\n# Clone the repository\ngit clone https://github.com/stevereiner/python-alfresco-api.git\ncd python-alfresco-api\n\n# Create virtual environment\npython -m venv venv\n\n# Activate virtual environment\nvenv\\Scripts\\activate\n\n# Verify activation (should show venv path)\nwhere python\n\n# Install dependencies\npip install -r requirements.txt\n\n# Deactivate when done\ndeactivate\n```\n\n#### Linux / MacOS\n\n```bash\n# Clone the repository\ngit clone https://github.com/stevereiner/python-alfresco-api.git\ncd python-alfresco-api\n\n# Create virtual environment\npython3 -m venv venv\n\n# Activate virtual environment\nsource venv/bin/activate\n\n# Verify activation (should show venv path)\nwhich python\n\n# Install dependencies\npip install -r requirements.txt\n\n# Deactivate when done\ndeactivate\n```\n\n\n### Package Installation\n\nInstall the package form PyPI use:\n\n```bash\npip install python-alfresco-api\n```\n\n\n### Development with source\n\nFor development of your project using python-alfresco-api to have debugging with source:\n\n```bash\n# After setting up virtual environment above\ngit clone https://github.com/your-org/python-alfresco-api.git\ncd python-alfresco-api\n\n# Activate your virtual environment first\n# Windows: venv\\Scripts\\activate\n# Linux/macOS: source venv/bin/activate\n\n# Install in development mode\npip install -e .\n```\n\n## Alfresco Installation \n\nIf you don't have an Alfresco server installed you can get a docker for the \nCommunity version from Github\n ```bash\n git clone https://github.com/Alfresco/acs-deployment.git\n```\n**Start Alfresco with Docker Compose**\n ```bash\n cd acs-deployment/docker-compose\n```\n Note: you will likely need to comment out activemq ports other than 8161\n in community-compose.yaml\n ```bash \n ports:\n - \"8161:8161\" # Web Console\n #- \"5672:5672\" # AMQP\n #- \"61616:61616\" # OpenWire\n #- \"61613:61613\" # STOMP\n\n docker-compose -f community-compose.yaml up\n```\n\n## \ud83c\udfaf Environment Setup\n\n### Environment Configuration (Recommended)\n\nFor easy configuration, copy the sample environment file:\n```bash\ncp sample-dot-env.txt .env\n# Edit .env with your Alfresco settings\n```\n\n## Factory Pattern \n\nThe factory pattern provides shared authentication and centralized configuration:\n\n```python\nfrom python_alfresco_api import ClientFactory\n\n# Automatic configuration (loads from .env file or environment variables)\nfactory = ClientFactory() # Uses ALFRESCO_URL, ALFRESCO_USERNAME, etc.\n\n# Or explicit configuration\nfactory = ClientFactory(\n base_url=\"http://localhost:8080\",\n username=\"admin\",\n password=\"admin\"\n)\n\n# Create individual clients (all share same authentication session)\nauth_client = factory.create_auth_client()\ncore_client = factory.create_core_client()\nsearch_client = factory.create_search_client()\nworkflow_client = factory.create_workflow_client()\ndiscovery_client = factory.create_discovery_client()\nmodel_client = factory.create_model_client()\nsearch_sql_client = factory.create_search_sql_client() # SOLR admin only\n\n# Can also use a master client like setup with all clients initialized\nmaster_client = factory.create_master_client()\n\n```\n\n\n### Authentication\n\nFor standard Alfresco authentication (recommended):\n\n```python\nfrom python_alfresco_api import AuthUtil, ClientFactory\n\n# Primary authentication pattern - Basic Auth with Alfresco\nauth_util = AuthUtil(\n base_url=\"http://localhost:8080\",\n username=\"admin\",\n password=\"admin\"\n)\n\n# Use with factory for shared authentication\nfactory = ClientFactory(auth_util=auth_util)\nclients = factory.create_all_clients()\n```\n\n**Alternative Authentication:**\n- `OAuth2AuthUtil` is available for enterprise OAuth2-based authentication but has not been live tested\n\n### Sync and Async Usage\n\n```python\nimport asyncio\nfrom python_alfresco_api import ClientFactory\n\nasync def main():\n factory = ClientFactory(\n base_url=\"http://localhost:8080\",\n username=\"admin\",\n password=\"admin\"\n )\n \n # Create core client for node operations\n core_client = factory.create_core_client()\n \n # Sync node operation\n sync_node = core_client.get_node(\"-my-\")\n print(f\"Sync: User folder '{sync_node.entry.name}'\")\n \n # Async node operation\n async_node = await core_client.get_node_async(\"-my-\")\n print(f\"Async: User folder '{async_node.entry.name}'\")\n\n# Run the async example\nasyncio.run(main())\n```\n\n## \ud83c\udfaf Key Operations & Examples\n\n### Essential Operation Samples\n\nQuick examples of the most common operations. **\ud83d\udc49 For complete coverage, see [\ud83d\udcd6 Essential Operations Guide](docs/ESSENTIAL_OPERATIONS_GUIDE.md)**\n\n#### Basic Setup\n```python\nfrom python_alfresco_api import ClientFactory\nfrom python_alfresco_api.utils import content_utils_highlevel\n\nfactory = ClientFactory(base_url=\"http://localhost:8080\", username=\"admin\", password=\"admin\")\ncore_client = factory.create_core_client()\n```\n\n#### Create Folder & Upload Document\n```python\n# Create folder (High-Level Utility)\nfolder_result = content_utils_highlevel.create_folder_highlevel(\n core_client=core_client,\n name=\"My Project Folder\", \n parent_id=\"-my-\"\n)\n\n# Upload document with auto-versioning\ndocument_result = content_utils_highlevel.create_and_upload_file_highlevel(\n core_client=core_client,\n file_path=\"/path/to/document.pdf\",\n parent_id=folder_result['id']\n)\n```\n\n#### Search Content\n```python\nfrom python_alfresco_api.utils import search_utils\n\nsearch_client = factory.create_search_client()\n\n# Simple text search (already optimized!)\nresults = search_utils.simple_search(\n search_client=search_client,\n query_str=\"finance AND reports\",\n max_items=25\n)\n```\n\n#### Download Document\n```python\n# Download document content\ncontent_response = core_client.nodes.get_content(node_id=document_id)\n\n# Save to file\nwith open(\"downloaded_document.pdf\", \"wb\") as file:\n file.write(content_response.content)\n```\n\n#### Get & Set Properties\n```python\nfrom python_alfresco_api.utils import content_utils_highlevel\n\n# Get node properties and details\nnode_info = content_utils_highlevel.get_node_info_highlevel(\n core_client=core_client,\n node_id=document_id\n)\nprint(f\"Title: {node_info.get('properties', {}).get('cm:title', 'No title')}\")\n\n# Update node properties\nupdate_request = {\n \"properties\": {\n \"cm:title\": \"Updated Document Title\",\n \"cm:description\": \"Updated via Python API\"\n }\n}\nupdated_node = core_client.nodes.update(node_id=document_id, request=update_request)\n```\n\n#### Document Versioning - Checkout & Checkin\n```python\nfrom python_alfresco_api.utils import version_utils_highlevel\n\n# Checkout document (lock for editing)\ncheckout_result = version_utils_highlevel.checkout_document_highlevel(\n core_client=core_client,\n node_id=document_id\n)\n\n# Later: Checkin with updated content (create new version)\ncheckin_result = version_utils_highlevel.checkin_document_highlevel(\n core_client=core_client,\n node_id=document_id,\n content=\"Updated document content\",\n comment=\"Fixed formatting and added new section\"\n)\n```\n\n### \ud83d\udcda Complete Documentation & Examples\n\n| Resource | Purpose | What You'll Find |\n|----------|---------|------------------|\n| **[\ud83d\udcd6 Essential Operations Guide](docs/ESSENTIAL_OPERATIONS_GUIDE.md)** | **Complete operation coverage** | All operations with both high-level utilities and V1.1 APIs |\n| **[\ud83d\udcc1 examples/operations/](examples/operations/)** | **Copy-paste examples** | Windows-compatible, production-ready code |\n| **[\ud83e\uddea tests/test_mcp_v11_true_high_level_apis_fixed.py](tests/test_mcp_v11_true_high_level_apis_fixed.py)** | **MCP Server patterns** | 15 operations with sync/async patterns |\n| **[\ud83e\uddea tests/test_highlevel_utils.py](tests/test_highlevel_utils.py)** | **High-level utilities testing** | Real Alfresco integration examples |\n\n#### \ud83c\udfaf Production-Ready Examples (examples/operations/)\n\n| Example File | Key Operations |\n|--------------|----------------|\n| **[upload_document.py](examples/operations/upload_document.py)** | Document upload, automatic versioning, batch uploads |\n| **[versioning_workflow.py](examples/operations/versioning_workflow.py)** | Checkout \u2192 Edit \u2192 Checkin workflow, version history |\n| **[basic_operations.py](examples/operations/basic_operations.py)** | Folder creation, CRUD operations, browsing, deletion |\n| **[search_operations.py](examples/operations/search_operations.py)** | Content search, metadata queries, advanced search |\n\n\n\n### \ud83d\udd04 Model Architecture & Conversion (V1.1)\n\nV1.1 implements a dual model system with conversion utilities:\n\n| Component | Model Type | Purpose |\n|-----------|------------|---------|\n| **Raw Client Models** | `@_attrs_define` | Complete OpenAPI domain models (`RepositoryInfo`, `NodeEntry`, etc.) |\n| **Pydantic Models** | `BaseModel` | AI/LLM integration, validation, type safety |\n| **Conversion Utils** | Bridge utilities | Transformation between attrs \u2194 Pydantic |\n\n**For detailed guidance**, see **[\ud83d\udcd6 Pydantic Models Guide](docs/PYDANTIC_MODELS_GUIDE.md)** and **[\ud83d\udd04 Conversion Utilities Design](docs/CONVERSION_UTILITIES_DESIGN.md)**.\n\n```python\n# \u2705 V1.1: Two model systems with conversion utilities\nfrom python_alfresco_api.models.alfresco_core_models import NodeBodyCreate # Pydantic\nfrom python_alfresco_api.raw_clients.alfresco_core_client.models import NodeBodyCreate as AttrsNodeBodyCreate # attrs\nfrom python_alfresco_api.clients.conversion_utils import pydantic_to_attrs_dict\n\n# 1. Use Pydantic for validation and AI integration\npydantic_model = NodeBodyCreate(name=\"document.pdf\", nodeType=\"cm:content\")\n\n# 2. Convert for raw client usage \nfactory = ClientFactory()\ncore_client = factory.create_core_client()\n\n# Option A: Manual conversion via model_dump()\nresult = core_client.create_node(pydantic_model.model_dump())\n\n# Option B: Conversion utilities (V1.1)\nattrs_dict = pydantic_to_attrs_dict(pydantic_model, target_class_name=\"NodeBodyCreate\") \nresult = core_client.create_node(attrs_dict)\n\n# 3. Raw clients return attrs-based domain models\nrepository_info = discovery_client.get_repository_information() # Returns attrs RepositoryInfo\n# Convert to dict for further processing\nrepo_dict = repository_info.to_dict()\n```\n\n### V1.2 Roadmap: Unified Pydantic Architecture\n\nV1.2 will migrate raw client models from attrs to Pydantic v2:\n\n```python\n# \ud83c\udfaf V1.2 Target: Single Pydantic model system\nfrom python_alfresco_api.raw_clients.alfresco_core_client.models import NodeBodyCreate # Will be Pydantic!\n\n# No conversion needed - everything is Pydantic BaseModel\npydantic_model = NodeBodyCreate(name=\"document.pdf\", nodeType=\"cm:content\")\nresult = core_client.create_node(pydantic_model) # Direct usage!\n```\n\n**Notes**\n- V1.1: Dual system with conversion utilities\n- Pydantic models: Available for AI/LLM integration and validation \n- Raw client models: attrs-based with 328+ complete domain models\n- V1.2: Will unify to Pydantic v2 throughout\n\n\n## \ud83d\udd0c Event System\n\n### ActiveMQ Integration (Community Edition)\n\n```python\nfrom python_alfresco_api.activemq_events import AlfrescoActiveMQEventClient\n\n# Create event client\nevent_client = AlfrescoActiveMQEventClient(\n activemq_host=\"localhost\",\n activemq_port=61616,\n username=\"admin\",\n password=\"admin\"\n)\n\n# Register event handler\nasync def node_created_handler(notification):\n print(f\"Node created: {notification.nodeId}\")\n\nevent_client.register_event_handler(\"alfresco.node.created\", node_created_handler)\n\n# Start listening\nawait event_client.connect()\nawait event_client.start_listening()\n```\n\n### Event Gateway (Enterprise Edition)\n\n```python\nfrom python_alfresco_api.event_client import AlfrescoEventClient\n\n# Unified event client (auto-detects available systems)\nevent_client = AlfrescoEventClient()\n\n# Works with both Community (ActiveMQ) and Enterprise (Event Gateway)\nawait event_client.create_subscription(\"node-events\")\nawait event_client.start_listening()\n```\n\n\n## \ud83d\udd27 For Developing the Python Alfresco API Package\n\nFor complete development documentation including the **3-step generation process** (Pydantic models \u2192 HTTP clients \u2192 High-level APIs), see **[\ud83d\udcd6 Package Developers Guide](docs/PACKAGE_DEVELOPERS_GUIDE.md)**.\n\n\n## \ud83e\uddea Development and Testing\n\n### Development Setup\n\nFor development, testing, and contributing:\n\n```bash\npip install -r requirements-dev.txt\n```\n\nFor most development work on python-alfresco-api, you can develop directly without regenerating code:\n\n```bash\ngit clone https://github.com/stevereiner/python-alfresco-api.git\ncd python-alfresco-api\n\n# Install in development mode\npip install -e .\n```\n\n> **Note**: For proper pytest execution, work from the source directory with `pip install -e .` rather than testing from separate directories. This avoids import path conflicts.\n\n### Run Tests\n\n```bash\ncd python-alfresco-api\n\n# Simple - just run all tests pytest\npytest\n\n# Run all tests with coverage\npytest --cov=python_alfresco_api --cov-report=html\n\n# Custom test runner with additional features\npython run_tests.py\n# Features:\n# - Environment validation (venv, dependencies)\n# - Colored output with progress tracking\n# - Test selection for 44%+ coverage baseline\n# - Performance metrics (client creation speed)\n# - Live Alfresco server detection\n# - HTML coverage reports (htmlcov/index.html)\n# - Test summary with next steps\n```\n\n### Live Integration Tests\n\nTo run tests against a live Alfresco server \n(Note: This package was developed and tested with Community Edition)\n\n ```bash\n\n # Run one test (test live with Alfresco)\n pytest tests/test_mcp_v11_true_high_level_apis_fixed.py -v\n \n ```\n\n## \ud83d\udd04 Project Structure\n\n```\npython-alfresco-api/\n\u251c\u2500\u2500 python_alfresco_api/\n\u2502 \u251c\u2500\u2500 __init__.py # Main exports\n\u2502 \u251c\u2500\u2500 auth_util.py # Authentication utility\n\u2502 \u251c\u2500\u2500 client_factory.py # Client factory pattern\n\u2502 \u251c\u2500\u2500 clients/ # Individual API clients + utilities\n\u2502 \u2502 \u251c\u2500\u2500 auth_client.py\n\u2502 \u2502 \u251c\u2500\u2500 core_client.py\n\u2502 \u2502 \u251c\u2500\u2500 discovery_client.py\n\u2502 \u2502 \u251c\u2500\u2500 search_client.py\n\u2502 \u2502 \u251c\u2500\u2500 workflow_client.py\n\u2502 \u2502 \u251c\u2500\u2500 model_client.py\n\u2502 \u2502 \u251c\u2500\u2500 search_sql_client.py\n\u2502 \u2502 \u2514\u2500\u2500 conversion_utils.py # Pydantic \u2194 attrs conversion utilities\n\u2502 \u251c\u2500\u2500 models/ # Pydantic v2 models (available for separate use)\n\u2502 \u2502 \u251c\u2500\u2500 alfresco_auth_models.py\n\u2502 \u2502 \u251c\u2500\u2500 alfresco_core_models.py\n\u2502 \u2502 \u251c\u2500\u2500 alfresco_discovery_models.py\n\u2502 \u2502 \u251c\u2500\u2500 alfresco_search_models.py\n\u2502 \u2502 \u251c\u2500\u2500 alfresco_workflow_models.py\n\u2502 \u2502 \u251c\u2500\u2500 alfresco_model_models.py\n\u2502 \u2502 \u2514\u2500\u2500 alfresco_search_sql_models.py\n\u2502 \u251c\u2500\u2500 raw_clients/ # Generated HTTP clients\n\u2502 \u251c\u2500\u2500 utils/ # Utility functions\n\u2502 \u2502 \u251c\u2500\u2500 content_utils.py\n\u2502 \u2502 \u251c\u2500\u2500 node_utils.py\n\u2502 \u2502 \u251c\u2500\u2500 search_utils.py\n\u2502 \u2502 \u251c\u2500\u2500 version_utils.py\n\u2502 \u2502 \u2514\u2500\u2500 mcp_formatters.py\n\u2502 \u2514\u2500\u2500 events/ # Event system (Community + Enterprise)\n\u2502 \u251c\u2500\u2500 __init__.py # Event exports\n\u2502 \u251c\u2500\u2500 event_client.py # Unified event client (AlfrescoEventClient)\n\u2502 \u2514\u2500\u2500 models.py # Event models (EventSubscription, EventNotification)\n\u251c\u2500\u2500 config/ # Code generation configurations\n\u2502 \u251c\u2500\u2500 auth.yaml # Auth API config \u2192 auth_client\n\u2502 \u251c\u2500\u2500 core.yaml # Core API config \u2192 core_client\n\u2502 \u251c\u2500\u2500 discovery.yaml # Discovery API config \u2192 discovery_client\n\u2502 \u251c\u2500\u2500 search.yaml # Search API config \u2192 search_client\n\u2502 \u251c\u2500\u2500 workflow.yaml # Workflow API config \u2192 workflow_client\n\u2502 \u251c\u2500\u2500 model.yaml # Model API config \u2192 model_client\n\u2502 \u251c\u2500\u2500 search_sql.yaml # Search SQL API config \u2192 search_sql_client\n\u2502 \u251c\u2500\u2500 general.yaml # Unified config \u2192 alfresco_client\n\u2502 \u2514\u2500\u2500 README.md # Configuration documentation\n\u251c\u2500\u2500 openapi/ # OpenAPI specifications (checked in)\n\u2502 \u251c\u2500\u2500 openapi2/ # Original OpenAPI 2.0 specs\n\u2502 \u251c\u2500\u2500 openapi2-processed/ # Cleaned OpenAPI 2.0 specs\n\u2502 \u2514\u2500\u2500 openapi3/ # Converted OpenAPI 3.0 specs\n\u251c\u2500\u2500 tests/ # Comprehensive test suite\n\u251c\u2500\u2500 scripts/ # Generation scripts\n\u251c\u2500\u2500 docs/ # Comprehensive documentation\n\u2502 \u251c\u2500\u2500 PYDANTIC_MODELS_GUIDE.md # Complete Pydantic models guide\n\u2502 \u251c\u2500\u2500 CLIENT_TYPES_GUIDE.md # Client architecture guide \n\u2502 \u251c\u2500\u2500 CONVERSION_UTILITIES_DESIGN.md # Model conversion utilities\n\u2502 \u251c\u2500\u2500 REQUEST_TYPES_GUIDE.md # Node & Search request documentation\n\u2502 \u2514\u2500\u2500 API_DOCUMENTATION_INDEX.md # Complete API reference\n\u251c\u2500\u2500 examples/ # Working usage examples\n\u251c\u2500\u2500 requirements.txt # Runtime dependencies\n\u251c\u2500\u2500 requirements-dev.txt # Development dependencies\n\u251c\u2500\u2500 run_tests.py # Test runner with nice display\n\u2514\u2500\u2500 README.md # This file\n```\n\n\n\n## \ud83d\udccb Requirements\n\n### Runtime Requirements\n\n- **Python**: 3.10+\n- **pydantic**: >=2.0.0,<3.0.0\n- **requests**: >=2.31.0\n- **httpx**: >=0.24.0 (for async support)\n- **aiohttp**: >=3.8.0 (for async HTTP)\n\n### Optional Dependencies\n\n- **stomp.py**: >=8.1.0 (for ActiveMQ events)\n- **ujson**: >=5.7.0 (faster JSON parsing)\n- **requests-oauthlib**: >=1.3.0 (OAuth support)\n\n## \ud83d\udee0\ufe0f Contributing\n\nFor development workflows, code generation, testing, and contribution guidelines, see **[\ud83d\udcd6 Package Developers Guide](docs/PACKAGE_DEVELOPERS_GUIDE.md)**.\n\n## \ud83e\udd1d Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Run tests: `pytest`\n5. Submit a pull request\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.\n\n## \ud83c\udd98 Support\n\n- **Issues**: [GitHub Issues](https://github.com/stevereiner/python-alfresco-api/issues)\n- **Documentation**: [Project Documentation](docs/)\n- **Examples**: [Usage Examples](examples/)\n\n## \ud83d\udd17 Related Projects\n\n- **Model Context Protocol (MCP)**: [MCP Documentation](https://modelcontextprotocol.io/docs) - Standard for AI-data source and function integration\n- **Alfresco Community Edition**: [Community Documentation](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services-Community-Edition/25.1/Alfresco-Content-Services-Community-Edition/Introduction)\n- **Alfresco Enterprise Edition**: [Enterprise Documentation](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/25.1/Alfresco-Content-Services/Introduction)\n- **Pydantic**: [Type validation library](https://pydantic.dev/)\n- **Datamodel-code-generator**: [Pydantic model generator](https://github.com/koxudaxi/datamodel-code-generator)\n- **Openapi-python-client**: [HTTP client generator](https://github.com/openapi-generators/openapi-python-client)\n- **MCP Server based on Python Alfresco API**: [python-alfresco-mcp-server](https://github.com/stevereiner/python-alfresco-mcp-server)\n\n## \u2b50 Star History\n\nIf this project helps you, please consider giving it a star! \u2b50\n\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Python Client for all Alfresco Content Services REST APIs, with Pydantic v2 Models, and Event Support",
"version": "1.1.1",
"project_urls": {
"Bug Tracker": "https://github.com/stevereiner/python-alfresco-api/issues",
"Documentation": "https://github.com/stevereiner/python-alfresco-api/docs",
"Homepage": "https://github.com/stevereiner/python-alfresco-api",
"Repository": "https://github.com/stevereiner/python-alfresco-api"
},
"split_keywords": [
"alfresco",
" content-management",
" document-management",
" ecm",
" rest-api"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "9756ce72e878805ab141b89fb40b44c41bf55d26399b3872eb5af058622cc377",
"md5": "075e6d6a93e53fd2e50fc8be78a525e0",
"sha256": "8a673f63cb2d6f381a728aa5a07a8426982ebc4c24928084a9a92ad4f37bfaf8"
},
"downloads": -1,
"filename": "python_alfresco_api-1.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "075e6d6a93e53fd2e50fc8be78a525e0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 931200,
"upload_time": "2025-07-21T11:51:46",
"upload_time_iso_8601": "2025-07-21T11:51:46.135542Z",
"url": "https://files.pythonhosted.org/packages/97/56/ce72e878805ab141b89fb40b44c41bf55d26399b3872eb5af058622cc377/python_alfresco_api-1.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "aaec7e9014be61405867f191682ed9d89dbf8305d151d183831494177ce67502",
"md5": "4d40f32e66513b817a673878a32eff93",
"sha256": "c381139a6b8959b7daf6bda9e2cc868c8b03aa7ea82979f87e827822e35ca7dd"
},
"downloads": -1,
"filename": "python_alfresco_api-1.1.1.tar.gz",
"has_sig": false,
"md5_digest": "4d40f32e66513b817a673878a32eff93",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 796349,
"upload_time": "2025-07-21T11:51:47",
"upload_time_iso_8601": "2025-07-21T11:51:47.825381Z",
"url": "https://files.pythonhosted.org/packages/aa/ec/7e9014be61405867f191682ed9d89dbf8305d151d183831494177ce67502/python_alfresco_api-1.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-21 11:51:47",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "stevereiner",
"github_project": "python-alfresco-api",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "httpx",
"specs": [
[
">=",
"0.25.0"
]
]
},
{
"name": "requests",
"specs": [
[
">=",
"2.31.0"
]
]
},
{
"name": "aiohttp",
"specs": [
[
">=",
"3.8.0"
]
]
},
{
"name": "pydantic",
"specs": [
[
"<",
"3.0.0"
],
[
">=",
"2.0.0"
]
]
},
{
"name": "attrs",
"specs": [
[
">=",
"23.1.0"
]
]
},
{
"name": "python-dateutil",
"specs": [
[
">=",
"2.8.0"
]
]
},
{
"name": "typing-extensions",
"specs": [
[
">=",
"4.7.0"
]
]
},
{
"name": "PyYAML",
"specs": [
[
">=",
"6.0"
]
]
},
{
"name": "stomp.py",
"specs": [
[
">=",
"8.1.0"
]
]
},
{
"name": "ujson",
"specs": [
[
">=",
"5.7.0"
]
]
},
{
"name": "requests-oauthlib",
"specs": [
[
">=",
"1.3.0"
]
]
},
{
"name": "yarl",
"specs": [
[
">=",
"1.9.0"
]
]
}
],
"lcname": "python-alfresco-api"
}