scruby 0.3.0__py3-none-any.whl → 0.4.0__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 scruby might be problematic. Click here for more details.

scruby/db.py CHANGED
@@ -1,19 +1,4 @@
1
- """Creation and management of the database.
2
-
3
- Examples:
4
- >>> from scruby import Scruby
5
- >>> db = Scruby()
6
- >>> await db.set_key("key name", "Some text")
7
- None
8
- >>> await db.get_key("key name")
9
- "Some text"
10
- >>> await db.has_key("key name")
11
- True
12
- >>> await db.delete_key("key name")
13
- None
14
- >>> await db.napalm()
15
- None
16
- """
1
+ """Creation and management of the database."""
17
2
 
18
3
  from __future__ import annotations
19
4
 
@@ -21,46 +6,33 @@ __all__ = ("Scruby",)
21
6
 
22
7
  import hashlib
23
8
  from shutil import rmtree
24
- from typing import Literal
9
+ from typing import Generic, TypeVar
25
10
 
26
11
  import orjson
27
12
  from anyio import Path, to_thread
28
13
 
29
- type ValueOfKey = str | int | float | list | dict | Literal[True] | Literal[False] | None
14
+ T = TypeVar("T")
30
15
 
31
16
 
32
- class Scruby:
17
+ class Scruby(Generic[T]): # noqa: UP046
33
18
  """Creation and management of the database.
34
19
 
35
- Examples:
36
- >>> from scruby import Scruby
37
- >>> db = Scruby()
38
- >>> await db.set_key("key name", "Some text")
39
- None
40
- >>> await db.get_key("key name")
41
- "Some text"
42
- >>> await db.has_key("key name")
43
- True
44
- >>> await db.delete_key("key name")
45
- None
46
- >>> await db.napalm()
47
- None
48
-
49
20
  Args:
50
- db_path: Path to root directory of databases. Defaule by = "ScrubyDB" (in root of project)
21
+ db_name: Path to root directory of databases. By default = "ScrubyDB" (in root of project)
51
22
  """
52
23
 
53
24
  def __init__( # noqa: D107
54
25
  self,
55
- db_path: str = "ScrubyDB",
26
+ class_model: T,
27
+ db_name: str = "ScrubyDB",
56
28
  ) -> None:
57
- super().__init__()
58
- self.__db_path = db_path
29
+ self.__class_model = class_model
30
+ self.__db_name = db_name
59
31
 
60
32
  @property
61
- def db_path(self) -> str:
33
+ def db_name(self) -> str:
62
34
  """Get database name."""
63
- return self.__db_path
35
+ return self.__db_name
64
36
 
65
37
  async def get_leaf_path(self, key: str) -> Path:
66
38
  """Get the path to the database cell by key.
@@ -71,10 +43,10 @@ class Scruby:
71
43
  # Key to md5 sum.
72
44
  key_md5: str = hashlib.md5(key.encode("utf-8")).hexdigest() # noqa: S324
73
45
  # Convert md5 sum in the segment of path.
74
- segment_path_md5: str = "/".join(list(key_md5))
46
+ separated_md5: str = "/".join(list(key_md5))
75
47
  # The path of the branch to the database.
76
48
  branch_path: Path = Path(
77
- *(self.__db_path, segment_path_md5),
49
+ *(self.__db_name, self.__class_model.__name__, separated_md5),
78
50
  )
79
51
  # If the branch does not exist, need to create it.
80
52
  if not await branch_path.exists():
@@ -86,46 +58,31 @@ class Scruby:
86
58
  async def set_key(
87
59
  self,
88
60
  key: str,
89
- value: ValueOfKey,
61
+ value: T,
90
62
  ) -> None:
91
63
  """Asynchronous method for adding and updating keys to database.
92
64
 
93
- Examples:
94
- >>> from scruby import Scruby
95
- >>> db = Scruby()
96
- >>> await db.set_key("key name", "Some text")
97
- None
98
-
99
65
  Args:
100
66
  key: Key name.
101
67
  value: Value of key.
102
68
  """
103
69
  # The path to the database cell.
104
70
  leaf_path: Path = await self.get_leaf_path(key)
71
+ value_json: str = value.model_dump_json()
105
72
  # Write key-value to the database.
106
73
  if await leaf_path.exists():
107
74
  # Add new key or update existing.
108
75
  data_json: bytes = await leaf_path.read_bytes()
109
76
  data: dict = orjson.loads(data_json) or {}
110
- data[key] = value
77
+ data[key] = value_json
111
78
  await leaf_path.write_bytes(orjson.dumps(data))
112
79
  else:
113
80
  # Add new key to a blank leaf.
114
- await leaf_path.write_bytes(data=orjson.dumps({key: value}))
81
+ await leaf_path.write_bytes(orjson.dumps({key: value_json}))
115
82
 
116
- async def get_key(self, key: str) -> ValueOfKey:
83
+ async def get_key(self, key: str) -> T:
117
84
  """Asynchronous method for getting key from database.
118
85
 
119
- Examples:
120
- >>> from scruby import Scruby
121
- >>> db = Scruby()
122
- >>> await db.set_key("key name", "Some text")
123
- None
124
- >>> await db.get_key("key name")
125
- "Some text"
126
- >>> await db.get_key("key missing")
127
- KeyError
128
-
129
86
  Args:
130
87
  key: Key name.
131
88
  """
@@ -135,22 +92,13 @@ class Scruby:
135
92
  if await leaf_path.exists():
136
93
  data_json: bytes = await leaf_path.read_bytes()
137
94
  data: dict = orjson.loads(data_json) or {}
138
- return data[key]
95
+ obj: T = self.__class_model.model_validate_json(data[key])
96
+ return obj
139
97
  raise KeyError()
140
98
 
141
99
  async def has_key(self, key: str) -> bool:
142
100
  """Asynchronous method for checking presence of key in database.
143
101
 
144
- Examples:
145
- >>> from scruby import Scruby
146
- >>> db = Scruby()
147
- >>> await db.set_key("key name", "Some text")
148
- None
149
- >>> await db.has_key("key name")
150
- True
151
- >>> await db.has_key("key missing")
152
- False
153
-
154
102
  Args:
155
103
  key: Key name.
156
104
  """
@@ -170,16 +118,6 @@ class Scruby:
170
118
  async def delete_key(self, key: str) -> None:
171
119
  """Asynchronous method for deleting key from database.
172
120
 
173
- Examples:
174
- >>> from scruby import Scruby
175
- >>> db = Scruby()
176
- >>> await db.set_key("key name", "Some text")
177
- None
178
- >>> await db.delete_key("key name")
179
- None
180
- >>> await db.delete_key("key missing")
181
- KeyError
182
-
183
121
  Args:
184
122
  key: Key name.
185
123
  """
@@ -195,20 +133,10 @@ class Scruby:
195
133
  raise KeyError()
196
134
 
197
135
  async def napalm(self) -> None:
198
- """Asynchronous method for full database deletion (Arg: db_path).
136
+ """Asynchronous method for full database deletion (Arg: db_name).
199
137
 
200
138
  Warning:
201
139
  - `Be careful, this will remove all keys.`
202
-
203
- Examples:
204
- >>> from scruby import Scruby
205
- >>> db = Scruby()
206
- >>> await db.set_key("key name", "Some text")
207
- None
208
- >>> await db.napalm()
209
- None
210
- >>> await db.napalm()
211
- FileNotFoundError
212
140
  """
213
- await to_thread.run_sync(rmtree, self.__db_path)
141
+ await to_thread.run_sync(rmtree, self.__db_name)
214
142
  return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scruby
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: A fast key-value storage library.
5
5
  Project-URL: Homepage, https://github.com/kebasyaty/scruby
6
6
  Project-URL: Repository, https://github.com/kebasyaty/scruby
@@ -11,7 +11,7 @@ Author-email: kebasyaty <kebasyaty@gmail.com>
11
11
  License-Expression: MIT
12
12
  License-File: LICENSE
13
13
  Keywords: database,db,scruby,store
14
- Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Development Status :: 4 - Beta
15
15
  Classifier: Intended Audience :: Developers
16
16
  Classifier: License :: OSI Approved :: MIT License
17
17
  Classifier: Operating System :: MacOS :: MacOS X
