Python's mimetypes module maps file extensions to MIME types and back. Essential for web servers, file uploads, and content negotiation.

Basic Usage

import mimetypes
 
# Extension to MIME type
print(mimetypes.guess_type('image.png'))
# ('image/png', None)
 
print(mimetypes.guess_type('document.pdf'))
# ('application/pdf', None)
 
print(mimetypes.guess_type('archive.tar.gz'))
# ('application/x-tar', 'gzip')
# Returns (type, encoding)

MIME Type to Extension

import mimetypes
 
# MIME type to extension
print(mimetypes.guess_extension('image/png'))     # .png
print(mimetypes.guess_extension('text/html'))     # .html
print(mimetypes.guess_extension('application/json'))  # .json

Handling URLs

import mimetypes
 
# Works with URLs
print(mimetypes.guess_type('https://example.com/photo.jpg'))
# ('image/jpeg', None)
 
# Query strings ignored
print(mimetypes.guess_type('https://api.example.com/data.json?v=2'))
# ('application/json', None)

Strict vs Non-Strict

import mimetypes
 
# Strict: only official IANA types
mimetypes.guess_type('file.md', strict=True)
# (None, None) - .md not in strict list
 
# Non-strict: includes common non-IANA types
mimetypes.guess_type('file.md', strict=False)
# ('text/markdown', None)

Adding Custom Types

import mimetypes
 
# Add a custom mapping
mimetypes.add_type('application/x-custom', '.cust')
 
print(mimetypes.guess_type('data.cust'))
# ('application/x-custom', None)
 
# Add with strict=True for IANA compliance
mimetypes.add_type('application/vnd.myapp', '.myapp', strict=True)

Listing Known Types

import mimetypes
 
# Initialize (loads system database)
mimetypes.init()
 
# All known extensions for a type
print(mimetypes.guess_all_extensions('image/jpeg'))
# ['.jpe', '.jpeg', '.jpg']
 
# Check specific type's extensions
print(mimetypes.guess_all_extensions('text/plain'))
# ['.txt', '.asc', '.text', ...]

Type Maps

import mimetypes
 
# Extension to type mapping
mimetypes.init()
print(mimetypes.types_map['.html'])  # text/html
print(mimetypes.types_map['.json'])  # application/json
 
# Common extensions
print(mimetypes.suffix_map)  # Suffix encoding map (.gz, .bz2, etc.)
print(mimetypes.encodings_map)  # Extension to encoding

Practical Examples

Content-Type Header

import mimetypes
import os
 
def get_content_type(filepath):
    """Get Content-Type header for a file."""
    mime_type, encoding = mimetypes.guess_type(filepath)
    if mime_type is None:
        mime_type = 'application/octet-stream'
    if encoding:
        return f'{mime_type}; charset={encoding}'
    return mime_type
 
print(get_content_type('index.html'))  # text/html
print(get_content_type('data.json'))   # application/json
print(get_content_type('unknown.xyz')) # application/octet-stream

File Upload Validation

import mimetypes
 
ALLOWED_TYPES = {
    'image/jpeg',
    'image/png',
    'image/gif',
    'application/pdf',
}
 
def is_allowed_file(filename):
    mime_type, _ = mimetypes.guess_type(filename)
    return mime_type in ALLOWED_TYPES
 
print(is_allowed_file('photo.jpg'))   # True
print(is_allowed_file('script.py'))   # False
print(is_allowed_file('doc.pdf'))     # True

Static File Server

import mimetypes
from pathlib import Path
 
def serve_file(filepath):
    path = Path(filepath)
    if not path.exists():
        return None, 404
    
    content_type, encoding = mimetypes.guess_type(str(path))
    content_type = content_type or 'application/octet-stream'
    
    return {
        'content': path.read_bytes(),
        'content_type': content_type,
        'encoding': encoding,
    }, 200
 
# Usage
response, status = serve_file('static/style.css')
# response['content_type'] = 'text/css'

Group Files by Type

import mimetypes
from pathlib import Path
from collections import defaultdict
 
def group_by_mime_type(directory):
    groups = defaultdict(list)
    for path in Path(directory).iterdir():
        if path.is_file():
            mime_type, _ = mimetypes.guess_type(str(path))
            mime_type = mime_type or 'unknown'
            groups[mime_type].append(path.name)
    return dict(groups)
 
# Example output:
# {
#   'image/png': ['logo.png', 'icon.png'],
#   'text/html': ['index.html'],
#   'application/json': ['config.json'],
# }

Common MIME Types

ExtensionMIME Type
.htmltext/html
.csstext/css
.jsapplication/javascript
.jsonapplication/json
.pngimage/png
.jpgimage/jpeg
.gifimage/gif
.svgimage/svg+xml
.pdfapplication/pdf
.zipapplication/zip
.txttext/plain
.xmlapplication/xml

Platform Differences

The database varies by platform:

  • Reads /etc/mime.types on Unix
  • Uses Windows Registry on Windows
  • Falls back to built-in database
import mimetypes
 
# See what files are loaded
mimetypes.init()
print(mimetypes.knownfiles)  # List of loaded mime.types files

Summary

The mimetypes module handles file type detection:

  • guess_type(filename) → MIME type
  • guess_extension(mime_type) → extension
  • add_type() for custom mappings
  • Works with paths and URLs

Essential for web servers, file uploads, and anywhere you need to determine content types.

React to this post: