Complete Phase 1 foundation: Tasks 1.1 and 1.2

 Task 1.1 - Project Foundation Setup:
- Repository structure with Python packaging (setup.py, pyproject.toml)
- Development dependencies and requirements
- Contributing guidelines and MIT license
- GitHub workflows for CI/CD (test.yml, release.yml)
- Issue and PR templates for community contributions
- Comprehensive project documentation

 Task 1.2 - Core Client Structure:
- wikijs package with proper module organization
- Core client class foundation in client.py
- Exception hierarchy for error handling
- Base model classes and page models
- Type checking support (py.typed)
- Utility modules and helper functions

📊 Progress: Phase 1 MVP Development now 40% complete
🎯 Next: Task 1.3 - Authentication System implementation

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-29 13:25:36 -04:00
parent 3554d7d69c
commit 11b6be87c8
31 changed files with 3805 additions and 115 deletions

49
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,49 @@
---
name: Bug Report
about: Create a report to help us improve
title: '[BUG] '
labels: ['bug']
assignees: ''
---
## Bug Description
A clear and concise description of what the bug is.
## Steps to Reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
## Expected Behavior
A clear and concise description of what you expected to happen.
## Actual Behavior
A clear and concise description of what actually happened.
## Code Example
If applicable, add code snippets to help explain your problem.
```python
# Your code here
```
## Environment
- **SDK Version**: [e.g. 0.1.0]
- **Python Version**: [e.g. 3.11.0]
- **Operating System**: [e.g. Ubuntu 22.04]
- **Wiki.js Version**: [e.g. 2.5.300]
## Error Messages
If applicable, add any error messages or stack traces.
```
Paste error messages here
```
## Additional Context
Add any other context about the problem here.
## Possible Solution
If you have suggestions on how to fix the bug, please describe them here.

View File

@@ -0,0 +1,59 @@
---
name: Feature Request
about: Suggest an idea for this project
title: '[FEATURE] '
labels: ['enhancement']
assignees: ''
---
## Feature Summary
A clear and concise description of the feature you'd like to request.
## Problem Statement
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
## Proposed Solution
Describe the solution you'd like.
A clear and concise description of what you want to happen.
## Use Case
Describe your use case for this feature.
- Who would benefit from this feature?
- What problem does it solve?
- How would you use it?
## API Design (if applicable)
If you have ideas about how the API should look, include them here.
```python
# Example of how you envision using this feature
client = WikiJSClient(...)
result = client.new_feature.do_something()
```
## Alternatives Considered
Describe alternatives you've considered.
A clear and concise description of any alternative solutions or features you've considered.
## Implementation Notes
If you have ideas about implementation, include them here.
- Are there any technical challenges?
- Dependencies that might be needed?
- Breaking changes required?
## Additional Context
Add any other context, screenshots, or examples about the feature request here.
## Priority
How important is this feature to you?
- [ ] Nice to have
- [ ] Important for my use case
- [ ] Critical for my use case
## Contribution
Are you willing to contribute to implementing this feature?
- [ ] Yes, I can implement this
- [ ] Yes, but I need guidance
- [ ] No, but I can help with testing
- [ ] No, I just want to request it

66
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,66 @@
# Pull Request
## Description
Brief description of what this PR does and why.
## Type of Change
Please delete options that are not relevant.
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)
- [ ] Test improvements
## Related Issues
Closes #(issue_number)
Relates to #(issue_number)
## Changes Made
-
-
-
## Testing
- [ ] Tests pass locally
- [ ] Added tests for new functionality
- [ ] Updated existing tests
- [ ] Manual testing completed
Describe any testing you performed:
## Documentation
- [ ] Updated docstrings
- [ ] Updated README if needed
- [ ] Updated API documentation
- [ ] Added/updated examples
## Code Quality
- [ ] Code follows the style guidelines
- [ ] Self-review of the code completed
- [ ] Code is commented where necessary
- [ ] No new warnings introduced
## Breaking Changes
If this introduces breaking changes, please describe them and provide migration guidance:
## Screenshots/Examples
If applicable, add screenshots or code examples to help explain your changes.
```python
# Example usage
```
## Additional Notes
Any additional information that reviewers should know.
---
## Reviewer Checklist
- [ ] Code follows project style guidelines
- [ ] Changes are well documented
- [ ] Tests are adequate and pass
- [ ] No obvious bugs or performance issues
- [ ] Breaking changes are properly documented

