Skip to content

Commit ef1e6bc

Browse files
committed
Add fetch utility functions and tests
1 parent 471d43a commit ef1e6bc

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/virtualship/cli/_fetch.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import hashlib
2+
from datetime import datetime
3+
4+
from pydantic import BaseModel
5+
6+
7+
def _hash(s: str, *, length: int) -> str:
8+
"""Create a hash of a string."""
9+
assert length % 2 == 0, "Length must be even."
10+
half_length = length // 2
11+
12+
return hashlib.shake_128(s.encode("utf-8")).hexdigest(half_length)
13+
14+
15+
def create_hash(s: str) -> str:
16+
"""Create an 8 digit hash of a string."""
17+
return _hash(s, length=8)
18+
19+
20+
def hash_model(model: BaseModel) -> str:
21+
"""
22+
Hash a Pydantic model.
23+
24+
:param region: The region to hash.
25+
:returns: The hash.
26+
"""
27+
return create_hash(model.model_dump_json())
28+
29+
30+
def filename_to_hash(filename: str) -> str:
31+
"""Extract hash from filename of the format YYYYMMDD_HHMMSS_{hash}."""
32+
return filename.split("_")[-1]
33+
34+
35+
def hash_to_filename(hash: str) -> str:
36+
"""Return a filename of the format YYYYMMDD_HHMMSS_{hash}."""
37+
return f"{datetime.now().strftime('%Y%m%d_%H%M%S')}_{hash}"

tests/cli/test_fetch.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from pydantic import BaseModel
2+
3+
from virtualship.cli._fetch import (
4+
create_hash,
5+
filename_to_hash,
6+
hash_model,
7+
hash_to_filename,
8+
)
9+
10+
11+
def test_create_hash():
12+
assert len(create_hash("correct-length")) == 8
13+
assert create_hash("same") == create_hash("same")
14+
assert create_hash("unique1") != create_hash("unique2")
15+
16+
17+
def test_hash_filename_roundtrip():
18+
hash_ = create_hash("test")
19+
assert filename_to_hash(hash_to_filename(hash_)) == hash_
20+
21+
22+
def test_hash_model():
23+
class TestModel(BaseModel):
24+
a: int
25+
b: str
26+
27+
hash_model(TestModel(a=0, b="b"))

0 commit comments

Comments
 (0)