FontLift Python bindings and CLI powered by PyO3
Project description
FontLift
A cross-platform font management library and CLI tool written in Rust, consolidating the functionality of the existing Swift and C++ implementations into a unified codebase.
Overview
FontLift provides:
- Core Library: Cross-platform font management abstraction
- Platform Implementations: Native macOS and Windows integration
- CLI Tool: Command-line interface for font operations
- Python Bindings: PyO3 bindings for Python integration
Status (2025-12-03)
- macOS: Parity with the Swift CLI including install/uninstall/remove, descriptor-based listing, cleanup with prune/cache toggles, and fake-registry/dry-run support.
- Windows: Registry + GDI install/uninstall/list and cache cleanup (FontCache + Adobe) are implemented; needs validation on a Windows host and golden-output capture.
- Python: Bindings expose
FontliftFontSource/FontliftFontFaceInfo, name-based operations, cleanup toggles, and a Fire CLI; wheels build viamaturin. - CI: GitHub Actions matrix on macOS 14 and Windows runs
cargo fmt,cargo clippy, platform-scoped tests, andmaturin develop+pytestfor Python bindings.
Architecture
The project is organized into several crates:
fontlift-core: Core traits, types, and platform-agnostic logicfontlift-platform-mac: macOS-specific implementation using Core Textfontlift-platform-win: Windows-specific implementation using Registry APIsfontlift-cli: Command-line interface built with Clapfontlift-python: Python bindings using PyO3
Features
Font Management
- ✅ Install fonts (user-level and system-level)
- ✅ Uninstall fonts (keeping files)
- ✅ Remove fonts (uninstall and delete)
- ✅ List installed fonts with metadata
- ✅ Clear font caches
- ✅ Cross-platform support (macOS, Windows)
Font Formats Supported
- TrueType (.ttf, .ttc)
- OpenType (.otf, .otc)
- Web Open Font Format (.woff, .woff2)
- macOS dfont (.dfont)
Safety Features
- Validation of font files before installation
- Protection against modifying system fonts
- Proper error handling and reporting
- Scope-based operations (user vs system)
Quick Start
As a Rust Library
use fontlift_core::{FontManager, FontScope};
use fontlift_platform_mac::MacFontManager; // or WinFontManager
let manager = MacFontManager::new();
let font_path = std::path::PathBuf::from("my-font.ttf");
// Install font for current user
manager.install_font(&font_path, FontScope::User)?;
// List installed fonts
let fonts = manager.list_installed_fonts()?;
for font in fonts {
println!("{}: {}", font.family_name, font.style);
}
CLI Usage
# Install a font
fontlift install my-font.ttf
# List installed fonts (sorted; path-only output is deduped)
fontlift list
# List installed fonts as deterministic JSON
fontlift list --json
# Install multiple fonts or an entire directory (non-recursive)
fontlift install my-font.ttf extras/AnotherFont.otf fonts/
# Preview changes without touching the system
fontlift install my-font.ttf --dry-run --quiet
# Install system-wide (requires admin)
fontlift install my-font.ttf --admin
# List installed fonts with detailed fields (use --sorted to dedupe names/paths when combining)
fontlift list --path --name --sorted
# Uninstall a font
fontlift uninstall --name "MyFont"
# Remove a font (uninstall + delete)
fontlift remove my-font.ttf
# Clear font caches
fontlift cleanup
# Clear system caches (requires admin)
fontlift cleanup --admin
# Prune stale registrations without touching caches
fontlift cleanup --prune-only
# Clear caches only (skip pruning)
fontlift cleanup --cache-only
# Generate shell completions (bash|zsh|fish|powershell|elvish)
fontlift completions bash > /usr/local/etc/bash_completion.d/fontlift
Python Integration
import fontlift
# Create manager
manager = fontlift.FontliftManager()
# List fonts
fonts = manager.list_fonts()
for font in fonts:
print(f"{font['family_name']}: {font['style']}")
# Install font
manager.install_font("my-font.ttf")
# Or use functional API
fontlift.install("my-font.ttf", admin=False)
fontlift.list()
fontlift.cleanup(prune=True, cache=True, admin=False, dry_run=True)
# Fire CLI mirror with JSON/quiet/verbose/dry-run toggles (parity with Rust CLI)
# fontliftpy list --json --path --name --sorted
# fontliftpy install my-font.ttf --dry_run True --quiet True
Platform-Specific Details
macOS
- Uses Core Text APIs for font registration
- Supports both user (
~/Library/Fonts) and system (/Library/Fonts) scopes - Cache clearing via
atsutilcommands - Safe handling of system font protection
Windows
- Uses Windows Registry and GDI APIs
- Supports per-user and system-wide font installation
- Registry-based font tracking
- Safe handling of Windows Fonts directory protection
Building
Prerequisites
- Rust 1.75+
- Platform-specific build tools:
- macOS: Xcode Command Line Tools
- Windows: Visual Studio Build Tools
Build Commands
# Build all workspace members
cargo build --workspace
# Build release
cargo build --workspace --release
# Run tests
cargo test --workspace
# Run with specific features
cargo build --workspace --features "python"
Platform-Specific Builds
# Build only current platform
cargo build -p fontlift-core
cargo build -p fontlift-platform-mac # macOS only
cargo build -p fontlift-platform-win # Windows only
# Build CLI
cargo build -p fontlift-cli
# Build Python bindings
cargo build -p fontlift-python
Packaging (CLI + Python wheels)
- Windows: run from the "x64 Native Tools" developer prompt with Visual Studio Build Tools installed; ensure Python 3.12+ is on PATH for PyO3.
- Cross-platform build helper:
./build.shwill run fmt/clippy, build the workspace, and, whenmaturinis available, emit wheels viacrates/fontlift-python/Cargo.tomlintodist-<mode>-<platform>-<arch>/. - Python wheels only:
maturin build -m crates/fontlift-python/Cargo.toml --release -o dist. - CLI release artifacts:
cargo build -p fontlift-cli --releaseproducestarget/release/fontlift/fontlift.exeready for packaging or signing.
Testing
# Run all tests
cargo test --workspace
# Run specific crate tests
cargo test -p fontlift-core
cargo test -p fontlift-cli
# Run documentation tests
cargo test --doc
# Run with logging
RUST_LOG=debug cargo test --workspace
Development
Project Structure
fontlift/
├── Cargo.toml # Workspace configuration
├── README.md
├── crates/
│ ├── fontlift-core/ # Core library
│ ├── fontlift-platform-mac/ # macOS implementation
│ ├── fontlift-platform-win/ # Windows implementation
│ ├── fontlift-cli/ # Command-line interface
│ └── fontlift-python/ # Python bindings
└── docs/
└── platform-specific.md
Adding New Platforms
- Create a new crate:
fontlift-platform-{platform} - Implement the
FontManagertrait - Add platform-specific dependencies
- Update workspace and CLI integration
- Add tests and documentation
Code Style
- Use
cargo fmtfor formatting - Use
cargo clippy -- -D warningsfor linting - Follow Rust API guidelines
- Document all public APIs
Error Handling
FontLift uses a comprehensive error type system:
FontNotFound: Font file doesn't existInvalidFormat: Not a valid font fileRegistrationFailed: Platform registration failedSystemFontProtection: Attempted to modify system fontPermissionDenied: Insufficient privilegesAlreadyInstalled: Font already existsUnsupportedOperation: Platform doesn't support operation
Security Considerations
- Font files are validated before installation
- System fonts are protected from modification
- Scope-based privilege separation
- Safe path handling and sandboxing
- No network operations by default
Performance
- Minimal memory allocations
- Efficient font metadata extraction
- Lazy loading of platform resources
- Async operations where applicable
- Optimized for bulk operations
Roadmap
- Linux platform support (fontconfig integration)
- Font collection (.ttc/.otc) handling
- Variable font metadata extraction
- Font conflict detection and resolution
- Batch installation/uninstallation
- Font preview generation
- GUI application (via testypf integration)
Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
See CONTRIBUTING.md for detailed guidelines.
License
FontLift is licensed under the Apache License 2.0. See LICENSE for details.
Changelog
See CHANGELOG.md for version history and release notes.
Made by FontLab https://www.fontlab.com/
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fontlift-5.0.13-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: fontlift-5.0.13-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 370.6 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79a672b446c0e2b1ec626540e3b1df3e78c629c5dc3476082fcbe122a319564b
|
|
| MD5 |
da111608bb0b033d12fbbfc143940da9
|
|
| BLAKE2b-256 |
a3e8e9156b68d584b492f9e056c957b4b082ac09bb664562fcad41af3d57948f
|