66
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,66 @@
name: Release
on:
push:
tags:
- 'v*'
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run tests
run: pytest tests/ -v --cov=wikijs --cov-fail-under=85
- name: Run security scan
run: bandit -r wikijs
release:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
- name: Build package
run: python -m build
- name: Check package
run: twine check dist/*
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: dist/*
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}

111
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,111 @@
name: Test Suite
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Lint with flake8
run: flake8 wikijs tests
- name: Format check with black
run: black --check wikijs tests
- name: Import sort check
run: isort --check-only wikijs tests
- name: Type check with mypy
run: mypy wikijs
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run unit tests
run: pytest tests/ -v --cov=wikijs --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run security scan with bandit
run: bandit -r wikijs -f json -o bandit-report.json || true
- name: Upload bandit report
uses: actions/upload-artifact@v3
with:
name: bandit-report
path: bandit-report.json
package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
- name: Build package
run: python -m build
- name: Check package
run: twine check dist/*

134
.gitignore vendored
View File

@@ -1,6 +1,6 @@
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/
*.py[codz] *.py[cod]
*$py.class *$py.class
# C extensions # C extensions
@@ -27,15 +27,9 @@ share/python-wheels/
MANIFEST MANIFEST
# PyInstaller # PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest *.manifest
*.spec *.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports # Unit test / coverage reports
htmlcov/ htmlcov/
.tox/ .tox/
@@ -46,28 +40,11 @@ htmlcov/
nosetests.xml nosetests.xml
coverage.xml coverage.xml
*.cover *.cover
*.py.cover *.py,cover
.hypothesis/ .hypothesis/
.pytest_cache/ .pytest_cache/
cover/ cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation # Sphinx documentation
docs/_build/ docs/_build/
@@ -83,60 +60,22 @@ profile_default/
ipython_config.py ipython_config.py
# pyenv # pyenv
# For a library or package, you might want to ignore these files since the code is .python-version
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv # pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. Pipfile.lock
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# poetry # poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. poetry.lock
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
#poetry.toml
# pdm # pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. .pdm.toml
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
#pdm.lock
#pdm.toml
.pdm-python
.pdm-build/
# pixi # PEP 582
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
#pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/ __pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments # Environments
.env .env
.envrc
.venv .venv
env/ env/
venv/ venv/
@@ -144,16 +83,6 @@ ENV/
env.bak/ env.bak/
venv.bak/ venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy # mypy
.mypy_cache/ .mypy_cache/
.dmypy.json .dmypy.json
@@ -168,40 +97,19 @@ dmypy.json
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/
# PyCharm # IDEs
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can .idea/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore .vscode/
# and can be added to the global gitignore or merged into this file. For a more nuclear *.swp
# option (not recommended) you can uncomment the following to ignore the entire idea folder. *.swo
#.idea/
# Abstra # OS files
# Abstra is an AI-powered process automation framework. .DS_Store
# Ignore directories containing user credentials, local state, and settings. Thumbs.db
# Learn more at https://abstra.io/docs
.abstra/
# Visual Studio Code # Project specific
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore *.db
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore *.sqlite
# and can be added to the global gitignore or merged into this file. However, if you prefer, .temp/
# you could uncomment the following to ignore the entire vscode folder wiki-test-data/
# .vscode/ test-wiki/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# Cursor
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
# refer to https://docs.cursor.com/context/ignore-files
.cursorignore
.cursorindexingignore
# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/

117
CHANGELOG.md Normal file
View File

@@ -0,0 +1,117 @@
# Changelog
All notable changes to the Wiki.js Python SDK will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Project foundation and repository structure
- Python packaging configuration (setup.py, pyproject.toml)
- CI/CD pipeline with GitHub Actions
- Code quality tools (black, isort, flake8, mypy, bandit)
- Comprehensive documentation structure
- Contributing guidelines and community governance
- Issue and PR templates for GitHub
### Changed
- N/A
### Deprecated
- N/A
### Removed
- N/A
### Fixed
- N/A
### Security
- Added automated security scanning with bandit
## Release Planning
### [0.1.0] - Target: 2 weeks from start
**MVP Release - Basic Wiki.js Integration**
#### Planned Features
- Core WikiJSClient with HTTP transport
- API key authentication
- Pages API with full CRUD operations (list, get, create, update, delete)
- Type-safe data models with Pydantic
- Comprehensive error handling
- >85% test coverage
- Complete API documentation
- PyPI package publication
#### Success Criteria
- [ ] Package installable via `pip install wikijs-python-sdk`
- [ ] Basic page operations work with real Wiki.js instance
- [ ] All quality gates pass (tests, coverage, linting, security)
- [ ] Documentation sufficient for basic usage
### [0.2.0] - Target: 4 weeks from start
**Essential Features - Complete API Coverage**
#### Planned Features
- Users API (full CRUD operations)
- Groups API (management and permissions)
- Assets API (file upload and management)
- System API (health checks and info)
- Enhanced error handling with detailed context
- Configuration management (file and environment-based)
- Basic CLI interface
- Performance benchmarks
### [0.3.0] - Target: 7 weeks from start
**Production Ready - Reliability & Performance**
#### Planned Features
- Retry logic with exponential backoff
- Circuit breaker for fault tolerance
- Intelligent caching with multiple backends
- Rate limiting and API compliance
- Performance monitoring and metrics
- Bulk operations for efficiency
- Connection pooling optimization
### [1.0.0] - Target: 11 weeks from start
**Enterprise Grade - Advanced Features**
#### Planned Features
- Full async/await support with aiohttp
- Advanced CLI with interactive mode
- Plugin architecture for extensibility
- Advanced authentication (JWT rotation, OAuth2)
- Enterprise security features
- Webhook support and verification
- Multi-tenancy support
---
## Development Notes
### Versioning Strategy
- **MAJOR**: Breaking changes that require user action
- **MINOR**: New features that are backward compatible
- **PATCH**: Bug fixes and improvements that are backward compatible
### Quality Standards
All releases must meet:
- [ ] >85% test coverage (>90% for minor releases)
- [ ] 100% type coverage on public APIs
- [ ] All quality gates pass (linting, formatting, security)
- [ ] Complete documentation for new features
- [ ] No known critical bugs
### Community Involvement
- Feature requests welcomed through GitHub issues
- Community feedback incorporated into release planning
- Breaking changes require community discussion period
- Beta releases available for testing major features
---
*This changelog is maintained as part of our commitment to transparency and professional development practices. All changes are documented to help users understand what's new, what's changed, and how to upgrade safely.*

523
CLAUDE.md Normal file
View File

@@ -0,0 +1,523 @@
# CLAUDE.md - AI Development Coordinator
**🤖 AI Development Orchestration System**
**Project**: Wiki.js Python SDK
**Version**: 1.0
**Last Updated**: July 2025
**Status**: Active Development
---
## 🎯 CRITICAL: READ THIS FIRST
**⚠️ MANDATORY ACTIONS FOR EVERY CLAUDE SESSION:**
1. **📚 ALWAYS REFER TO DOCUMENTATION**: Before any development work, review relevant documentation:
- `docs/wikijs_sdk_architecture.md` for technical decisions
- `docs/wikijs_sdk_release_plan.md` for current phase requirements
- `docs/RISK_MANAGEMENT.md` for risk considerations
- `docs/GOVERNANCE.md` for contribution standards
2. **📊 UPDATE PROGRESS TRACKING**: After completing any task, update the completion percentages in this document
3. **🔄 TRIGGER DOCUMENTATION UPDATES**: When completing milestones, update relevant documentation files
4. **✅ VALIDATE QUALITY CHECKPOINTS**: Ensure all quality gates pass before marking tasks complete
5. **🚨 ERROR PREVENTION**: Follow the error prevention guidelines to avoid common issues
---
## 📋 PROJECT CONTEXT & STATUS
### **Project Overview**
**Name**: wikijs-python-sdk
**Purpose**: Professional-grade Python SDK for Wiki.js API integration
**Development Approach**: AI-powered, community-driven, open source
**Target**: Complete professional development lifecycle demonstration
### **Current Development State**
```yaml
Overall_Completion: 15%
Current_Phase: "Phase 1 - MVP Development"
Active_Tasks: "Project Foundation Setup"
Next_Milestone: "v0.1.0 MVP Release"
Target_Date: "2 weeks from start"
```
### **Repository Structure Status**
```
wikijs-python-sdk/ # ✅ COMPLETE
├── README.md # ✅ COMPLETE - Central documentation hub
├── docs/wikijs_sdk_architecture.md # ✅ COMPLETE - Technical foundation
├── docs/wikijs_sdk_release_plan.md # ✅ COMPLETE - Release strategy
├── docs/RISK_MANAGEMENT.md # ✅ COMPLETE - Risk framework
├── docs/GOVERNANCE.md # ✅ COMPLETE - Community charter
├── CLAUDE.md # ✅ COMPLETE - This file
├── CONTRIBUTING.md # ✅ COMPLETE - Task 1.1
├── LICENSE # ✅ COMPLETE - Task 1.1
├── setup.py # ✅ COMPLETE - Task 1.1
├── pyproject.toml # ✅ COMPLETE - Task 1.1
├── requirements.txt # ✅ COMPLETE - Task 1.1
├── requirements-dev.txt # ✅ COMPLETE - Task 1.1
├── .gitignore # ✅ COMPLETE - Task 1.1
├── CHANGELOG.md # ✅ COMPLETE - Task 1.1
├── .github/ # ✅ COMPLETE - Task 1.1
│ ├── workflows/ # CI/CD pipelines
│ ├── ISSUE_TEMPLATE/ # Bug & feature templates
│ └── PULL_REQUEST_TEMPLATE.md # PR template
├── wikijs/ # ✅ COMPLETE - Task 1.2
│ ├── __init__.py # Core package initialization
│ ├── version.py # Version management
│ ├── client.py # Main WikiJSClient class
│ ├── exceptions.py # Exception hierarchy
│ ├── py.typed # Type checking marker
│ ├── models/ # Data models
│ │ ├── __init__.py # Model exports
│ │ ├── base.py # Base model functionality
│ │ └── page.py # Page-related models
│ ├── auth/ # Authentication (Task 1.3)
│ ├── endpoints/ # API endpoints (Task 1.4)
│ └── utils/ # Utility functions
│ ├── __init__.py # Utility exports
│ └── helpers.py # Helper functions
├── tests/ # 🔄 PENDING - Task 1.5
├── docs/ # 🔄 PENDING - Task 1.6
└── examples/ # 🔄 PENDING - Task 1.6
```
---
## 📊 PHASE COMPLETION TRACKING
### **Phase 0: Foundation (100% COMPLETE) ✅**
```yaml
Status: COMPLETE
Completion: 100%
Key_Deliverables:
- ✅ Architecture Documentation
- ✅ Development Plan
- ✅ Risk Management Plan
- ✅ Community Governance Charter
- ✅ Central README Hub
- ✅ AI Development Coordinator (this file)
```
### **Phase 1: MVP Development (0% COMPLETE) 🔄**
```yaml
Status: IN_PROGRESS
Completion: 40%
Target_Completion: 100%
Current_Task: "Task 1.3 - Authentication System"
Task_Breakdown:
Task_1.1_Project_Foundation: # ✅ COMPLETE
Status: "COMPLETE"
Completion: 100%
Estimated_Time: "3 hours"
Claude_Requests: "15-20"
Task_1.2_Core_Client: # ✅ COMPLETE
Status: "COMPLETE"
Completion: 100%
Estimated_Time: "8 hours"
Claude_Requests: "30-40"
Task_1.3_Authentication: # ⏳ PENDING
Status: "PENDING"
Completion: 0%
Estimated_Time: "4 hours"
Claude_Requests: "15-20"
Task_1.4_Pages_API: # ⏳ PENDING
Status: "PENDING"
Completion: 0%
Estimated_Time: "6 hours"
Claude_Requests: "25-30"
Task_1.5_Testing: # ⏳ PENDING
Status: "PENDING"
Completion: 0%
Estimated_Time: "6 hours"
Claude_Requests: "20-25"
Task_1.6_Documentation: # ⏳ PENDING
Status: "PENDING"
Completion: 0%
Estimated_Time: "4 hours"
Claude_Requests: "15-20"
Task_1.7_Release: # ⏳ PENDING
Status: "PENDING"
Completion: 0%
Estimated_Time: "2 hours"
Claude_Requests: "10-15"
```
### **Phase 2: Essential Features (0% COMPLETE) ⏳**
```yaml
Status: PLANNED
Completion: 0%
Target_Start: "After Phase 1 Complete"
```
### **Phase 3: Reliability & Performance (0% COMPLETE) ⏳**
```yaml
Status: PLANNED
Completion: 0%
Target_Start: "After Phase 2 Complete"
```
### **Phase 4: Advanced Features (0% COMPLETE) ⏳**
```yaml
Status: PLANNED
Completion: 0%
Target_Start: "After Phase 3 Complete"
```
---
## 🎯 CURRENT FOCUS: TASK 1.1 - PROJECT FOUNDATION
### **Task 1.1 Detailed Breakdown**
```yaml
Task: "Project Foundation Setup"
Status: "IN_PROGRESS"
Priority: "HIGH"
Completion: 0%
Subtasks:
1.1.1_Repository_Structure:
Description: "Create basic project file structure"
Status: "PENDING"
Files_To_Create:
- CONTRIBUTING.md
- LICENSE (MIT)
- .gitignore
- setup.py
- pyproject.toml
- requirements.txt
- requirements-dev.txt
1.1.2_Python_Packaging:
Description: "Configure Python packaging and dependencies"
Status: "PENDING"
Files_To_Create:
- setup.py with full configuration
- pyproject.toml with tool configurations
- requirements.txt with core dependencies
- requirements-dev.txt with development tools
1.1.3_CI_CD_Pipeline:
Description: "Set up GitHub Actions workflows"
Status: "PENDING"
Files_To_Create:
- .github/workflows/test.yml
- .github/workflows/release.yml
- .github/ISSUE_TEMPLATE/bug_report.md
- .github/ISSUE_TEMPLATE/feature_request.md
- .github/PULL_REQUEST_TEMPLATE.md
1.1.4_Initial_Documentation:
Description: "Create contributor-focused documentation"
Status: "PENDING"
Files_To_Create:
- CONTRIBUTING.md (detailed contribution guide)
- CHANGELOG.md (version history template)
```
### **Completion Criteria for Task 1.1**
- [ ] All repository structure files created
- [ ] Python packaging properly configured
- [ ] CI/CD pipeline functional
- [ ] Contributing guidelines complete
- [ ] All files pass linting and validation
- [ ] **UPDATE PROGRESS**: Set Task_1.1 completion to 100%
---
## 🔄 AUTOMATIC TRIGGERS & ACTIONS
### **📊 Progress Update Triggers**
**TRIGGER**: After completing any subtask or task
**ACTION**: Update completion percentages in this document
**FORMAT**:
```yaml
# Update the relevant section with new percentage
Task_1.1_Project_Foundation:
Status: "COMPLETE" # or "IN_PROGRESS"
Completion: 100% # Updated percentage
```
### **📚 Documentation Update Triggers**
**TRIGGER**: When reaching specific milestones
**ACTIONS TO PERFORM**:
#### **After Task 1.1 Complete**:
```yaml
Files_To_Update:
- README.md: Update development status section
- DEVELOPMENT_PLAN.md: Mark Task 1.1 as complete
- This file (CLAUDE.md): Update progress tracking
```
#### **After Phase 1 Complete**:
```yaml
Files_To_Update:
- README.md: Update feature list and status badges
- CHANGELOG.md: Create v0.1.0 release notes
- DEVELOPMENT_PLAN.md: Mark Phase 1 complete
- ARCHITECTURE.md: Update implementation status
```
### **✅ Quality Checkpoint Triggers**
**TRIGGER**: Before marking any task complete
**MANDATORY CHECKS**:
- [ ] All code passes linting (black, flake8, mypy)
- [ ] All tests pass with >85% coverage
- [ ] Documentation is updated and accurate
- [ ] Security scan passes (bandit)
- [ ] No critical issues in code review
---
## 🚨 ERROR PREVENTION GUIDELINES
### **🔧 Development Environment Setup**
```yaml
Required_Python_Version: ">=3.8"
Required_Tools:
- git
- python (3.8+)
- pip
- pre-commit (for quality checks)
Setup_Commands:
- "python -m pip install --upgrade pip"
- "pip install -e '.[dev]'"
- "pre-commit install"
```
### **📂 File Creation Standards**
**ALWAYS FOLLOW THESE PATTERNS**:
#### **Python Files**:
```python
# Standard header for all Python files
"""Module docstring describing purpose and usage."""
import sys
from typing import Dict, List, Optional
# Local imports last
from .exceptions import WikiJSException
```
#### **Configuration Files**:
- Use consistent formatting (black, isort)
- Include comprehensive comments
- Follow established Python community standards
- Validate syntax before committing
#### **Documentation Files**:
- Use consistent markdown formatting
- Include complete examples
- Cross-reference related documentation
- Keep TOC updated
### **🔍 Common Error Prevention**
```yaml
Avoid_These_Mistakes:
- Creating files without proper headers
- Missing type hints in public APIs
- Incomplete error handling
- Missing tests for new functionality
- Outdated documentation
- Hardcoded values instead of configuration
- Missing docstrings for public methods
- Inconsistent code formatting
```
---
## 🎯 DEVELOPMENT SESSION GUIDANCE
### **Session Startup Checklist**
**EVERY SESSION MUST START WITH**:
1. [ ] Review current phase and task status from this document
2. [ ] Check completion percentages and identify next actions
3. [ ] Review relevant documentation (Architecture, Development Plan)
4. [ ] Confirm understanding of current task requirements
5. [ ] Identify potential risks from Risk Management Plan
### **Session Workflow**
```yaml
1. Context_Loading:
- Read current task details from this document
- Review architectural requirements
- Check quality standards from governance
2. Development_Work:
- Follow established patterns from architecture
- Implement according to development plan specifications
- Apply risk mitigation strategies
- Maintain quality standards
3. Session_Completion:
- Update progress tracking in this document
- Trigger documentation updates if milestone reached
- Validate quality checkpoints
- Prepare context for next session
```
### **Quality Validation Before Task Completion**
```yaml
Code_Quality:
- [ ] All code follows black formatting
- [ ] Type hints on all public APIs
- [ ] Docstrings on all public methods
- [ ] Error handling implemented
- [ ] No hardcoded values
Testing:
- [ ] Unit tests written for new functionality
- [ ] Integration tests updated
- [ ] All tests pass
- [ ] Coverage maintained >85%
Documentation:
- [ ] API documentation updated
- [ ] Examples provided
- [ ] README updated if needed
- [ ] Changelog updated
Security:
- [ ] No hardcoded secrets
- [ ] Input validation implemented
- [ ] Security scan passes
- [ ] Dependencies checked for vulnerabilities
```
---
## 📋 TASK REFERENCE GUIDE
### **Immediate Next Actions** (Task 1.1)
**PRIORITY ORDER**:
1. **Create Repository Structure** (setup.py, requirements.txt, .gitignore)
2. **Configure Python Packaging** (pyproject.toml, dependencies)
3. **Set Up CI/CD Pipeline** (GitHub Actions workflows)
4. **Create Contributing Guidelines** (CONTRIBUTING.md)
### **Task Dependencies**
```yaml
Task_1.1: No dependencies (can start immediately)
Task_1.2: Requires Task 1.1 complete (packaging setup needed)
Task_1.3: Requires Task 1.2 complete (core client foundation needed)
Task_1.4: Requires Task 1.3 complete (authentication needed for API calls)
Task_1.5: Requires Task 1.4 complete (functionality to test)
Task_1.6: Requires Task 1.5 complete (stable code to document)
Task_1.7: Requires Task 1.6 complete (documentation for release)
```
### **Resource Optimization**
```yaml
# Optimize Claude usage by batching related work
Batch_1: "Repository setup + packaging configuration"
Batch_2: "Core client implementation + basic auth"
Batch_3: "API endpoints + error handling"
Batch_4: "Testing framework + initial tests"
Batch_5: "Documentation + examples"
Batch_6: "Release preparation + final validation"
```
---
## 🎯 SUCCESS CRITERIA & MILESTONES
### **Phase 1 Success Criteria**
```yaml
Functional_Requirements:
- [ ] Basic Wiki.js API integration working
- [ ] Pages CRUD operations functional
- [ ] Authentication system operational
- [ ] Error handling comprehensive
- [ ] Package installable via pip
Quality_Requirements:
- [ ] >85% test coverage achieved
- [ ] All quality gates passing
- [ ] Documentation complete and accurate
- [ ] Security scan passes
- [ ] Performance benchmarks established
Community_Requirements:
- [ ] Contributing guidelines clear
- [ ] Code of conduct established
- [ ] Issue templates configured
- [ ] Community communication channels active
```
### **Release Readiness Checklist**
```yaml
v0.1.0_Release_Criteria:
Technical:
- [ ] All Phase 1 tasks complete
- [ ] CI/CD pipeline operational
- [ ] Package builds successfully
- [ ] All tests pass
- [ ] Documentation comprehensive
Quality:
- [ ] Code review complete
- [ ] Security scan clean
- [ ] Performance benchmarks met
- [ ] User acceptance testing passed
Community:
- [ ] Release notes prepared
- [ ] Community notified
- [ ] PyPI package published
- [ ] GitHub release created
```
---
## 🔄 CONTINUOUS IMPROVEMENT
### **Learning & Adaptation**
This document evolves based on development experience:
**After Each Task**:
- Update completion tracking
- Refine time estimates based on actual effort
- Improve error prevention guidelines
- Enhance quality checkpoints
**After Each Phase**:
- Comprehensive retrospective
- Process optimization
- Documentation improvement
- Community feedback integration
### **Version History**
- **v1.0** (July 2025): Initial AI development coordinator
- Future versions will track improvements and lessons learned
---
## 🚀 READY FOR DEVELOPMENT
**CURRENT INSTRUCTION**: Begin Task 1.1 - Project Foundation Setup
**FOCUS**: Create repository structure, Python packaging, and CI/CD pipeline
**SUCCESS CRITERIA**: All foundational files created and validated
**NEXT SESSION TARGET**: Complete Task 1.1 and begin Task 1.2
**REMEMBER**: Always refer to documentation, update progress, and maintain quality standards!
---
**🤖 AI Developer: You are ready to begin professional SDK development. Follow this coordinator for guidance, track progress diligently, and build something amazing!**

342
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,342 @@
# Contributing to Wiki.js Python SDK
Thank you for your interest in contributing to the Wiki.js Python SDK! This guide will help you get started with contributing to this AI-assisted, community-driven project.
## 🎯 Project Context
This project is being developed entirely with AI assistance (Claude), showcasing professional development practices while building a production-ready SDK for Wiki.js. We welcome contributors of all experience levels!
**Current Status**: MVP Development (Phase 1)
**Focus**: Core functionality and foundational quality
## 🚀 Getting Started
### Prerequisites
- Python 3.8 or higher
- Git
- A GitHub account
- (Optional) A Wiki.js instance for testing
### Development Setup
1. **Fork the Repository**
```bash
# Fork on GitHub, then clone your fork
git clone https://github.com/yourusername/wikijs-python-sdk.git
cd wikijs-python-sdk
```
2. **Set Up Development Environment**
```bash
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install
```
3. **Verify Setup**
```bash
# Run tests
pytest
# Run quality checks
pre-commit run --all-files
```
## 📋 Development Process
### Finding Work
1. **Check Current Priorities**
- Review [CLAUDE.md](CLAUDE.md) for current development tasks
- See [Development Plan](docs/wikijs_sdk_release_plan.md) for roadmap
- Look for issues labeled `good first issue`
2. **Understand Architecture**
- Read [Architecture Overview](docs/wikijs_sdk_architecture.md)
- Review existing code patterns
- Check the [Risk Management](docs/RISK_MANAGEMENT.md) for known issues
### Making Changes
1. **Create Feature Branch**
```bash
git checkout -b feature/your-feature-name
```
2. **Follow Code Standards**
- Write type hints for all public APIs
- Add docstrings to all public methods (Google style)
- Follow existing code patterns
- Keep functions small and focused
3. **Write Tests**
- Add unit tests for new functionality
- Maintain >85% code coverage
- Use descriptive test names
- Include edge cases
4. **Update Documentation**
- Update docstrings for changed methods
- Add examples for new features
- Update README if needed
### Code Quality Standards
#### Python Style
```python
def example_function(param: str, optional: Optional[int] = None) -> bool:
"""Example function following our standards.
Args:
param: Description of the parameter
optional: Optional parameter with default
Returns:
Boolean result of the operation
Raises:
ValueError: If param is empty
Example:
>>> example_function("test")
True
"""
if not param:
raise ValueError("param cannot be empty")
# Implementation here
return True
```
#### Testing Patterns
```python
import pytest
from wikijs import WikiJSClient
from wikijs.exceptions import WikiJSException
class TestWikiJSClient:
"""Test WikiJS client functionality."""
def test_client_initialization_success(self):
"""Test successful client initialization."""
client = WikiJSClient("https://wiki.example.com", "api-key")
assert client.base_url == "https://wiki.example.com"
def test_client_initialization_invalid_url(self):
"""Test client initialization with invalid URL."""
with pytest.raises(ValueError, match="Invalid URL"):
WikiJSClient("invalid-url", "api-key")
```
### Submitting Changes
1. **Run Quality Checks**
```bash
# Format code
black wikijs tests
isort wikijs tests
# Run linting
flake8 wikijs tests
mypy wikijs
# Run tests
pytest --cov=wikijs --cov-fail-under=85
# Security scan
bandit -r wikijs
```
2. **Commit Changes**
```bash
git add .
git commit -m "feat: add new feature description
Detailed description of what was changed and why.
Closes #123"
```
3. **Create Pull Request**
- Push to your fork
- Create PR against `main` branch
- Fill out the PR template completely
- Link related issues
## 🤝 Community Guidelines
### Communication
- **Be respectful** and constructive in all interactions
- **Ask questions** if anything is unclear
- **Help others** when you can
- **Focus on the code**, not the person
### Code Review Process
1. **Maintainer Review**: All PRs reviewed by project maintainer
2. **Feedback**: Address review comments promptly
3. **Discussion**: Open discussion encouraged for design decisions
4. **Approval**: PR approved when all checks pass and review complete
### Response Times
- **Issues**: Response within 48-72 hours
- **Pull Requests**: Initial review within 1 week
- **Questions**: Community-driven with maintainer backup
## 🏗️ Architecture & Patterns
### Project Structure
```
wikijs/
├── __init__.py # Package entry point
├── client.py # Main client class
├── exceptions.py # Exception hierarchy
├── models/ # Data models (Pydantic)
├── auth/ # Authentication handlers
├── endpoints/ # API endpoint implementations
└── utils/ # Utility functions
```
### Key Patterns
- **Dependency Injection**: Use abstract interfaces
- **Type Safety**: Full type hints and validation
- **Error Handling**: Comprehensive exception hierarchy
- **Testing**: Mock external dependencies
- **Documentation**: Example-driven docstrings
## 🧪 Testing Guidelines
### Test Categories
- **Unit Tests**: Test individual components in isolation
- **Integration Tests**: Test component interactions
- **End-to-End**: Test with real Wiki.js instance (CI only)
### Test Organization
```
tests/
├── unit/
│ ├── test_client.py
│ ├── test_models.py
│ └── test_auth.py
├── integration/
│ └── test_api_endpoints.py
└── conftest.py # Shared fixtures
```
### Writing Good Tests
```python
def test_specific_behavior_with_expected_outcome():
"""Test description should be clear and specific."""
# Arrange
client = WikiJSClient("https://example.com", "key")
# Act
result = client.some_method()
# Assert
assert result.expected_property == "expected_value"
```
## 🐛 Bug Reports
### Before Reporting
1. Check existing issues
2. Test with latest version
3. Provide minimal reproduction case
### Bug Report Checklist
- [ ] Clear description of the problem
- [ ] Steps to reproduce
- [ ] Expected vs actual behavior
- [ ] Environment details
- [ ] Error messages/stack traces
- [ ] Minimal code example
## ✨ Feature Requests
### Before Requesting
1. Check if feature already exists
2. Search existing feature requests
3. Consider if it fits project scope
### Feature Request Checklist
- [ ] Clear use case description
- [ ] Proposed API design
- [ ] Implementation considerations
- [ ] Breaking change analysis
## 🚢 Release Process
Releases are managed by maintainers:
1. **Version Bump**: Update version in `wikijs/version.py`
2. **Changelog**: Update `CHANGELOG.md` with changes
3. **Tag Release**: Create git tag `v0.1.0`
4. **Automated**: GitHub Actions handles building and PyPI publishing
## 📚 Documentation
### Types of Documentation
- **API Reference**: Auto-generated from docstrings
- **User Guides**: How-to guides and tutorials
- **Examples**: Real-world usage examples
- **Architecture**: Technical design decisions
### Documentation Standards
- Write for your audience (users vs contributors)
- Include practical examples
- Keep it up-to-date with code changes
- Use clear, concise language
## 🤖 AI Development Context
This project uses Claude AI for development coordination. If you're interested in the AI-assisted development process:
- See [CLAUDE.md](CLAUDE.md) for AI coordination details
- Development tasks are tracked and managed through AI sessions
- Quality standards are maintained through automated tooling
- Community contributions are integrated with AI-assisted development
## ❓ Getting Help
### Questions and Support
- **GitHub Discussions**: General questions and community chat
- **GitHub Issues**: Bug reports and feature requests
- **Documentation**: Check docs for existing answers
- **Code Review**: Learn through the review process
### Common Questions
**Q: How do I set up a test Wiki.js instance?**
A: Check the testing documentation for local setup instructions.
**Q: What should I work on first?**
A: Look for `good first issue` labels or check CLAUDE.md for current priorities.
**Q: How do I add a new API endpoint?**
A: Follow the existing patterns in `wikijs/endpoints/` and add corresponding tests.
## 🙏 Recognition
All contributors are recognized in:
- `CONTRIBUTORS.md` file
- Release notes for significant contributions
- GitHub contributors page
Significant contributors may be invited to become maintainers.
---
**Ready to contribute?**
1. Read our [Governance](docs/GOVERNANCE.md) guidelines
2. Check the [current development status](CLAUDE.md)
3. Look for [good first issues](https://github.com/yourusername/wikijs-python-sdk/labels/good%20first%20issue)
4. Join the discussion!
**Questions?** Don't hesitate to ask in [GitHub Discussions](https://github.com/yourusername/wikijs-python-sdk/discussions) or create an issue.

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Wiki.js Python SDK Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

162
README.md
View File

@@ -1,2 +1,160 @@
# wikijs-sdk-python # Wiki.js Python SDK
A comprehensive, Python SDK for Wiki.js
[![PyPI version](https://badge.fury.io/py/wikijs-python-sdk.svg)](https://badge.fury.io/py/wikijs-python-sdk)
[![Python Support](https://img.shields.io/pypi/pyversions/wikijs-python-sdk.svg)](https://pypi.org/project/wikijs-python-sdk/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![CI Status](https://github.com/yourusername/wikijs-python-sdk/workflows/Test%20Suite/badge.svg)](https://github.com/yourusername/wikijs-python-sdk/actions)
[![Coverage](https://codecov.io/gh/yourusername/wikijs-python-sdk/branch/main/graph/badge.svg)](https://codecov.io/gh/yourusername/wikijs-python-sdk)
**A professional Python SDK for Wiki.js API integration, developed entirely with AI assistance.**
> **🚧 Status**: Currently in Phase 1 - MVP Development (0% complete)
> **Next Milestone**: v0.1.0 with basic Wiki.js integration and Pages API
---
## 🚀 Quick Start
### Installation
```bash
# Coming soon - not yet published
pip install wikijs-python-sdk
```
### Basic Usage
```python
from wikijs import WikiJSClient
# Initialize client
client = WikiJSClient('https://wiki.example.com', auth='your-api-key')
# List pages
pages = client.pages.list()
# Get a specific page
page = client.pages.get(123)
# Create a new page
from wikijs.models import PageCreate
new_page = client.pages.create(PageCreate(
title="Getting Started",
path="getting-started",
content="# Welcome\n\nThis is your first page!"
))
```
---
## 🎯 Current Development Status
### **Phase 1: MVP Development** (Target: 2 weeks)
- 🔄 **In Progress**: Project foundation setup
- 🎯 **Goal**: Basic Wiki.js integration with Pages API
- 📦 **Deliverable**: Installable package with core functionality
| Component | Status | Description |
|-----------|--------|-------------|
| **Project Setup** | 🔄 In Progress | Repository structure, packaging, CI/CD |
| **Core Client** | ⏳ Pending | HTTP client with authentication |
| **Pages API** | ⏳ Pending | CRUD operations for wiki pages |
| **Testing** | ⏳ Pending | Comprehensive test suite |
| **Documentation** | ⏳ Pending | API reference and examples |
### **Planned Features**
- **v0.2.0**: Complete API coverage (Users, Groups, Assets)
- **v0.3.0**: Production features (retry logic, caching, monitoring)
- **v1.0.0**: Enterprise features (async support, plugins, advanced CLI)
---
## 📚 Documentation
### **For Users**
- **[Quick Start](#quick-start)**: Basic setup and usage
- **[API Reference](docs/api_reference.md)**: Complete SDK documentation *(Coming soon)*
- **[Examples](examples/)**: Real-world usage examples *(Coming soon)*
### **For Contributors**
- **[Contributing Guide](CONTRIBUTING.md)**: How to contribute *(Coming soon)*
- **[Development Setup](docs/development.md)**: Local development guide *(Coming soon)*
### **For Maintainers**
- **[Architecture](docs/wikijs_sdk_architecture.md)**: Technical design and patterns
- **[Development Plan](docs/wikijs_sdk_release_plan.md)**: Complete roadmap and milestones
- **[AI Coordination](CLAUDE.md)**: AI-assisted development workflow
---
## 🤝 Contributing
We welcome contributions! This project showcases AI-powered development with professional standards.
**Getting Started:**
1. Check our [Development Plan](docs/wikijs_sdk_release_plan.md) for current priorities
2. Review the [Architecture](docs/wikijs_sdk_architecture.md) for technical context
3. See [AI Coordination](CLAUDE.md) for development workflow
4. Start with issues labeled `good first issue` *(Coming soon)*
**Community:**
- 💬 **GitHub Discussions**: Questions and community chat *(Coming soon)*
- 🐛 **GitHub Issues**: Bug reports and feature requests *(Coming soon)*
---
## 🛠️ Development Setup
### Prerequisites
- Python 3.8+
- Git
- Wiki.js instance for testing
### Local Development
```bash
# Clone and setup (when repository is published)
git clone https://github.com/yourusername/wikijs-python-sdk
cd wikijs-python-sdk
pip install -e ".[dev]"
# Run tests
pytest
# Run quality checks
pre-commit run --all-files
```
---
## 🏆 Project Features
### **Current (MVP in development)**
- 🔄 Synchronous HTTP client
- 🔄 API key authentication
- 🔄 Pages CRUD operations
- 🔄 Comprehensive error handling
- 🔄 Type-safe models with validation
### **Planned Enhancements**
- ⚡ Async/await support
- 💾 Intelligent caching
- 🔄 Retry logic with backoff
- 💻 CLI tools
- 🔧 Plugin system
- 🛡️ Advanced security features
---
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
---
## 🙏 Acknowledgments
- **Wiki.js**: The excellent knowledge management platform this SDK supports
- **Claude (Anthropic)**: AI assistant powering the complete development process
- **Python Community**: For exceptional tools and development standards
---
**Ready to contribute?** Check out our [development documentation](docs/) or explore the [AI coordination workflow](CLAUDE.md) to see how this project is built!

187
docs/GOVERNANCE.md Normal file
View File

@@ -0,0 +1,187 @@
# Wiki.js Python SDK - Community Governance
**Project**: wikijs-python-sdk
**Stage**: MVP Development
**Version**: 1.0
**Last Updated**: July 2025
---
## 🎯 Mission Statement
Create a high-quality Python SDK for Wiki.js that serves developers' needs while fostering an inclusive, collaborative community.
**Core Values:**
- **Quality**: Prioritize working code and user experience
- **Simplicity**: Keep processes lightweight and focused
- **Community**: Welcome contributors of all experience levels
- **Transparency**: Open development with clear communication
---
## 👥 Project Roles
### **Maintainer**
**Current**: Project Lead
**Responsibilities:**
- Project direction and roadmap decisions
- Code review and merge approval
- Release management
- Community support and issue triage
**Authority:**
- Final decision on feature additions
- Merge rights to main branch
- Create releases and manage PyPI publishing
### **Contributors**
**Anyone participating in the project**
**How to Contribute:**
- Report bugs with clear reproduction steps
- Suggest features with use cases
- Submit pull requests following our standards
- Help answer questions in discussions
- Improve documentation and examples
**Recognition:**
- All contributors listed in CONTRIBUTORS.md
- Significant contributors highlighted in releases
- Path to maintainer role for consistent contributors
---
## 🚀 Development Process
### **Issue Management**
1. **Bug Reports**: Use issue templates with reproduction steps
2. **Feature Requests**: Describe use case and expected behavior
3. **Questions**: Use GitHub Discussions for general help
4. **Priority**: Focus on MVP completion, then community feedback
### **Pull Request Process**
1. **Fork & Branch**: Create feature branch from `main`
2. **Develop**: Follow coding standards and write tests
3. **Test**: Ensure all tests pass and coverage maintained
4. **Review**: Maintainer reviews and provides feedback
5. **Merge**: Approved changes merged to main
### **Release Process**
- **Version**: Semantic versioning (MAJOR.MINOR.PATCH)
- **Frequency**: Regular releases based on feature completion
- **Testing**: All quality gates must pass before release
- **Communication**: Release notes published with each version
---
## 📋 Quality Standards
### **Code Requirements**
- **Tests**: All new features must include tests
- **Coverage**: Maintain >85% test coverage
- **Types**: Type hints required for public APIs
- **Style**: Follow black, isort, flake8 formatting
- **Documentation**: Docstrings for all public methods
### **Review Criteria**
- [ ] Code follows established patterns
- [ ] Tests cover new functionality
- [ ] Documentation updated if needed
- [ ] No breaking changes without discussion
- [ ] Performance impact considered
---
## 🤝 Community Guidelines
### **Expected Behavior**
- Be respectful and constructive in all interactions
- Focus on the code and ideas, not the person
- Welcome newcomers and help them get started
- Share knowledge and learn from others
- Assume good intentions in communications
### **Unacceptable Behavior**
- Personal attacks or harassment
- Discriminatory language or behavior
- Trolling or intentionally disruptive behavior
- Sharing private information without consent
### **Enforcement**
- **Level 1**: Private discussion with maintainer
- **Level 2**: Public warning and guidance
- **Level 3**: Temporary restriction from participation
- **Level 4**: Permanent ban (only for severe violations)
Report issues to: [Maintainer Contact] - all reports handled confidentially.
---
## 📞 Communication Channels
### **GitHub Issues**
- Bug reports and feature requests
- Project planning and roadmap discussions
- Technical questions about implementation
### **GitHub Discussions** *(Coming Soon)*
- General help and usage questions
- Community showcase and success stories
- Brainstorming new ideas and improvements
### **Response Expectations**
- **Issues**: Response within 48-72 hours
- **Pull Requests**: Initial review within 1 week
- **Discussions**: Community-driven with maintainer backup
---
## 🔄 Decision Making
### **For MVP Development**
- **Maintainer Authority**: Final decisions on scope and implementation
- **Community Input**: Gathered through issues and discussions
- **Focus**: Complete MVP first, then expand based on feedback
### **Post-MVP Development**
- **Feature Requests**: Community voting and discussion
- **Breaking Changes**: Require community discussion period
- **Major Decisions**: Seek consensus among active contributors
---
## 📈 Growth & Evolution
### **Path to Contributor Recognition**
1. **First-time Contributors**: Welcomed and guided through process
2. **Regular Contributors**: Recognized in releases and documentation
3. **Core Contributors**: Trusted with triage and review responsibilities
4. **Maintainers**: Full project authority for proven long-term contributors
### **Governance Evolution**
This lightweight governance will evolve as the community grows:
- **10+ Contributors**: Add formal contributor guidelines
- **Community Growth**: Implement more structured decision processes
- **Multiple Maintainers**: Establish maintainer team processes
---
## 🚀 Getting Started
### **New Contributors**
1. **Read** this governance and project README
2. **Browse** open issues labeled `good first issue`
3. **Ask Questions** in GitHub Discussions
4. **Start Small** with documentation or test improvements
5. **Follow** the pull request process
### **Quick Links**
- **[Development Plan](wikijs_sdk_release_plan.md)**: Current roadmap and priorities
- **[Architecture](wikijs_sdk_architecture.md)**: Technical design overview
- **[CLAUDE.md](../CLAUDE.md)**: AI-assisted development workflow
- **[Contributing Guide](../CONTRIBUTING.md)**: Detailed contribution process *(Coming Soon)*
---
**Questions about governance?** Start a discussion or reach out to the maintainer directly. We're here to help and always open to improving our processes!
**Ready to contribute?** Check out our [current development priorities](wikijs_sdk_release_plan.md) and jump in!

237
docs/RISK_MANAGEMENT.md Normal file
View File

@@ -0,0 +1,237 @@
# Wiki.js Python SDK - Risk Management
**Project**: wikijs-python-sdk
**Stage**: MVP Development
**Version**: 1.0
**Last Updated**: July 2025
---
## 🎯 Overview
This document identifies and addresses key risks for the MVP development phase. As an AI-assisted project in early development, we focus on the most critical risks that could impact successful delivery.
### **Risk Management Approach**
- **Proactive Identification**: Anticipate issues before they occur
- **Practical Mitigation**: Focus on actionable solutions
- **Regular Review**: Assess risks weekly during development
- **Continuous Learning**: Update strategies based on experience
---
## 🔴 High Priority Risks
### **R1: Development Timeline Delays**
**Risk**: MVP development takes longer than 2-week target
**Probability**: Medium | **Impact**: High | **Level**: 🔴 HIGH
**Causes:**
- Underestimated task complexity
- Scope creep during development
- Technical challenges with Wiki.js API integration
- AI session limitations affecting development flow
**Mitigation Strategies:**
-**Strict Scope Control**: No feature additions during MVP development
-**Daily Progress Tracking**: Update completion status in CLAUDE.md
-**Buffer Time**: Built-in 20% buffer for unexpected issues
-**Fallback Plan**: Reduce MVP scope if timeline at risk
**Monitoring:**
- Track actual vs. estimated time for each task
- Weekly milestone reviews
- Early warning if >20% behind schedule
---
### **R2: Wiki.js API Compatibility Issues**
**Risk**: Changes in Wiki.js API break SDK functionality
**Probability**: Medium | **Impact**: High | **Level**: 🔴 HIGH
**Causes:**
- Wiki.js API changes without notice
- Undocumented API behavior
- Version compatibility issues
- Authentication method changes
**Mitigation Strategies:**
-**Version Pinning**: Test against specific Wiki.js versions
-**Graceful Degradation**: Handle API errors without complete failure
-**Documentation**: Clear supported version requirements
-**Testing**: Comprehensive integration tests with real Wiki.js instance
**Monitoring:**
- Test against latest Wiki.js releases
- Monitor Wiki.js changelog and releases
- Community feedback on compatibility issues
---
### **R3: Quality Standards Not Met**
**Risk**: Code quality falls below professional standards
**Probability**: Low | **Impact**: High | **Level**: 🔴 HIGH
**Causes:**
- Rushing to meet timeline
- Skipping tests or documentation
- Inconsistent code style
- Insufficient error handling
**Mitigation Strategies:**
-**Automated Checks**: CI/CD pipeline with quality gates
-**Test Coverage**: Maintain >85% coverage requirement
-**Code Review**: All changes reviewed before merge
-**Documentation**: API docs required for all public methods
**Quality Gates:**
- [ ] Tests: 100% pass rate
- [ ] Coverage: >85% line coverage
- [ ] Types: 100% mypy compliance
- [ ] Lint: 0 flake8 errors
- [ ] Format: 100% black compliance
---
## 🟡 Medium Priority Risks
### **R4: Package Distribution Issues**
**Risk**: Problems publishing to PyPI or package installation
**Probability**: Medium | **Impact**: Medium | **Level**: 🟡 MEDIUM
**Mitigation:**
- Test packaging and installation locally
- Use automated publishing workflow
- Validate package metadata and dependencies
### **R5: Documentation Gaps**
**Risk**: Incomplete or unclear documentation affects adoption
**Probability**: High | **Impact**: Medium | **Level**: 🟡 MEDIUM
**Mitigation:**
- Write documentation alongside code
- Include practical examples for all features
- Test documentation with fresh install
### **R6: Community Reception Issues**
**Risk**: Negative feedback or low adoption
**Probability**: Low | **Impact**: Medium | **Level**: 🟡 MEDIUM
**Mitigation:**
- Focus on solving real developer problems
- Engage with Wiki.js community early
- Gather feedback and iterate quickly
---
## 🟢 Low Priority Risks
### **R7: Performance Issues**
**Risk**: SDK performance doesn't meet expectations
**Probability**: Low | **Impact**: Low | **Level**: 🟢 LOW
**Note**: Performance optimization planned for Phase 3, not critical for MVP
### **R8: Security Vulnerabilities**
**Risk**: Security issues in dependencies or code
**Probability**: Low | **Impact**: Medium | **Level**: 🟢 LOW
**Mitigation**: Automated security scanning in CI/CD pipeline
---
## 📊 Risk Monitoring
### **Weekly Risk Review**
Every week during MVP development:
1. **Assess Current Risks**: Review probability and impact
2. **Check Mitigation Status**: Ensure strategies are working
3. **Identify New Risks**: Add emerging risks to list
4. **Update Action Plans**: Adjust strategies as needed
### **Risk Indicators**
**Red Flags** (Immediate attention required):
- >1 day behind schedule on critical path
- Test coverage drops below 80%
- Major Wiki.js compatibility issue discovered
- Critical bug discovered in core functionality
**Yellow Flags** (Monitor closely):
- Minor delays in non-critical tasks
- Documentation feedback indicates confusion
- Community engagement lower than expected
### **Escalation Process**
1. **🟢 Low Risk**: Handle in normal development process
2. **🟡 Medium Risk**: Discuss in weekly reviews
3. **🔴 High Risk**: Immediate mitigation action required
4. **🚨 Critical Risk**: Consider scope reduction or timeline adjustment
---
## 🔄 Contingency Plans
### **Timeline Recovery Plan**
**If >20% behind schedule:**
1. **Assess**: Identify specific blockers and time needed
2. **Prioritize**: Focus only on core MVP features
3. **Reduce Scope**: Remove non-essential features
4. **Communicate**: Update timeline expectations
**Minimum Viable Features** (Cannot be removed):
- Basic HTTP client with Wiki.js integration
- API key authentication
- Pages CRUD operations (list, get, create)
- Basic error handling
- Package installation via pip
### **API Compatibility Failure Plan**
**If Wiki.js API breaks compatibility:**
1. **Document**: Clearly specify supported Wiki.js versions
2. **Workaround**: Implement fallback behavior where possible
3. **Communicate**: Notify users of compatibility limitations
4. **Update**: Plan fix for next release
### **Quality Failure Plan**
**If quality standards not met:**
1. **Stop**: Halt new feature development
2. **Fix**: Address quality issues first
3. **Review**: Identify process improvements
4. **Resume**: Continue with improved practices
---
## 📈 Risk Learning & Improvement
### **Post-MVP Risk Review**
After MVP completion, conduct comprehensive review:
- **What Risks Materialized**: Which predictions were accurate
- **What We Missed**: Risks that weren't anticipated
- **Mitigation Effectiveness**: Which strategies worked best
- **Process Improvements**: How to improve risk management
### **Future Phase Risk Planning**
Use MVP experience to improve risk management for:
- **Phase 2**: Essential features and community feedback
- **Phase 3**: Production readiness and performance
- **Phase 4**: Enterprise features and scaling
---
## 🎯 Success Criteria
**MVP Risk Management Success:**
- [ ] MVP delivered within 2-week timeline (±20%)
- [ ] All quality gates passed before release
- [ ] No critical bugs discovered in first week after release
- [ ] Package successfully installed by early users
- [ ] Documentation sufficient for basic usage
**Risk Management Process Success:**
- [ ] All high-priority risks actively monitored
- [ ] Mitigation strategies effectively implemented
- [ ] Early warning systems prevented major issues
- [ ] Lessons learned documented for future phases
---
*This risk management plan focuses on MVP development. A comprehensive risk framework will be developed for later phases based on lessons learned and project growth.*

View File

@@ -0,0 +1,374 @@
# Wiki.js Python SDK - Architecture Overview
**Version:** 1.0.0
**Status:** MVP Design Phase
**Date:** July 2025
---
## 📋 Executive Summary
### Project Vision
Create a professional Python SDK for Wiki.js that provides intuitive API access, robust error handling, and enterprise-grade features through a clean, extensible architecture.
### Core Objectives
- **Developer Experience**: Intuitive, well-documented API
- **Reliability**: Built-in retry logic and graceful error handling
- **Performance**: Efficient resource management and caching
- **Maintainability**: Clean architecture with comprehensive testing
---
## 🏗️ High-Level Architecture
### System Overview
```mermaid
graph TB
subgraph "Client Applications"
A[Python Scripts]
B[Web Applications]
C[CLI Tools]
end
subgraph "SDK Core"
D[WikiJS Client]
E[Authentication]
F[Configuration]
end
subgraph "API Endpoints"
G[Pages API]
H[Users API]
I[Groups API]
J[Assets API]
end
subgraph "Infrastructure"
K[HTTP Client]
L[Error Handling]
M[Caching Layer]
end
subgraph "External"
N[Wiki.js Server]
end
A --> D
B --> D
C --> D
D --> E
D --> F
D --> G
D --> H
D --> I
D --> J
G --> K
H --> K
I --> K
J --> K
K --> L
K --> M
K --> N
```
### Architecture Principles
#### **1. Separation of Concerns**
- Authentication isolated from API communication
- Clear boundaries between endpoint handlers and HTTP transport
- Modular design allowing independent testing
#### **2. Dependency Inversion**
- Abstract interfaces for HTTP clients and authentication
- Pluggable components for caching and configuration
- Easily mockable dependencies for testing
#### **3. Fail-Fast & Graceful Degradation**
- Early validation of inputs and configuration
- Comprehensive error handling with meaningful messages
- Graceful handling of network failures
---
## 🔧 Core Components
### **WikiJS Client**
```python
class WikiJSClient:
"""Main client for Wiki.js API interactions"""
def __init__(self, base_url: str, auth: AuthHandler, config: ClientConfig = None)
# Properties
.pages # Pages API endpoint
.users # Users API endpoint
.groups # Groups API endpoint
.assets # Assets API endpoint
```
**Responsibilities:**
- Central coordination of all API operations
- Authentication and configuration management
- HTTP request/response handling
- Error propagation and logging
### **Authentication System**
```python
class AuthHandler(ABC):
"""Abstract authentication interface"""
def get_headers(self) -> Dict[str, str]
def is_valid(self) -> bool
def refresh(self) -> None
class APIKeyAuth(AuthHandler):
"""API key authentication implementation"""
class JWTAuth(AuthHandler): # Future
"""JWT token authentication implementation"""
```
**Design Features:**
- Pluggable authentication strategies
- Automatic token refresh for JWT
- Header management abstraction
### **API Endpoints**
```python
class BaseEndpoint:
"""Base functionality for all API endpoints"""
class PagesEndpoint(BaseEndpoint):
"""Pages API operations"""
def list(self, limit: int = 50) -> List[Page]
def get(self, page_id: int) -> Page
def create(self, page_data: PageCreate) -> Page
def update(self, page_id: int, **kwargs) -> Page
def delete(self, page_id: int) -> bool
```
**Design Features:**
- Consistent interface across all endpoints
- Type-safe request/response models
- Built-in validation and error handling
### **Data Models**
```python
class BaseModel(Pydantic.BaseModel):
"""Base model with validation and serialization"""
class Page(BaseModel):
id: int
title: str
path: str
content: str
created_at: datetime
updated_at: datetime
# Business logic methods
@property
def word_count(self) -> int
def to_markdown(self) -> str
```
**Design Features:**
- Pydantic-based validation
- Rich domain models with business logic
- Automatic serialization/deserialization
---
## 📊 Data Flow
### Request Flow
```mermaid
sequenceDiagram
participant App as Application
participant Client as WikiJS Client
participant Auth as Auth Handler
participant HTTP as HTTP Client
participant API as Wiki.js API
App->>Client: pages.get(123)
Client->>Auth: get_headers()
Auth-->>Client: {"Authorization": "Bearer..."}
Client->>HTTP: request(GET, /api/pages/123)
HTTP->>API: HTTP Request
API-->>HTTP: 200 OK + Data
HTTP-->>Client: Response Data
Client-->>App: Page Object
```
### Error Handling Flow
```mermaid
flowchart TD
A[API Request] --> B{HTTP Status}
B -->|200-299| C[Success Response]
B -->|400-499| D[Client Error]
B -->|500-599| E[Server Error]
B -->|Timeout| F[Network Error]
D --> G[ValidationError]
E --> H[APIError]
F --> I[ConnectionError]
G --> J[Log & Return Error]
H --> J
I --> J
C --> K[Parse & Return Data]
```
---
## 🗂️ Project Structure
### Directory Layout
```
wikijs-python-sdk/
├── wikijs/ # Main package
│ ├── __init__.py # Package entry point
│ ├── client.py # Main client class
│ ├── exceptions.py # Exception hierarchy
│ ├── models/ # Data models
│ │ ├── __init__.py
│ │ ├── base.py # Base model
│ │ └── page.py # Page model
│ ├── auth/ # Authentication
│ │ ├── __init__.py
│ │ ├── base.py # Auth interface
│ │ └── api_key.py # API key auth
│ ├── endpoints/ # API endpoints
│ │ ├── __init__.py
│ │ ├── base.py # Base endpoint
│ │ └── pages.py # Pages API
│ └── utils/ # Utilities
│ ├── __init__.py
│ └── helpers.py # Helper functions
├── tests/ # Test suite
├── docs/ # Documentation
└── examples/ # Usage examples
```
### Module Responsibilities
| Module | Purpose | Key Classes |
|--------|---------|-------------|
| `client.py` | Main SDK interface | `WikiJSClient` |
| `exceptions.py` | Error handling | `WikiJSException`, `APIError` |
| `models/` | Data structures | `Page`, `User`, `Group` |
| `auth/` | Authentication | `AuthHandler`, `APIKeyAuth` |
| `endpoints/` | API operations | `PagesEndpoint`, `UsersEndpoint` |
| `utils/` | Helper functions | Validation, serialization |
---
## 🔌 Extensibility Design
### Plugin Architecture (Future)
```python
class Plugin(ABC):
"""Plugin interface for SDK extensions"""
def before_request(self, request: Request) -> Request
def after_response(self, response: Response) -> Response
class CachePlugin(Plugin):
"""Caching functionality as a plugin"""
class MetricsPlugin(Plugin):
"""Metrics collection as a plugin"""
```
### Configuration System
```python
@dataclass
class ClientConfig:
# Connection settings
base_url: str
timeout: int = 30
verify_ssl: bool = True
# Features
cache_enabled: bool = False
retry_enabled: bool = True
# Advanced
plugins: List[Plugin] = field(default_factory=list)
```
---
## 🚀 Development Phases
### **Phase 1: MVP (Current)**
- ✅ Core client with HTTP transport
- ✅ API key authentication
- ✅ Pages API with full CRUD
- ✅ Basic error handling
- ✅ Type-safe models
### **Phase 2: Essential Features**
- Users, Groups, Assets APIs
- Enhanced error handling with context
- Configuration management system
- Basic CLI interface
### **Phase 3: Production Ready**
- Retry logic with exponential backoff
- Caching system with multiple backends
- Rate limiting and circuit breaker
- Performance monitoring
### **Phase 4: Enterprise Grade**
- Async support with asyncio
- Plugin architecture
- Advanced authentication (JWT, OAuth2)
- Comprehensive CLI with interactive mode
---
## 🎯 Design Decisions
### **Technology Choices**
| Component | Technology | Rationale |
|-----------|------------|-----------|
| **HTTP Client** | `requests` | Industry standard, reliable, well-documented |
| **Validation** | `pydantic` | Type safety, automatic validation, great DX |
| **Testing** | `pytest` | Powerful, flexible, extensive plugin ecosystem |
| **CLI** | `click` + `rich` | User-friendly, feature-rich, beautiful output |
| **Async** | `aiohttp` | Native asyncio support, high performance |
### **Key Architectural Decisions**
1. **Synchronous First**: Start with sync API, add async later
2. **Type Safety**: Full type hints and runtime validation
3. **Modular Design**: Clear separation of concerns
4. **Configuration**: Support both programmatic and file-based config
5. **Error Handling**: Comprehensive hierarchy with actionable messages
---
## 📈 Quality Standards
### **Code Quality**
- **Type Coverage**: 100% type hints on public APIs
- **Test Coverage**: >90% line coverage maintained
- **Documentation**: All public methods documented
- **Code Style**: Black + isort + flake8 compliance
### **Performance Targets**
- **Cold Start**: <100ms import time
- **Request Latency**: <50ms overhead per request
- **Memory Usage**: <50MB for typical workloads
- **Throughput**: >1000 req/s with connection pooling
### **Security**
- No hardcoded credentials or secrets
- Input validation on all user data
- Secure defaults for all configuration
- Regular dependency security scanning
---
*For detailed implementation specifications, see [Technical Specifications](technical/)*
*For development tasks and coordination, see [CLAUDE.md](../CLAUDE.md)*

View File

@@ -0,0 +1,204 @@
# Wiki.js Python SDK - Release Plan
**Project Name:** `wikijs-python-sdk`
**Repository:** `https://github.com/yourusername/wikijs-python-sdk`
**License:** MIT
**Target Audience:** Python developers, DevOps engineers, Data scientists
---
## 📋 Project Overview
### Vision Statement
Develop a production-ready Python SDK for Wiki.js that evolves from a simple, functional MVP to a comprehensive enterprise-grade solution through incremental releases.
### Release Philosophy
- **MVP First**: Ship a working, useful product quickly
- **Incremental Value**: Each release adds meaningful functionality
- **Backward Compatibility**: Maintain API stability across releases
- **Community Driven**: Gather feedback and iterate
### Success Metrics
- **Adoption**: >100 PyPI downloads in first month
- **Quality**: >90% test coverage maintained
- **Community**: >10 GitHub stars, >3 contributors
- **Stability**: <1% error rate in production usage
---
## 🎯 Release Timeline
```mermaid
gantt
title Wiki.js SDK Development Timeline
dateFormat YYYY-MM-DD
section Phase 1: MVP
Project Setup :p1-setup, 2025-07-29, 3d
Core Implementation :p1-core, after p1-setup, 8d
Release v0.1.0 :milestone, p1-release, after p1-core, 1d
section Phase 2: Essential Features
API Expansion :p2-features, after p1-release, 10d
Release v0.2.0 :milestone, p2-release, after p2-features, 1d
section Phase 3: Production Ready
Reliability Features :p3-reliability, after p2-release, 15d
Release v0.3.0 :milestone, p3-release, after p3-reliability, 1d
section Phase 4: Enterprise
Advanced Features :p4-advanced, after p3-release, 20d
Release v1.0.0 :milestone, p4-release, after p4-advanced, 1d
```
---
## 🚀 Phase 1: MVP Release (v0.1.0)
**Target:** 2 weeks from start
**Goal:** Basic, functional Wiki.js integration
### Core Features
- **HTTP Client**: Synchronous requests with basic error handling
- **Authentication**: API key authentication
- **Pages API**: Complete CRUD operations (list, get, create, update, delete)
- **Models**: Type-safe data models with validation
- **Testing**: Comprehensive test suite with >85% coverage
- **Documentation**: API documentation and usage examples
### Success Criteria
- [ ] Package installable via `pip install wikijs-python-sdk`
- [ ] Basic page operations work with real Wiki.js instance
- [ ] >85% test coverage with passing CI/CD
- [ ] Complete API documentation
*Detailed task breakdown available in [CLAUDE.md](../CLAUDE.md)*
---
## 🔧 Phase 2: Essential Features (v0.2.0)
**Target:** 4 weeks from start
**Goal:** Complete API coverage and enhanced usability
### Key Features
- **Complete API Coverage**: Users, Groups, Assets, System APIs
- **Enhanced Error Handling**: Detailed error context and recovery suggestions
- **Configuration System**: File-based and environment variable configuration
- **Basic CLI**: Command-line interface for common operations
- **Improved Documentation**: Comprehensive guides and examples
### Success Criteria
- [ ] All major Wiki.js APIs covered
- [ ] Configuration via files and environment variables
- [ ] Basic CLI functionality working
- [ ] >90% test coverage
- [ ] Performance benchmarks established
---
## ⚡ Phase 3: Production Ready (v0.3.0)
**Target:** 7 weeks from start
**Goal:** Enterprise-grade reliability and performance
### Key Features
- **Retry Logic**: Exponential backoff with jitter for failed requests
- **Circuit Breaker**: Fault tolerance for unreliable connections
- **Intelligent Caching**: Multi-backend caching with smart invalidation
- **Rate Limiting**: Respect API limits and prevent abuse
- **Monitoring**: Performance metrics and health monitoring
- **Bulk Operations**: Efficient batch processing capabilities
### Success Criteria
- [ ] Production-ready reliability features
- [ ] Performance benchmarks show >50% improvement
- [ ] Cache hit ratio >80% in typical usage
- [ ] Zero-downtime error handling
- [ ] Comprehensive monitoring and logging
---
## 🌟 Phase 4: Enterprise Grade (v1.0.0)
**Target:** 11 weeks from start
**Goal:** Full-featured enterprise SDK
### Key Features
- **Async Support**: Complete asyncio integration with aiohttp
- **Advanced CLI**: Interactive mode, progress bars, bulk operations
- **Plugin Architecture**: Extensible middleware and custom auth providers
- **Advanced Security**: JWT rotation, OAuth2, audit logging
- **Enterprise Features**: Multi-tenancy, custom headers, webhooks
- **Performance Optimizations**: Connection pooling, request batching
### Success Criteria
- [ ] Feature parity with official SDKs
- [ ] Async performance >3x sync performance
- [ ] Plugin ecosystem established
- [ ] Enterprise security features complete
- [ ] Comprehensive documentation and tutorials
---
## 📦 Deployment & Distribution
### Release Process
1. **Automated Testing**: All tests pass with quality gates
2. **Security Scanning**: Dependency and code security validation
3. **Performance Benchmarking**: Regression testing
4. **Documentation Update**: Synchronized with code changes
5. **PyPI Publishing**: Automated package distribution
6. **GitHub Release**: Tagged release with changelog
### Version Management
- **Semantic Versioning**: MAJOR.MINOR.PATCH
- **MAJOR**: Breaking changes
- **MINOR**: New features, backward compatible
- **PATCH**: Bug fixes, backward compatible
### Quality Gates
| Check | Tool | Threshold |
|-------|------|-----------|
| Tests | pytest | 100% pass |
| Coverage | pytest-cov | >90% |
| Types | mypy | 100% pass |
| Lint | flake8 | 0 errors |
| Security | bandit | 0 issues |
| Format | black | 100% formatted |
---
## 🤝 Community & Maintenance
### Community Building
- **Documentation First**: Comprehensive guides and examples
- **Issue Templates**: Structured bug reports and feature requests
- **Contributing Guidelines**: Clear onboarding for new contributors
- **Code of Conduct**: Inclusive community standards
### Long-term Maintenance
- **Regular Updates**: Monthly releases with improvements
- **Security Patches**: Rapid response to security issues
- **Compatibility**: Support for new Wiki.js versions
- **Performance**: Continuous optimization and monitoring
---
## 📈 Success Tracking
### Key Metrics
- **PyPI Downloads**: Measure adoption growth
- **GitHub Engagement**: Stars, forks, issues, PRs
- **Test Coverage**: Maintain >90% throughout development
- **Performance**: Response time and throughput benchmarks
- **Community**: Contributors, issue resolution time
### Milestone Reviews
- **After Each Phase**: Comprehensive retrospective
- **Process Optimization**: Improve development efficiency
- **Community Feedback**: Incorporate user suggestions
- **Technical Debt**: Address accumulated debt
---
*For detailed development tasks and AI coordination, see [CLAUDE.md](../CLAUDE.md)*

124
pyproject.toml Normal file
View File

@@ -0,0 +1,124 @@
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
dynamic = ["version"]
[tool.setuptools.dynamic]
version = {attr = "wikijs.version.__version__"}
[tool.black]
line-length = 88
target-version = ['py38']
include = '\.pyi?$'
extend-exclude = '''
/(
# directories
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| build
| dist
)/
'''
[tool.isort]
profile = "black"
multi_line_output = 3
line_length = 88
known_first_party = ["wikijs"]
known_third_party = ["pytest", "requests", "pydantic"]
[tool.mypy]
python_version = "3.8"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true
strict_equality = true
[[tool.mypy.overrides]]
module = [
"requests.*",
"aiohttp.*",
]
ignore_missing_imports = true
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"--strict-markers",
"--strict-config",
"--cov=wikijs",
"--cov-report=term-missing",
"--cov-report=html",
"--cov-report=xml",
"--cov-fail-under=85",
]
markers = [
"unit: Unit tests",
"integration: Integration tests",
"slow: Slow tests",
"network: Tests requiring network access",
]
[tool.coverage.run]
source = ["wikijs"]
omit = [
"*/tests/*",
"*/test_*",
"wikijs/cli/*", # CLI tested separately initially
]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
]
[tool.bandit]
exclude_dirs = ["tests"]
skips = ["B101"] # Skip assert_used test
[tool.flake8]
max-line-length = 88
select = ["E", "W", "F", "C", "N"]
ignore = [
"E203", # whitespace before ':' (conflicts with black)
"E501", # line too long (handled by black)
"W503", # line break before binary operator (conflicts with black)
]
exclude = [
".git",
"__pycache__",
"build",
"dist",
".eggs",
"*.egg-info",
".venv",
"venv",
".tox"
]
per-file-ignores = [
"tests/*:F401,F811", # Allow unused imports in tests
"__init__.py:F401", # Allow unused imports in __init__.py
]
max-complexity = 10

