Skip to main content

Utilities for working with Universal Type Identifiers (UTIs)

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

utitools-0.1.1.tar.gz (27.0 kB view hashes)

Uploaded Source

Built Distribution

utitools-0.1.1-py3-none-any.whl (22.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page