mimetypes: detecte tipos MIME de arquivos

Publicado em: 20/08/2026
Tempo de leitura: 7 minutos
Pasta com arquivos representando tipos MIME identificados com mimetypes no Python

O módulo mimetypes da biblioteca padrão do Python ajuda a relacionar extensões de arquivo com tipos de mídia usados em HTTP, e-mail e armazenamento. Ele responde perguntas como: um arquivo terminado em .png provavelmente é image/png? Um nome terminado em .json deve usar application/json? A resposta é útil para servidores web, APIs, uploads, downloads e ferramentas de automação.

Apesar de simples, o módulo precisa ser usado com cuidado. Ele normalmente trabalha a partir do nome ou da URL, não examina o conteúdo binário real. Portanto, mimetypes é excelente para inferência, configuração e experiência do usuário, mas não deve ser tratado como uma barreira de segurança isolada.

O que é um MIME type

Um tipo de mídia descreve a natureza de um recurso. Ele costuma ter a forma tipo/subtipo, como text/html, image/jpeg, application/pdf ou application/zip. Navegadores, clientes HTTP, servidores, proxies e sistemas de armazenamento usam essa informação para decidir como entregar, exibir ou processar o conteúdo.

O nome histórico MIME veio do e-mail, mas os tipos de mídia hoje aparecem em vários protocolos. Em HTTP, o header Content-Type informa o formato do corpo. Em uploads multipart, cada parte também pode declarar um tipo. Em sistemas internos, o tipo ajuda a escolher visualizadores, pipelines e regras de retenção.

Primeiro exemplo com guess_type

import mimetypes

mime_type, encoding = mimetypes.guess_type("relatorio.pdf")
print(mime_type)  # application/pdf
print(encoding)   # None

guess_type() retorna uma tupla. O primeiro valor é o tipo estimado. O segundo indica uma codificação de conteúdo associada ao sufixo, como gzip em certos nomes terminados em .gz. Essa codificação não é charset. Ela representa uma camada de compressão ou transformação.

Quando a extensão não é conhecida, o tipo pode ser None. O código deve ter uma política explícita para esse caso, por exemplo usar application/octet-stream, rejeitar o arquivo ou exigir inspeção adicional.

URLs e nomes de arquivo

O módulo consegue analisar nomes e URLs. Entretanto, strings com query string, fragments ou nomes pouco convencionais podem exigir normalização antes da inferência. Não remova partes arbitrariamente sem entender o contexto. Para decompor URLs, consulte o guia de urllib.parse no Python.

from urllib.parse import urlsplit
import mimetypes

url = "https://exemplo.com/assets/manual.pdf?download=1"
path = urlsplit(url).path
mime_type, encoding = mimetypes.guess_type(path)

Use apenas o caminho para inferir pela extensão. Ainda assim, não faça download automático de qualquer URL. A validação de origem, redirects, DNS, timeout e tamanho continua necessária. O artigo sobre urllib.request no Python mostra como aplicar limites ao buscar recursos externos.

Content-Type em respostas HTTP

Um servidor simples pode usar mimetypes para escolher o header da resposta. Se o tipo não for reconhecido, use um fallback conservador.

import mimetypes
from pathlib import Path

def content_type_for(path: Path) -> str:
    mime_type, _ = mimetypes.guess_type(path.name)
    return mime_type or "application/octet-stream"

Não permita que o cliente controle livremente o caminho local. Resolva a rota contra um diretório permitido, bloqueie path traversal e confirme que o arquivo final está dentro da raiz. A extensão correta não torna um caminho seguro.

Uploads: extensão não prova conteúdo

Um usuário pode renomear um executável para foto.jpg. Nesse caso, guess_type() provavelmente retornará image/jpeg, embora os bytes não representem uma imagem. Por isso, valide uploads em camadas:

Primeiro, limite tamanho, quantidade e frequência. Depois, normalize o nome, gere um identificador interno e não use o nome original como caminho. Em seguida, verifique a assinatura ou faça parsing com uma biblioteca adequada ao formato. Finalmente, armazene fora de diretórios executáveis e sirva com headers seguros.

Para criar nomes temporários e áreas isoladas durante a validação, veja tempfile no Python. Para calcular integridade e deduplicação, o guia de hashlib no Python apresenta SHA-256 e BLAKE2.

Extensões compostas e compressão

Arquivos como backup.tar.gz combinam formato e codificação. Dependendo da tabela disponível, o retorno pode indicar um tipo para TAR e uma codificação gzip. Não confunda esse segundo valor com o tipo final do conteúdo descompactado.

import mimetypes

mime_type, encoding = mimetypes.guess_type("backup.tar.gz")
print(mime_type)
print(encoding)

Ao aceitar arquivos compactados, também aplique limites de expansão, número de entradas, profundidade e caminhos internos. Os artigos sobre zipfile no Python e tarfile no Python explicam esses riscos.

Adicionar tipos personalizados

Aplicações podem registrar extensões próprias com add_type().

import mimetypes

mimetypes.add_type("application/vnd.exemplo.relatorio+json", ".reljson")
print(mimetypes.guess_type("dados.reljson"))

Faça esse registro na inicialização e documente a decisão. Evite alterar mappings globais de forma inesperada em bibliotecas reutilizáveis. Em testes, isole o estado ou reinicialize as tabelas quando necessário.

Modo estrito

Algumas funções aceitam o parâmetro strict. Em modo estrito, o módulo tende a considerar apenas tipos registrados oficialmente. Com strict=False, pode incluir extensões comuns adicionais conhecidas pela plataforma.

mime_type, encoding = mimetypes.guess_type("imagem.webp", strict=False)

