docs: Add comprehensive Wiki.js version compatibility documentation

Add detailed compatibility documentation and version detection:

- Add Wiki.js 2.x compatibility badge and requirements to README
- Create comprehensive docs/compatibility.md guide
  - Detailed version support matrix (2.2 through 2.5.308+)
  - API schema differences between 2.x and 3.x
  - Version detection examples and troubleshooting
  - Known compatibility issues and solutions
  - Future 3.x support planning
- Enhance test_connection() in both sync and async clients
  - Add API version compatibility detection
  - Better error messages for incompatible versions
  - Detect Wiki.js 3.x and provide clear guidance
- Update package metadata
  - Add Wiki.js compatibility keywords to setup.py and pyproject.toml
  - Add compatibility documentation link to project URLs

SDK supports Wiki.js 2.x (versions 2.2 - 2.5.308+)
Wiki.js 3.x (alpha) not yet supported due to different API schema

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude
2025-10-23 20:01:14 +00:00
parent 6fbd24d737
commit 5cd55e65af
6 changed files with 496 additions and 17 deletions

View File

@@ -2,6 +2,7 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python Support](https://img.shields.io/badge/python-3.8+-blue.svg)](https://python.org) [![Python Support](https://img.shields.io/badge/python-3.8+-blue.svg)](https://python.org)
[![Wiki.js Support](https://img.shields.io/badge/Wiki.js-2.2+-green.svg)](https://docs.requarks.io/releases)
[![Repository](https://img.shields.io/badge/repo-Gitea-green.svg)](https://gitea.hotserv.cloud/lmiranda/py-wikijs) [![Repository](https://img.shields.io/badge/repo-Gitea-green.svg)](https://gitea.hotserv.cloud/lmiranda/py-wikijs)
[![Issues](https://img.shields.io/badge/issues-Gitea-blue.svg)](https://gitea.hotserv.cloud/lmiranda/py-wikijs/issues) [![Issues](https://img.shields.io/badge/issues-Gitea-blue.svg)](https://gitea.hotserv.cloud/lmiranda/py-wikijs/issues)
@@ -50,6 +51,21 @@ new_page = client.pages.create(PageCreate(
--- ---
## 📋 Requirements
### System Requirements
- **Python**: 3.8 or higher
- **Wiki.js**: 2.2 or higher (tested with 2.5.x series)
- **API Access**: Valid API key with appropriate permissions
### Compatibility Notes
> **✅ Supported**: This SDK is designed for **Wiki.js 2.x** (versions 2.2 through 2.5.308+)
> **⚠️ Not Supported**: Wiki.js 3.x (alpha) uses a different API schema and is not yet supported
For detailed compatibility information, see [docs/compatibility.md](docs/compatibility.md).
---
## 🎯 Current Development Status ## 🎯 Current Development Status
### **Phase 1: MVP Development** ✅ **COMPLETE** ### **Phase 1: MVP Development** ✅ **COMPLETE**
@@ -76,6 +92,8 @@ new_page = client.pages.create(PageCreate(
### **For Users** ### **For Users**
- **[Quick Start](#quick-start)**: Basic setup and usage - **[Quick Start](#quick-start)**: Basic setup and usage
- **[Requirements](#requirements)**: System and Wiki.js version requirements
- **[Compatibility Guide](docs/compatibility.md)**: Detailed version compatibility information
- **[API Reference](docs/api_reference.md)**: Complete SDK documentation - **[API Reference](docs/api_reference.md)**: Complete SDK documentation
- **[User Guide](docs/user_guide.md)**: Comprehensive usage guide with examples - **[User Guide](docs/user_guide.md)**: Comprehensive usage guide with examples
- **[Examples](examples/)**: Real-world usage examples and code samples - **[Examples](examples/)**: Real-world usage examples and code samples
@@ -111,9 +129,11 @@ We welcome contributions! This project showcases systematic development with pro
## 🛠️ Development Setup ## 🛠️ Development Setup
### Prerequisites ### Prerequisites
- Python 3.8+ See [Requirements](#requirements) for system and Wiki.js version requirements.
Additional development tools:
- Git - Git
- Wiki.js instance for testing - Wiki.js 2.x instance for testing (2.2 or higher)
### Local Development ### Local Development
```bash ```bash

405
docs/compatibility.md Normal file
View File

@@ -0,0 +1,405 @@
# Wiki.js Compatibility Guide
**Last Updated**: October 2025
**SDK Version**: v0.1.0+
---
## 📋 Overview
This document provides detailed information about Wiki.js version compatibility for the py-wikijs Python SDK.
---
## ✅ Supported Versions
This SDK is compatible with **Wiki.js 2.x** (version 2.2 and higher).
### Tested Versions
| Wiki.js Version | Status | Notes |
|-----------------|--------|-------|
| **2.5.308** | ✅ Fully Tested | Current stable release |
| **2.5.x series** | ✅ Supported | All 2.5.x versions |
| **2.4.x series** | ✅ Supported | Limited testing |
| **2.3.x series** | ✅ Supported | Limited testing |
| **2.2.x series** | ✅ Supported | API baseline version |
| **2.0 - 2.1** | ⚠️ Partial | Missing API features |
| **1.x series** | ❌ Not Supported | Legacy version |
| **3.x (alpha)** | ❌ Not Supported | Different API schema |
### Version Requirements
**Minimum Requirements:**
- **Wiki.js**: 2.2 or higher
- **Python**: 3.8 or higher
- **API Access**: API key authentication enabled
**Recommended:**
- **Wiki.js**: 2.5.x (latest stable)
- **Python**: 3.10 or higher
- **Permissions**: Full admin API key for complete functionality
---
## 🔍 API Version Details
### Wiki.js 2.x API Schema
This SDK uses the **Wiki.js 2.x GraphQL API schema**, which features nested query structure:
```graphql
# Pages API (2.x)
query {
pages {
list(limit: 10) {
id
title
path
}
}
}
# Users API (2.x)
query {
users {
list {
id
name
email
}
}
}
# Groups API (2.x)
query {
groups {
list {
id
name
permissions
}
}
}
# Assets API (2.x)
query {
assets {
list {
id
filename
fileSize
}
}
}
```
### Key API Features by Version
| Feature | Version Added | SDK Support |
|---------|---------------|-------------|
| **GraphQL API** | 2.0 | ✅ |
| **API Key Authentication** | 2.2 | ✅ |
| **Pages API** | 2.2 | ✅ Full CRUD |
| **Users API** | 2.2 | ✅ Full CRUD |
| **Groups API** | 2.2 | ✅ Full CRUD |
| **Assets API** | 2.2 | ✅ Full management |
| **Page Rules** | 2.3 | ✅ Supported |
| **Batch Operations** | N/A | ✅ SDK feature |
| **Auto-Pagination** | N/A | ✅ SDK feature |
---
## ⚠️ Not Supported: Wiki.js 3.x
### Why 3.x Is Not Supported
Wiki.js 3.x (currently in alpha) introduces **breaking API changes**:
1. **Flattened GraphQL Schema**: Queries moved to root level
2. **Different Naming Convention**: `users.list``usersList`
3. **Modified Response Format**: Different data structures
4. **New Authentication Methods**: Updated auth flow
### Example 3.x API Difference
```graphql
# Wiki.js 2.x (Supported)
query {
pages {
list { id title }
}
}
# Wiki.js 3.x (Not Supported)
query {
pagesList { id title }
}
```
### When Will 3.x Be Supported?
Support for Wiki.js 3.x will be considered when:
- ✅ 3.x reaches stable/beta status (no ETA yet)
- ✅ API schema is finalized
- ✅ Community adoption begins
**Planned Approach**: Release as separate major version (v2.0.0 or v3.0.0) with dual support strategy.
---
## 🔧 Version Detection
### Automatic Compatibility Check
The SDK includes automatic version detection in the `test_connection()` method:
```python
from wikijs import WikiJSClient
client = WikiJSClient('https://wiki.example.com', auth='your-api-key')
try:
if client.test_connection():
print("✅ Compatible Wiki.js version detected")
except Exception as e:
print(f"❌ Compatibility issue: {e}")
```
### Manual Version Check
To manually verify your Wiki.js version:
```python
from wikijs import WikiJSClient
client = WikiJSClient('https://wiki.example.com', auth='your-api-key')
# Test with a simple query
try:
pages = client.pages.list(limit=1)
print(f"✅ API compatible - found {len(pages)} page(s)")
except Exception as e:
print(f"❌ API incompatible: {e}")
```
### GraphQL Introspection
You can also check the API schema directly:
```python
client = WikiJSClient('https://wiki.example.com', auth='your-api-key')
# Query for API schema information
query = """
query {
__schema {
queryType {
name
}
}
}
"""
try:
response = client._request("POST", "/graphql", json_data={"query": query})
print(f"API Schema: {response}")
except Exception as e:
print(f"Schema check failed: {e}")
```
---
## 🚀 Feature Compatibility Matrix
### Core Features
| Feature | Wiki.js 2.2 | Wiki.js 2.3 | Wiki.js 2.4 | Wiki.js 2.5 |
|---------|-------------|-------------|-------------|-------------|
| Pages CRUD | ✅ | ✅ | ✅ | ✅ |
| Users CRUD | ✅ | ✅ | ✅ | ✅ |
| Groups CRUD | ✅ | ✅ | ✅ | ✅ |
| Assets Management | ✅ | ✅ | ✅ | ✅ |
| Page Rules | ⚠️ Basic | ✅ | ✅ | ✅ |
| Batch Operations | ✅ | ✅ | ✅ | ✅ |
| Async Support | ✅ | ✅ | ✅ | ✅ |
| Caching | ✅ | ✅ | ✅ | ✅ |
### SDK Features (Version Independent)
These features work across all supported Wiki.js versions:
-**Synchronous Client**: Full support
-**Async Client**: Full support with aiohttp
-**Type Safety**: Pydantic models with validation
-**Error Handling**: Comprehensive exception hierarchy
-**Retry Logic**: Exponential backoff on failures
-**Connection Pooling**: Efficient HTTP connections
-**Batch Operations**: SDK-level batch processing
-**Auto-Pagination**: Seamless iteration over large datasets
-**Caching**: LRU cache with TTL support
---
## 🐛 Known Compatibility Issues
### Issue 1: API Key Permissions
**Affected Versions**: All
**Symptom**: 403 Forbidden errors on certain operations
**Cause**: Insufficient API key permissions
**Solution**: Ensure API key has appropriate permissions for the operations you need
```python
# Test permissions
try:
pages = client.pages.list() # Requires read permission
client.pages.create(...) # Requires write permission
client.users.list() # Requires admin permission
except PermissionError as e:
print(f"Permission denied: {e}")
```
### Issue 2: GraphQL Rate Limiting
**Affected Versions**: 2.4+
**Symptom**: 429 Too Many Requests
**Cause**: Too many API calls in short time
**Solution**: Use SDK's built-in retry logic or implement rate limiting
```python
from wikijs import WikiJSClient
from wikijs.cache import MemoryCache
# Enable caching to reduce API calls
cache = MemoryCache(ttl=300)
client = WikiJSClient(
'https://wiki.example.com',
auth='your-api-key',
cache=cache
)
```
### Issue 3: Large File Uploads
**Affected Versions**: All
**Symptom**: Timeout or memory errors on large asset uploads
**Cause**: Default timeout too short for large files
**Solution**: Increase timeout for upload operations
```python
# Increase timeout for large uploads
client = WikiJSClient(
'https://wiki.example.com',
auth='your-api-key',
timeout=300 # 5 minutes
)
# Upload large file
with open('large-file.pdf', 'rb') as f:
asset = client.assets.upload(f, folder_id=1)
```
---
## 📊 Compatibility Testing
### How We Test Compatibility
1. **Unit Tests**: Test against mocked API responses
2. **Integration Tests**: Test against live Wiki.js 2.5.x instance
3. **Manual Testing**: Periodic testing against 2.4.x and 2.3.x
4. **Community Reports**: User feedback on different versions
### Running Compatibility Tests
```bash
# Run full test suite
pytest
# Run integration tests only
pytest -m integration
# Run with specific Wiki.js version
WIKIJS_VERSION=2.5.308 pytest -m integration
```
### Reporting Compatibility Issues
If you encounter compatibility issues:
1. **Check this guide** for known issues
2. **Verify Wiki.js version**: Ensure you're running 2.2+
3. **Test with examples**: Try SDK examples first
4. **Report issue**: Include Wiki.js version, SDK version, and error details
---
## 🔮 Future Compatibility
### Planned Support
| Version | Status | Timeline |
|---------|--------|----------|
| **Wiki.js 2.6+** | ✅ Planned | Automatic (same API) |
| **Wiki.js 3.0** | 📅 Future | When 3.0 reaches beta |
| **Backward Compat** | ✅ Committed | Will maintain 2.x support |
### Migration Strategy for 3.x
When Wiki.js 3.x becomes stable:
1. **Dual Support**: Maintain both 2.x and 3.x compatibility
2. **Version Detection**: Auto-detect Wiki.js version
3. **Clear Documentation**: Migration guide for 3.x users
4. **Gradual Transition**: Long deprecation period for 2.x
Example future API:
```python
# Future: Automatic version detection
from wikijs import WikiJSClient
# Will work with both 2.x and 3.x
client = WikiJSClient('https://wiki.example.com', auth='key')
# Or force specific version
from wikijs.v2 import WikiJSClient as WikiJSClientV2
from wikijs.v3 import WikiJSClient as WikiJSClientV3
client_v2 = WikiJSClientV2(...) # Force 2.x API
client_v3 = WikiJSClientV3(...) # Force 3.x API
```
---
## 📞 Support
### Getting Help
- **Documentation**: [Full documentation](../README.md)
- **Examples**: [Usage examples](../examples/)
- **Issues**: [Report compatibility issues](https://gitea.hotserv.cloud/lmiranda/py-wikijs/issues)
### Resources
- **Wiki.js Documentation**: https://docs.requarks.io/
- **Wiki.js Releases**: https://docs.requarks.io/releases
- **Wiki.js GraphQL API**: https://docs.requarks.io/dev/api
- **Community Forum**: https://github.com/requarks/wiki/discussions
---
## 📝 Version History
| SDK Version | Min Wiki.js | Max Wiki.js | Notes |
|-------------|-------------|-------------|-------|
| **0.1.0** | 2.2 | 2.5.308+ | Initial release |
| **0.2.0** | 2.2 | 2.5.308+ | Added async support |
---
**Last Updated**: October 2025
**Next Review**: When Wiki.js 3.0 beta is released
For the latest compatibility information, always check this guide or visit the [project repository](https://gitea.hotserv.cloud/lmiranda/py-wikijs).

View File

@@ -30,7 +30,7 @@ dependencies = [
"typing-extensions>=4.0.0", "typing-extensions>=4.0.0",
] ]
dynamic = ["version"] dynamic = ["version"]
keywords = ["wiki", "wikijs", "api", "sdk", "client", "http", "rest"] keywords = ["wiki", "wikijs", "wiki.js", "api", "sdk", "client", "http", "rest", "graphql", "wiki.js-2.x"]
[project.optional-dependencies] [project.optional-dependencies]
dev = [ dev = [
@@ -64,6 +64,8 @@ Homepage = "https://gitea.hotserv.cloud/lmiranda/py-wikijs"
"Bug Reports" = "https://gitea.hotserv.cloud/lmiranda/py-wikijs/issues" "Bug Reports" = "https://gitea.hotserv.cloud/lmiranda/py-wikijs/issues"
Source = "https://gitea.hotserv.cloud/lmiranda/py-wikijs" Source = "https://gitea.hotserv.cloud/lmiranda/py-wikijs"
Documentation = "https://gitea.hotserv.cloud/lmiranda/py-wikijs/src/branch/main/docs" Documentation = "https://gitea.hotserv.cloud/lmiranda/py-wikijs/src/branch/main/docs"
Compatibility = "https://gitea.hotserv.cloud/lmiranda/py-wikijs/src/branch/main/docs/compatibility.md"
"Wiki.js" = "https://js.wiki"
[tool.setuptools.dynamic] [tool.setuptools.dynamic]
version = {attr = "wikijs.version.__version__"} version = {attr = "wikijs.version.__version__"}

View File

@@ -54,6 +54,8 @@ setup(
"Bug Reports": "https://gitea.hotserv.cloud/lmiranda/py-wikijs/issues", "Bug Reports": "https://gitea.hotserv.cloud/lmiranda/py-wikijs/issues",
"Source": "https://gitea.hotserv.cloud/lmiranda/py-wikijs", "Source": "https://gitea.hotserv.cloud/lmiranda/py-wikijs",
"Documentation": "https://gitea.hotserv.cloud/lmiranda/py-wikijs/src/branch/main/docs", "Documentation": "https://gitea.hotserv.cloud/lmiranda/py-wikijs/src/branch/main/docs",
"Compatibility": "https://gitea.hotserv.cloud/lmiranda/py-wikijs/src/branch/main/docs/compatibility.md",
"Wiki.js": "https://js.wiki",
}, },
packages=find_packages(), packages=find_packages(),
include_package_data=True, include_package_data=True,
@@ -84,6 +86,6 @@ setup(
"Topic :: Documentation", "Topic :: Documentation",
"Typing :: Typed", "Typing :: Typed",
], ],
keywords=["wiki", "wikijs", "api", "sdk", "client", "http", "rest"], keywords=["wiki", "wikijs", "wiki.js", "api", "sdk", "client", "http", "rest", "graphql", "wiki.js-2.x"],
zip_safe=False, zip_safe=False,
) )

View File

@@ -278,19 +278,24 @@ class AsyncWikiJSClient:
return parse_wiki_response(data) return parse_wiki_response(data)
async def test_connection(self) -> bool: async def test_connection(self) -> bool:
"""Test connection to Wiki.js instance. """Test connection to Wiki.js instance and verify API compatibility.
This method validates the connection by making an actual GraphQL query This method validates the connection by making an actual GraphQL query
to the Wiki.js API, ensuring both connectivity and authentication work. to the Wiki.js API, ensuring both connectivity and authentication work.
It also performs basic API version compatibility detection.
Returns: Returns:
True if connection successful True if connection successful and API version is compatible
Raises: Raises:
ConfigurationError: If client is not properly configured ConfigurationError: If client is not properly configured or API version incompatible
ConnectionError: If cannot connect to server ConnectionError: If cannot connect to server
AuthenticationError: If authentication fails AuthenticationError: If authentication fails
TimeoutError: If connection test times out TimeoutError: If connection test times out
Note:
This SDK is designed for Wiki.js 2.x (2.2+). Wiki.js 3.x uses a different
API schema and is not yet supported.
""" """
if not self.base_url: if not self.base_url:
raise ConfigurationError("Base URL not configured") raise ConfigurationError("Base URL not configured")
@@ -299,7 +304,8 @@ class AsyncWikiJSClient:
raise ConfigurationError("Authentication not configured") raise ConfigurationError("Authentication not configured")
try: try:
# Test with minimal GraphQL query to validate API access # Test with minimal GraphQL query to validate API access and version
# This query uses the 2.x nested structure
query = """ query = """
query { query {
site { site {
@@ -315,12 +321,28 @@ class AsyncWikiJSClient:
# Check for GraphQL errors # Check for GraphQL errors
if "errors" in response: if "errors" in response:
error_msg = response["errors"][0].get("message", "Unknown error") error_msg = response["errors"][0].get("message", "Unknown error")
# Check if error indicates API version mismatch
if "Cannot query field" in error_msg or "Unknown type" in error_msg:
raise ConfigurationError(
f"Incompatible Wiki.js API version detected. "
f"This SDK requires Wiki.js 2.2 or higher (2.x series). "
f"Wiki.js 3.x is not yet supported. Error: {error_msg}"
)
raise AuthenticationError(f"GraphQL query failed: {error_msg}") raise AuthenticationError(f"GraphQL query failed: {error_msg}")
# Verify we got expected data structure # Verify we got expected data structure (2.x format)
if "data" not in response or "site" not in response["data"]: if "data" not in response or "site" not in response["data"]:
raise APIError("Unexpected response format from Wiki.js API") # This might indicate a 3.x API or completely different API
raise ConfigurationError(
"Incompatible Wiki.js API detected. "
"This SDK requires Wiki.js 2.x (version 2.2 or higher). "
"Wiki.js 3.x uses a different API schema and is not yet supported. "
"See docs/compatibility.md for more information."
)
# Connection successful and API version compatible
return True return True
except AuthenticationError: except AuthenticationError:
@@ -335,6 +357,10 @@ class AsyncWikiJSClient:
# Re-raise connection errors as-is # Re-raise connection errors as-is
raise raise
except ConfigurationError:
# Re-raise configuration errors as-is
raise
except APIError: except APIError:
# Re-raise API errors as-is # Re-raise API errors as-is
raise raise

View File

@@ -243,19 +243,24 @@ class WikiJSClient:
return parse_wiki_response(data) return parse_wiki_response(data)
def test_connection(self) -> bool: def test_connection(self) -> bool:
"""Test connection to Wiki.js instance. """Test connection to Wiki.js instance and verify API compatibility.
This method validates the connection by making an actual GraphQL query This method validates the connection by making an actual GraphQL query
to the Wiki.js API, ensuring both connectivity and authentication work. to the Wiki.js API, ensuring both connectivity and authentication work.
It also performs basic API version compatibility detection.
Returns: Returns:
True if connection successful True if connection successful and API version is compatible
Raises: Raises:
ConfigurationError: If client is not properly configured ConfigurationError: If client is not properly configured or API version incompatible
ConnectionError: If cannot connect to server ConnectionError: If cannot connect to server
AuthenticationError: If authentication fails AuthenticationError: If authentication fails
TimeoutError: If connection test times out TimeoutError: If connection test times out
Note:
This SDK is designed for Wiki.js 2.x (2.2+). Wiki.js 3.x uses a different
API schema and is not yet supported.
""" """
if not self.base_url: if not self.base_url:
raise ConfigurationError("Base URL not configured") raise ConfigurationError("Base URL not configured")
@@ -264,7 +269,8 @@ class WikiJSClient:
raise ConfigurationError("Authentication not configured") raise ConfigurationError("Authentication not configured")
try: try:
# Test with minimal GraphQL query to validate API access # Test with minimal GraphQL query to validate API access and version
# This query uses the 2.x nested structure
query = """ query = """
query { query {
site { site {
@@ -278,16 +284,30 @@ class WikiJSClient:
# Check for GraphQL errors # Check for GraphQL errors
if "errors" in response: if "errors" in response:
error_msg = response["errors"][0].get("message", "Unknown error") error_msg = response["errors"][0].get("message", "Unknown error")
# Check if error indicates API version mismatch
if "Cannot query field" in error_msg or "Unknown type" in error_msg:
raise ConfigurationError(
f"Incompatible Wiki.js API version detected. "
f"This SDK requires Wiki.js 2.2 or higher (2.x series). "
f"Wiki.js 3.x is not yet supported. Error: {error_msg}"
)
raise AuthenticationError( raise AuthenticationError(
f"GraphQL query failed: {error_msg}" f"GraphQL query failed: {error_msg}"
) )
# Verify we got expected data structure # Verify we got expected data structure (2.x format)
if "data" not in response or "site" not in response["data"]: if "data" not in response or "site" not in response["data"]:
raise APIError( # This might indicate a 3.x API or completely different API
"Unexpected response format from Wiki.js API" raise ConfigurationError(
"Incompatible Wiki.js API detected. "
"This SDK requires Wiki.js 2.x (version 2.2 or higher). "
"Wiki.js 3.x uses a different API schema and is not yet supported. "
"See docs/compatibility.md for more information."
) )
# Connection successful and API version compatible
return True return True
except AuthenticationError: except AuthenticationError:
@@ -302,6 +322,10 @@ class WikiJSClient:
# Re-raise connection errors as-is # Re-raise connection errors as-is
raise raise
except ConfigurationError:
# Re-raise configuration errors as-is
raise
except APIError: except APIError:
# Re-raise API errors as-is # Re-raise API errors as-is
raise raise