Skip to main content

utitools

utitools is a simple Python module designed primarily for use on macOS. It allows you to:

  • Retrieve the Uniform Type Identifier (UTI) for a given file suffix.
  • Get the preferred file extension for a given UTI.

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.

Features

  • Works with CoreServices for macOS versions <= 11 (Big Sur) using Objective-C bridge for working with UTIs.
  • Uses the UniformTypeIdentifiers framework for macOS >= 12 (Monterey).
  • On platforms other than macOS, falls back to a cached dictionary for UTI and extension mappings loaded via a CSV file.
  • Provides utility functions to convert between file extensions and UTIs.

Installation

You can install utitools from PyPI using pip:

pip install utitools

Alternatively, you can install it from the source code:

  1. Clone this repository.

    git clone https://github.com/rhettbull/utitools.git
    
  2. Install flit if you don't already have it.

    python3 -m pip install flit
    
  3. Run flit install from the root of the repository.

    cd utitools
    flit install
    

Usage

Here are the available functions:

1. 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'
>>>

2. 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'
>>>

3. 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'
>>>

4. 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']
>>>

5. 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
>>>

macOS Version Compatibility

The code path of utitools changes depending on the macOS version:

  • macOS ≤ 11 (Big Sur): Uses the deprecated methods UTTypeCopyPreferredTagWithClass and UTTypeCreatePreferredIdentifierForTag from CoreServices.
  • macOS ≥ 12 (Monterey): Uses the modern UniformTypeIdentifiers module.

Non-macOS Usage

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.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Packaging with pyinstaller or other tools

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.

Metadata

Release files for utitools 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for utitools 0.5.0
File Size Uploaded Provenance
utitools-0.5.0.tar.gz 28.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for utitools 0.5.0
File Interpreter ABI Platform
utitools-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 51.7 kB

Release files / utitools-0.5.0.tar.gz

Download URL utitools-0.5.0.tar.gz
Size 28.6 kB
Tags Source
SHA-256 checksum
How to use checksums
5db9e2b3f85982f6844ae4009130c82431332540f066fcf4fe63f31ab54a7d7c
BLAKE2b-256 checksum
How to use checksums
1f85ef3741a4ac3472a34b15cf8871eb77dd426a5900ebd2e6be9cf449cbf102
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.32.4

Release files / utitools-0.5.0-py3-none-any.whl

Download URL utitools-0.5.0-py3-none-any.whl
Size 23.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cfabee0037c7e2d98d3bfd9af1eda73d99bad5f32b8d35f58bd94b5545e32713
BLAKE2b-256 checksum
How to use checksums
0d0074ff216c295d2e513c26741ed9da6f915db18b333ce756c05a81a7e902cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.32.4

Security for utitools 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page