diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 85e8397..7590933 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,32 +35,9 @@ jobs: 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 }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6ddc58b..5e7f5ae 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,7 @@ MANIFEST *.spec # Unit test / coverage reports -htmlcov/ +tests/htmlcov/ .tox/ .nox/ .coverage diff --git a/CLAUDE.md b/CLAUDE.md index dbf345f..9f47a85 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,4 +1,4 @@ -# CLAUDE.md - AI Development Coordinator +# CLAUDE.md - AI Development Coordinator (Created by leomiranda) **🤖 AI Development Orchestration System** **Project**: Wiki.js Python SDK @@ -10,7 +10,7 @@ ## 🎯 CRITICAL: READ THIS FIRST -**⚠️ MANDATORY ACTIONS FOR EVERY CLAUDE SESSION:** +**⚠️ MANDATORY ACTIONS FOR EVERY AI DEVELOPMENT SESSION:** 1. **📚 ALWAYS REFER TO DOCUMENTATION**: Before any development work, review relevant documentation: - `docs/wikijs_sdk_architecture.md` for technical decisions @@ -34,6 +34,7 @@ **Name**: wikijs-python-sdk **Purpose**: Professional-grade Python SDK for Wiki.js API integration **Development Approach**: AI-powered, community-driven, open source +**Deployment Strategy**: GitHub-only installation (pip install git+https://github.com/...) **Target**: Complete professional development lifecycle demonstration ### **Current Development State** @@ -115,43 +116,44 @@ Task_Breakdown: Status: "COMPLETE" Completion: 100% Estimated_Time: "3 hours" - Claude_Requests: "15-20" + AI_Sessions: "15-20" Task_1.2_Core_Client: # ✅ COMPLETE Status: "COMPLETE" Completion: 100% Estimated_Time: "8 hours" - Claude_Requests: "30-40" + AI_Sessions: "30-40" Task_1.3_Authentication: # ✅ COMPLETE Status: "COMPLETE" Completion: 100% Estimated_Time: "4 hours" - Claude_Requests: "15-20" + AI_Sessions: "15-20" Task_1.4_Pages_API: # ✅ COMPLETE Status: "COMPLETE" Completion: 100% Estimated_Time: "6 hours" - Claude_Requests: "25-30" + AI_Sessions: "25-30" Task_1.5_Testing: # ✅ COMPLETE Status: "COMPLETE" Completion: 100% Estimated_Time: "6 hours" - Claude_Requests: "20-25" + AI_Sessions: "20-25" Task_1.6_Documentation: # ✅ COMPLETE Status: "COMPLETE" Completion: 100% Estimated_Time: "4 hours" - Claude_Requests: "15-20" + AI_Sessions: "15-20" - Task_1.7_Release: # ⏳ PENDING - Status: "PENDING" - Completion: 0% + Task_1.7_GitHub_Release: # ✅ COMPLETE + Status: "COMPLETE" + Completion: 100% Estimated_Time: "2 hours" - Claude_Requests: "10-15" + AI_Sessions: "10-15" + Note: "GitHub-only deployment strategy implemented" ``` ### **Phase 2: Essential Features (0% COMPLETE) ⏳** @@ -422,7 +424,7 @@ Task_1.7: Requires Task 1.6 complete (documentation for release) ### **Resource Optimization** ```yaml -# Optimize Claude usage by batching related work +# Optimize AI usage by batching related work Batch_1: "Repository setup + packaging configuration" Batch_2: "Core client implementation + basic auth" Batch_3: "API endpoints + error handling" @@ -508,13 +510,13 @@ This document evolves based on development experience: ## 🚀 READY FOR DEVELOPMENT -**CURRENT INSTRUCTION**: Begin Task 1.1 - Project Foundation Setup +**CURRENT INSTRUCTION**: Phase 1 Complete - GitHub-Only Deployment Ready -**FOCUS**: Create repository structure, Python packaging, and CI/CD pipeline +**FOCUS**: Project is ready for GitHub-only installation and usage -**SUCCESS CRITERIA**: All foundational files created and validated +**SUCCESS CRITERIA**: Users can install via `pip install git+https://github.com/...` -**NEXT SESSION TARGET**: Complete Task 1.1 and begin Task 1.2 +**DEPLOYMENT STRATEGY**: GitHub-only (no PyPI publishing required) **REMEMBER**: Always refer to documentation, update progress, and maintain quality standards! diff --git a/README.md b/README.md index 1234164..58cb213 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ # Wiki.js Python SDK -[![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) +[![Python Support](https://img.shields.io/badge/python-3.8+-blue.svg)](https://python.org) [![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) @@ -18,8 +17,13 @@ ### Installation ```bash -# Coming soon - not yet published -pip install wikijs-python-sdk +# Install directly from GitHub +pip install git+https://github.com/yourusername/wikijs-python-sdk.git + +# Or clone and install locally +git clone https://github.com/yourusername/wikijs-python-sdk.git +cd wikijs-python-sdk +pip install -e . ``` ### Basic Usage @@ -84,7 +88,6 @@ new_page = client.pages.create(PageCreate( ### **For Maintainers** - **[Architecture](docs/wikijs_sdk_architecture.md)**: Technical design and patterns - **[Development Plan](docs/wikijs_sdk_release_plan.md)**: Complete roadmap and milestones -- **[PyPI Publishing](docs/PIP_INSTRUCTIONS.md)**: Complete guide to publishing on PyPI - **[AI Coordination](CLAUDE.md)**: AI-assisted development workflow --- @@ -159,7 +162,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file ## 🙏 Acknowledgments - **Wiki.js**: The excellent knowledge management platform this SDK supports -- **Claude (Anthropic)**: AI assistant powering the complete development process +- **leomiranda**: Developer who created this SDK with AI assistance - **Python Community**: For exceptional tools and development standards --- diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 96d7f2d..1d92885 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -44,10 +44,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Comprehensive error handling - >85% test coverage - Complete API documentation -- PyPI package publication +- GitHub release publication #### Success Criteria -- [ ] Package installable via `pip install wikijs-python-sdk` +- [ ] Package installable via `pip install git+https://github.com/...` - [ ] Basic page operations work with real Wiki.js instance - [ ] All quality gates pass (tests, coverage, linting, security) - [ ] Documentation sufficient for basic usage diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index b50e200..86d01a7 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -4,7 +4,7 @@ Thank you for your interest in contributing to the Wiki.js Python SDK! This guid ## 🎯 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! +This project was developed by leomiranda with AI assistance, 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 @@ -277,7 +277,7 @@ 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 +4. **Automated**: GitHub Actions handles testing and GitHub release creation ## 📚 Documentation @@ -295,7 +295,7 @@ Releases are managed by maintainers: ## 🤖 AI Development Context -This project uses Claude AI for development coordination. If you're interested in the AI-assisted development process: +This project was developed by leomiranda using AI assistance 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 diff --git a/docs/PIP_INSTRUCTIONS.md b/docs/PIP_INSTRUCTIONS.md deleted file mode 100644 index e32dbdd..0000000 --- a/docs/PIP_INSTRUCTIONS.md +++ /dev/null @@ -1,232 +0,0 @@ -# PyPI Publishing Instructions - -This document provides step-by-step instructions for publishing the Wiki.js Python SDK to PyPI. - -## Prerequisites - -- Package has been built and tested locally -- All tests pass with >85% coverage -- Documentation is complete and up-to-date -- GitHub repository is properly configured - -## Pre-Publishing Checklist - -### 1. Update Repository URLs -Replace `yourusername` with your actual GitHub username in the following files: - -**setup.py** (lines 44, 46-48): -```python -url="https://github.com/YOUR_USERNAME/wikijs-python-sdk", -project_urls={ - "Bug Reports": "https://github.com/YOUR_USERNAME/wikijs-python-sdk/issues", - "Source": "https://github.com/YOUR_USERNAME/wikijs-python-sdk", - "Documentation": "https://github.com/YOUR_USERNAME/wikijs-python-sdk/docs", -} -``` - -**pyproject.toml** (lines 65-68): -```toml -[project.urls] -Homepage = "https://github.com/YOUR_USERNAME/wikijs-python-sdk" -"Bug Reports" = "https://github.com/YOUR_USERNAME/wikijs-python-sdk/issues" -Source = "https://github.com/YOUR_USERNAME/wikijs-python-sdk" -Documentation = "https://github.com/YOUR_USERNAME/wikijs-python-sdk/docs" -``` - -**README.md** (lines 6-7): -```markdown -[![CI Status](https://github.com/YOUR_USERNAME/wikijs-python-sdk/workflows/Test%20Suite/badge.svg)](https://github.com/YOUR_USERNAME/wikijs-python-sdk/actions) -[![Coverage](https://codecov.io/gh/YOUR_USERNAME/wikijs-python-sdk/branch/main/graph/badge.svg)](https://codecov.io/gh/YOUR_USERNAME/wikijs-python-sdk) -``` - -### 2. Verify Package Name Availability -Check if `wikijs-python-sdk` is available on PyPI: -- Visit https://pypi.org/project/wikijs-python-sdk/ -- If it returns a 404, the name is available -- If needed, update the package name in `setup.py` and `pyproject.toml` - -### 3. Version Management -Ensure the version in `wikijs/version.py` reflects the release: -```python -__version__ = "0.1.0" # Update as needed -``` - -## PyPI Account Setup - -### 1. Create Accounts -Register for both test and production PyPI: -- **Test PyPI**: https://test.pypi.org/account/register/ -- **Production PyPI**: https://pypi.org/account/register/ - -### 2. Generate API Tokens -For each account, create API tokens: -1. Go to Account Settings -2. Navigate to "API tokens" -3. Click "Add API token" -4. Choose scope: "Entire account" (for first upload) -5. Save the token securely - -## Publishing Process - -### 1. Install Publishing Tools -```bash -pip install twine build -``` - -### 2. Build the Package -```bash -# Clean previous builds -rm -rf dist/ build/ *.egg-info/ - -# Build the package -python -m build -``` - -### 3. Validate the Package -```bash -# Check package for common issues -twine check dist/* -``` - -Expected output: -``` -Checking dist/wikijs_python_sdk-0.1.0-py3-none-any.whl: PASSED -Checking dist/wikijs_python_sdk-0.1.0.tar.gz: PASSED -``` - -### 4. Test Upload (Recommended) -Always test on Test PyPI first: - -```bash -# Upload to Test PyPI -twine upload --repository testpypi dist/* -``` - -When prompted: -- **Username**: `__token__` -- **Password**: Your Test PyPI API token - -### 5. Test Installation -```bash -# Test installation from Test PyPI -pip install --index-url https://test.pypi.org/simple/ wikijs-python-sdk - -# Test basic functionality -python -c "from wikijs import WikiJSClient; print('Import successful')" -``` - -### 6. Production Upload -Once testing is successful: - -```bash -# Upload to production PyPI -twine upload dist/* -``` - -When prompted: -- **Username**: `__token__` -- **Password**: Your Production PyPI API token - -### 7. Verify Production Installation -```bash -# Install from PyPI -pip install wikijs-python-sdk - -# Verify installation -python -c "from wikijs import WikiJSClient; print('Production install successful')" -``` - -## Post-Publishing Tasks - -### 1. Update Documentation -- Update README.md installation instructions -- Remove "Coming soon" notes -- Add PyPI badge if desired - -### 2. Create GitHub Release -1. Go to your GitHub repository -2. Click "Releases" → "Create a new release" -3. Tag version: `v0.1.0` -4. Release title: `v0.1.0 - MVP Release` -5. Copy changelog content as description -6. Attach built files from `dist/` - -### 3. Announce Release -- Update project status in README.md -- Consider posting to relevant communities -- Update project documentation - -## Troubleshooting - -### Common Issues - -**"Package already exists"** -- The package name is taken -- Update package name in configuration files -- Or contact PyPI if you believe you own the name - -**"Invalid authentication credentials"** -- Verify you're using `__token__` as username -- Check that the API token is correct and has proper scope -- Ensure the token hasn't expired - -**"File already exists"** -- You're trying to upload the same version twice -- Increment the version number in `wikijs/version.py` -- Rebuild the package - -**Package validation errors** -- Run `twine check dist/*` for detailed error messages -- Common issues: missing README, invalid metadata -- Fix issues and rebuild - -### Getting Help - -- **PyPI Help**: https://pypi.org/help/ -- **Packaging Guide**: https://packaging.python.org/ -- **Twine Documentation**: https://twine.readthedocs.io/ - -## Automated Publishing (Future) - -Consider setting up GitHub Actions for automated publishing: - -```yaml -# .github/workflows/publish.yml -name: Publish to PyPI - -on: - release: - types: [published] - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.9' - - name: Install dependencies - run: | - pip install build twine - - name: Build package - run: python -m build - - name: Publish to PyPI - env: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} - run: twine upload dist/* -``` - -## Security Notes - -- Never commit API tokens to version control -- Use repository secrets for automated publishing -- Regularly rotate API tokens -- Use scoped tokens when possible -- Monitor package downloads for suspicious activity - ---- - -**Next Steps**: Once published, users can install with `pip install wikijs-python-sdk` \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index fa1cba7..3579015 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,8 +45,6 @@ dev = [ "bandit[toml]>=1.7.0", "responses>=0.20.0", "ipython>=8.0.0", - "twine>=4.0.0", - "build>=0.8.0", ] async = [ "aiohttp>=3.8.0", @@ -156,6 +154,9 @@ exclude_lines = [ "if TYPE_CHECKING:", ] +[tool.coverage.html] +directory = "tests/htmlcov" + [tool.bandit] exclude_dirs = ["tests"] skips = ["B101"] # Skip assert_used test diff --git a/setup.py b/setup.py deleted file mode 100644 index fa96b87..0000000 --- a/setup.py +++ /dev/null @@ -1,106 +0,0 @@ -"""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="contact@wikijs-sdk.dev", - 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, -) \ No newline at end of file diff --git a/tests/utils/test_helpers.py b/tests/utils/test_helpers.py index c6af34f..8cf4ca5 100644 --- a/tests/utils/test_helpers.py +++ b/tests/utils/test_helpers.py @@ -50,6 +50,11 @@ class TestNormalizeUrl: # The normalize_url function adds https:// to URLs without checking scheme result = normalize_url("ftp://wiki.example.com") assert result == "https://ftp://wiki.example.com" + + def test_normalize_url_invalid_format(self): + """Test invalid URL format raises ValidationError.""" + with pytest.raises(ValidationError, match="Invalid URL format"): + normalize_url("not a valid url with spaces") def test_normalize_url_no_scheme(self): """Test URL without scheme gets https:// added.""" @@ -325,6 +330,16 @@ class TestUtilityEdgeCases: """Test validate_url when urlparse raises exception.""" # This is hard to trigger, but test the exception path assert validate_url("") is False + + def test_validate_url_malformed_url(self): + """Test validate_url with malformed URL that causes exception.""" + # Test with a string that could cause urlparse to raise an exception + import sys + from unittest.mock import patch + + with patch('wikijs.utils.helpers.urlparse') as mock_urlparse: + mock_urlparse.side_effect = Exception("Parse error") + assert validate_url("http://example.com") is False def test_sanitize_path_whitespace_only(self): """Test sanitize_path with whitespace-only input."""