utitools


Nameutitools JSON
Version 0.4.0 PyPI version JSON
download
home_pageNone
SummaryUtilities for working with Uniform Type Identifiers (UTIs)
upload_time2025-08-09 12:05:45
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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:

```bash
pip install utitools
```

Alternatively, you can install it from the source code:

1. Clone this repository.
   ```bash
   git clone https://github.com/rhettbull/utitools.git
   ```

2. Install [flit](https://flit.readthedocs.io/en/latest/) if you don't already have it.
   ```bash
   python3 -m pip install flit
   ```

3. Run `flit install` from the root of the repository.
   ```bash
   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.

```pycon
>>> 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.

```pycon
>>> 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.

```pycon
>>> 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.

```pycon
>>> 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:

```pycon
>>> 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:

```pycon
>>> 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](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](https://github.com/rhettbull/utitools/issues).

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "utitools",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": null,
    "author": null,
    "author_email": "Rhet Turnbull <rturnbull+git@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/e9/14/36b76591c7f9025e91b1af5b4544fc91a0b6e54ac0627d301253372701fa/utitools-0.4.0.tar.gz",
    "platform": null,
    "description": "# utitools\n\n`utitools` is a simple Python module designed primarily for use on macOS. It allows you to:\n\n- Retrieve the Uniform Type Identifier (UTI) for a given file suffix.\n- Get the preferred file extension for a given UTI.\n\nWhile 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.\n\n## Features\n\n- Works with CoreServices for macOS versions <= 11 (Big Sur) using Objective-C bridge for working with UTIs.\n- Uses the `UniformTypeIdentifiers` framework for macOS >= 12 (Monterey).\n- On platforms other than macOS, falls back to a cached dictionary for UTI and extension mappings loaded via a CSV file.\n- Provides utility functions to convert between file extensions and UTIs.\n\n## Installation\n\nYou can install `utitools` from PyPI using pip:\n\n```bash\npip install utitools\n```\n\nAlternatively, you can install it from the source code:\n\n1. Clone this repository.\n   ```bash\n   git clone https://github.com/rhettbull/utitools.git\n   ```\n\n2. Install [flit](https://flit.readthedocs.io/en/latest/) if you don't already have it.\n   ```bash\n   python3 -m pip install flit\n   ```\n\n3. Run `flit install` from the root of the repository.\n   ```bash\n   cd utitools\n   flit install\n   ```\n\n## Usage\n\nHere are the available functions:\n\n### 1. `uti_for_suffix(suffix: str) -> str | None`\n\nGet the UTI for a given file suffix.\n\n```pycon\n>>> from utitools import uti_for_suffix\n>>> uti_for_suffix(\".jpeg\")\n'public.jpeg'\n>>> uti_for_suffix(\"jpg\")\n'public.jpeg'\n>>>\n```\n\n### 2. `preferred_suffix_for_uti(uti: str) -> str | None`\n\nGet the preferred file extension for a given UTI.\n\n```pycon\n>>> from utitools import preferred_suffix_for_uti\n>>> preferred_suffix_for_uti(\"public.jpeg\")\n'.jpeg'\n>>>\n```\n\n### 3. `uti_for_path(path: str | os.PathLike) -> str | None`\n\nGet the UTI for a file at the given path based on its file extension.\n\n```pycon\n>>> from utitools import uti_for_path\n>>> uti_for_path(\"/tmp/screenshot.png\")\n'public.png'\n>>>\n```\n\n### 4. `content_type_tree_for_uti(uti: str) -> list[str]`\n\nGet the UTI content type tree for a given UTI. This is hierarchical list of UTIs that the given UTI conforms to.\n\n```pycon\n>>> from utitools import content_type_tree_for_uti\n>>> content_type_tree_for_uti(\"public.heic\")\n['public.heic', 'public.heif-standard', 'public.image', 'public.data', 'public.item', 'public.content']\n>>>\n```\n\n### 5. `conforms_to_uti(uti1: str, uti2: str) -> bool`\n\nReturn True if `uti1` conforms to `uti2`, otherwise False.\n\nThis is useful for checking if a UTI conforms to a parent UTI. For example, to check if a given UTI is an image:\n\n```pycon\n>>> from utitools import conforms_to_uti\n>>> conforms_to_uti(\"public.jpeg\", \"public.image\")\nTrue\n>>> conforms_to_uti(\"public.jpeg\", \"public.video\")\nFalse\n>>>\n```\n\nThese 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:\n\n```pycon\n>>> from utitools import uti_for_path, conforms_to_uti\n>>> def is_image(path):\n...     return conforms_to_uti(uti_for_path(path), \"public.image\")\n...\n>>> is_image(\"img_1234.jpg\")\nTrue\n>>> is_image(\"img_1234.txt\")\nFalse\n>>>\n```\n\n## macOS Version Compatibility\n\nThe code path of `utitools` changes depending on the macOS version:\n\n- **macOS \u2264 11 (Big Sur)**: Uses the deprecated methods `UTTypeCopyPreferredTagWithClass` and `UTTypeCreatePreferredIdentifierForTag` from `CoreServices`.\n- **macOS \u2265 12 (Monterey)**: Uses the modern `UniformTypeIdentifiers` module.\n\n## Non-macOS Usage\n\nOn 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.\n\nThe 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.\n\nThere 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.\n\nI use this library primarily to get UTIs for various image and video formats on macOS so this process is sufficient for my uses.\n\nOn 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.\n\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n## Packaging with pyinstaller or other tools\n\nTo 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.\n\n---\n\nFeel free to contribute or submit issues via [GitHub issues](https://github.com/rhettbull/utitools/issues).\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Utilities for working with Uniform Type Identifiers (UTIs)",
    "version": "0.4.0",
    "project_urls": {
        "Home": "https://github.com/RhetTbull/utitools",
        "Issues": "https://github.com/RhetTbull/utitools/issues",
        "Source": "https://github.com/RhetTbull/utitools"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "31d7df4363799c128c93b59590ff59953405db8165a029f483f434eab4a64573",
                "md5": "75825d7bacb95fce2db811c50b08bbdd",
                "sha256": "21d6892779f6866329572146ed8dc97c19631d4c5059e49c04a5593ac06b0fbc"
            },
            "downloads": -1,
            "filename": "utitools-0.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "75825d7bacb95fce2db811c50b08bbdd",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 23002,
            "upload_time": "2025-08-09T12:05:44",
            "upload_time_iso_8601": "2025-08-09T12:05:44.273782Z",
            "url": "https://files.pythonhosted.org/packages/31/d7/df4363799c128c93b59590ff59953405db8165a029f483f434eab4a64573/utitools-0.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e91436b76591c7f9025e91b1af5b4544fc91a0b6e54ac0627d301253372701fa",
                "md5": "aab700b2712dc55b50ca269b91f40117",
                "sha256": "71a7303ac26094f597999ae31848a1864ffffe3e049396459aa1458defdbaf71"
            },
            "downloads": -1,
            "filename": "utitools-0.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "aab700b2712dc55b50ca269b91f40117",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 28166,
            "upload_time": "2025-08-09T12:05:45",
            "upload_time_iso_8601": "2025-08-09T12:05:45.925852Z",
            "url": "https://files.pythonhosted.org/packages/e9/14/36b76591c7f9025e91b1af5b4544fc91a0b6e54ac0627d301253372701fa/utitools-0.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-09 12:05:45",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "RhetTbull",
    "github_project": "utitools",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "utitools"
}
        
Elapsed time: 0.76223s