The mimetypes module maps filenames to MIME types. Essential for web servers, file uploads, and any code that needs to know what kind of file it's handling.
Guess MIME Type
Get type from filename:
import mimetypes
# From filename
mime_type, encoding = mimetypes.guess_type('document.pdf')
print(mime_type) # application/pdf
print(encoding) # None
# Compressed files
mime_type, encoding = mimetypes.guess_type('data.txt.gz')
print(mime_type) # text/plain
print(encoding) # gzipCommon Types
import mimetypes
files = ['image.jpg', 'script.js', 'style.css', 'data.json',
'page.html', 'doc.docx', 'video.mp4', 'song.mp3']
for filename in files:
mime, _ = mimetypes.guess_type(filename)
print(f"{filename}: {mime}")
# image.jpg: image/jpeg
# script.js: text/javascript
# style.css: text/css
# data.json: application/json
# page.html: text/html
# doc.docx: application/vnd.openxmlformats-officedocument.wordprocessingml.document
# video.mp4: video/mp4
# song.mp3: audio/mpegGuess Extension
Get extension from MIME type:
import mimetypes
# Single extension
ext = mimetypes.guess_extension('image/jpeg')
print(ext) # .jpg
ext = mimetypes.guess_extension('text/html')
print(ext) # .html
ext = mimetypes.guess_extension('application/json')
print(ext) # .jsonAll Extensions for Type
import mimetypes
# Get all known extensions for a type
exts = mimetypes.guess_all_extensions('image/jpeg')
print(exts) # ['.jpe', '.jpeg', '.jpg']
exts = mimetypes.guess_all_extensions('text/plain')
print(exts) # ['.txt', '.c', '.h', ...]Add Custom Types
import mimetypes
# Add custom type
mimetypes.add_type('application/x-custom', '.custom')
# Now it works
mime, _ = mimetypes.guess_type('file.custom')
print(mime) # application/x-customInitialize Database
import mimetypes
# Initialize with system files (usually done automatically)
mimetypes.init()
# Add custom files
mimetypes.init(files=['/etc/mime.types', 'my-types.txt'])Check Type Categories
import mimetypes
def get_type_category(filename):
"""Get broad category of file type."""
mime, _ = mimetypes.guess_type(filename)
if mime is None:
return 'unknown'
main_type = mime.split('/')[0]
return main_type
files = ['photo.png', 'song.mp3', 'movie.mp4', 'doc.txt', 'app.exe']
for f in files:
print(f"{f}: {get_type_category(f)}")
# photo.png: image
# song.mp3: audio
# movie.mp4: video
# doc.txt: text
# app.exe: applicationFile Upload Validation
import mimetypes
ALLOWED_TYPES = {'image/jpeg', 'image/png', 'image/gif'}
def is_allowed_upload(filename):
"""Check if file type is allowed."""
mime, _ = mimetypes.guess_type(filename)
return mime in ALLOWED_TYPES
print(is_allowed_upload('photo.jpg')) # True
print(is_allowed_upload('script.js')) # False
print(is_allowed_upload('image.png')) # TrueHTTP Content-Type Header
import mimetypes
def get_content_type(filename):
"""Get Content-Type header value."""
mime, encoding = mimetypes.guess_type(filename)
if mime is None:
return 'application/octet-stream'
# Add charset for text types
if mime.startswith('text/'):
return f'{mime}; charset=utf-8'
return mime
print(get_content_type('page.html')) # text/html; charset=utf-8
print(get_content_type('image.png')) # image/png
print(get_content_type('unknown.xyz')) # application/octet-streamStatic File Server
import mimetypes
from http.server import HTTPServer, SimpleHTTPRequestHandler
class ContentTypeHandler(SimpleHTTPRequestHandler):
def guess_type(self, path):
"""Override to use mimetypes."""
mime, _ = mimetypes.guess_type(path)
if mime:
return mime
return 'application/octet-stream'URL Handling
Works with URLs too:
import mimetypes
url = 'https://example.com/images/photo.jpg?size=large'
mime, _ = mimetypes.guess_type(url)
print(mime) # image/jpegStrict Mode
import mimetypes
# Strict mode only uses official IANA types
mime, _ = mimetypes.guess_type('file.mp3', strict=True)
print(mime) # audio/mpeg
# Non-strict includes platform-specific types
mime, _ = mimetypes.guess_type('file.mp3', strict=False)
print(mime) # audio/mpegList All Types
import mimetypes
# All extension mappings
print(mimetypes.types_map) # {'.js': 'text/javascript', ...}
# Common types
print(mimetypes.common_types) # Core types onlyImage Type Helper
import mimetypes
def is_image(filename):
"""Check if file is an image."""
mime, _ = mimetypes.guess_type(filename)
return mime is not None and mime.startswith('image/')
def get_image_type(filename):
"""Get specific image format."""
mime, _ = mimetypes.guess_type(filename)
if mime and mime.startswith('image/'):
return mime.split('/')[1] # jpeg, png, gif, etc.
return None
print(is_image('photo.jpg')) # True
print(get_image_type('photo.jpg')) # jpegEmail Attachment Types
import mimetypes
def get_attachment_params(filename):
"""Get MIME parts for email attachment."""
mime, _ = mimetypes.guess_type(filename)
if mime is None:
return 'application', 'octet-stream'
maintype, subtype = mime.split('/')
return maintype, subtype
maintype, subtype = get_attachment_params('report.pdf')
print(f"maintype={maintype}, subtype={subtype}")
# maintype=application, subtype=pdfLimitations
import mimetypes
# Based on extension, not content!
mime, _ = mimetypes.guess_type('malware.jpg') # Still returns image/jpeg
# For content-based detection, use python-magic:
# import magic
# magic.from_file('file.jpg', mime=True)When to Use mimetypes
Use mimetypes when:
- Setting Content-Type headers
- Validating file uploads (by extension)
- Routing files to handlers
- Email attachments
Use python-magic when:
- Need content-based detection
- Security-critical file validation
- Extension might be wrong/missing
The mimetypes module is fast and dependency-free—perfect for most file type needs based on filename.
React to this post: