Aplicações que recebem uploads, enviam anexos, servem arquivos ou geram respostas HTTP precisam descrever o formato do conteúdo. O módulo mimetypes no Python oferece uma tabela de associações entre extensões e tipos MIME, permitindo transformar nomes como relatorio.pdf em application/pdf ou descobrir extensões possíveis para um tipo conhecido.
O recurso é útil em APIs, servidores web, sistemas de armazenamento, clientes de e-mail e pipelines de documentos. Entretanto, ele trabalha principalmente com o nome e a extensão do arquivo. Ele não abre o conteúdo nem comprova que os bytes correspondem ao tipo declarado. Neste guia você aprenderá a usar a API corretamente, separar tipo de encoding, registrar extensões próprias e evitar decisões de segurança baseadas apenas no sufixo.
O conteúdo complementa nossos guias sobre tempfile no Python, fileinput, importlib.resources, shlex e filecmp.
O que é um tipo MIME
Um tipo MIME descreve a categoria e o formato de um conteúdo. Ele costuma ter duas partes separadas por barra, como text/plain, image/png, application/json e audio/mpeg. Em HTTP, esse valor normalmente aparece no cabeçalho Content-Type.
O tipo ajuda o consumidor a escolher como interpretar os bytes, mas não é uma garantia de segurança. Navegadores, bibliotecas e sistemas operacionais podem aplicar regras adicionais, e arquivos maliciosos podem usar extensões enganosas.
Descobrir o tipo de um caminho
Em versões modernas, use guess_file_type() quando você possui um caminho de arquivo.
import mimetypes
tipo, encoding = mimetypes.guess_file_type("relatorio.pdf")
print(tipo) # application/pdf
print(encoding) # NoneA função retorna uma tupla. O primeiro item é o tipo MIME ou None quando a extensão não é conhecida. O segundo item informa um encoding associado ao nome, como gzip.
guess_type para URLs
guess_type() continua sendo a interface destinada a URLs. Desde o Python 3.13, passar caminhos de arquivo a ela está suavemente obsoleto; para arquivos locais, prefira guess_file_type().
tipo, encoding = mimetypes.guess_type(
"https://exemplo.com/download/dados.json"
)
print(tipo) # application/jsonSeparar URLs de caminhos reduz ambiguidades, principalmente no Windows, onde letras de unidade e barras podem ser interpretadas de maneira diferente.
Tipo MIME não é encoding
Um arquivo como backup.tar.gz pode produzir:
tipo, encoding = mimetypes.guess_file_type("backup.tar.gz")
print(tipo) # application/x-tar
print(encoding) # gzipO valor gzip é adequado para um cabeçalho Content-Encoding. Ele não representa Content-Transfer-Encoding de mensagens de e-mail e também não informa a codificação de caracteres do conteúdo textual.
Modo estrito
Por padrão, as consultas usam strict=True e priorizam tipos oficiais registrados. Com strict=False, o módulo também consulta associações comuns não padronizadas.
tipo, encoding = mimetypes.guess_file_type(
"imagem.pict",
strict=False,
)Em APIs públicas, o modo estrito costuma produzir resultados mais previsíveis. O modo flexível pode ajudar em aplicativos desktop e ferramentas que precisam reconhecer formatos antigos.
Descobrir uma extensão
Quando o tipo MIME é conhecido, guess_extension() devolve uma extensão possível.
extensao = mimetypes.guess_extension("image/png")
print(extensao) # .pngA associação não prova que determinado fluxo de bytes usa essa extensão. Vários tipos possuem mais de uma opção, e plataformas diferentes podem carregar tabelas adicionais.
Listar todas as extensões
extensoes = mimetypes.guess_all_extensions("image/jpeg")
print(extensoes)Use essa função em filtros de interface, importadores e validadores de configuração. Não presuma uma ordem universal entre as extensões retornadas.
Registrar um tipo personalizado
Formatos internos podem ser adicionados com add_type().
mimetypes.add_type(
"application/vnd.minhaempresa.relatorio+json",
".mrel",
)
tipo, _ = mimetypes.guess_file_type("fechamento.mrel")A extensão válida começa com ponto. A documentação do Python 3.14 avisa que extensões inválidas sem ponto passarão a gerar ValueError no Python 3.16. Corrigir registros agora evita quebra futura.
Associações globais e isolamento
mimetypes.add_type() altera as tabelas globais do processo. Em aplicações com plugins, testes paralelos ou clientes diferentes, essa mudança pode vazar entre componentes.
Quando você precisa de bancos independentes, crie objetos MimeTypes.
banco = mimetypes.MimeTypes()
banco.add_type("application/x-projeto", ".proj")
print(banco.guess_file_type("dados.proj"))Esse desenho facilita testes e evita que uma integração modifique o comportamento de todas as outras.
Inicialização e sistema operacional
O módulo pode combinar tabelas internas, arquivos mime.types instalados e, no Windows, informações do registro. Portanto, o mesmo sufixo pode produzir resultados diferentes entre ambientes.
mimetypes.init(files=[])Passar uma lista vazia impede a aplicação dos padrões do sistema e mantém somente valores conhecidos pela base interna. Isso é útil em builds reproduzíveis e testes que precisam de respostas consistentes.
Carregar um arquivo mime.types
mimetypes.init(files=["config/mime.types"])Arquivos posteriores têm precedência sobre anteriores. Trate esse arquivo como configuração confiável, controle sua versão e valide conflitos antes do deploy.
Ler associações sem alterar o estado
read_mime_types() lê um arquivo e retorna um dicionário.
mapa = mimetypes.read_mime_types("config/mime.types")
if mapa is None:
raise RuntimeError("arquivo MIME indisponível")O retorno None indica que o arquivo não existe ou não pôde ser lido. Não confunda isso com um dicionário vazio.
Uploads: extensão não valida conteúdo
Um usuário pode renomear programa.exe para foto.jpg. mimetypes responderá com base no nome e poderá indicar image/jpeg. Por isso, uploads exigem uma estratégia em camadas:
- limite de tamanho;
- lista permitida de extensões;
- detecção do formato pelos bytes com biblioteca adequada;
- armazenamento fora da raiz pública;
- nome gerado pelo servidor;
- antivírus ou sandbox quando o risco justificar;
- resposta com cabeçalhos seguros.
O tipo informado pelo navegador também não deve ser considerado prova, pois vem do cliente.
Servir downloads com segurança
tipo, encoding = mimetypes.guess_file_type(caminho)
content_type = tipo or "application/octet-stream"application/octet-stream é um fallback razoável para bytes desconhecidos. Para arquivos que devem ser baixados, use também Content-Disposition: attachment, normalize o nome e impeça caracteres de controle nos cabeçalhos.
Não acrescente charset automaticamente
text/plain não informa se o arquivo usa UTF-8, Latin-1 ou outro encoding de caracteres. Só acrescente charset=utf-8 quando sua aplicação realmente controla ou detectou a codificação.
Arquivos compactados
Em nomes como dados.json.gz, o módulo pode separar o tipo do arquivo original e o programa de compressão. Isso ajuda a construir respostas HTTP, mas sua aplicação ainda precisa confirmar se o arquivo está realmente comprimido e limitar a expansão para evitar bombas de compressão.
URLs com parâmetros
Em URLs complexas, extraia o caminho antes de consultar o tipo. Parâmetros, fragments e nomes gerados podem prejudicar a interpretação.
from urllib.parse import urlparse
url = "https://exemplo.com/foto.png?versao=2"
caminho = urlparse(url).path
tipo, encoding = mimetypes.guess_type(caminho)Uso em e-mails
Ao anexar um arquivo, o tipo MIME ajuda a definir maintype e subtype. Ainda assim, abra o arquivo em modo binário, trate tipos desconhecidos e não aceite caminhos arbitrários vindos de entrada externa.
tipo, _ = mimetypes.guess_file_type("contrato.pdf")
principal, subtipo = (tipo or "application/octet-stream").split("/", 1)Testes reproduzíveis
Como o sistema operacional pode ampliar as tabelas, testes devem controlar a inicialização ou validar apenas tipos garantidos. Inclua casos sem extensão, extensões maiúsculas, arquivos compostos como .tar.gz, tipos personalizados e nomes Unicode.
Interface de linha de comando
O módulo também pode ser executado diretamente.
python -m mimetypes arquivo.png
python -m mimetypes --extension application/json
python -m mimetypes --lenient imagem.pictEssa interface é útil para diagnóstico rápido em servidores e containers.
Erros frequentes
- Tratar extensão como validação do conteúdo.
- Confundir
Content-Encodingcom charset. - Usar
guess_type()para caminhos novos em vez deguess_file_type(). - Ignorar resultados
None. - Alterar a tabela global dentro de cada requisição.
- Presumir respostas idênticas em todos os sistemas.
- Registrar extensões sem o ponto inicial.
- Servir conteúdo desconhecido inline no navegador.
Boas práticas
- Use
guess_file_type()para caminhos. - Defina fallback como
application/octet-stream. - Valide bytes separadamente em uploads.
- Prefira bancos
MimeTypesisolados em integrações. - Controle tabelas externas e versões.
- Teste em todos os sistemas suportados.
- Não inferir charset apenas pelo tipo.
- Use listas permitidas e nomes gerados pelo servidor.
Conclusão
O módulo mimetypes no Python é uma ferramenta prática para mapear nomes de arquivos, URLs, extensões e tipos MIME. Ele simplifica anexos, downloads, respostas HTTP e interfaces de configuração, especialmente quando o código distingue corretamente tipo e encoding.
Sua principal limitação é deliberada: a resposta vem das tabelas e do nome, não da análise dos bytes. Use o módulo para metadados e conveniência, mas combine-o com validação real de conteúdo, políticas de upload e cabeçalhos seguros. Consulte a documentação oficial de mimetypes e o registro oficial de media types da IANA ao definir tipos públicos ou personalizados.