@@ -26,7 +26,8 @@ Classifier: Topic :: Database
26
26
  Classifier: Typing :: Typed
27
27
  Requires-Python: <4.0,>=3.12
28
28
  Requires-Dist: anyio>=4.10.0
29
- Requires-Dist: orjson>=3.11.2
29
+ Requires-Dist: orjson>=3.11.3
30
+ Requires-Dist: pydantic>=2.11.7
30
31
  Description-Content-Type: text/markdown
31
32
 
32
33
  <div align="center">
@@ -94,33 +95,47 @@ uv add scruby
94
95
 
95
96
  ```python
96
97
  import anyio
98
+ import datetime
99
+ from pydantic import BaseModel
97
100
  from scruby import Scruby
98
101
 
99
102
 
100
103
  async def main() -> None:
101
104
  """Example."""
102
105
 
103
- db = Scruby()
104
- await db.set_key("key name", "Some text")
105
- # Update key
106
- await db.set_key("key name", "Some new text")
106
+ class User(BaseModel):
107
+ """User model."""
107
108
 
108
- user_details = {
109
- "first name": "John",
110
- "last name": "Smith",
111
- "email": "John_Smith@gmail.com",
112
- "phone": "+447986123456",
113
- }
114
- await db.set_key("+447986123456", user_details)
109
+ first_name: str
110
+ last_name: str
111
+ birthday: datetime.datetime
112
+ email: str
113
+ phone: str
115
114
 
116
- await db.get_key("key name") # => "Some text"
115
+
116
+ db = Scruby(
117
+ class_model=User,
118
+ db_name="ScrubyDB", # By default = "ScrubyDB"
119
+ )
120
+
121
+ user = User(
122
+ first_name="John",
123
+ last_name="Smith",
124
+ birthday=datetime.datetime(1970, 1, 1), # noqa: DTZ001
125
+ email="John_Smith@gmail.com",
126
+ phone="+447986123456",
127
+ )
128
+
129
+ await db.set_key("+447986123456", user)
130
+
131
+ await db.get_key("+447986123456") # => user
117
132
  await db.get_key("key missing") # => KeyError
118
133
 
119
- await db.has_key("key name") # => True
134
+ await db.has_key("+447986123456") # => True
120
135
  await db.has_key("key missing") # => False
121
136
 
122
- await db.delete_key("key name")
123
- await db.delete_key("key name") # => KeyError
137
+ await db.delete_key("+447986123456")
138
+ await db.delete_key("+447986123456") # => KeyError
124
139
  await db.delete_key("key missing") # => KeyError
125
140
 
126
141
  # Full database deletion.
@@ -0,0 +1,7 @@
1
+ scruby/__init__.py,sha256=TCxUjBI5A0KZcwvfmgaBVl8ScuzzOVvALl_T4iqSR9c,603
2
+ scruby/db.py,sha256=86e-U3IvNADoYhHv4PHGikqnH4KWVJEpu3d7oGuUc3s,4600
3
+ scruby/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ scruby-0.4.0.dist-info/METADATA,sha256=Oi3khca39iX9qdOuF-SEMtT6rkbESwDS8Wy3Zhjo8-o,6512
5
+ scruby-0.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
+ scruby-0.4.0.dist-info/licenses/LICENSE,sha256=2zZINd6m_jNYlowdQImlEizyhSui5cBAJZRhWQURcEc,1095
7
+ scruby-0.4.0.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- scruby/__init__.py,sha256=TCxUjBI5A0KZcwvfmgaBVl8ScuzzOVvALl_T4iqSR9c,603
2
- scruby/db.py,sha256=otENL-t7ie_8Fgzcteh2WsXFPu9pM4DBUdO_2GB1vwk,6565
3
- scruby/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- scruby-0.3.0.dist-info/METADATA,sha256=Dkz32lF7SmIWBEdXNhuhHQkYunAas6A84cEaVu08bYM,6256
5
- scruby-0.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
- scruby-0.3.0.dist-info/licenses/LICENSE,sha256=2zZINd6m_jNYlowdQImlEizyhSui5cBAJZRhWQURcEc,1095
7
- scruby-0.3.0.dist-info/RECORD,,
File without changes