26
requirements-dev.txt Normal file
View File

@@ -0,0 +1,26 @@
# Development dependencies for Wiki.js Python SDK
-r requirements.txt
# Testing
pytest>=7.0.0
pytest-cov>=4.0.0
pytest-asyncio>=0.21.0
responses>=0.20.0
# Code quality
black>=22.0.0
isort>=5.10.0
flake8>=5.0.0
mypy>=0.991
bandit[toml]>=1.7.0
# Pre-commit hooks
pre-commit>=2.20.0
# Development tools
ipython>=8.0.0
twine>=4.0.0
build>=0.8.0
# Optional async support (for future phases)
aiohttp>=3.8.0

4
requirements.txt Normal file
View File

@@ -0,0 +1,4 @@
# Core dependencies for Wiki.js Python SDK
requests>=2.28.0
pydantic>=1.10.0
typing-extensions>=4.0.0

106
setup.py Normal file
View File

@@ -0,0 +1,106 @@
"""Setup configuration for wikijs-python-sdk."""
import os
from setuptools import setup, find_packages
# Read version from file
def get_version():
version_file = os.path.join(os.path.dirname(__file__), "wikijs", "version.py")
if os.path.exists(version_file):
with open(version_file) as f:
for line in f:
if line.startswith("__version__"):
return line.split("=")[1].strip().strip('"').strip("'")
return "0.1.0" # Fallback version
# Read long description from README
def get_long_description():
readme_path = os.path.join(os.path.dirname(__file__), "README.md")
if os.path.exists(readme_path):
with open(readme_path, "r", encoding="utf-8") as fh:
return fh.read()
return "A professional Python SDK for Wiki.js API integration"
# Read requirements
def get_requirements():
req_path = os.path.join(os.path.dirname(__file__), "requirements.txt")
if os.path.exists(req_path):
with open(req_path) as f:
return [
line.strip()
for line in f
if line.strip() and not line.startswith("#")
]
return ["requests>=2.28.0", "pydantic>=1.10.0"]
setup(
name="wikijs-python-sdk",
version=get_version(),
author="Wiki.js SDK Contributors",
author_email="",
description="A professional Python SDK for Wiki.js API integration",
long_description=get_long_description(),
long_description_content_type="text/markdown",
url="https://github.com/yourusername/wikijs-python-sdk",
project_urls={
"Bug Reports": "https://github.com/yourusername/wikijs-python-sdk/issues",
"Source": "https://github.com/yourusername/wikijs-python-sdk",
"Documentation": "https://github.com/yourusername/wikijs-python-sdk/docs",
},
packages=find_packages(exclude=["tests*", "docs*", "examples*"]),
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
"Topic :: Documentation",
"Typing :: Typed",
],
python_requires=">=3.8",
install_requires=get_requirements(),
extras_require={
"dev": [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
"pytest-asyncio>=0.21.0",
"black>=22.0.0",
"isort>=5.10.0",
"flake8>=5.0.0",
"mypy>=0.991",
"pre-commit>=2.20.0",
"bandit[toml]>=1.7.0",
"responses>=0.20.0",
],
"async": [
"aiohttp>=3.8.0",
],
"cli": [
"click>=8.0.0",
"rich>=12.0.0",
],
"all": [
"aiohttp>=3.8.0",
"click>=8.0.0",
"rich>=12.0.0",
],
},
entry_points={
"console_scripts": [
"wikijs=wikijs.cli.main:main [cli]",
],
},
include_package_data=True,
package_data={
"wikijs": ["py.typed"],
},
keywords="wiki wikijs api sdk client http rest",
zip_safe=False,
)