Escolha uma política coerente. Sistemas interoperáveis podem preferir tipos padronizados. Ferramentas locais podem aceitar mappings mais amplos. Registre o tipo efetivamente enviado para facilitar diagnóstico.

Dependência do sistema operacional

As tabelas podem variar entre ambientes porque o módulo pode carregar informações do sistema. Um tipo reconhecido no computador do desenvolvedor pode não existir no contêiner de produção. Por isso, teste as extensões relevantes e registre explicitamente mappings críticos.

Em imagens Docker mínimas, não presuma que o banco de tipos será idêntico ao de uma distribuição desktop. Use testes automatizados para confirmar os tipos que sua aplicação realmente suporta.

guess_extension e ambiguidades

O caminho inverso também existe: obter uma extensão provável a partir de um tipo.

import mimetypes

print(mimetypes.guess_extension("image/jpeg"))
print(mimetypes.guess_all_extensions("image/jpeg"))

Vários sufixos podem representar o mesmo tipo, como .jpg e .jpeg. Não use o retorno para preservar o nome original. Prefira uma extensão canônica definida pela aplicação.

Charsets não vêm automaticamente

text/plain não informa por si só se os bytes estão em UTF-8, Latin-1 ou outra codificação. O módulo não detecta charset. Se você controla a geração do texto, declare explicitamente charset=utf-8. Para decodificação incremental e tratamento de erros, consulte codecs no Python.

Sniffing do navegador

Alguns navegadores tentam adivinhar o conteúdo quando o tipo parece incorreto. Isso pode criar riscos, especialmente em uploads enviados de volta ao usuário. Quando apropriado, envie X-Content-Type-Options: nosniff e um Content-Disposition coerente.

Arquivos que não devem ser executados ou exibidos inline podem ser servidos como download. Mesmo assim, nomes e headers precisam de escape e validação.

Política prática para APIs

Uma API segura pode comparar três sinais: extensão normalizada, tipo declarado pelo cliente e inspeção real do conteúdo. Divergências devem gerar rejeição ou revisão, não correção silenciosa. O tipo informado pelo cliente é apenas uma dica.

Para imagens, abra o arquivo com uma biblioteca que decodifique o formato e regrave quando necessário. Para PDFs, valide estrutura, tamanho e política de processamento. Para arquivos de texto, limite bytes, detecte ou imponha encoding e rejeite conteúdo inesperado.

Testes recomendados

Teste extensões em maiúsculas e minúsculas, nomes sem extensão, múltiplos pontos, URLs com query, tipos desconhecidos, extensões personalizadas, arquivos compactados e diferenças entre sistemas. Inclua também casos maliciosos como foto.jpg.exe, nomes muito longos e caracteres de controle.

Os testes devem verificar a decisão final da aplicação, não apenas o retorno do módulo. Um tipo estimado corretamente ainda pode ser proibido pela política de upload.

Erros comuns

Os erros mais frequentes são confiar apenas na extensão, tratar encoding como charset, executar arquivos porque o tipo parece seguro, usar nomes originais como caminhos, aceitar tipos desconhecidos sem política, presumir mappings idênticos em todos os sistemas e esquecer headers de download.

Conclusão

mimetypes oferece uma forma rápida e portátil de inferir tipos de mídia a partir de nomes e URLs. Ele é útil para definir Content-Type, organizar arquivos, escolher visualizadores e validar regras iniciais. Seu limite central é importante: ele normalmente analisa o nome, não os bytes.

Use o módulo como uma camada de metadados, combinado com validação de conteúdo, limites, armazenamento seguro e headers defensivos. Consulte a documentação oficial de mimetypes e o registro de media types da IANA.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código HTML em uma tela representando análise com html.parser no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    html.parser no Python: analise HTML

    Aprenda html.parser no Python para extrair texto, links e metadados, processar HTML em blocos e evitar confundir parsing com sanitização.

    Ler mais

    Tempo de leitura: 6 minutos
    20/08/2026
    Pessoa usando laptop em uma sessão web representando cookies com http.cookiejar no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    http.cookiejar no Python: gerencie cookies

    Aprenda http.cookiejar no Python para manter sessões, aplicar políticas, persistir cookies com segurança e integrar com urllib.request.

    Ler mais

    Tempo de leitura: 6 minutos
    20/08/2026
    Rack de servidores representando conexões HTTP de baixo nível com http.client no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    http.client no Python: HTTP de baixo nível

    Aprenda http.client no Python para controlar conexões HTTP e HTTPS, streaming, headers, TLS, reutilização, limites e erros de protocolo.

    Ler mais

    Tempo de leitura: 5 minutos
    20/08/2026
    Código HTML em uma tela representando crawling responsável com robotparser no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    robotparser no Python: leia robots.txt

    Aprenda urllib.robotparser no Python para respeitar robots.txt, crawl-delay, request-rate, sitemaps, cache e limites de crawling.

    Ler mais

    Tempo de leitura: 5 minutos
    20/08/2026
    Teclas formando HTTP representando requisições com urllib.request no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    urllib.request no Python: HTTP nativo

    Aprenda urllib.request no Python para fazer GET, POST e downloads com timeout, TLS, redirects, proxies, limites e tratamento de erros.

    Ler mais

    Tempo de leitura: 5 minutos
    19/08/2026
    Cabos Ethernet conectados representando servidores de rede com socketserver no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    socketserver no Python: crie servidores

    Aprenda socketserver no Python para criar servidores TCP e UDP, aplicar concorrência, limites, timeouts e encerramento seguro.

    Ler mais

    Tempo de leitura: 6 minutos
    19/08/2026