# Slices TypeID library

## What is TypeID?

A TypeID is a unique identifier for an object in Slices. It can never be re-used to refer to another item.

It consists of a prefix that indicates the type of object, followed by the infrastructure ID, and a unique base32 suffix.

## Technical details

A TypeID is a string, consisting of 3 components separated by underscores:
- **Prefix**: A prefix that indicates the type of object (e.g., `r` for resource, `exp` for experiment, `flavor` for flavor, etc.).
  The prefix must consist of lowercase letters and be maximum 10 chars long. 
  Regex pattern: `[a-z]{1,10}`
- **Domain**: A top level domain that indicates the infrastructure where the object is provisioned (e.g., `example.com`).
  It allows for global uniqueness across different infrastructures and also provides a hint about where the object is located.
  The domain must consist of lowercase letters, digits, dots and hyphens, and must start with a lowercase letter. It should be maximum 55 chars long. 
  Regex pattern: `[a-z][a-z0-9.-]{1,55}`
- **Suffix**: A unique base32 suffix of 26 chars (e.g., `01kjsxktfrf70agz88x0k1vzy5`). This encodes a UUID (128-bit = 16 byte). 
  The base32 encoding uses the alphabet `0123456789abcdefghjkmnpqrstvwxyz` (i.e., it excludes `i`, `l`, `o`, and `u` to avoid confusion).
  Note that each char in base32 encoding represents 5 bits, so 26 chars represent 130 bits, which is enough to encode a 128-bit UUID with 2 bits zero padding.

## Prefixes

The following prefixes are currently defined:
- `user`: User (e.g., `user_example.com_01kjsxktfrf70agz88x0k1vzy5`)
- `proj`: Project (e.g., `proj_example.com_01kjsxktfrf70agz88x0k1vzy5`)
- `exp`: Experiment (e.g., `exp_example.com_01kjsxktfrf70agz88x0k1vzy5`)
- `r`: Resource (e.g., `r_example.com_01kjsxktfrf70agz88x0k1vzy5`)
- `m`: Machine (e.g., `m_example.com_01kjsxktfrf70agz88x0k1vzy5`)
- `flavor`: Flavor (e.g., `flavor_example.com_01kjsxktfrf70agz88x0k1vzy5`)
- `image`: Image (e.g., `image_example.com_01kjsxktfrf70agz88x0k1vzy5`)
- `task`: Task (e.g., `task_example.com_01kjsxktfrf70agz88x0k1vzy5`)

## Installation

Add this library to your `pyproject.toml` dependencies:

```toml
dependencies=[
   ...
   "slices-typeid>=1.0.0, <2",
   ...
```

The import where needed:
```python
from slices_typeid import TypeID
```

## Usage

```python
from slices_typeid import TypeID
from uuid import UUID

id_a = TypeID.from_string("r_example.com_01kjsxktfrf70agz88x0k1vzy5")
print(id_a.type)  # Output: "r"
print(id_a.domain)  # Output: "example.com"
print(id_a.suffix)  # Output: "01kjsxktfrf70agz88x0k1vzy5"
print(id_a.uuid)  # Output: 019cb3d9-e9f8-79c0-a87d-08e8261dffc5

id_b = TypeID.from_uuid(suffix=UUID("019cb3d9-e9f8-79c0-a87d-08e8261dffc5"), type="r", domain="example.com")
print(id_b)  # Output: "r_example.com_01kjsxktfrf70agz88x0k1vzy5"
```

## pre-commit

This repository uses [pre-commit](https://pre-commit.com/) to run checks before commits. To set it up, run:

```bash
pip install pre-commit
pre-commit install
```

The pre-commit configuration is defined in `.pre-commit-config.yaml`.
It includes checks for code formatting, linting, and security issues. 
You can run the checks manually with:

```bash
pre-commit run --all-files
```

The pre-commit config includes pyright. pyright needs access to the project's dependencies to work properly. 
In `pyproject.toml`, the virtual env for pyright is configured to be `.venv`.
This is the local that [`uv`](https://docs.astral.sh/uv/) creates the virtual env when running `uv sync`.

To skip pre-commit checks for a commit, you can use the `--no-verify` flag:
```bash
git commit -m "Your commit message" --no-verify
```

To skip just pyright checks, use the `SKIP` environment variable:
```bash
SKIP=pyright git commit -m "Your commit message"
```