77
wikijs/__init__.py Normal file
View File

@@ -0,0 +1,77 @@
"""Wiki.js Python SDK - Professional SDK for Wiki.js API integration.
This package provides a comprehensive Python SDK for interacting with Wiki.js
instances, including support for pages, users, groups, and system management.
Example:
Basic usage:
>>> from wikijs import WikiJSClient
>>> client = WikiJSClient('https://wiki.example.com', auth='your-api-key')
>>> # API endpoints will be available as development progresses
Features:
- Type-safe data models with validation
- Comprehensive error handling
- Automatic retry logic with exponential backoff
- Professional logging and debugging support
- Context manager support for resource cleanup
"""
from .client import WikiJSClient
from .exceptions import (
WikiJSException,
APIError,
AuthenticationError,
ConfigurationError,
ValidationError,
ClientError,
ServerError,
NotFoundError,
PermissionError,
RateLimitError,
ConnectionError,
TimeoutError,
)
from .models import BaseModel, Page, PageCreate, PageUpdate
from .version import __version__, __version_info__
# Public API
__all__ = [
# Main client
"WikiJSClient",
# Data models
"BaseModel",
"Page",
"PageCreate",
"PageUpdate",
# Exceptions
"WikiJSException",
"APIError",
"AuthenticationError",
"ConfigurationError",
"ValidationError",
"ClientError",
"ServerError",
"NotFoundError",
"PermissionError",
"RateLimitError",
"ConnectionError",
"TimeoutError",
# Version info
"__version__",
"__version_info__",
]
# Package metadata
__author__ = "Wiki.js SDK Contributors"
__email__ = ""
__license__ = "MIT"
__description__ = "Professional Python SDK for Wiki.js API integration"
__url__ = "https://github.com/yourusername/wikijs-python-sdk"
# For type checking
__all__ += ["__author__", "__email__", "__license__", "__description__", "__url__"]

