Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs #53

Merged
merged 1 commit into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading