Files
py-wikijs/docs/deployment.md
Claude c18d00cd47 build: Add PyPI package deployment support
Complete package deployment configuration for PyPI publishing:

- Add MANIFEST.in to control package distribution
  - Include LICENSE, README, requirements files
  - Include docs/ and examples/ directories
  - Include type stub marker (py.typed)
  - Exclude test files and development artifacts

- Fix dependency specification
  - Add pydantic[email] for email validation support
  - Required for User model EmailStr fields
  - Update both requirements.txt and pyproject.toml

- Create comprehensive deployment documentation
  - docs/deployment.md - Complete PyPI publishing guide
    - Pre-deployment checklist
    - Build and test procedures
    - PyPI upload instructions
    - Troubleshooting guide
    - CI/CD automation examples
  - DEPLOYMENT_READY.md - Deployment status summary
    - What's included in distributions
    - Verification test results
    - Quick deployment steps
    - PyPI vs Gitea comparison

Package is now 100% ready for PyPI deployment:
 Builds successfully (sdist + wheel)
 Installs correctly with all dependencies
 Imports work without errors
 All files properly included
 Complete documentation provided

Testing:
- Successfully built wikijs_python_sdk-0.1.0.tar.gz (134 KB)
- Successfully built wikijs_python_sdk-0.1.0-py3-none-any.whl (66 KB)
- Verified installation and imports work correctly
- All dependencies resolve properly

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 20:13:51 +00:00

11 KiB

Deployment Guide - Publishing py-wikijs to PyPI

Last Updated: October 2025 Target Audience: Maintainers and release managers


📋 Overview

This guide covers how to build, test, and publish the wikijs-python-sdk package to PyPI (Python Package Index).


Pre-Deployment Checklist

1. Code Quality

  • All tests pass (pytest)
  • Code coverage ≥85% (pytest --cov)
  • Linting passes (black, flake8, mypy)
  • Security scan passes (bandit)
  • No critical bugs in issue tracker

2. Documentation

  • README.md is up to date
  • CHANGELOG.md has release notes
  • API documentation is current
  • Examples are tested and working
  • Compatibility guide is accurate

3. Version Management

  • Version bumped in wikijs/version.py
  • CHANGELOG.md updated with new version
  • Git tag created for release
  • No uncommitted changes
  • LICENSE file present (MIT)
  • setup.py metadata correct
  • pyproject.toml metadata correct
  • Author information accurate

🔧 Prerequisites

Required Tools

# Install build and publishing tools
pip install --upgrade pip
pip install build twine

PyPI Account Setup

  1. Create PyPI Account: https://pypi.org/account/register/
  2. Create API Token:
  3. Save Token Securely: Store in password manager or environment variable

Configure PyPI Credentials

Option 1: Using .pypirc file (Recommended for local development)

# Create ~/.pypirc
cat > ~/.pypirc << 'EOF'
[distutils]
index-servers =
    pypi
    testpypi

[pypi]
username = __token__
password = pypi-AgEIcHlwaS5vcmc...YOUR-TOKEN-HERE...