19
wikijs/auth/__init__.py Normal file
View File

@@ -0,0 +1,19 @@
"""Authentication module for wikijs-python-sdk.
This module will contain authentication handlers for different
authentication methods supported by Wiki.js.
Future implementations:
- API key authentication
- JWT token authentication
- OAuth2 authentication
"""
# Placeholder for future authentication implementations
# from .base import AuthHandler
# from .api_key import APIKeyAuth
# from .jwt import JWTAuth
__all__ = [
# Will be implemented in Task 1.3
]

261
wikijs/client.py Normal file
View File

@@ -0,0 +1,261 @@
"""Main WikiJS client for wikijs-python-sdk."""
import json
from typing import Any, Dict, Optional, Union
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from .exceptions import (
APIError,
AuthenticationError,
ConfigurationError,
ConnectionError,
TimeoutError,
create_api_error,
)
from .utils import normalize_url, build_api_url, parse_wiki_response, extract_error_message
class WikiJSClient:
"""Main client for interacting with Wiki.js API.
This client provides a high-level interface for all Wiki.js API operations
including pages, users, groups, and system management. It handles authentication,
error handling, and response parsing automatically.
Args:
base_url: The base URL of your Wiki.js instance
auth: Authentication (API key string or auth handler)
timeout: Request timeout in seconds (default: 30)
verify_ssl: Whether to verify SSL certificates (default: True)
user_agent: Custom User-Agent header
Example:
Basic usage with API key:
>>> client = WikiJSClient('https://wiki.example.com', auth='your-api-key')
>>> # Will be available after endpoints are implemented:
>>> # pages = client.pages.list()
Attributes:
base_url: The normalized base URL
timeout: Request timeout setting
verify_ssl: SSL verification setting
"""
def __init__(
self,
base_url: str,
auth: Union[str, "AuthHandler"],
timeout: int = 30,
verify_ssl: bool = True,
user_agent: Optional[str] = None,
):
# Validate and normalize base URL
self.base_url = normalize_url(base_url)
# Store authentication
if isinstance(auth, str):
# Simple API key - will be handled by auth module later
self._api_key = auth
self._auth_handler = None
else:
# Auth handler (for future implementation)
self._api_key = None
self._auth_handler = auth
# Request configuration
self.timeout = timeout
self.verify_ssl = verify_ssl
self.user_agent = user_agent or f"wikijs-python-sdk/0.1.0"
# Initialize HTTP session
self._session = self._create_session()
# Endpoint handlers (will be initialized as we implement them)
# self.pages = PagesEndpoint(self)
# self.users = UsersEndpoint(self)
# self.groups = GroupsEndpoint(self)
def _create_session(self) -> requests.Session:
"""Create configured HTTP session with retry strategy.
Returns:
Configured requests session
"""
session = requests.Session()
# Configure retry strategy
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["HEAD", "GET", "OPTIONS", "POST", "PUT", "DELETE"],
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)
# Set default headers
session.headers.update({
"User-Agent": self.user_agent,
"Accept": "application/json",
"Content-Type": "application/json",
})
# Set authentication headers
if self._api_key:
session.headers["Authorization"] = f"Bearer {self._api_key}"
elif self._auth_handler:
auth_headers = self._auth_handler.get_headers()
session.headers.update(auth_headers)
return session
def _request(
self,
method: str,
endpoint: str,
params: Optional[Dict[str, Any]] = None,
json_data: Optional[Dict[str, Any]] = None,
**kwargs
) -> Dict[str, Any]:
"""Make HTTP request to Wiki.js API.
Args:
method: HTTP method (GET, POST, PUT, DELETE)
endpoint: API endpoint path
params: Query parameters
json_data: JSON data for request body
**kwargs: Additional request parameters
Returns:
Parsed response data
Raises:
AuthenticationError: If authentication fails
APIError: If API returns an error
ConnectionError: If connection fails
TimeoutError: If request times out
"""
# Build full URL
url = build_api_url(self.base_url, endpoint)
# Prepare request arguments
request_kwargs = {
"timeout": self.timeout,
"verify": self.verify_ssl,
"params": params,
**kwargs
}
# Add JSON data if provided
if json_data is not None:
request_kwargs["json"] = json_data
try:
# Make request
response = self._session.request(method, url, **request_kwargs)
# Handle response
return self._handle_response(response)
except requests.exceptions.Timeout as e:
raise TimeoutError(f"Request timed out after {self.timeout} seconds") from e
except requests.exceptions.ConnectionError as e:
raise ConnectionError(f"Failed to connect to {self.base_url}") from e
except requests.exceptions.RequestException as e:
raise APIError(f"Request failed: {str(e)}") from e
def _handle_response(self, response: requests.Response) -> Dict[str, Any]:
"""Handle HTTP response and extract data.
Args:
response: HTTP response object
Returns:
Parsed response data
Raises:
AuthenticationError: If authentication fails (401)
APIError: If API returns an error
"""
# Handle authentication errors
if response.status_code == 401:
raise AuthenticationError("Authentication failed - check your API key")
# Handle other HTTP errors
if not response.ok:
error_message = extract_error_message(response)
raise create_api_error(
response.status_code,
error_message,
response
)
# Parse JSON response
try:
data = response.json()
except json.JSONDecodeError as e:
raise APIError(f"Invalid JSON response: {str(e)}") from e
# Parse Wiki.js specific response format
return parse_wiki_response(data)
def test_connection(self) -> bool:
"""Test connection to Wiki.js instance.
Returns:
True if connection successful
Raises:
ConfigurationError: If client is not properly configured
ConnectionError: If cannot connect to server
AuthenticationError: If authentication fails
"""
if not self.base_url:
raise ConfigurationError("Base URL not configured")
if not self._api_key and not self._auth_handler:
raise ConfigurationError("Authentication not configured")
try:
# Try to hit a basic endpoint (will implement with actual endpoints)
# For now, just test basic connectivity
response = self._session.get(
self.base_url,
timeout=self.timeout,
verify=self.verify_ssl
)
return True
except requests.exceptions.Timeout:
raise TimeoutError(f"Connection test timed out after {self.timeout} seconds")
except requests.exceptions.ConnectionError as e:
raise ConnectionError(f"Cannot connect to {self.base_url}: {str(e)}")
except Exception as e:
raise ConnectionError(f"Connection test failed: {str(e)}")
def __enter__(self):
"""Context manager entry."""
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Context manager exit - close session."""
self.close()
def close(self):
"""Close the HTTP session and clean up resources."""
if self._session:
self._session.close()
def __repr__(self) -> str:
"""String representation of client."""
return f"WikiJSClient(base_url='{self.base_url}')"

View File

@@ -0,0 +1,22 @@
"""API endpoints module for wikijs-python-sdk.
This module will contain endpoint handlers for different
Wiki.js API endpoints.
Future implementations:
- Pages API (CRUD operations)
- Users API (user management)
- Groups API (group management)
- Assets API (file management)
- System API (system information)
"""
# Placeholder for future endpoint implementations
# from .base import BaseEndpoint
# from .pages import PagesEndpoint
# from .users import UsersEndpoint
# from .groups import GroupsEndpoint
__all__ = [
# Will be implemented in Task 1.4
]

109
wikijs/exceptions.py Normal file
View File

@@ -0,0 +1,109 @@
"""Exception hierarchy for wikijs-python-sdk."""
from typing import Any, Dict, Optional
class WikiJSException(Exception):
"""Base exception for all SDK errors."""
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
super().__init__(message)
self.message = message
self.details = details or {}
class ConfigurationError(WikiJSException):
"""Raised when there's an issue with SDK configuration."""
pass
class AuthenticationError(WikiJSException):
"""Raised when authentication fails."""
pass
class ValidationError(WikiJSException):
"""Raised when input validation fails."""
def __init__(self, message: str, field: Optional[str] = None, value: Any = None):
super().__init__(message)
self.field = field
self.value = value
class APIError(WikiJSException):
"""Base class for API-related errors."""
def __init__(
self,
message: str,
status_code: Optional[int] = None,
response: Optional[Any] = None,
details: Optional[Dict[str, Any]] = None
):
super().__init__(message, details)
self.status_code = status_code
self.response = response
class ClientError(APIError):
"""Raised for 4xx HTTP status codes (client errors)."""
pass
class ServerError(APIError):
"""Raised for 5xx HTTP status codes (server errors)."""
pass
class NotFoundError(ClientError):
"""Raised when a requested resource is not found (404)."""
pass
class PermissionError(ClientError):
"""Raised when access is forbidden (403)."""
pass
class RateLimitError(ClientError):
"""Raised when rate limit is exceeded (429)."""
def __init__(self, message: str, retry_after: Optional[int] = None, **kwargs):
super().__init__(message, status_code=429, **kwargs)
self.retry_after = retry_after
class ConnectionError(WikiJSException):
"""Raised when there's a connection issue."""
pass
class TimeoutError(WikiJSException):
"""Raised when a request times out."""
pass
def create_api_error(status_code: int, message: str, response: Any = None) -> APIError:
"""Create appropriate API error based on status code.
Args:
status_code: HTTP status code
message: Error message
response: Raw response object
Returns:
Appropriate APIError subclass instance
"""
if status_code == 404:
return NotFoundError(message, status_code=status_code, response=response)
elif status_code == 403:
return PermissionError(message, status_code=status_code, response=response)
elif status_code == 429:
return RateLimitError(message, status_code=status_code, response=response)
elif 400 <= status_code < 500:
return ClientError(message, status_code=status_code, response=response)
elif 500 <= status_code < 600:
return ServerError(message, status_code=status_code, response=response)
else:
return APIError(message, status_code=status_code, response=response)

