This simple example project shows how to include
brotlicffi
into projects supporting both CPython
and other Python implementations like PyPy.
Basically it boils down to these two steps:
Include the two dependencies in your install_requires
/requirements.txt
:
# install_requires:
from setuptools import setup
setup(
...,
install_requires=[
"brotli; platform_python_implementation == 'CPython'",
"brotlicffi; platform_python_implementation != 'CPython'"
]
)
# requirements.txt:
brotli; platform_python_implementation == 'CPython'
brotlicffi; platform_python_implementation != 'CPython'
...then you can import the bindings in your project like so:
try:
import brotlicffi as brotli
except ImportError:
import brotli
It should be that simple! Now let's see our example project in action:
Build the project sdist locally
$ cd example/
$ python setup.py sdist
$ ls dist/
example-brotli-project-0.1.0.tar.gz
Run python:3.7-slim
Docker image to test against CPython
$ docker run --rm -it -v $(pwd)/dist:/dist python:3.7-slim /bin/bash
Install the example project
$ python -m pip install /dist/example-brotli-project-0.1.0.tar.gz
Processing /dist/example-brotli-project-0.1.0.tar.gz
Collecting brotli
Downloading Brotli-1.0.9-cp37-cp37-manylinux1_x86_64.whl (357 kB)
|████████████████████████████████| 357 kB 1.9 MB/s
Building wheels for collected packages: example-brotli-project
Building wheel for example-brotli-project (setup.py) ... done
Created wheel for example-brotli-project: filename=example_brotli_project-0.1.0-py3-none-any.whl size=1976 sha256=b94975444c08cf82f395c8277e29b5b6f3b3270dd4f7d224482e4493be89c6bd
Stored in directory: /root/.cache/pip/wheels/be/67/36/911a88789436560de345984e6c4c3785098e98b92dcbab5980
Successfully built example-brotli-project
Installing collected packages: brotli, example-brotli-project
Successfully installed brotli-1.0.9 example-brotli-project-0.1.0
Notice that Brotli
is installed from PyPI instead of brotlicffi
on CPython.
Now run the program and see the output:
$ example-brotli-project "Hello, world!"
Compressing data: b'Hello, world!'
Compressed data: b'\x0b\x06\x80Hello, world!\x03'
Decompressed data: b'Hello, world!'
Run pypy:3.7-slim
Docker image to test against PyPy
$ docker run --rm -it -v $(pwd)/dist:/dist pypy:3.7-slim /bin/bash
$ pypy -m pip install /dist/example-brotli-project-0.1.0.tar.gz
Processing /dist/example-brotli-project-0.1.0.tar.gz
Collecting brotlicffi
Downloading brotlicffi-0.8.0-pp37-pypy37_pp73-manylinux1_x86_64.whl (341 kB)
|████████████████████████████████| 341 kB 2.8 MB/s
Requirement already satisfied: cffi>=1.0.0 in /opt/pypy/lib_pypy (from brotlicffi->example-brotli-project==0.1.0) (1.14.2)
Building wheels for collected packages: example-brotli-project
Building wheel for example-brotli-project (setup.py) ... done
Created wheel for example-brotli-project: filename=example_brotli_project-0.1.0-py3-none-any.whl size=1976 sha256=566f5bfb3a0d74d11485b02b929a09d6e6cc8bab7c409cf30ff50f2067692356
Stored in directory: /root/.cache/pip/wheels/cb/e1/0f/337346ea74252e5b652824bb0f2fc82e81208f9f8e3de42465
Successfully built example-brotli-project
Installing collected packages: brotlicffi, example-brotli-project
Successfully installed brotlicffi-0.8.0 example-brotli-project-0.1.0
Notice now that brotlicffi
is installed from PyPI instead of Brotli
on CPython.
Now run the program and see the output:
$ example-brotli-project "Hello, world!"
Compressing data: b'Hello, world!'
Compressed data: b'\x0b\x06\x80Hello, world!\x03'
Decompressed data: b'Hello, world!'
Identical output compared to CPython! 🎉