Utilities for working with Uniform Type Identifiers (UTIs) in python
MIT License
utitools
is a simple Python module designed primarily for use on macOS. It allows you to:
While designed for macOS, utitools
also works on other platforms by falling back to a cached dictionary for UTI and extension mappings loaded via a CSV file.
UniformTypeIdentifiers
framework for macOS >= 12 (Monterey).You can install utitools
from PyPI using pip:
pip install utitools
Alternatively, you can install it from the source code:
Clone this repository.
git clone https://github.com/rhettbull/utitools.git
Install flit if you don't already have it.
python3 -m pip install flit
Run flit install
from the root of the repository.
cd utitools
flit install
Here are the available functions:
uti_for_suffix(suffix: str) -> str | None
Get the UTI for a given file suffix.
>>> from utitools import uti_for_suffix
>>> uti_for_suffix(".jpeg")
'public.jpeg'
>>> uti_for_suffix("jpg")
'public.jpeg'
>>>
preferred_suffix_for_uti(uti: str) -> str | None
Get the preferred file extension for a given UTI.
>>> from utitools import preferred_suffix_for_uti
>>> preferred_suffix_for_uti("public.jpeg")
'.jpeg'
>>>
uti_for_path(path: str | os.PathLike) -> str | None
Get the UTI for a file at the given path based on its file extension.
>>> from utitools import uti_for_path
>>> uti_for_path("/tmp/screenshot.png")
'public.png'
>>>
content_type_tree_for_uti(uti: str) -> list[str]
Get the UTI content type tree for a given UTI. This is hierarchical list of UTIs that the given UTI conforms to.
>>> from utitools import content_type_tree_for_uti
>>> content_type_tree_for_uti("public.heic")
['public.heic', 'public.heif-standard', 'public.image', 'public.data', 'public.item', 'public.content']
>>>
conforms_to_uti(uti1: str, uti2: str) -> bool
Return True if uti1
conforms to uti2
, otherwise False.
This is useful for checking if a UTI conforms to a parent UTI. For example, to check if a given UTI is an image:
>>> from utitools import conforms_to_uti
>>> conforms_to_uti("public.jpeg", "public.image")
True
>>> conforms_to_uti("public.jpeg", "public.video")
False
>>>
These functions can be combined in useful ways. For example, the following shows a simple is_image()
function that provides a quick way to check if a file is an image:
>>> from utitools import uti_for_path, conforms_to_uti
>>> def is_image(path):
... return conforms_to_uti(uti_for_path(path), "public.image")
...
>>> is_image("img_1234.jpg")
True
>>> is_image("img_1234.txt")
False
>>>
The code path of utitools
changes depending on the macOS version:
UTTypeCopyPreferredTagWithClass
and UTTypeCreatePreferredIdentifierForTag
from CoreServices
.UniformTypeIdentifiers
module.On non-macOS platforms, utitools
does not have direct access to macOS UTI APIs. Instead, it relies on a cached dictionary loaded from a CSV (uti.csv
) containing mappings of file extensions and UTIs. This provides a level of compatibility for platforms like Windows or Linux.
The CSV file must be generated using the script generate_uti_csv.py
on macOS. The script calls the macOS APIs for every possible file extension under a specified lenght and writes the mappings to the CSV file. The CSV file must then be placed in src/utitools
. This file is then used by utitools
on non-macOS platforms. This is a hack but it works. PRs are welcome to improve this or provide a native way to get UTIs on non-macOS platforms.
There is also a uti_tree.json
file that is used to look up content trees on non-macOS systems. This file is generated by the generate_uti_tree.py
script which must be run on macOS then placed in the src/utitools
directory.
I use this library primarily to get UTIs for various image and video formats on macOS so this process is sufficient for my uses.
On non-macOS platforms, only UTIs known to macOS Ventura for suffixes up to 6 characters are supported. This is because the CSV file is generated using the generate_uti_csv.py
script which only generates mappings for suffixes up to 6 characters. This covers all my use cases. PRs are welcome to improve this.
This project is licensed under the MIT License. See the LICENSE file for details.
To package utitools
with pyinstaller
or other tools, you may need to include the uti.csv
and uti_tree.json
files in your distribution manifest. These files are located in the src/utitools
directory. Directions will depend on the tool you are using.
Feel free to contribute or submit issues via GitHub issues.