11
wikijs/models/__init__.py Normal file
View File

@@ -0,0 +1,11 @@
"""Data models for wikijs-python-sdk."""
from .base import BaseModel
from .page import Page, PageCreate, PageUpdate
__all__ = [
"BaseModel",
"Page",
"PageCreate",
"PageUpdate",
]

90
wikijs/models/base.py Normal file
View File

@@ -0,0 +1,90 @@
"""Base model functionality for wikijs-python-sdk."""
from datetime import datetime
from typing import Any, Dict, Optional
from pydantic import BaseModel as PydanticBaseModel, ConfigDict
class BaseModel(PydanticBaseModel):
"""Base model with common functionality for all data models.
Provides:
- Automatic validation via Pydantic
- JSON serialization/deserialization
- Field aliases for API compatibility
- Consistent datetime handling
"""
model_config = ConfigDict(
# Allow population by field name or alias
populate_by_name=True,
# Validate assignment to attributes
validate_assignment=True,
# Use enum values instead of names
use_enum_values=True,
# Allow extra fields for forward compatibility
extra="ignore",
# Serialize datetime as ISO format
json_encoders={
datetime: lambda v: v.isoformat() if v else None
}
)
def to_dict(self, exclude_none: bool = True) -> Dict[str, Any]:
"""Convert model to dictionary.
Args:
exclude_none: Whether to exclude None values
Returns:
Dictionary representation of the model
"""
return self.model_dump(exclude_none=exclude_none, by_alias=True)
def to_json(self, exclude_none: bool = True) -> str:
"""Convert model to JSON string.
Args:
exclude_none: Whether to exclude None values
Returns:
JSON string representation of the model
"""
return self.model_dump_json(exclude_none=exclude_none, by_alias=True)
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "BaseModel":
"""Create model instance from dictionary.
Args:
data: Dictionary data
Returns:
Model instance
"""
return cls(**data)
@classmethod
def from_json(cls, json_str: str) -> "BaseModel":
"""Create model instance from JSON string.
Args:
json_str: JSON string
Returns:
Model instance
"""
return cls.model_validate_json(json_str)
class TimestampedModel(BaseModel):
"""Base model with timestamp fields."""
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
@property
def is_new(self) -> bool:
"""Check if this is a new (unsaved) model."""
return self.created_at is None

