A Python library for detecting file types using multiple inference strategies, including path-based extraction, magic number detection, and AI-powered content analysis.
Backend behavior is checked against independently reviewed MIME and extension facts on Linux, macOS, and Windows. The report preserves raw detector output, normalized semantic output, runtime versions, correctness, and cross-platform divergence. It does not reduce runtime-dependent behavior to one static percentage.
See Backend Conformance for the methodology, latest workflow artifact, and reproduction commands.
- Multiple Inference Methods: Choose from lexical, magic-based, AI-powered, or hybrid inference strategies
- Type-Safe API: Type hints and type-safe inference method selection
- Flexible Input: Supports both
Pathobjects and string paths - Performance Optimized: Hybrid inference combines Magic and Magika when it improves the result
- Well-Tested: Comprehensive automated test suite
- Extensible: Base class architecture for custom inferencer implementations
pip install filetype-detectorOr using rye:
rye syncUse the installed terminal interface to filter a directory live and compare Lexical, Magic, Magika, and Hybrid results for the selected file:
filetype-detector-demo path/to/filespython -m filetype_detector path/to/files is equivalent. The directory is
optional and defaults to the current working directory.
Important: MagicInferencer and HybridInferencer require the libmagic system library to be installed.
sudo apt-get update
sudo apt-get install libmagic1sudo dnf install file-libs
# or for older versions:
# sudo yum install file-libssudo pacman -S fileUsing Homebrew:
brew install libmagicUsing MacPorts:
sudo port install fileWindows users need to use python-magic-bin as an alternative:
pip install python-magic-binOr download libmagic DLL manually from file.exe releases.
apk add --no-cache fileAfter installation, verify libmagic is available:
file --versionIf the command works, libmagic is properly installed.
Recommended: Use AutoInferencer with backend="hybrid" for the best balance of performance and accuracy:
Content-based backends require the supplied path to reference an existing file.
from filetype_detector import AutoInferencer
inferencer = AutoInferencer(backend="hybrid")
ft = inferencer.infer("document.pdf")
'.pdf' in ft.extensions # True
ft.mime_types # ('application/pdf',)All infer() methods return a FileType instance. See FileType for details.
For more examples and usage patterns, see the documentation site.
infer()가 반환하는 FileType은 frozen dataclass로, 확장자와 MIME 타입을 함께 보관한다.
from filetype_detector import FileType
ft = FileType.from_extension('.pdf')
ft.extensions # ('.pdf',)
ft.mime_types # ('application/pdf',)
ft2 = FileType.from_mimetype('image/jpeg')
ft2.extensions # ('.jfif', '.jpe', '.jpeg', '.jpg') – OS별로 다를 수 있음| 프로퍼티 | 타입 | 설명 |
|---|---|---|
extensions |
tuple[str, ...] |
연관된 파일 확장자 목록 |
mime_types |
tuple[str, ...] |
연관된 MIME 타입 목록 |
팩토리 메서드: FileType.from_extension(ext), FileType.from_mimetype(mime)
Choose the right inferencer based on your needs:
| Inferencer | Avg. Time (per file) | Memory | Throughput | Best For |
|---|---|---|---|---|
| LexicalInferencer | < 0.001ms | Minimal | 50,000+ files/sec | Trusted extensions |
| MagicInferencer | ~1-5ms | Low | 200-500 files/sec | Content-based detection |
| MagikaInferencer | ~5-10ms* | High** | 100-200 files/sec | Highest accuracy (text) |
| HybridInferencer | ~1-6ms | Medium | 150-400 files/sec | ⭐ Recommended default |
* After initial model load (~100-200ms one-time overhead)
** Model loaded into memory (~50-100MB)
For most use cases: Use AutoInferencer(backend="hybrid") - it delegates to HybridInferencer, which automatically uses Magic for binary files and Magika for text files.
See Choosing an Inferencer for a full decision guide and known limitations per inferencer.
Fastest method - extracts file extensions directly from paths without reading file contents.
from filetype_detector import LexicalInferencer
inferencer = LexicalInferencer()
ft = inferencer.infer("document.pdf")
'.pdf' in ft.extensions # True
inferencer.infer("file_without_ext") # Raises ValueErrorUses python-magic (libmagic) to detect file types based on magic numbers and file signatures.
from filetype_detector import MagicInferencer
inferencer = MagicInferencer()
ft = inferencer.infer("file.dat") # reads file content, ignores extension
ft.extensions # e.g. ('.pdf',) even if the name says .dat
ft.mime_types # e.g. ('application/pdf',)System Requirements: Requires libmagic system library. See Installation section.
AI-powered detection with confidence scores. Especially effective for text files.
from filetype_detector import MagikaInferencer
inferencer = MagikaInferencer()
ft = inferencer.infer("script.py")
'.py' in ft.extensions # True
# infer_with_score returns (str, float), not FileType
extension, score = inferencer.infer_with_score("data.json") # ('.json', 0.98)Smart two-stage approach: uses Magic for all files, then Magika for text files.
from filetype_detector import HybridInferencer
inferencer = HybridInferencer()
# Text file: Magic detects text/plain, then Magika refines to .py
ft = inferencer.infer("script.py")
'.py' in ft.extensions # True
# Binary file: Magic result is used directly, Magika is skipped
ft = inferencer.infer("document.pdf")
'.pdf' in ft.extensions # TrueIf you want the same behavior through the unified interface, use AutoInferencer(backend="hybrid").
System Requirements: Requires libmagic system library. See Installation section.
파일 성격과 요구사항에 따라 추론기를 선택한다.
파일 이름(확장자)을 신뢰할 수 있는가?
├─ 예 → LexicalInferencer (파일 읽기 없음, 가장 빠름)
└─ 아니오 / 불확실
├─ 주로 바이너리? (PDF, Office, 이미지, 압축 등)
│ └─ MagicInferencer
├─ 주로 텍스트? (Python, JSON, HTML, CSV 등)
│ └─ MagikaInferencer (세부 분류 + 신뢰도 점수)
└─ 혼합 / 미확정
└─ HybridInferencer (기본값 추천)
| 상황 | 추천 |
|---|---|
| CI 파이프라인 등 이미 정제된 파일 | LexicalInferencer |
| 확장자 없는 파일, 잘못된 확장자 검증 | MagicInferencer |
.py / .json / .csv 등 텍스트 세분화 |
MagikaInferencer |
신뢰도 점수(infer_with_score)가 필요할 때 |
MagikaInferencer |
| 업로드 파일 등 무엇이 올지 모를 때 | HybridInferencer |
| 단일 진입점으로 backend만 교체하고 싶을 때 | AutoInferencer |
확장자가 없거나 잘못된 경우 탐지 불가. 파일 내용을 읽지 않으므로 위변조 파일을 그대로 통과시킨다.
text/plain으로 분류되는 파일들의 세부 구분이 불가능하다. Python, JSON, CSV 등이 동일하게 text/plain을 반환한다.
Compound Document 포맷(구 .doc, .ppt, .xls)은 같은 컨테이너를 공유하므로 여러 확장자가 후보로 반환된다.
- 텍스트 파일 외에는 이점이 제한적이다. 바이너리 파일에서는
MagicInferencer와 동등하거나 열등한 경우가 있다. - HWP: 학습 데이터에 없어 빈 결과를 반환한다.
- ZIP 기반 포맷 (HWPX, ODF, ePub 등): 내부 구조를 분석하지 않아
.epub등으로 오분류될 수 있다. - 모델 로딩 비용: 첫 인스턴스화 시 100–200ms의 오버헤드가 있다.
Magic 결과가 text/로 시작할 때만 Magika를 호출한다.
ZIP 기반 포맷(HWPX, ODF 등)과 Compound Document 포맷은 Magic으로만 처리되며 Magika가 적용되지 않는다.
- ✅ Multiple inference strategies - Choose the right method for your use case
- ✅ Type-safe API - Full type hints and type-safe method selection
- ✅ Flexible input - Supports both
Pathobjects and string paths - ✅ Performance optimized - Hybrid inference combines fast binary detection with more detailed text detection
- ✅ Well-tested - Comprehensive test suite
- ✅ Extensible - Base class architecture for custom implementations
- Tutorial: Getting Started
- How-to Guides: choosing an inferencer, bulk processing, and extending the library
- Reference: API pages for
AutoInferencer,BaseInferencer, and each inferencer - Explanation: inference strategy trade-offs and architecture notes
For detailed usage examples, error handling, and advanced patterns, see the documentation site.
Candidate review data lives in
tests/truth/backend_inventory_candidates.json. Collectors evaluate only the
matching verified records in tests/truth/backend_inventory.json. The reviewed
three-platform semantic baseline lives in
tests/truth/backend_conformance_baseline.json.
Validate the inventory pair before collecting observations:
rye run python -m scripts.conformance.cli review \
--candidates tests/truth/backend_inventory_candidates.json \
--inventory tests/truth/backend_inventory.json \
--root . \
--require-completeRun the inventory, collector, evaluator, report, and baseline contracts:
rye run python -m pytest tests/conformance -qThe dedicated Backend conformance workflow collects fresh-process observations on Ubuntu, macOS, and Windows. See the Backend Conformance reference for local collection and aggregation commands.
Delegation correctness:
rye run python -m pytest tests/test_auto_inferencer.py -vInferencer control flow, errors, and fallbacks:
rye run python -m pytest tests/test_magic_inferencer.py tests/test_magika_inferencer.py tests/test_hybrid_inferencer.py -vrye sync && \
rye run python -m scripts.conformance.cli review \
--candidates tests/truth/backend_inventory_candidates.json \
--inventory tests/truth/backend_inventory.json \
--root . \
--require-complete && \
rye run python -m pytest && \
rye run ruff check src tests scripts examples && \
rye run mypy src/filetype_detector scripts/conformance --ignore-missing-imports && \
rye run mkdocs build --strictAll inferencers inherit from BaseInferencer, which defines a common interface:
from abc import ABC, abstractmethod
from typing import Union
from pathlib import Path
from filetype_detector import FileType
class BaseInferencer(ABC):
@abstractmethod
def infer(self, file_path: Union[Path, str]) -> FileType:
"""Infer file type from path. Returns a FileType instance."""
raise NotImplementedErrorYou can create custom inferencers by subclassing BaseInferencer:
from filetype_detector import BaseInferencer, FileType
from typing import Union
from pathlib import Path
class CustomInferencer(BaseInferencer):
def infer(self, file_path: Union[Path, str]) -> FileType:
# Your custom logic here
return FileType.from_extension(".custom")Runtime dependencies:
python-magic>=0.4.27: Magic-number file detectionmagika>=1.0.1: AI-powered content detectionrich>=14.2.0: Styled inference outputtextual>=8.2.8: Interactive terminal interface
Development, documentation, and fixture-generation packages are isolated in
the dev, docs, and fixtures optional extras.
- Python >= 3.10
This project is open source. See LICENSE file for details.
Contributions are welcome! Please ensure:
- All tests pass:
pytest tests/ -v - Code follows the existing style
- New features include appropriate tests
- Documentation is updated
- python-magic for libmagic bindings
- Google Magika for AI-powered file type detection