You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构建包含HTML Tidy的自包含PyTidyLib Python Wheel

Building a Self-Contained PyTidyLib Wheel (No System Tidy Dependency)

Great question! Creating a self-contained PyTidyLib wheel means bundling the HTML Tidy library directly into the package so users don’t need to install it via apt/rpm or other system package managers. Here’s a practical, step-by-step guide to make this happen:


1. Get or Build HTML Tidy Binaries

First, you need platform-specific Tidy library files to bundle. You can either:

  • Pre-build binaries: Download pre-compiled libtidy.so (Linux), libtidy.dylib (macOS), or tidy.dll (Windows) from trusted sources like the official Tidy repository.
  • Build from source: Clone the Tidy repo, then compile with flags to create a position-independent shared library (critical for bundling):
    • For Linux/macOS: Run ./configure --enable-shared --with-pic && make to generate the shared library.
    • For Windows: Use MinGW or MSVC to compile a DLL, ensuring it’s compatible with your target Python versions.

Store these binaries in a subfolder within the PyTidyLib package (e.g., pytidylib/lib/).

2. Modify PyTidyLib to Load the Bundled Library

The original PyTidyLib relies on ctypes.util.find_library() to locate the system-installed Tidy. We need to override this to load our bundled version first.

Open the pytidylib/tidy.py file and replace the library loading logic with something like this:

import os
import sys
from ctypes import cdll, util

def load_tidy_library():
    # Get the path to our bundled library folder
    package_dir = os.path.dirname(os.path.abspath(__file__))
    lib_dir = os.path.join(package_dir, "lib")

    # Platform-specific library names
    if os.name == "nt":
        lib_path = os.path.join(lib_dir, "tidy.dll")
    elif sys.platform == "darwin":
        lib_path = os.path.join(lib_dir, "libtidy.dylib")
    else:
        lib_path = os.path.join(lib_dir, "libtidy.so")

    # Try loading bundled library first, fall back to system if missing
    try:
        return cdll.LoadLibrary(lib_path)
    except OSError:
        return cdll.LoadLibrary(util.find_library("tidy"))

# Replace the original library reference
tidy = load_tidy_library()

3. Configure Packaging to Include Binaries

Update the package’s build configuration to include the bundled library files in the wheel.

Option A: Using setup.py

If the project uses setup.py, add a package_data entry:

from setuptools import setup, find_packages

setup(
    name="pytidylib-selfcontained",  # Custom name to distinguish from upstream
    version="0.3.2",  # Match upstream version plus your suffix if needed
    packages=find_packages(),
    package_data={
        "pytidylib": ["lib/*"],  # Include all files in the lib subfolder
    },
    # Add other metadata (author, license, etc.) as needed
)

Option B: Using pyproject.toml (Modern Approach)

For projects using pyproject.toml, add this section:

[project]
name = "pytidylib-selfcontained"
version = "0.3.2"
packages = ["pytidylib"]

[tool.setuptools.package-data]
pytidylib = ["lib/*"]

4. Build the Wheel

Run this command in the project root directory to generate the self-contained wheel:

pip wheel .

This will create a .whl file that includes both the PyTidyLib code and your bundled Tidy binaries.

For cross-platform wheels (supporting Linux, macOS, Windows), use tools like cibuildwheel to automate building across different environments.

5. Test the Wheel

Install the wheel on a system with no system-wide Tidy installed to verify it works:

pip install pytidylib-selfcontained-0.3.2-py3-none-any.whl

Then run a quick test script:

from pytidylib import tidy_document

raw_html = "<html><body><p>Hello, unformatted HTML!</p></body>"
cleaned_html, errors = tidy_document(raw_html)
print("Cleaned HTML:", cleaned_html)

Key Notes

  • License Compliance: Ensure you adhere to the licenses of both PyTidyLib (MIT) and HTML Tidy (BSD-like) when distributing your bundled wheel.
  • Binary Compatibility: For Linux, build on an older distro (e.g., CentOS 7) to maximize compatibility with newer systems (thanks to glibc backward compatibility).
  • Fallback Logic: The modified code includes a fallback to the system library if the bundled version is missing, which adds robustness.

内容的提问来源于stack exchange,提问作者guettli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:25:27