188
wikijs/models/page.py Normal file
View File

@@ -0,0 +1,188 @@
"""Page-related data models for wikijs-python-sdk."""
import re
from datetime import datetime
from typing import List, Optional
from pydantic import Field, validator
from .base import BaseModel, TimestampedModel
class Page(TimestampedModel):
"""Represents a Wiki.js page.
This model contains all the data for a wiki page including
content, metadata, and computed properties.
"""
id: int = Field(..., description="Unique page identifier")
title: str = Field(..., description="Page title")
path: str = Field(..., description="Page path/slug")
content: str = Field(..., description="Page content")
# Optional fields that may be present
description: Optional[str] = Field(None, description="Page description")
is_published: bool = Field(True, description="Whether page is published")
is_private: bool = Field(False, description="Whether page is private")
# Metadata
tags: List[str] = Field(default_factory=list, description="Page tags")
locale: str = Field("en", description="Page locale")
# Author information
author_id: Optional[int] = Field(None, alias="authorId")
author_name: Optional[str] = Field(None, alias="authorName")
author_email: Optional[str] = Field(None, alias="authorEmail")
# Editor information
editor: Optional[str] = Field(None, description="Editor used")
@validator("path")
def validate_path(cls, v):
"""Validate page path format."""
if not v:
raise ValueError("Path cannot be empty")
# Remove leading/trailing slashes and normalize
v = v.strip("/")
# Check for valid characters (letters, numbers, hyphens, underscores, slashes)
if not re.match(r"^[a-zA-Z0-9\-_/]+$", v):
raise ValueError("Path contains invalid characters")
return v
@validator("title")
def validate_title(cls, v):
"""Validate page title."""
if not v or not v.strip():
raise ValueError("Title cannot be empty")
# Limit title length
if len(v) > 255:
raise ValueError("Title cannot exceed 255 characters")
return v.strip()
@property
def word_count(self) -> int:
"""Calculate word count from content."""
if not self.content:
return 0
# Simple word count - split on whitespace
words = self.content.split()
return len(words)
@property
def reading_time(self) -> int:
"""Estimate reading time in minutes (assuming 200 words per minute)."""
return max(1, self.word_count // 200)
@property
def url_path(self) -> str:
"""Get the full URL path for this page."""
return f"/{self.path}"
def extract_headings(self) -> List[str]:
"""Extract markdown headings from content.
Returns:
List of heading text (without # markers)
"""
if not self.content:
return []
headings = []
for line in self.content.split("\n"):
line = line.strip()
if line.startswith("#"):
# Remove # markers and whitespace
heading = re.sub(r"^#+\s*", "", line).strip()
if heading:
headings.append(heading)
return headings
def has_tag(self, tag: str) -> bool:
"""Check if page has a specific tag.
Args:
tag: Tag to check for
Returns:
True if page has the tag
"""
return tag.lower() in [t.lower() for t in self.tags]
class PageCreate(BaseModel):
"""Data model for creating a new page."""
title: str = Field(..., description="Page title")
path: str = Field(..., description="Page path/slug")
content: str = Field(..., description="Page content")
# Optional fields
description: Optional[str] = Field(None, description="Page description")
is_published: bool = Field(True, description="Whether to publish immediately")
is_private: bool = Field(False, description="Whether page should be private")
tags: List[str] = Field(default_factory=list, description="Page tags")
locale: str = Field("en", description="Page locale")
editor: str = Field("markdown", description="Editor to use")
@validator("path")
def validate_path(cls, v):
"""Validate page path format."""
if not v:
raise ValueError("Path cannot be empty")
# Remove leading/trailing slashes and normalize
v = v.strip("/")
# Check for valid characters
if not re.match(r"^[a-zA-Z0-9\-_/]+$", v):
raise ValueError("Path contains invalid characters")
return v
@validator("title")
def validate_title(cls, v):
"""Validate page title."""
if not v or not v.strip():
raise ValueError("Title cannot be empty")
if len(v) > 255:
raise ValueError("Title cannot exceed 255 characters")
return v.strip()
class PageUpdate(BaseModel):
"""Data model for updating an existing page."""
# All fields optional for partial updates
title: Optional[str] = Field(None, description="Page title")
content: Optional[str] = Field(None, description="Page content")
description: Optional[str] = Field(None, description="Page description")
is_published: Optional[bool] = Field(None, description="Publication status")
is_private: Optional[bool] = Field(None, description="Privacy status")
tags: Optional[List[str]] = Field(None, description="Page tags")
@validator("title")
def validate_title(cls, v):
"""Validate page title if provided."""
if v is not None:
if not v.strip():
raise ValueError("Title cannot be empty")
if len(v) > 255:
raise ValueError("Title cannot exceed 255 characters")
return v.strip()
return v

0
wikijs/py.typed Normal file
View File

15
wikijs/utils/__init__.py Normal file
View File

@@ -0,0 +1,15 @@
"""Utility functions for wikijs-python-sdk."""
from .helpers import (
normalize_url,
sanitize_path,
validate_url,
parse_wiki_response,
)
__all__ = [
"normalize_url",
"sanitize_path",
"validate_url",
"parse_wiki_response",
]

209
wikijs/utils/helpers.py Normal file
View File

@@ -0,0 +1,209 @@
"""Helper utilities for wikijs-python-sdk."""
import re
from typing import Any, Dict, Optional
from urllib.parse import urljoin, urlparse
from ..exceptions import APIError, ValidationError
def normalize_url(base_url: str) -> str:
"""Normalize a base URL for API usage.
Args:
base_url: Base URL to normalize
Returns:
Normalized URL without trailing slash
Raises:
ValidationError: If URL is invalid
"""
if not base_url:
raise ValidationError("Base URL cannot be empty")
# Add https:// if no scheme provided
if not base_url.startswith(("http://", "https://")):
base_url = f"https://{base_url}"
# Validate URL format
if not validate_url(base_url):
raise ValidationError(f"Invalid URL format: {base_url}")
# Remove trailing slash
return base_url.rstrip("/")
def validate_url(url: str) -> bool:
"""Validate URL format.
Args:
url: URL to validate
Returns:
True if URL is valid
"""
try:
result = urlparse(url)
return all([result.scheme, result.netloc])
except Exception:
return False
def sanitize_path(path: str) -> str:
"""Sanitize a wiki page path.
Args:
path: Path to sanitize
Returns:
Sanitized path
Raises:
ValidationError: If path is invalid
"""
if not path:
raise ValidationError("Path cannot be empty")
# Remove leading/trailing slashes and whitespace
path = path.strip().strip("/")
# Replace spaces with hyphens
path = re.sub(r"\s+", "-", path)
# Remove invalid characters, keep only alphanumeric, hyphens, underscores, slashes
path = re.sub(r"[^a-zA-Z0-9\-_/]", "", path)
# Remove multiple consecutive hyphens or slashes
path = re.sub(r"[-/]+", lambda m: m.group(0)[0], path)
if not path:
raise ValidationError("Path contains no valid characters")
return path
def build_api_url(base_url: str, endpoint: str) -> str:
"""Build full API URL from base URL and endpoint.
Args:
base_url: Base URL (already normalized)
endpoint: API endpoint path
Returns:
Full API URL
"""
# Ensure endpoint starts with /
if not endpoint.startswith("/"):
endpoint = f"/{endpoint}"
# Wiki.js API is typically at /graphql, but we'll use REST-style for now
api_base = f"{base_url}/api"
return urljoin(api_base, endpoint.lstrip("/"))
def parse_wiki_response(response_data: Dict[str, Any]) -> Dict[str, Any]:
"""Parse Wiki.js API response data.
Args:
response_data: Raw response data from API
Returns:
Parsed response data
Raises:
APIError: If response indicates an error
"""
if not isinstance(response_data, dict):
return response_data
# Check for error indicators
if "error" in response_data:
error_info = response_data["error"]
if isinstance(error_info, dict):
message = error_info.get("message", "Unknown API error")
code = error_info.get("code")
else:
message = str(error_info)
code = None
raise APIError(f"API Error: {message}", details={"code": code})
# Handle GraphQL-style errors
if "errors" in response_data:
errors = response_data["errors"]
if errors:
first_error = errors[0] if isinstance(errors, list) else errors
message = first_error.get("message", "GraphQL error") if isinstance(first_error, dict) else str(first_error)
raise APIError(f"GraphQL Error: {message}", details={"errors": errors})
return response_data
def extract_error_message(response: Any) -> str:
"""Extract error message from response.
Args:
response: Response object or data
Returns:
Error message string
"""
if hasattr(response, "json"):
try:
data = response.json()
if isinstance(data, dict):
# Try common error message fields
for field in ["message", "error", "detail", "msg"]:
if field in data:
return str(data[field])
except Exception:
pass
if hasattr(response, "text"):
return response.text[:200] + "..." if len(response.text) > 200 else response.text
return str(response)
def chunk_list(items: list, chunk_size: int) -> list:
"""Split list into chunks of specified size.
Args:
items: List to chunk
chunk_size: Size of each chunk
Returns:
List of chunks
"""
if chunk_size <= 0:
raise ValueError("Chunk size must be positive")
return [items[i:i + chunk_size] for i in range(0, len(items), chunk_size)]
def safe_get(data: Dict[str, Any], key: str, default: Any = None) -> Any:
"""Safely get value from dictionary with dot notation support.
Args:
data: Dictionary to get value from
key: Key (supports dot notation like "user.name")
default: Default value if key not found
Returns:
Value or default
"""
if "." not in key:
return data.get(key, default)
keys = key.split(".")
current = data
for k in keys:
if isinstance(current, dict) and k in current:
current = current[k]
else:
return default
return current

7
wikijs/version.py Normal file
View File

@@ -0,0 +1,7 @@
"""Version information for wikijs-python-sdk."""
__version__ = "0.1.0"
__version_info__ = (0, 1, 0)
# Version history
# 0.1.0 - MVP Release: Basic Wiki.js integration with Pages API