Skip to content

feat: add Python bindings with PyPI publishing#6

Merged
clroot merged 11 commits intomainfrom
feat/python-bindings
Feb 18, 2026
Merged

feat: add Python bindings with PyPI publishing#6
clroot merged 11 commits intomainfrom
feat/python-bindings

Conversation

@clroot
Copy link
Owner

@clroot clroot commented Feb 18, 2026

Summary

  • UniFFI 기반 Python 바인딩 추가 (pip install slimg)
  • Pythonic 래퍼 API: slimg.open(), slimg.convert(), slimg.crop(), slimg.resize(), slimg.extend(), slimg.optimize() 등 15개 public API
  • maturin bindings = "uniffi" 모드로 기존 slimg-ffi 크레이트 재사용
  • 75개 pytest 테스트 (Format, Decode, Convert, Crop, Extend, Resize, Optimize)
  • CI: python-bindings.yml (3 OS × 2 Python 버전 빌드 & 테스트)
  • CI: publish.yml에 PyPI 배포 통합 (5 플랫폼 wheel + sdist, Trusted Publisher)

Test plan

  • 75개 pytest 테스트 통과 (0.14s)
  • CI에서 macOS/Linux/Windows × Python 3.9/3.13 빌드 확인
  • 릴리스 태그 푸시 시 PyPI 배포 확인

🤖 Generated with Claude Code

Implement the full public API layer over UniFFI-generated _lowlevel
bindings: Format enum with extension/can_encode/from_path/from_bytes,
Image and Result classes, Resize/Crop/Extend namespace helpers, and
public functions (open, decode, convert, crop, extend, resize, optimize,
optimize_file). All 75 tests pass.
@gemini-code-assist
Copy link

Summary of Changes

Hello @clroot, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands the utility of the slimg image optimization library by introducing robust Python bindings. It provides a comprehensive and intuitive Python API that wraps the core Rust functionalities, allowing Python developers to easily perform image decoding, conversion, and various manipulation operations. The changes include a well-structured project layout, extensive unit tests, and full integration into the CI/CD pipeline for automated builds and PyPI distribution, ensuring broad platform support and ease of use.

Highlights

  • Python Bindings: Introduced official Python bindings for the slimg image optimization library, making its Rust-powered functionalities accessible to Python developers via pip install slimg.
  • Pythonic API: Provided a user-friendly Pythonic wrapper API with 15 public functions, including slimg.open(), slimg.convert(), slimg.crop(), slimg.resize(), slimg.extend(), and slimg.optimize().
  • Build System Integration: Leveraged maturin with UniFFI bindings to reuse the existing slimg-ffi Rust crate, enabling seamless integration and multi-platform wheel generation.
  • Comprehensive Testing: Added 75 pytest tests covering various image operations such as format handling, decoding, conversion, cropping, extending, resizing, and optimization.
  • CI/CD & PyPI Publishing: Integrated a new CI workflow (python-bindings.yml) for building and testing across macOS, Linux, and Windows with Python 3.9/3.13, and automated PyPI publishing into publish.yml for 5 platform wheels and source distribution using Trusted Publisher.
Changelog
  • bindings/python/.gitignore
    • Added Python-specific ignore rules for virtual environments, compiled files, and native modules.
  • bindings/python/README.md
    • Added detailed documentation for Python bindings, including installation instructions, usage examples, supported formats, API reference, and platform compatibility.
  • bindings/python/pyproject.toml
    • Configured maturin for building the Python package, specifying project metadata, dependencies, classifiers, and UniFFI binding details.
  • bindings/python/slimg/init.py
    • Created the main package entry point, importing and exposing Pythonic wrapper APIs from _types.py.
  • bindings/python/slimg/_types.py
    • Implemented Pythonic wrapper classes and functions for Format, Image, Result, Resize, Crop, Extend, and core operations like open, decode, convert, crop_image, extend_image, resize_image, optimize, and optimize_file.
  • bindings/python/tests/conftest.py
    • Added pytest fixtures for creating sample RGBA images and helper functions for pixel value retrieval.
  • bindings/python/tests/test_convert.py
    • Added tests for image conversion to various formats (PNG, WebP, JPEG), including quality settings, resize operations within the pipeline, and full pipeline tests with crop and extend.
  • bindings/python/tests/test_decode.py
    • Added tests for decoding images from bytes and files, validating image properties, and handling invalid input.
  • bindings/python/tests/test_format.py
    • Added tests for the Format enum's utility methods, covering extension retrieval, encoding capability, and format detection from file paths and magic bytes.
  • bindings/python/tests/test_operations.py
    • Added tests for standalone image manipulation operations, including region and aspect-ratio cropping, aspect-ratio and size extending with various fill colors, and resizing by width, height, exact dimensions, fit, and scale.
  • bindings/python/tests/test_optimize.py
    • Added tests for optimizing image data from bytes and files, ensuring format preservation and error handling.
  • crates/slimg-ffi/uniffi.toml
    • Updated UniFFI configuration to include Python bindings alongside existing Kotlin settings.
  • docs/plans/2026-02-19-python-bindings-design.md
    • Added a design document outlining the architecture, project structure, build system, Pythonic API design principles, and CI/CD strategy for the new Python bindings.
  • docs/plans/2026-02-19-python-bindings-plan.md
    • Added a detailed implementation plan, breaking down the development of Python bindings and CI/CD integration into step-by-step tasks.
Ignored Files
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/publish.yml
    • .github/workflows/python-bindings.yml
Activity
  • The author reported that 75 pytest tests passed in 0.14 seconds.
  • The author verified CI builds for macOS, Linux, and Windows across Python 3.9 and 3.13.
  • The author confirmed that PyPI distribution will be triggered upon pushing a release tag.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

maturin develop requires a virtualenv which wasn't set up in CI.
Switch to maturin build + pip install which works with system Python.
- Add input validation: quality (0-100), Image buffer size, fill tuple
  channel ranges (0-255)
- Consistent exception handling: optimize_file now raises SlimgError
  instead of FileNotFoundError for I/O errors
- Add smoke test and version check jobs to publish workflow
- Complete SlimgError variant list in README documentation
- Add 14 new validation tests (89 total)
- Add performance note to resize_image docstring
- Export resize() in slimg-ffi following the same pattern as crop/extend
- Remove PNG encode/decode workaround from Python resize_image()
- Regenerate Kotlin bindings with new resize function
- Add 6 resize tests for Kotlin bindings
- Update all Cargo.toml, pyproject.toml, gradle.properties
- Update Kotlin README: fix outdated version (0.1.2 → 0.3.1),
  add missing crop/extend/resize docs, complete error variant list
@clroot clroot merged commit af69e20 into main Feb 18, 2026
14 checks passed
@clroot clroot deleted the feat/python-bindings branch February 18, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant