pyguides

mimetypes module

The mimetypes module converts between filenames and MIME type strings. When you need to know whether a file is image/png or text/html based on its extension — or when you need to go the other direction and find the right extension for an application/json upload — mimetypes has you covered.

It works by reading system-wide mime.types files and the Windows registry (on Windows), and stores the results in lookup tables that are fast to query.

Quick Example

import mimetypes

mimetypes.init()

mime, encoding = mimetypes.guess_type("document.pdf")
print(mime)       # 'application/pdf'
print(encoding)   # None

mime, encoding = mimetypes.guess_type("archive.tar.gz")
print(mime)       # 'application/x-tar'
print(encoding)    # 'gzip'

The return value is always a tuple of (type, encoding). Most files have no encoding, so the second element is None.

Guessing MIME Types

guess_type(url, strict=True)

Given a filename, path, or URL, returns the MIME type and encoding:

mimetypes.guess_type("image.png")        # ('image/png', None)
mimetypes.guess_type("script.js")        # ('text/javascript', None)
mimetypes.guess_type("data.json")        # ('application/json', None)
mimetypes.guess_type("report.pdf")       # ('application/pdf', None)

The strict argument controls whether only IANA-registered MIME types are used (strict=True) or whether non-standard but common types are included too (strict=False).

Note: Passing a file path instead of a URL is soft deprecated in Python 3.13. Use guess_file_type() instead.

guess_file_type(path, *, strict=True)

New in Python 3.13. Does the same job as guess_type() but is explicit about accepting a file path:

mimetypes.guess_file_type("/path/to/image.png")  # ('image/png', None)

Guessing Extensions

guess_extension(type, strict=True)

Given a MIME type string, returns the most common file extension (with leading dot):

mimetypes.guess_extension("application/json")   # '.json'
mimetypes.guess_extension("text/html")          # '.html'
mimetypes.guess_extension("image/png")          # '.png'
mimetypes.guess_extension("text/plain")          # '.txt'

Returns None if the type isn’t known.

guess_all_extensions(type, strict=True)

Returns a list of all possible extensions for a MIME type:

mimetypes.guess_all_extensions("text/plain")
# ['.txt', '.text', ...]

Adding Custom Mappings

add_type(type, ext, strict=True)

Add your own type-to-extension or extension-to-type mappings:

mimetypes.add_type("application/x-custom", ".custom")

mimetypes.guess_extension("application/x-custom")  # '.custom'
mimetypes.guess_type("file.custom")                # ('application/x-custom', None)

When an extension already exists, calling add_type() with a new type replaces it. When a type already exists, the new extension is appended to its list of known extensions.

Use strict=False to register non-standard types without polluting the IANA list.

Initializing the Database

init(files=None)

guess_type() and related functions call init() automatically on first use if the database hasn’t been initialized yet. But you can call it explicitly to control which files are loaded:

# Use only the built-in types, skip system defaults
mimetypes.init(files=[])

# Add custom files on top of system defaults
mimetypes.init(files=["/etc/myapp/mime.types"])

Calling init() repeatedly is allowed. Each call reloads the database.

read_mime_types(filename)

Loads mappings from a mime.types format file. Returns a dictionary or None if the file can’t be read:

types = mimetypes.read_mime_types("/etc/myapp/mime.types")
if types:
    print(types[".custom"])  # 'application/x-custom'

The MimeTypes Class

The module provides a global database, but you can create independent MimeTypes instances for applications that need separate type mappings:

import mimetypes

# Create a fresh database with additional files
db = mimetypes.MimeTypes(filenames=["/path/to/project.mime.types"])

# Use it like the module functions
mime = db.guess_type("document.pdf")
print(mime)  # ('application/pdf', None)

The class has the same methods as the module-level functions: guess_type(), guess_file_type(), guess_extension(), guess_all_extensions(), and add_type().

It also has read() / readfp() for loading additional mime.types files, and read_windows_registry() on Windows.

How the Lookup Tables Work

The module maintains several dictionaries you’ll occasionally need to work with directly:

  • mimetypes.types_map — maps extensions to MIME types (e.g. .htmltext/html)
  • mimetypes.encodings_map — maps extensions to encoding names (e.g. .gzgzip)
  • mimetypes.suffix_map — maps compound suffixes (e.g. .tgz.tar.gz)
  • mimetypes.common_types — non-standard but common types

These are useful when you need to inspect or iterate over all known mappings:

for ext, mime in mimetypes.types_map.items():
    if mime.startswith("text/"):
        print(ext, mime)

Command-Line Interface

The module is executable directly from the terminal:

# Get MIME type from filename
$ python -m mimetypes document.pdf
type: application/pdf encoding: None

# Get MIME type from URL
$ python -m mimetypes https://example.com/report.html
type: text/html encoding: None

# Get extension from MIME type
$ python -m mimetypes --extension text/javascript
.js

# Include non-standard types
$ python -m mimetypes --lenient --extension application/x-shader
.shader

See Also