Skip to content

Commit

Permalink
Add docs (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
aminalaee authored Jun 14, 2024
1 parent d4902b3 commit 88739a3
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 25 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ jobs:
- name: Install dependencies
run: pip install -r requirements.txt
- name: Check code
run: |
make lint
run: make lint
- name: Check docs
run: make docs_build

linux:
name: "Linux: ${{ matrix.target }}"
Expand Down Expand Up @@ -251,6 +252,10 @@ jobs:
- uses: actions/download-artifact@v3
with:
name: wheels
- name: Build and publish docs
run: |
pip install -r requirements.txt
make docs_build && make docs_deploy
- name: Publish to PyPI
uses: PyO3/maturin-action@v1
env:
Expand Down
13 changes: 12 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,21 @@ lint:
test:
pytest tests -vvv


.PHONY: bench
bench:
richbench benchmarks/

.PHONY: docs_build
docs_build:
mkdocs build

.PHONY: docs_serve
docs_serve:
mkdocs serve --dev-addr localhost:8080

.PHONY: docs_deploy
docs_deploy:
mkdocs gh-deploy --force

.PHONY: all
all: format build lint test
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Python UUID implementation using Rust's UUID library.
This will make `uuid4` function around 10x faster.

This package can be a drop-in replacement to the standard library UUID
which implements existing UUID versions like V4 in Rust
and also adds draft UUID versions like V6.
which implements existing UUID versions like v4 in Rust
and also adds draft UUID versions like v6.

Avaialble UUID versions:

Expand Down Expand Up @@ -63,12 +63,12 @@ UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
```

## Compat module
## Compatibility

In some cases you might need `UUID` instances to be returned
In some cases, for example if you are using `Django`, you might need `UUID` instances to be returned
from the standrad-library `uuid`, not a custom `UUID` class.
In that case you can use the `uuid_utils.compat` which comes with a performance penalty
in comparison with the `uuid_utils` default behaviour, but still faster than the standard-library.
in comparison with the `uuid_utils` default behaviour, but is still faster than the standard-library.

```py
>>> import uuid_utils.compat as uuid
Expand All @@ -80,16 +80,16 @@ UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')

## Benchmarks

| Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
|-----------------|---------|---------|---------|-----------------|-----------------|-----------------|
| UUID V1 | 0.058 | 0.059 | 0.058 | 0.005 (12.0x) | 0.005 (11.9x) | 0.005 (12.0x) |
| UUID V3 | 0.063 | 0.064 | 0.063 | 0.008 (7.9x) | 0.008 (8.1x) | 0.008 (8.0x) |
| UUID V4 | 0.041 | 0.041 | 0.041 | 0.004 (11.1x) | 0.004 (10.8x) | 0.004 (10.9x) |
| UUID V5 | 0.064 | 0.066 | 0.065 | 0.008 (8.1x) | 0.008 (8.1x) | 0.008 (8.1x) |
| UUID from hex | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.6x) |
| UUID from bytes | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.7x) |
| UUID from int | 0.024 | 0.025 | 0.024 | 0.004 (6.6x) | 0.004 (6.7x) | 0.004 (6.6x) |
| UUID from fields | 0.028 | 0.028 | 0.028 | 0.009 (3.1x) | 0.009 (3.1x) | 0.009 (3.1x) |
| Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
| ---------------- | ----- | ----- | ----- | ------------- | ------------- | ------------- |
| UUID v1 | 0.058 | 0.059 | 0.058 | 0.005 (12.0x) | 0.005 (11.9x) | 0.005 (12.0x) |
| UUID v3 | 0.063 | 0.064 | 0.063 | 0.008 (7.9x) | 0.008 (8.1x) | 0.008 (8.0x) |
| UUID v4 | 0.041 | 0.041 | 0.041 | 0.004 (11.1x) | 0.004 (10.8x) | 0.004 (10.9x) |
| UUID v5 | 0.064 | 0.066 | 0.065 | 0.008 (8.1x) | 0.008 (8.1x) | 0.008 (8.1x) |
| UUID from hex | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.6x) |
| UUID from bytes | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.7x) |
| UUID from int | 0.024 | 0.025 | 0.024 | 0.004 (6.6x) | 0.004 (6.7x) | 0.004 (6.6x) |
| UUID from fields | 0.028 | 0.028 | 0.028 | 0.009 (3.1x) | 0.009 (3.1x) | 0.009 (3.1x) |

## How to develop locally

Expand Down
8 changes: 4 additions & 4 deletions benchmarks/bench_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ def uuid_utils_uuid5() -> None:


__benchmarks__ = [
(uuid_uuid1, uuid_utils_uuid1, "UUID V1"),
(uuid_uuid3, uuid_utils_uuid3, "UUID V3"),
(uuid_uuid4, uuid_utils_uuid4, "UUID V4"),
(uuid_uuid5, uuid_utils_uuid5, "UUID V5"),
(uuid_uuid1, uuid_utils_uuid1, "UUID v1"),
(uuid_uuid3, uuid_utils_uuid3, "UUID v3"),
(uuid_uuid4, uuid_utils_uuid4, "UUID v4"),
(uuid_uuid5, uuid_utils_uuid5, "UUID v5"),
]
27 changes: 27 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class `uuid_utils.UUID`

| Property | Description |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `bytes` | the UUID as a 16-byte string (containing the six integer fields in big-endian byte order) |
| `bytes_le` | the UUID as a 16-byte string (with time_low, time_mid, and time_hi_version in little-endian byte order) |
| `fields` | a tuple of the six integer fields of the UUID, which are also available as six individual attributes and two derived attributes |
| `hex` | the UUID as a 32-character hexadecimal string |
| `int` | the UUID as a 128-bit integer |
| `urn` | the UUID as a URN as specified in RFC 4122 |
| `variant` | the UUID variant (one of the constants RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE) |
| `version` | the UUID version number |
| `is_safe` | An enum indicating whether the UUID has been generated in a way that is safe for multiprocessing applications, via `uuid_generate_time_safe(3)` |
| `timestamp` | The timestamp of the UUID in milliseconds since epoch. Only works for UUID versions 1, 6 and 7, otherwise raises `ValueError`. |

module `uuid_utils`

| Function | Description |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `uuid1` | Generate a UUID from a host ID, sequence number, and the current time. If `node` is not given, `getnode()` is used to obtain the hardware address. If `clock_seq` is given, it is used as the sequence number; otherwise a random 14-bit sequence number is chosen. |
| `uuid3` | Generate a UUID from the MD5 hash of a namespace UUID and a name. |
| `uuid4` | Generate a random UUID. |
| `uuid5` | Generate a UUID from the SHA-1 hash of a namespace UUID and a name. |
| `uuid6` | Generate a version 6 UUID using the given timestamp and a host ID. This is similar to version 1 UUIDs, except that it is lexicographically sortable by timestamp. |
| `uuid7` | Generate a version 7 UUID using a time value and random bytes. |
| `uuid8` | Generate a custom UUID comprised almost entirely of user-supplied bytes. |
| `getnode` | Get the hardware address as a 48-bit positive integer. |
105 changes: 105 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Python UUID Utils

<p align="center">
<a href="https://pypi.org/project/uuid-utils/">
<img src="https://badge.fury.io/py/uuid-utils.svg" alt="Package version">
</a>
<a href="https://pypi.org/project/uuid-utils" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/uuid-utils.svg?color=%2334D058" alt="Supported Python versions">
</a>
</p>

---

Python UUID implementation using Rust's UUID library.
This will make `uuid4` function around 10x faster.

This package can be a drop-in replacement to the standard library UUID
which implements existing UUID versions like v4 in Rust
and also adds draft UUID versions like v6.

Avaialble UUID versions:

- `uuid1` - Version 1 UUIDs using a timestamp and monotonic counter.
- `uuid3` - Version 3 UUIDs based on the MD5 hash of some data.
- `uuid4` - Version 4 UUIDs with random data.
- `uuid5` - Version 5 UUIDs based on the SHA1 hash of some data.
- `uuid6` - Version 6 UUIDs using a timestamp and monotonic counter.
- `uuid7` - Version 7 UUIDs using a Unix timestamp ordered by time.
- `uuid8` - Version 8 UUIDs using user-defined data.

<sup>Please note that UUID versions 6, 7 and 8 are still in draft RFC.</sup><br>

## Installation
Using `pip`:
```shell
$ pip install uuid-utils
```
or, using `conda`:

```shell
$ conda install -c conda-forge uuid-utils
```

## Example

