typeid-python 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of typeid-python might be problematic. Click here for more details.
- typeid/__init__.py +2 -2
- typeid/base32.py +4 -2
- typeid/cli.py +42 -0
- typeid/typeid.py +37 -7
- {typeid_python-0.2.0.dist-info → typeid_python-0.2.2.dist-info}/METADATA +40 -7
- typeid_python-0.2.2.dist-info/RECORD +11 -0
- {typeid_python-0.2.0.dist-info → typeid_python-0.2.2.dist-info}/WHEEL +1 -1
- typeid_python-0.2.0.dist-info/RECORD +0 -10
- {typeid_python-0.2.0.dist-info → typeid_python-0.2.2.dist-info}/LICENSE +0 -0
typeid/__init__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from .typeid import TypeID, from_string, from_uuid
|
|
1
|
+
from .typeid import TypeID, from_string, from_uuid, get_prefix_and_suffix
|
|
2
2
|
|
|
3
|
-
__all__ = ("TypeID", "from_string", "from_uuid")
|
|
3
|
+
__all__ = ("TypeID", "from_string", "from_uuid", "get_prefix_and_suffix")
|
typeid/base32.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
1
3
|
from typeid.constants import SUFFIX_LEN
|
|
2
4
|
|
|
3
5
|
ALPHABET = "0123456789abcdefghjkmnpqrstvwxyz"
|
|
@@ -263,7 +265,7 @@ TABLE = [
|
|
|
263
265
|
]
|
|
264
266
|
|
|
265
267
|
|
|
266
|
-
def encode(src:
|
|
268
|
+
def encode(src: List[int]) -> str:
|
|
267
269
|
dst = [""] * SUFFIX_LEN
|
|
268
270
|
|
|
269
271
|
if len(src) != 16:
|
|
@@ -302,7 +304,7 @@ def encode(src: list) -> str:
|
|
|
302
304
|
return "".join(dst)
|
|
303
305
|
|
|
304
306
|
|
|
305
|
-
def decode(s: str) ->
|
|
307
|
+
def decode(s: str) -> List[int]:
|
|
306
308
|
v = bytes(s, encoding="utf-8")
|
|
307
309
|
|
|
308
310
|
if (
|
typeid/cli.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
from uuid6 import UUID
|
|
5
|
+
|
|
6
|
+
from typeid import TypeID, base32, from_uuid, get_prefix_and_suffix
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.group()
|
|
10
|
+
def cli():
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@cli.command()
|
|
15
|
+
@click.option("-p", "--prefix")
|
|
16
|
+
def new(prefix: Optional[str] = None) -> None:
|
|
17
|
+
typeid = TypeID(prefix=prefix)
|
|
18
|
+
click.echo(str(typeid))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@cli.command()
|
|
22
|
+
@click.argument("uuid")
|
|
23
|
+
@click.option("-p", "--prefix")
|
|
24
|
+
def encode(uuid: str, prefix: Optional[str] = None) -> None:
|
|
25
|
+
typeid = from_uuid(suffix=UUID(uuid), prefix=prefix)
|
|
26
|
+
click.echo(str(typeid))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@cli.command()
|
|
30
|
+
@click.argument("encoded")
|
|
31
|
+
def decode(encoded: str) -> None:
|
|
32
|
+
prefix, suffix = get_prefix_and_suffix(encoded)
|
|
33
|
+
|
|
34
|
+
decoded_bytes = bytes(base32.decode(suffix))
|
|
35
|
+
uuid = UUID(bytes=decoded_bytes)
|
|
36
|
+
|
|
37
|
+
click.echo(f"type: {prefix}")
|
|
38
|
+
click.echo(f"uuid: {uuid}")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
cli()
|
typeid/typeid.py
CHANGED
|
@@ -18,6 +18,16 @@ class TypeID:
|
|
|
18
18
|
self._prefix = prefix or ""
|
|
19
19
|
self._suffix = suffix
|
|
20
20
|
|
|
21
|
+
@classmethod
|
|
22
|
+
def from_string(cls, string: str):
|
|
23
|
+
prefix, suffix = get_prefix_and_suffix(string=string)
|
|
24
|
+
return cls(suffix=suffix, prefix=prefix)
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def from_uuid(cls, suffix: UUID, prefix: Optional[str] = None):
|
|
28
|
+
suffix_str = _convert_uuid_to_b32(suffix)
|
|
29
|
+
return TypeID(suffix=suffix_str, prefix=prefix)
|
|
30
|
+
|
|
21
31
|
@property
|
|
22
32
|
def suffix(self) -> str:
|
|
23
33
|
return self._suffix
|
|
@@ -26,6 +36,10 @@ class TypeID:
|
|
|
26
36
|
def prefix(self) -> str:
|
|
27
37
|
return self._prefix
|
|
28
38
|
|
|
39
|
+
@property
|
|
40
|
+
def uuid(self) -> UUID:
|
|
41
|
+
return _convert_b32_to_uuid(self.suffix)
|
|
42
|
+
|
|
29
43
|
def __str__(self) -> str:
|
|
30
44
|
value = ""
|
|
31
45
|
if self.prefix:
|
|
@@ -38,22 +52,38 @@ class TypeID:
|
|
|
38
52
|
return False
|
|
39
53
|
return value.prefix == self.prefix and value.suffix == self.suffix
|
|
40
54
|
|
|
55
|
+
def __hash__(self) -> int:
|
|
56
|
+
return hash((self.prefix, self.suffix))
|
|
57
|
+
|
|
41
58
|
|
|
42
59
|
def from_string(string: str) -> TypeID:
|
|
43
|
-
|
|
60
|
+
"""Consider TypeID.from_string instead."""
|
|
61
|
+
return TypeID.from_string(string=string)
|
|
44
62
|
|
|
63
|
+
|
|
64
|
+
def from_uuid(suffix: UUID, prefix: Optional[str] = None) -> TypeID:
|
|
65
|
+
"""Consider TypeID.from_uuid instead."""
|
|
66
|
+
return TypeID.from_uuid(suffix=suffix, prefix=prefix)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_prefix_and_suffix(string: str) -> tuple:
|
|
70
|
+
parts = string.split("_")
|
|
71
|
+
suffix = None
|
|
72
|
+
prefix = None
|
|
45
73
|
if len(parts) == 1:
|
|
46
|
-
|
|
74
|
+
suffix = parts[0]
|
|
47
75
|
elif len(parts) == 2 and parts[0] != "":
|
|
48
|
-
|
|
76
|
+
suffix = parts[1]
|
|
77
|
+
prefix = parts[0]
|
|
49
78
|
else:
|
|
50
79
|
raise InvalidTypeIDStringException(f"Invalid TypeID: {string}")
|
|
51
80
|
|
|
52
|
-
|
|
53
|
-
def from_uuid(suffix: UUID, prefix: Optional[str] = None) -> TypeID:
|
|
54
|
-
suffix_str = _convert_uuid_to_b32(suffix)
|
|
55
|
-
return TypeID(suffix=suffix_str, prefix=prefix)
|
|
81
|
+
return prefix, suffix
|
|
56
82
|
|
|
57
83
|
|
|
58
84
|
def _convert_uuid_to_b32(uuid_instance: UUID) -> str:
|
|
59
85
|
return base32.encode(list(uuid_instance.bytes))
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _convert_b32_to_uuid(b32: str) -> UUID:
|
|
89
|
+
return UUID(bytes=bytes(base32.decode(b32)))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: typeid-python
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Python implementation of TypeIDs: type-safe, K-sortable, and globally unique identifiers inspired by Stripe IDs
|
|
5
5
|
Home-page: https://github.com/akhundMurad/typeid-python
|
|
6
6
|
License: MIT
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Provides-Extra: cli
|
|
19
20
|
Requires-Dist: uuid6 (>=2023.5.2,<2024.0.0)
|
|
20
21
|
Project-URL: Repository, https://github.com/akhundMurad/typeid-python
|
|
21
22
|
Description-Content-Type: text/markdown
|
|
@@ -48,18 +49,20 @@ This particular implementation provides an pip package that can be used by any P
|
|
|
48
49
|
|
|
49
50
|
- PyPI:
|
|
50
51
|
|
|
51
|
-
```
|
|
52
|
+
```console
|
|
52
53
|
pip install typeid-python
|
|
53
54
|
```
|
|
54
55
|
|
|
55
56
|
- Poetry:
|
|
56
57
|
|
|
57
|
-
```
|
|
58
|
+
```console
|
|
58
59
|
poetry add typeid-python
|
|
59
60
|
```
|
|
60
61
|
|
|
61
62
|
## Usage
|
|
62
63
|
|
|
64
|
+
### Basic
|
|
65
|
+
|
|
63
66
|
- Create TypeID Instance:
|
|
64
67
|
|
|
65
68
|
```python
|
|
@@ -79,9 +82,9 @@ This particular implementation provides an pip package that can be used by any P
|
|
|
79
82
|
- Create TypeID from string:
|
|
80
83
|
|
|
81
84
|
```python
|
|
82
|
-
from typeid import
|
|
85
|
+
from typeid import TypeID
|
|
83
86
|
|
|
84
|
-
typeid = from_string("user_01h45ytscbebyvny4gc8cr8ma2")
|
|
87
|
+
typeid = TypeID.from_string("user_01h45ytscbebyvny4gc8cr8ma2")
|
|
85
88
|
|
|
86
89
|
print(str(typeid)) # "user_01h45ytscbebyvny4gc8cr8ma2"
|
|
87
90
|
```
|
|
@@ -89,14 +92,44 @@ This particular implementation provides an pip package that can be used by any P
|
|
|
89
92
|
- Create TypeID from uuid7:
|
|
90
93
|
|
|
91
94
|
```python
|
|
92
|
-
from typeid import
|
|
95
|
+
from typeid import TypeID
|
|
93
96
|
from uuid6 import uuid7
|
|
94
97
|
|
|
95
98
|
uuid = uuid7() # UUID('01890bf0-846f-7762-8605-5a3abb40e0e5')
|
|
96
99
|
prefix = "user"
|
|
97
100
|
|
|
98
|
-
typeid = from_uuid(prefix=prefix, suffix=uuid)
|
|
101
|
+
typeid = TypeID.from_uuid(prefix=prefix, suffix=uuid)
|
|
99
102
|
|
|
100
103
|
print(str(typeid)) # "user_01h45z113fexh8c1at7axm1r75"
|
|
101
104
|
```
|
|
102
105
|
|
|
106
|
+
### CLI-tool
|
|
107
|
+
|
|
108
|
+
- Install dependencies:
|
|
109
|
+
|
|
110
|
+
```console
|
|
111
|
+
pip install typeid-python[cli]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- To generate a new TypeID, run:
|
|
115
|
+
|
|
116
|
+
```console
|
|
117
|
+
$ python3 -m typeid.cli new -p prefix
|
|
118
|
+
prefix_01h2xcejqtf2nbrexx3vqjhp41
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- To decode an existing TypeID into a UUID run:
|
|
122
|
+
|
|
123
|
+
```console
|
|
124
|
+
$ python3 -m typeid.cli decode prefix_01h2xcejqtf2nbrexx3vqjhp41
|
|
125
|
+
type: prefix
|
|
126
|
+
uuid: 0188bac7-4afa-78aa-bc3b-bd1eef28d881
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- And to encode an existing UUID into a TypeID run:
|
|
130
|
+
|
|
131
|
+
```console
|
|
132
|
+
$ python3 -m typeid.cli encode 0188bac7-4afa-78aa-bc3b-bd1eef28d881 --prefix prefix
|
|
133
|
+
prefix_01h2xcejqtf2nbrexx3vqjhp41
|
|
134
|
+
```
|
|
135
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
typeid/__init__.py,sha256=bS8J12-a6sOcTIHBumVs9qLRxCX5P-KWVLeMw6m1e_U,149
|
|
2
|
+
typeid/base32.py,sha256=UTYXJjb95_nn-vYIpw7nquguBac4GZ0TL0oE6BuujPg,6504
|
|
3
|
+
typeid/cli.py,sha256=h93_EAOzWO3bqubgL83Q-smHp11lvxMjgAunwyTWwFM,872
|
|
4
|
+
typeid/constants.py,sha256=2ApV0agNys2yI9NM8oQZbyTR2rgP-VtxXGrM6glBB2Q,37
|
|
5
|
+
typeid/errors.py,sha256=QPHZ-DJg5OpPOHtuetsqMCYu-E_aHMJZTTeFqx9Gz_4,207
|
|
6
|
+
typeid/typeid.py,sha256=_hu8bHjFVcwe2QklrFmYZOj2ycltuL8p_XjAq2ncviY,2480
|
|
7
|
+
typeid/validation.py,sha256=yvLO5lfMkJpduZzql_FJlj4hW6HcWURWYLRQvR92SSM,899
|
|
8
|
+
typeid_python-0.2.2.dist-info/LICENSE,sha256=f98oZ9FId4i3835UJYGw066BU8PSc57L1utGWS1ypcs,1070
|
|
9
|
+
typeid_python-0.2.2.dist-info/METADATA,sha256=RDsPvAGyBmrLMR0cCxu0-6ZvuOjKSJ_ndX227zSftcY,4073
|
|
10
|
+
typeid_python-0.2.2.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
|
11
|
+
typeid_python-0.2.2.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
typeid/__init__.py,sha256=Xq1_XIJtLlxK0Nv4YXx6jJ5owUL7YSmHxBQA8Pd4-AY,101
|
|
2
|
-
typeid/base32.py,sha256=rPDHs0p66stn9VA82NkpSzBCjm93ILGso09zEPjlMwc,6469
|
|
3
|
-
typeid/constants.py,sha256=2ApV0agNys2yI9NM8oQZbyTR2rgP-VtxXGrM6glBB2Q,37
|
|
4
|
-
typeid/errors.py,sha256=QPHZ-DJg5OpPOHtuetsqMCYu-E_aHMJZTTeFqx9Gz_4,207
|
|
5
|
-
typeid/typeid.py,sha256=q79bFYCydq7mjYOA_OKOGv0oFZ60TMHdshR2It7Kcyk,1660
|
|
6
|
-
typeid/validation.py,sha256=yvLO5lfMkJpduZzql_FJlj4hW6HcWURWYLRQvR92SSM,899
|
|
7
|
-
typeid_python-0.2.0.dist-info/LICENSE,sha256=f98oZ9FId4i3835UJYGw066BU8PSc57L1utGWS1ypcs,1070
|
|
8
|
-
typeid_python-0.2.0.dist-info/METADATA,sha256=EteNUmTOcsHAjXV1ug2srkjFS21b9m0Zm8_Drmu6ZZg,3385
|
|
9
|
-
typeid_python-0.2.0.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
|
10
|
-
typeid_python-0.2.0.dist-info/RECORD,,
|
|
File without changes
|