[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-AgENdGVzdC5weXBp...YOUR-TEST-TOKEN-HERE...
EOF

chmod 600 ~/.pypirc

Option 2: Using environment variables (Recommended for CI/CD)

export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-AgEIcHlwaS5vcmc...YOUR-TOKEN-HERE...

📦 Building the Package

1. Clean Previous Builds

# Remove old build artifacts
rm -rf build/ dist/ *.egg-info wikijs_python_sdk.egg-info

# Verify clean state
git status

2. Update Version

# Edit wikijs/version.py
__version__ = "0.2.0"  # Update version number
__version_info__ = (0, 2, 0)

3. Update CHANGELOG

# Edit docs/CHANGELOG.md

## [0.2.0] - 2025-10-XX

### Added
- New feature descriptions
- API additions

### Changed
- Modified functionality

### Fixed
- Bug fixes

4. Build Distributions

# Build both source distribution (sdist) and wheel
python -m build

# This creates:
# - dist/wikijs_python_sdk-X.Y.Z.tar.gz (source distribution)
# - dist/wikijs_python_sdk-X.Y.Z-py3-none-any.whl (wheel)

5. Verify Build Contents

# Check source distribution contents
tar -tzf dist/wikijs_python_sdk-*.tar.gz | head -30

# Check wheel contents
python -m zipfile -l dist/wikijs_python_sdk-*-py3-none-any.whl | head -30

# Verify required files are included:
# - LICENSE
# - README.md
# - requirements.txt
# - docs/
# - examples/
# - wikijs/ (all source code)
# - wikijs/py.typed (type stub marker)

🧪 Testing the Package

1. Validate Package Metadata

# Check package metadata for errors
python -m twine check dist/*

# Should show:
# Checking dist/wikijs_python_sdk-X.Y.Z.tar.gz: PASSED
# Checking dist/wikijs_python_sdk-X.Y.Z-py3-none-any.whl: PASSED

2. Test Local Installation

# Create a test virtual environment
python -m venv test-env
source test-env/bin/activate  # On Windows: test-env\Scripts\activate

# Install from wheel
pip install dist/wikijs_python_sdk-*-py3-none-any.whl

# Test import
python -c "from wikijs import WikiJSClient, __version__; print(f'Version: {__version__}')"

# Test basic functionality
python << 'EOF'
from wikijs import WikiJSClient
from wikijs.models import PageCreate

# This should not error (will fail at connection, which is expected)
try:
    client = WikiJSClient('https://example.com', auth='test-key')
    print("✅ Client instantiation successful")
except Exception as e:
    print(f"❌ Error: {e}")
EOF

# Cleanup
deactivate
rm -rf test-env
# Upload to TestPyPI first
python -m twine upload --repository testpypi dist/*

# Install from TestPyPI
pip install --index-url https://test.pypi.org/simple/ \
    --extra-index-url https://pypi.org/simple/ \
    wikijs-python-sdk

# Test the installation
python -c "from wikijs import WikiJSClient; print('TestPyPI install successful')"

🚀 Publishing to PyPI

1. Final Pre-Publish Checks

# Ensure you're on the main branch
git checkout main

# Ensure everything is committed
git status

# Tag the release
git tag v0.2.0
git push origin v0.2.0

2. Upload to PyPI

# Upload to production PyPI
python -m twine upload dist/*

# You'll see output like:
# Uploading distributions to https://upload.pypi.org/legacy/
# Uploading wikijs_python_sdk-0.2.0-py3-none-any.whl
# Uploading wikijs_python_sdk-0.2.0.tar.gz
# View at:
# https://pypi.org/project/wikijs-python-sdk/0.2.0/

3. Verify Publication

# Visit PyPI page
# https://pypi.org/project/wikijs-python-sdk/

# Test installation from PyPI
pip install wikijs-python-sdk

# Verify version
python -c "from wikijs import __version__; print(__version__)"

🔄 Post-Publication Tasks

1. Update Documentation

  • Update README.md installation instructions
  • Update GitHub releases page
  • Announce release in community channels
  • Update project status badges

2. Git Housekeeping

# Create GitHub release
# Go to: https://github.com/l3ocho/py-wikijs/releases/new
# - Tag version: v0.2.0
# - Release title: v0.2.0 - Release Name
# - Description: Copy from CHANGELOG.md
# - Attach dist/ files

# Merge release branch if applicable
git checkout main
git merge release/v0.2.0
git push origin main

3. Prepare for Next Development Cycle

# Bump to next development version
# Edit wikijs/version.py
__version__ = "0.3.0-dev"

git add wikijs/version.py
git commit -m "chore: bump version to 0.3.0-dev"
git push

🐛 Troubleshooting

Build Failures

Problem: FileNotFoundError: requirements.txt

# Solution: Ensure MANIFEST.in includes requirements.txt
# Check MANIFEST.in contents:
cat MANIFEST.in

Problem: Missing documentation in package

# Solution: Update MANIFEST.in to include docs
recursive-include docs *.md

Upload Failures

Problem: 403 Forbidden - Invalid or non-existent authentication information

# Solution: Check your API token
# 1. Verify token is correct in ~/.pypirc
# 2. Ensure token has upload permissions
# 3. Try using environment variables instead
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=your-token-here
python -m twine upload dist/*

Problem: 400 File already exists

# Solution: You cannot re-upload the same version
# 1. Increment version in wikijs/version.py
# 2. Rebuild: python -m build
# 3. Upload again: python -m twine upload dist/*

Problem: Package name already taken

# Solution: Choose a different package name
# 1. Update name in setup.py and pyproject.toml
# 2. Rebuild package
# Note: wikijs-python-sdk is our chosen name

Installation Issues

Problem: ModuleNotFoundError after install

# Solution: Check dependencies are installed
pip show wikijs-python-sdk
pip install wikijs-python-sdk[all]  # Install all optional deps

Problem: Import errors with type hints

# Solution: Ensure py.typed file is in package
# Check if included: python -m zipfile -l dist/*.whl | grep py.typed

📊 Package Statistics

Size Guidelines

  • Wheel: Should be < 100 KB for SDK
  • Source: Should be < 200 KB including docs
  • Total dependencies: Keep minimal
# Check package sizes
ls -lh dist/

# Check dependency tree
pip install pipdeptree
pipdeptree -p wikijs-python-sdk

Download Stats

After publication, monitor package metrics:


🔐 Security Best Practices

1. Protect API Tokens

  • Never commit tokens to git
  • Use .gitignore for .pypirc
  • Rotate tokens periodically
  • Use scoped tokens (project-specific)

2. Package Security

# Run security scan before publishing
pip install safety
safety check --file requirements.txt

# Scan for vulnerabilities
bandit -r wikijs/

3. Signing Releases (Optional)

# Sign the release with GPG
gpg --detach-sign -a dist/wikijs_python_sdk-0.2.0.tar.gz

# Upload signatures
python -m twine upload dist/* --sign

📝 Checklist Summary

Pre-Release

  • Tests pass
  • Version bumped
  • CHANGELOG updated
  • Documentation current

Build

  • Clean build environment
  • Build succeeds
  • Package validated
  • Local test passes

Publish

  • TestPyPI upload (optional)
  • PyPI upload
  • Installation verified
  • Package page checked

Post-Release

  • Git tag created
  • GitHub release published
  • Documentation updated
  • Community notified

📞 Support

Resources

Getting Help


🎓 Additional Notes

Automated Publishing (CI/CD)

For automated releases via GitHub Actions:

# .github/workflows/publish.yml
name: Publish to PyPI

on:
  release:
    types: [published]

jobs:
  pypi-publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - 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/*

Alternative: Using Trusted Publishing

Modern approach (no API tokens needed):

  1. Configure trusted publisher on PyPI
  2. Use OIDC token from GitHub Actions
  3. More secure, no secrets needed

See: https://docs.pypi.org/trusted-publishers/


Last Updated: October 2025 Maintainer: leomiranda

For questions about deployment, open an issue on GitHub.