python-magic: “확장자 대신 파일 내용을 믿는” 가장 실용적인 방법
서버에 이미지 업로드 기능이 붙으면, 언젠가 이런 요구가 생깁니다.
- “
.png라고 올라오는데… 진짜 PNG 맞아?” - “이 파일이 이미지인지 문서인지 먼저 분기해야 해.”
- “외부 파서(Pillow/OpenCV)를 쓰기 전에, 최소한 타입을 확인하고 싶어.”
이때 가장 단단한 출발점은 확장자가 아니라 파일 내용입니다.
그리고 그 “내용 기반 판별”을 가장 손쉽게 가져오는 도구가 python-magic입니다.
python-magic은 무엇을 해주는가
python-magic은 libmagic이라는 C 라이브러리를 파이썬에서 쓰게 해주는 래퍼입니다. libmagic은 파일의 헤더(처음 몇 바이트) 같은 특징을 검사해 파일 타입을 식별합니다. 이 기능은 유닉스의 file 명령으로도 제공됩니다.
정리하면:
file(리눅스 명령) = “터미널에서 쓰는 인터페이스”libmagic= “핵심 엔진(판별 로직)”python-magic= “파이썬에서 libmagic을 호출하는 얇은 래퍼”
이번 글은 python-magic을 중심으로, “이 엔진이 대체 어떻게 파일 타입을 알아맞히는지”를 구조적으로 설명합니다.
핵심 엔진(libmagic)은 어떻게 동작하는가

libmagic의 정체는 간단합니다.
“파일 타입 판별 규칙이 모여 있는 데이터베이스를 읽고, 그 규칙대로 파일 바이트를 검사해서, 가장 그럴듯한 결론을 뽑는다.”
여기서 데이터베이스가 바로 magic database(매직 패턴 DB)이고, file/libmagic이 함께 씁니다. 보통 시스템에 컴파일된 형태(magic.mgc)로 설치돼 있습니다.
1) “매직 파일”은 규칙들의 모음이다
이 규칙은 기본적으로 이런 구성 요소로 이뤄집니다.
- 어디를 볼지(offset: 파일의 몇 바이트 위치)
- 어떤 방식으로 읽을지(type: 바이트/문자열/정수 등)
- 무엇과 비교할지(expected value/pattern)
- 무슨 결론을 낼지(message/MIME 등)
매뉴얼도 file이 “magic patterns”를 검사한다고 설명합니다.
또, 이 규칙들은 한 줄 한 줄이 테스트가 되고(오프셋/타입/값/메시지), 조건이 맞으면 더 구체적인 하위 테스트로 내려가는 “계층 구조”로도 조직됩니다.
리눅스의 file명령어에 대해서 자세히 알고 싶으신 분은 아래의 링크를 클릭해보세요.
2) 규칙 DB는 “텍스트 원본”과 “컴파일된 결과”가 있다
매직 DB는 원래 사람이 읽는 텍스트 조각들의 집합일 수 있고, 성능을 위해 보통 컴파일된 바이너리 DB(.mgc)로도 제공됩니다.
3) 결국 하는 일은 “확장자 대신 파일 내용을 본다”
file이 확장자 대신 내용을 보는 타입 추정기라는 점은 오래된 철학입니다.
python-magic은 그 철학을 “파이썬 코드 한 줄”로 가져오는 도구라고 보면 됩니다.
python-magic을 어떻게 쓰나
대표적인 사용 패턴은 두 가지입니다.
1) MIME 타입으로 받기 (가장 실용적)
업로드 처리, 라우팅, 로그/메트릭에 유용합니다.
import magic
mime = magic.from_file("upload.bin", mime=True)
print(mime) # 예: image/png
python-magic은 libmagic 기반으로 파일 타입 식별을 제공하고, 이 기능은 file 명령과 같은 계열이라는 점이 공식 설명에도 그대로 나옵니다.
2) bytes로 바로 판별하기 (업로드 스트림에 유리)
디스크에 저장하기 전에, 업로드된 바이트 일부만 보고 빠르게 판별하고 싶을 때가 많습니다.
import magic
with open("upload.bin", "rb") as f:
head = f.read(4096)
mime = magic.from_buffer(head, mime=True)
print(mime)
(버퍼 기반 판별은 “파일 저장 전 1차 필터”로 특히 좋습니다.)
개발자 관점에서 어디에 유용한가
1) 업로드 검증의 1차 방어선
- 확장자만으로 분기하지 않기
- “이미지로 처리해도 되는 파일인지” 최소한의 확인하기
2) 처리 파이프라인의 분기점
- 이미지라면 리사이즈/썸네일 파이프라인으로
- PDF/ZIP이면 다른 워커로
- 미확인 타입이면 격리/거절/추가 검증으로
3) “무거운 디코더”를 호출하기 전에 비용을 줄이기
Pillow 같은 디코더는 강력하지만, 호출 자체가 비용(메모리/CPU/취약점 표면)을 늘립니다. python-magic은 그 전에 “이 작업을 해도 되는지”를 판단하는 데 쓰기 좋습니다.
중요한 현실 체크: libmagic은 어디까지나 추정/식별 도구입니다. 보안적으로 완전한 판별(악성 페이로드 차단 등)이 목적이라면, 추가 검증(화이트리스트, 크기 제한, 샌드박스 디코딩 등)이 필요합니다.
마무리: python-magic은 “파일 타입 판별을 코드로 가져오는 가장 가벼운 방법”이다
python-magic이 제공하는 건 이미지 처리 자체가 아닙니다. 대신 “이 파일을 무엇으로 취급해야 하는지”를 빠르게 알려줍니다.
- 엔진은
file과 같은 libmagic - 판별 방식은 “규칙 DB + 바이트 검사”
- 개발 현장에서는 업로드 검증, 라우팅, 비용 절감에 특히 유용
이걸 익혀두면, 라이브러리가 부족한 환경에서도 “판별 → 분기 → 안전장치”를 구성할 수 있습니다.
다음 글 예고
- Pillow(PIL)의
open(),load(),verify()가 각각 무엇을 보장하고, 언제 어떤 메서드를 써야 하는지, 어떻게 작동하는지를 정리해보겠습니다.
관련글 보기