-
Notifications
You must be signed in to change notification settings - Fork 295
Build platform-specific wheels containing libmagic #294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
ec952d7
a437409
4a715e2
1adc0a5
20e2dc9
090b1d4
20d8fee
85d4422
2efa36d
0b43bc6
05df4f9
d2972b9
e182ae1
94718d5
359e007
bb9c685
b0fddf3
dc075e9
144132d
fe62a26
f7bbb03
2e6104e
ca4def3
ba87ffd
e112de3
eba05b6
8381a96
9c5f955
e6d5ed0
50504a2
9357f27
53d099b
9bf2e9c
f7341ce
da5b330
258efa4
3a55538
65fb61c
43c0c99
3e51048
d7b1171
620d78f
d3e886c
2bb9fa8
c8a599b
e1b154c
d111ace
33c827e
688edf0
9dd2ebc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
version: 2 | ||
updates: | ||
- package-ecosystem: "github-actions" | ||
directory: "/" | ||
schedule: | ||
interval: "monthly" | ||
groups: | ||
github-actions: | ||
patterns: | ||
- "*" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
name: wheels | ||
|
||
on: | ||
pull_request: | ||
push: | ||
branches: master | ||
release: | ||
types: [released, prereleased] | ||
workflow_dispatch: # allows running workflow manually from the Actions tab | ||
|
||
concurrency: # https://stackoverflow.com/questions/66335225#comment133398800_72408109 | ||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }} | ||
cancel-in-progress: ${{ github.event_name == 'pull_request' }} | ||
|
||
jobs: | ||
build-sdist: | ||
runs-on: ubuntu-latest | ||
|
||
env: | ||
PIP_DISABLE_PIP_VERSION_CHECK: 1 | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.x' | ||
|
||
- run: sudo apt-get install -y libmagic1 | ||
|
||
- name: Build source distribution | ||
run: | | ||
pip install --upgrade setuptools wheel pip build | ||
python -m build --sdist | ||
|
||
- uses: actions/upload-artifact@v4 | ||
with: | ||
name: dist | ||
path: dist/*.tar.* | ||
|
||
|
||
build-wheels-matrix: | ||
runs-on: ubuntu-latest | ||
outputs: | ||
include: ${{ steps.set-matrix.outputs.include }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.x' | ||
- run: pip install cibuildwheel==2.17.0 # sync version with pypa/cibuildwheel below | ||
- id: set-matrix | ||
env: | ||
# only mention one (trivial) python version, as py2.py3 wheels only need to be build once per arch | ||
CIBW_PROJECT_REQUIRES_PYTHON: '==3.12.*' | ||
# skip PyPy wheels for now, and skip i686 wheels because pytest is failing | ||
CIBW_SKIP: pp* *i686 | ||
run: | | ||
MATRIX_INCLUDE=$( | ||
{ | ||
cibuildwheel --print-build-identifiers --platform linux --arch all | jq -nRc '{"only": inputs, "os": "ubuntu-latest"}' \ | ||
&& cibuildwheel --print-build-identifiers --platform macos --arch x86_64 | jq -nRc '{"only": inputs, "os": "macos-13"}' \ | ||
&& cibuildwheel --print-build-identifiers --platform macos --arch arm64 | jq -nRc '{"only": inputs, "os": "macos-14"}' \ | ||
&& cibuildwheel --print-build-identifiers --platform windows --arch x86,AMD64 | jq -nRc '{"only": inputs, "os": "windows-latest"}' | ||
} | jq -sc | ||
) | ||
echo "include=$MATRIX_INCLUDE" >> $GITHUB_OUTPUT | ||
|
||
|
||
build-wheels: | ||
name: build ${{ matrix.only }} | ||
needs: build-wheels-matrix | ||
runs-on: ${{ matrix.os }} | ||
|
||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: ${{ fromJson(needs.build-wheels-matrix.outputs.include) }} | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Set up QEMU | ||
if: runner.os == 'Linux' | ||
uses: docker/setup-qemu-action@v3 | ||
|
||
# For Windows, grabbing latest file from MSYS2 is easier than building from source | ||
# It's generally up to date ref https://packages.msys2.org/base/mingw-w64-file | ||
- name: Setup MSYS2 and install file | ||
if: runner.os == 'Windows' | ||
uses: msys2/[email protected] | ||
with: | ||
msystem: ${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }} | ||
location: D:\ | ||
install: >- | ||
${{ endsWith(matrix.only, '32') && 'mingw-w64-i686-file' || 'mingw-w64-x86_64-file' }} | ||
|
||
# The DLL dependency tree flattened out ref "Dependencies" https://packages.msys2.org/packages/mingw-w64-x86_64-file | ||
- name: Copy Windows ddl and mgc | ||
if: runner.os == 'Windows' | ||
run: | | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/share/misc/magic.mgc" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libmagic-1.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libsystre-0.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libtre-5.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libasprintf-0.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libintl-8.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libatomic-1.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libgomp-1.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libquadmath-0.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libstdc++-6.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libcharset-1.dll" "magic" | ||
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libiconv-2.dll" "magic" | ||
|
||
# These are needed additionally in the win32 wheel ref https://packages.msys2.org/packages/mingw-w64-i686-file | ||
- name: Copy additional 32-bit runtime DLLs | ||
if: runner.os == 'Windows' && endsWith(matrix.only, '32') | ||
run: | | ||
cp "/msys64/mingw32/bin/libgcc_s_dw2-1.dll" "magic" | ||
cp "/msys64/mingw32/bin/libwinpthread-1.dll" "magic" | ||
|
||
- uses: pypa/[email protected] # sync version with pip install cibuildwheel above | ||
timeout-minutes: 10 | ||
with: | ||
only: ${{ matrix.only }} | ||
env: | ||
CIBW_BUILD_VERBOSITY: 1 | ||
# add compiled libmagic to the build directory (to include in the wheel) | ||
CIBW_BEFORE_BUILD_MACOS: sudo -E bash add_libmagic.sh | ||
CIBW_BEFORE_BUILD_LINUX: bash add_libmagic.sh | ||
# build macos wheels with maximum backwards compatibility (gcc -mmacosx-version-min flag) | ||
MACOSX_DEPLOYMENT_TARGET: ${{ ( endsWith( matrix.only, 'arm64' ) && '11.0' ) || '10.9' }} | ||
# simple smoke test run on each wheel: this is an HLS MP4 video, only recognised in recent versions of libmagic | ||
CIBW_TEST_COMMAND: python -c "import magic; assert magic.Magic(mime=True).from_buffer(b'\x00\x00\x00\x1cftypiso5\x00\x00\x00\x01isomiso5hlsf\x00\x00') == 'video/mp4'" | ||
|
||
- uses: actions/upload-artifact@v4 | ||
with: | ||
name: dist-${{ matrix.only }} | ||
path: wheelhouse/*.whl | ||
|
||
|
||
publish: | ||
if: github.event_name == 'release' | ||
needs: [build-sdist, build-wheels] | ||
runs-on: ubuntu-latest | ||
|
||
permissions: | ||
contents: write # softprops/action-gh-release | ||
id-token: write # pypa/gh-action-pypi-publish | ||
|
||
steps: | ||
- uses: actions/setup-python@v5 | ||
with: | ||
python-version: 3.x | ||
|
||
- uses: actions/download-artifact@v4 | ||
with: | ||
path: dist/ | ||
pattern: dist-* | ||
merge-multiple: true | ||
|
||
- run: ls -ltra dist/ | ||
|
||
- run: pip install --upgrade python-magic --find-links ./dist | ||
|
||
- name: Smoketest | ||
run: python -c "import magic; magic.Magic()" | ||
|
||
- name: Upload release assets | ||
uses: softprops/[email protected] | ||
with: | ||
files: dist/* | ||
|
||
- name: Publish package distributions to PyPI | ||
uses: pypa/[email protected] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,11 +3,11 @@ | |
[](https://github.com/ahupp/python-magic/actions/workflows/ci.yml) | ||
[](https://gitter.im/ahupp/python-magic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | ||
|
||
python-magic is a Python interface to the libmagic file type | ||
identification library. libmagic identifies file types by checking | ||
[python-magic](https://github.com/ahupp/python-magic) is a Python interface to the libmagic file type | ||
identification library. libmagic identifies file types by checking | ||
their headers according to a predefined list of file types. This | ||
functionality is exposed to the command line by the Unix command | ||
`file`. | ||
[`file`](https://www.darwinsys.com/file/). | ||
|
||
## Usage | ||
|
||
|
@@ -31,8 +31,7 @@ will fail throw if this is attempted. | |
```python | ||
>>> f = magic.Magic(uncompress=True) | ||
>>> f.from_file('testdata/test.gz') | ||
'ASCII text (gzip compressed data, was "test", last modified: Sat Jun 28 | ||
21:32:52 2008, from Unix)' | ||
'ASCII text (gzip compressed data, was "test", last modified: Sat Jun 28 21:32:52 2008, from Unix)' | ||
``` | ||
|
||
You can also combine the flag options: | ||
|
@@ -45,27 +44,53 @@ You can also combine the flag options: | |
|
||
## Installation | ||
|
||
The current stable version of python-magic is available on PyPI and | ||
can be installed by running `pip install python-magic`. | ||
This module is a simple [CDLL](https://docs.python.org/3/library/ctypes.html) wrapper around the libmagic C library. | ||
The current stable version of python-magic is available on [PyPI](http://pypi.python.org/pypi/python-magic/) | ||
and can be installed by running `pip install python-magic`. | ||
|
||
Other sources: | ||
Compiled libmagic and the magic database come bundled in the wheels on PyPI. | ||
You can use your own `magic.mgc` database by setting the `MAGIC` | ||
environment variable, or by using `magic.Magic(magic_file='path/to/magic.mgc')`. | ||
If you want to compile your own libmagic, circumvent the wheels | ||
by installing from source: `pip install python-magic --no-binary python-magic`. | ||
|
||
- PyPI: http://pypi.python.org/pypi/python-magic/ | ||
- GitHub: https://github.com/ahupp/python-magic | ||
For systems not supported by the wheels, pip installs from source, | ||
requiring libmagic to be available before installing python-magic: | ||
|
||
This module is a simple wrapper around the libmagic C library, and | ||
that must be installed as well: | ||
### Linux | ||
|
||
### Debian/Ubuntu | ||
The Linux wheels should run on most systems out of the box. | ||
|
||
Depending on your system and CPU architecture, there might be no compatible wheel uploaded. | ||
However, precompiled libmagic might still be available for your system: | ||
|
||
```sh | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It may be beneficial to add a library installation guide for SUSE as well There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you provide the relevant command? fwiw, I think mostly all linux flavours will be covered by the wheels in the PR description, so those users won't be needing the install from source instructions provided here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess that it would be Currently I don't have OpenSUSE at my disposal for tests and it's likely that it would be a default package. I don't promise anything, but I might find time soon-ish to test it. |
||
# Debian/Ubuntu | ||
apt-get update && apt-get install -y libmagic1 | ||
# Alpine | ||
apk add --update libmagic | ||
# RHEL | ||
ddelange marked this conversation as resolved.
Show resolved
Hide resolved
|
||
dnf install file-libs | ||
``` | ||
sudo apt-get install libmagic1 | ||
``` | ||
|
||
### Windows | ||
|
||
The DLLs that are bundled in the Windows wheels are compiled by @julian-r | ||
and are hosted at https://github.com/julian-r/file-windows/releases. | ||
|
||
For ARM64 Windows, you'll need to compile libmagic from source. | ||
|
||
### OSX | ||
|
||
- When using Homebrew: `brew install libmagic` | ||
- When using macports: `port install file` | ||
The Mac wheels are compiled with maximum backward compatibility. | ||
For older Macs, you'll need to install libmagic from source: | ||
|
||
```sh | ||
# homebrew | ||
brew install libmagic | ||
# macports | ||
port install file | ||
``` | ||
|
||
If python-magic fails to load the library it may be in a non-standard location, in which case you can set the environment variable `DYLD_LIBRARY_PATH` to point to it. | ||
|
||
|
@@ -78,7 +103,7 @@ If python-magic fails to load the library it may be in a non-standard location, | |
- 'MagicException: could not find any magic files!': some | ||
installations of libmagic do not correctly point to their magic | ||
database file. Try specifying the path to the file explicitly in the | ||
constructor: `magic.Magic(magic_file="path_to_magic_file")`. | ||
constructor: `magic.Magic(magic_file='path/to/magic.mgc')`. | ||
|
||
- 'WindowsError: [Error 193] %1 is not a valid Win32 application': | ||
Attempting to run the 32-bit libmagic DLL in a 64-bit build of | ||
|
@@ -88,7 +113,6 @@ If python-magic fails to load the library it may be in a non-standard location, | |
- 'WindowsError: exception: access violation writing 0x00000000 ' This may indicate you are mixing | ||
Windows Python and Cygwin Python. Make sure your libmagic and python builds are consistent. | ||
|
||
|
||
## Bug Reports | ||
|
||
python-magic is a thin layer over the libmagic C library. | ||
|
Uh oh!
There was an error while loading. Please reload this page.