mrkeyoor.com_
Tue 22 Sept 18:47 UTC
PyPIUtilsupdated 20 Sept 2026

python-magic review

python-magic 0.4.27 is a ctypes wrapper around libmagic, the native signature database behind the Unix file command. It can inspect a path, bytes, or an open descriptor and return a description, MIME guess, encoding, or possible extension. It can also inspect compressed content through libmagic. The wheel contains pure Python and no declared dependencies, but it does not include the shared library or its magic database. Version 0.4.27 only removed a stray pyproject.toml that broke some source builds; later repository changes have not been released to PyPI.

Verdict

python-magic 0.4.27 installed in 0.2 seconds as 1 pure Python package, yet every useful classification still depends on the host's libmagic and database. Choose it to match the system file command; avoid it when a self-contained wheel or reproducible cross-platform output matters.

We installed it

Lab card: what happened when we installed python-magicScreenshot of python-magic documentation
Install✓ · 0.2s1 package on disk · 1 MB
Importimport magic in 0.19s · pure Python · py.typed · requires Python >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
Known vulns0(pip-audit)

Answers from our run

Does python-magic install cleanly?

Yes. In a fresh container with an empty cache, pip install python-magic finished in 0.2s, leaving 1 package and 1 MB on disk. pip-audit reported no known vulnerabilities.

What does python-magic need to run?

Python >=2.7, !=3.0., !=3.1., !=3.2., !=3.3., !=3.4.*, and nothing compiled: it is pure Python. In our run import magic succeeded in 0.19s, and the package ships py.typed for type checkers.

python-magic or puremagic: which should you use?

puremagic: Use it when the image cannot provide native libmagic and Python-only matching is enough. python-magic 0.4.27 installed in 0.2 seconds as 1 pure Python package, yet every useful classification still depends on the host's libmagic and database.

When should you not use python-magic?

Installation must be self-contained in one wheel; the operating system still has to provide libmagic and its database

API stability4/5python-magic 0.4.27 retains the long-standing from_file, from_buffer, from_descriptor, and Magic interfaces, and the project says minor versions should remain compatible. Returned classifications can still change when libmagic or its database changes under the same Python API. Repository work newer than the PyPI release also means a source checkout may expose fixes and behavior that packaged installations do not have.
Docs3/5The README demonstrates file, buffer, MIME, and compressed-content calls, recommends a 2,048-byte sample, and gives concrete Linux, macOS, and Windows setup advice. It documents missing-database failures, Windows architecture mismatches, thread safety, and the competing magic module. Less common flags and exact native limits still require source inspection or the separate libmagic documentation.
Maintenance2/5The unarchived repository was pushed on July 20, 2026, and GitHub reports 27 open issues and pull requests, which shows continuing source activity. PyPI still serves 0.4.27 from June 7, 2022. Repository changelog work intended for later versions includes Windows discovery and symlink fixes, but ordinary pip users cannot receive those changes as a stable release.
Ecosystem4/5GitHub lists 2,917 stars, and the project wraps the same libmagic engine packaged by major Unix-like operating systems and used by the file command. That native reach gives it many signatures without Python dependencies. It also creates the main integration cost: a Python lockfile cannot capture the operating-system library, magic database, Windows DLL architecture, or the exact classifications each image returns.

Use it if

  • The deployment image already has libmagic and Python should agree with the host file command
  • Upload handling needs a content-signature MIME hint before considering the filename suffix
  • Code must classify a bounded byte prefix or open descriptor without creating another temporary file
  • The product ships and pins its own magic database beside a known libmagic build
Skip it if

Setup reality

We installed python-magic 0.4.27 in a fresh Python 3.12 Bookworm sandbox in 0.2 seconds. It left 1 package and 1 MB on disk, while pip-audit found 0 known vulnerabilities. The distribution declares 0 direct dependencies, is pure Python, includes py.typed, and uses the MIT license. Its metadata accepts Python 2.7 and versions newer than 3.4. import magic worked in 0.19 seconds.

That successful import does not make deployment self-contained. Debian and Ubuntu need libmagic1; macOS installations commonly use Homebrew or MacPorts. Windows needs a DLL whose architecture matches Python, and error 193 usually signals a 32-bit versus 64-bit mismatch. A missing magic database raises MagicException. Pass the exact magic_file path when automatic discovery cannot find the deployed file, and pin the image or OS package when classifications must stay repeatable.

The README recommends at least 2,048 bytes for buffer classification because shorter samples can be wrong. Read a bounded prefix instead of loading an entire upload. Descriptions are not stable enums and may contain versions or document metadata. MIME and encoding values are guesses too. Confirm a claimed type with the parser that will consume it before extraction, preview, or any security-sensitive operation.

The README says one Magic instance is unsafe across threads. Use convenience calls or create one detector per worker thread. uncompress=True lets native code examine compressed contents and increases CPU, memory, and decompression exposure, so hostile uploads need size and time limits. The competing native Python binding also imports as magic; dependency changes can therefore select a different API without changing your import statement.

Patterns

Get a human-readable file description describe-file

import magic
description = magic.from_file('document.pdf')

The description follows the installed database and may include changing version details, so do not store it as an enum.

Guess MIME type from content detect-file-mime

import magic
mime_type = magic.from_file('document.pdf', mime=True)

Content inspection is stronger than trusting a suffix, but the returned MIME value remains a heuristic.

Inspect a bounded upload prefix detect-buffer-mime

import magic
with open('upload.bin','rb') as handle:
    prefix = handle.read(2048)
mime_type = magic.from_buffer(prefix, mime=True)

The README recommends at least 2,048 bytes because smaller samples may be classified incorrectly.

Classify an open file descriptor detect-descriptor

import magic
with open('archive.tar','rb') as handle:
    description = magic.from_descriptor(handle.fileno())

Keep the descriptor open throughout the native call; availability follows the host libmagic build.

Inspect compressed contents inspect-compressed

detector = magic.Magic(mime=True, uncompress=True)
mime_type = detector.from_file('payload.gz')

Compressed inspection needs CPU, decompression, size, and time limits when the input is untrusted.

Use an explicit signature database pin-magic-database

detector = magic.Magic(mime=True, magic_file='/opt/app/magic/magic.mgc')
mime_type = detector.from_file('sample.bin')

The database must match the native library and be readable by the application's operating-system user.

Keep one detector per thread thread-local-detector

from threading import local
import magic
_state = local()
def detector():
    if not hasattr(_state, 'magic'): _state.magic = magic.Magic(mime=True)
    return _state.magic

The project explicitly warns that a Magic instance cannot be shared safely between threads.

Separate library and filesystem failures handle-native-error

try:
    mime_type = magic.from_file(path, mime=True)
except (OSError, magic.MagicException) as error:
    raise RuntimeError('classification unavailable') from error

OSError covers file access, while MagicException can report native library or database problems.

Alternatives

PackageRegistryPick it when
puremagicPyPIUse it when the image cannot provide native libmagic and Python-only matching is enough
filetypePyPIUse it for a small pure Python detector covering common binary formats
mimetypes-magicPyPIUse it when evaluating a newer packaged fork of the libmagic wrapper

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.