Skip to content

recipe: thrift 0.25.0 - #126

Merged
ndonkoHenri merged 7 commits into
flet-dev:mainfrom
ndonkoHenri:thrift
Oct 4, 2026
Merged

ndonkoHenri merged 7 commits into
flet-dev:mainfrom
ndonkoHenri:thrift

Conversation

@ndonkoHenri

@ndonkoHenri ndonkoHenri commented Oct 4, 2026 •

Copy link
Copy Markdown

Adds Apache Thrift's Python runtime with its optional C++ codec, thrift.protocol.fastbinary, built for Android and iOS. Requested in flet#6909.

Why a recipe

Upstream publishes desktop wheels only (cibuildwheel, since 0.24.0) and no pure-Python wheel, so flet build has nothing to install on mobile. The source_packages workaround suggested in the discussion builds the sdist for the build host instead. pip's isolated build drops serious_python's platform-faking sitecustomize, and pip never tag-checks a wheel it built itself. Verified on flet 1.0.3:

  • The APK carries a macOS Mach-O as lib/<abi>/libthrift-protocol-fastbinary.so for all three ABIs.
  • The iOS app ships a .fwork pointing at a framework that was never built.
  • The app runs on thrift's pure-Python fallback. The *Accelerated protocols retry the broken load on every construction and ran 12–23x slower than the plain classes.

Changes

  • CIBUILDWHEEL=1 makes setup.py fail when the extension doesn't compile, instead of building a pure-Python wheel.
  • mobile.patch drops setup.cfg's [install] optimize = 1. Its byte-compile step imports distutils in the cross interpreter and fails on 3.12+.
  • Android depends on flet-libcpp-shared for libc++_shared.so.
  • Skills:
    • new-mobile-recipe: an optional extension is not "pure Python" for source_packages; new shape row for forcing optional extensions.
    • forge-error-catalogue: the source_packages cause of the iOS lipo error, and the setup.cfg [install] optimize distutils failure.
    • local-recipe-testing: concurrent iOS builds share dist_ios; give each its own PUB_CACHE.

Validation

  • CI 6/6 with mobile_test_pythons=ALL (run): 11 passed, EXIT 0, on cp312, cp313 and cp314 for Android and iOS.
  • Tests:
    • The codec loads, and the Accelerated protocols bind it.
    • Output is byte-identical to pure Python, and round trips succeed.
    • Loopback TCP (framed, buffered, bare) and HTTP (buffered, bare) calls count native encodes and decodes.
    • All 11 fail against a pure-Python build, which is the negative control.
  • Wheels: Android DT_NEEDED lists libc++_shared.so with 16 KB LOAD alignment; iOS slices are MH_DYLIB.
  • Example built and run with flet 1.0.3 on an Android 14 arm64 emulator and an iOS 18.6 simulator: native codec active, RPC and declared exception working, 9–25x native gain for the example payload.
  • TLS probe on both platforms: TSSLSocket with the default context verifies against Flet's certifi bundle, and self-signed or expired hosts are rejected.
  • Two adversarial review rounds on the README, example and tests.

Consumer notes

Gives Flet apps a native-speed Thrift client over TCP or HTTP; the generated code is produced on desktop. Install, transport setup, TLS and error handling are in the recipe README, with a runnable telemetry-rpc example.

Apache Thrift's Python runtime with its optional C++ codec,
thrift.protocol.fastbinary, built for Android and iOS. Requested in
flet-dev/flet#6909.

Upstream ships desktop wheels only and no pure-Python wheel. The
source_packages workaround compiles the codec for the build host, so
the app carries a macOS binary and runs on thrift's pure-Python
fallback.

- CIBUILDWHEEL=1 makes setup.py fail instead of silently building a
  pure-Python wheel when the extension doesn't compile.
- mobile.patch drops setup.cfg's [install] optimize, whose
  byte-compile step needs distutils in the cross interpreter.
- Android depends on flet-libcpp-shared for libc++_shared.so.

Tests cover the codec loading and agreeing with pure Python, plus
loopback TCP and HTTP calls showing which transports decode natively.
All of them fail against a pure-Python build. README and a
telemetry-rpc example included.
… workaround [skip ci]

- new-mobile-recipe: an optional C extension is not "pure Python";
  source_packages compiles it for the build host and ships it to the
  phone. New shape row for forcing optional extensions.
- forge-error-catalogue: that cause under the iOS lipo entry, and the
  setup.cfg `[install] optimize` distutils failure.
- local-recipe-testing: flet 1.0.3 defaults, concurrent iOS builds
  sharing dist_ios, and finishing an iOS build on Xcode 27 (deployment
  target 13.0 rejected).
Second adversarial pass over the docs and example:
- Size-qualified speedups and fallback cost (5–30x for small structs).
- Native decoding needs a buffering transport for TSSLSocket and
  THttpClient too, not just TSocket.
- THttpClient raises unwrapped OSError; example catches
  (TException, OSError). New "Failures" subsection.
- Snippets run standalone; usage ends in a Flet control.
@ndonkoHenri
ndonkoHenri merged commit 0fadbfa into flet-dev:main Oct 4, 2026
7 of 12 checks passed
@ndonkoHenri
ndonkoHenri deleted the thrift branch October 4, 2026 12:45
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