```shell
>>> import uuid_utils as uuid

>>> # make a random UUID
>>> uuid.uuid4()
UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')

>>> # make a random UUID using a Unix timestamp which is time-ordered.
>>> uuid.uuid7()
UUID('018afa4a-0d21-7e6c-b857-012bc678552b')

>>> # make a UUID using a SHA-1 hash of a namespace UUID and a name
>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

>>> # make a UUID using an MD5 hash of a namespace UUID and a name
>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
```

## Compatibility

In some cases, for example if you are using `Django`, you might need `UUID` instances to be returned
from the standrad-library `uuid`, not a custom `UUID` class.
In that case you can use the `uuid_utils.compat` which comes with a performance penalty
in comparison with the `uuid_utils` default behaviour, but is still faster than the standard-library.

```py
>>> import uuid_utils.compat as uuid

>>> # make a random UUID
>>> uuid.uuid4()
UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')
```

## Benchmarks

| Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
| ---------------- | ----- | ----- | ----- | ------------- | ------------- | ------------- |
| UUID v1 | 0.058 | 0.059 | 0.058 | 0.005 (12.0x) | 0.005 (11.9x) | 0.005 (12.0x) |
| UUID v3 | 0.063 | 0.064 | 0.063 | 0.008 (7.9x) | 0.008 (8.1x) | 0.008 (8.0x) |
| UUID v4 | 0.041 | 0.041 | 0.041 | 0.004 (11.1x) | 0.004 (10.8x) | 0.004 (10.9x) |
| UUID v5 | 0.064 | 0.066 | 0.065 | 0.008 (8.1x) | 0.008 (8.1x) | 0.008 (8.1x) |
| UUID from hex | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.6x) |
| UUID from bytes | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.7x) |
| UUID from int | 0.024 | 0.025 | 0.024 | 0.004 (6.6x) | 0.004 (6.7x) | 0.004 (6.6x) |
| UUID from fields | 0.028 | 0.028 | 0.028 | 0.009 (3.1x) | 0.009 (3.1x) | 0.009 (3.1x) |

## How to develop locally

```shell
$ make build
$ make test
```

Or:

```shell
$ RUSTFLAGS="--cfg uuid_unstable" maturin develop --release
```
45 changes: 45 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
site_name: UUID-Utils
site_description: Python bindings to Rust UUID
site_url: https://aminalaee.dev/uuid-utils

theme:
name: "material"
palette:
primary: white
features:
- content.code.copy

repo_name: aminalaee/uuid-utils
repo_url: https://github.com/aminalaee/uuid-utils
edit_uri: ""

nav:
- Introduction: "index.md"
- API: "api.md"

markdown_extensions:
- markdown.extensions.codehilite:
guess_lang: false
- tables
- pymdownx.details
- pymdownx.highlight
- pymdownx.tabbed
- pymdownx.superfences

watch:
- python/

plugins:
- search

extra:
analytics:
provider: google
property: G-MV427T1Z9X
social:
- icon: fontawesome/brands/github
link: https://github.com/aminalaee
- icon: fontawesome/brands/twitter
link: https://twitter.com/aminalaee
- icon: fontawesome/brands/linkedin
link: https://www.linkedin.com/in/amin-alaee
9 changes: 6 additions & 3 deletions python/uuid_utils/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,15 @@ class UUID:
variant the UUID variant (one of the constants RESERVED_NCS,
RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
version the UUID version number (1 through 5, meaningful only
when the variant is RFC_4122)
version the UUID version number
is_safe An enum indicating whether the UUID has been generated in
a way that is safe for multiprocessing applications, via
uuid_generate_time_safe(3).
timestamp The timestamp of the UUID in milliseconds since epoch.
Only works for UUID versions 1, 6 and 7,
otherwise raises ValueError.
"""

def __init__(
Expand Down Expand Up @@ -165,7 +168,7 @@ def uuid7(timestamp: _Int | None = None, nanos: _Int | None = None) -> UUID:
...

def uuid8(bytes: _Bytes) -> UUID:
"""Generate a custom UUID comprised almost entirely of user-supplied bytes.."""
"""Generate a custom UUID comprised almost entirely of user-supplied bytes."""
...

NAMESPACE_DNS: UUID
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mkdocs==1.6.0
mkdocs-material==9.5.26
mypy==1.10.0
pytest==8.2.0
ruff==0.4.8

0 comments on commit 88739a3

Please sign in to comment.