scruby 2.3.0__py3-none-any.whl → 2.3.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.
scruby/cache.py CHANGED
@@ -67,7 +67,7 @@ class DocCache:
67
67
  for subclass in subclasses:
68
68
  collection_name: str = subclass.__name__
69
69
 
70
- # Create metadata for collection
70
+ # Create metadata for the collection if it is missing
71
71
  Metadata.create(collection_name)
72
72
 
73
73
  if HASH_REDUCE_LEFT == 0:
scruby/config.py CHANGED
@@ -27,7 +27,7 @@ import sys
27
27
  from typing import Any, ClassVar, Literal, Never, assert_never, final
28
28
  from uuid import uuid4
29
29
 
30
- from scruby.utils import add_to_env, get_from_env
30
+ from scruby.utils import Utils
31
31
 
32
32
 
33
33
  @final
@@ -77,10 +77,10 @@ class ScrubyConfig:
77
77
  delimiter: str = "/" if cls.sys_platform != "win32" else ""
78
78
  dotenv_path: str = f"{cls.db_root}{delimiter}.env.meta"
79
79
 
80
- db_id: str | None = get_from_env(
80
+ db_id: str | None = Utils.get_from_env(
81
81
  key=key,
82
82
  dotenv_path=dotenv_path,
83
- ) or add_to_env(
83
+ ) or Utils.add_to_env(
84
84
  key=key,
85
85
  value=str(uuid4())[:8],
86
86
  dotenv_path=dotenv_path,
@@ -116,10 +116,10 @@ class ScrubyConfig:
116
116
  delimiter: str = "/" if cls.sys_platform != "win32" else ""
117
117
  dotenv_path: str = f"{cls.db_root}{delimiter}.env.meta"
118
118
 
119
- hash_reduce_left: str | None = get_from_env(
119
+ hash_reduce_left: str | None = Utils.get_from_env(
120
120
  key=key,
121
121
  dotenv_path=dotenv_path,
122
- ) or add_to_env(
122
+ ) or Utils.add_to_env(
123
123
  key=key,
124
124
  value=str(cls.HASH_REDUCE_LEFT),
125
125
  dotenv_path=dotenv_path,
scruby/db.py CHANGED
@@ -40,12 +40,13 @@ class Scruby(
40
40
  self,
41
41
  class_model: Any,
42
42
  ) -> None:
43
- assert ScrubyModel in class_model.__bases__, (
44
- "Scruby => Argument `class_model` does not contain the base class `ScrubyModel`."
45
- )
46
- assert "key" in list(class_model.model_fields.keys()), (
47
- f"Model: {class_model.__name__} => The `key` field is missing."
48
- )
43
+ if __debug__:
44
+ if ScrubyModel not in class_model.__bases__:
45
+ msg = "Scruby => Argument `class_model` does not contain the base class `ScrubyModel`."
46
+ raise AssertionError(msg)
47
+ if "key" not in list(class_model.model_fields.keys()):
48
+ msg = f"Model: {class_model.__name__} => The `key` field is missing."
49
+ raise AssertionError(msg)
49
50
 
50
51
  super().__init__()
51
52
  self._class_model = class_model
@@ -191,11 +192,15 @@ class Scruby(
191
192
  Returns:
192
193
  None.
193
194
  """
194
- if __debug__ and plugins is not None:
195
- for plugin in plugins:
196
- if plugin.SCRUBY_VERSION != 2:
197
- msg = f"Plugin {plugin.__name__} does not apply to version 2."
198
- raise AssertionError(msg)
195
+ subclasses: list[Any] = ScrubyModel.__subclasses__()
196
+ if __debug__:
197
+ if len(subclasses) == 0:
198
+ raise AssertionError("Create least one model of document for your project.")
199
+ if plugins is not None:
200
+ for plugin in plugins:
201
+ if plugin.SCRUBY_VERSION != 2:
202
+ msg = f"Plugin {plugin.__name__} does not apply to version 2."
203
+ raise AssertionError(msg)
199
204
 
200
205
  ScrubyConfig.db_root = db_root
201
206
  ScrubyConfig.HASH_REDUCE_LEFT = hash_reduce_left
@@ -203,4 +208,4 @@ class Scruby(
203
208
  ScrubyConfig.plugins = plugins
204
209
  ScrubyConfig.init_params()
205
210
  ScrubyConfig.check_hash_reduce_left()
206
- DocCache.load_cache(ScrubyModel.__subclasses__())
211
+ DocCache.load_cache(subclasses)
scruby/utils.py CHANGED
@@ -2,10 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- __all__ = (
6
- "get_from_env",
7
- "add_to_env",
8
- )
5
+ __all__ = ("Utils",)
9
6
 
10
7
 
11
8
  from pathlib import Path
@@ -13,59 +10,68 @@ from pathlib import Path
13
10
  from dotenv import dotenv_values
14
11
 
15
12
 
16
- def get_from_env(
17
- key: str,
18
- dotenv_path: Path | str = ".env",
19
- ) -> str | None:
20
- """Get value by key from .env file.
21
-
22
- Returns:
23
- None
24
- """
25
- assert len(key) > 0, "`get_from_env` => `key` must not be the empty string."
26
-
27
- value: str | None = None
28
-
29
- if isinstance(dotenv_path, str):
30
- dotenv_path = Path(dotenv_path)
31
-
32
- if dotenv_path.exists():
33
- env_dict: dict[str, str | None] = dotenv_values(dotenv_path)
34
- value = env_dict.get(key)
35
-
36
- return value
37
-
38
-
39
- def add_to_env(
40
- key: str,
41
- value: str,
42
- dotenv_path: Path | str = ".env",
43
- ) -> str | None:
44
- """Add key-value to .env file.
45
-
46
- Returns:
47
- `value` or None
48
- """
49
- assert len(key) > 0, "`add_to_env` => `key` must not be the empty string."
50
- assert len(value) > 0, "`add_to_env` => `value` must not be the empty string."
51
-
52
- if isinstance(dotenv_path, str):
53
- assert len(dotenv_path) > 0, "`add_to_env` => `dotenv_path` must not be the empty string."
54
- dotenv_path = Path(dotenv_path)
55
-
56
- if dotenv_path.exists():
57
- env_dict: dict[str, str | None] = dotenv_values(dotenv_path)
58
- saved_value = env_dict.get(key)
59
- if saved_value is None:
60
- with dotenv_path.open("a+", encoding="utf-8") as env_file:
61
- content = f"\n{key}={value}"
62
- env_file.write(content)
13
+ class Utils:
14
+ """Set of helper methods."""
15
+
16
+ @staticmethod
17
+ def get_from_env(
18
+ key: str,
19
+ dotenv_path: Path | str = ".env",
20
+ ) -> str | None:
21
+ """Get value by key from .env file."""
22
+ assert len(key) > 0, "`get_from_env` => `key` must not be the empty string."
23
+
24
+ value: str | None = None
25
+
26
+ if isinstance(dotenv_path, str):
27
+ dotenv_path = Path(dotenv_path)
28
+
29
+ if dotenv_path.exists():
30
+ env_dict: dict[str, str | None] = dotenv_values(dotenv_path)
31
+ value = env_dict.get(key)
32
+
33
+ return value
34
+
35
+ @staticmethod
36
+ def add_to_env(
37
+ key: str,
38
+ value: str,
39
+ dotenv_path: Path | str = ".env",
40
+ ) -> str | None:
41
+ """Add key-value to .env file."""
42
+ assert len(key) > 0, "`add_to_env` => `key` must not be the empty string."
43
+ assert len(value) > 0, "`add_to_env` => `value` must not be the empty string."
44
+
45
+ if isinstance(dotenv_path, str):
46
+ assert len(dotenv_path) > 0, "`add_to_env` => `dotenv_path` must not be the empty string."
47
+ dotenv_path = Path(dotenv_path)
48
+
49
+ if dotenv_path.exists():
50
+ env_dict: dict[str, str | None] = dotenv_values(dotenv_path)
51
+ saved_value = env_dict.get(key)
52
+ if saved_value is None:
53
+ with dotenv_path.open("a+", encoding="utf-8") as env_file:
54
+ content = f"\n{key}={value}"
55
+ env_file.write(content)
56
+ else:
57
+ raise KeyError(f"`add_to_env` => Key `{key}` already exists.")
63
58
  else:
64
- raise KeyError(f"`add_to_env` => Key `{key}` already exists.")
65
- else:
66
- target_dir: str = "/".join(str(dotenv_path).split("/")[:-1])
67
- Path(target_dir).mkdir(parents=True, exist_ok=True)
68
- content = f"{key}={value}"
69
- dotenv_path.write_text(data=content, encoding="utf-8")
70
-
71
- return value
59
+ target_dir: str = "/".join(str(dotenv_path).split("/")[:-1])
60
+ Path(target_dir).mkdir(parents=True, exist_ok=True)
61
+ content = f"{key}={value}"
62
+ dotenv_path.write_text(data=content, encoding="utf-8")
63
+
64
+ return value
65
+
66
+ @staticmethod
67
+ def db_collection_list(db_root: Path | str) -> list[str] | None:
68
+ """Get a list of collections from a database directory."""
69
+ if isinstance(db_root, str):
70
+ assert len(db_root) > 0, "`add_to_env` => `dotenv_path` must not be the empty string."
71
+ db_root = Path(db_root)
72
+
73
+ directory_names: list[str] | None = None
74
+ if db_root.exists():
75
+ all_entries = Path.iterdir(db_root)
76
+ directory_names = [entry.name for entry in all_entries if entry.name != ".env.meta"] or None
77
+ return directory_names
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scruby
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: Asynchronous library for building and managing a hybrid database, by scheme of key-value.
5
5
  Project-URL: Bug Tracker, https://github.com/kebasyaty/scruby/issues
6
6
  Project-URL: Changelog, https://github.com/kebasyaty/scruby/blob/v2/CHANGELOG.md
@@ -90,13 +90,13 @@ Description-Content-Type: text/markdown
90
90
  <p>
91
91
  <b>Parameter `ScrubyConfig.HASH_REDUCE_LEFT - Scruby.run(hash_reduce_left = 7)`:</b>
92
92
  <br>
93
- 7 = 16 branches in collection (is default) -> ~16000+ docs, RAM ~2G+ (for development).
93
+ 7 = 16 branches in collection (is default) -> Docs: ~16000+, RAM: ~2G+, CPU: ~2G+ (for development).
94
94
  <br>
95
- 6 = 256 branches in collection -> ~256000+ docs, RAM ~4G+ (for small projects).
95
+ 6 = 256 branches in collection -> Docs: ~256000+, RAM: ~4G+, CPU: ~2G+ (for small projects).
96
96
  <br>
97
- 5 = 4096 branches in collection -> ~4096000+ docs, RAM ~6G+ (for large projects).
97
+ 5 = 4096 branches in collection -> Docs: ~4096000+, RAM: ~6G+, CPU: ~3G+ (for large projects).
98
98
  <br>
99
- 0 = 4294967296 branches in collection -> ~4,294967296×10¹²+ docs, RAM ~2G+ (access only by keys).
99
+ 0 = 4294967296 branches in collection -> Docs: ~4,294967296×10¹²+, RAM: ~2G+, CPU: ~2G+ (access only by keys).
100
100
  <br>
101
101
  <br>
102
102
  <b>If you notice the production server slowing down,</b><br>
@@ -1,13 +1,13 @@
1
1
  scruby/__init__.py,sha256=YIR8zFx0GmS8ha96-MU9yCgKeYNIh1K8idlQckfg21E,1324
2
2
  scruby/aggregation.py,sha256=NBFxQqyRqUG2KIuD9fbl4uzSHJWTaskjiZ1YNBa-Zbo,3575
3
- scruby/cache.py,sha256=wGnjuFlpA3sRGfp4vv3o3nXR_tOC8HtuzFv1TyrKEyk,3997
4
- scruby/config.py,sha256=INAFqNAeF8BifIywjElC97rawfTLuqpRfieUdAO7A6k,5122
5
- scruby/db.py,sha256=3erS6kDcjNy6KBx_8x58P6lI_2DzaIkYg3DK5_NQ_iY,6796
3
+ scruby/cache.py,sha256=j_uRBF72p7kzUK6GMHIIqb8nM2RneCod45dbbI1KTjQ,4018
4
+ scruby/config.py,sha256=oyBEOzmKy9vka23ZDvP8Jqu-HMYn8HCmJ0j2TfOs-0w,5127
5
+ scruby/db.py,sha256=oulRx20bezbv2IwcsDq6TgsXo_zQz8ZE6ohmWg4kv2k,7107
6
6
  scruby/errors.py,sha256=lTWiHzyO5Es9Nkf7quODJjONGn6ifcL95qlpA4epQQM,1386
7
7
  scruby/meta.py,sha256=dfr8q3TWhVcEl-lZuH5yd9rbO9vAPBhXBO3VYCNcOWo,1283
8
8
  scruby/model.py,sha256=1infUd1G-zxj5Z93mNOp1Wi2anD6TKDgu5Y0KEVcH2k,292
9
9
  scruby/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- scruby/utils.py,sha256=ZwWxSyh_BAOQkXlIqXFOlX2lHVk9rfYGQiVqtTk8PpE,1865
10
+ scruby/utils.py,sha256=fCBBrp-tgRKh4bukjWRUQhkOsNCxGN4lbXcymBqCsbE,2587
11
11
  scruby/mixins/__init__.py,sha256=nT79e80zXliuTGhR9CFosI2-3PQUCKwXbR7wPiFwgrU,669
12
12
  scruby/mixins/collection.py,sha256=3Gn9zIT-WnSCBd-IgpE9tobRlW675YX__qaWoUOWIJM,1758
13
13
  scruby/mixins/count.py,sha256=CGpyOpsG25uC5utI2ByNxq2iTbJocj6w5tXrC1_cP40,2561
@@ -16,8 +16,8 @@ scruby/mixins/delete.py,sha256=InKVIud_ZYx9-CchUz_IygQDXMynNi4jQ0HKYeHC_R8,4328
16
16
  scruby/mixins/find.py,sha256=oEZRE6RqIBdwvNr8iSYyod8hI6ibi_egJP0pyXmJiss,9169
17
17
  scruby/mixins/keys.py,sha256=MvBy_8fQGROaQATK2qse2V8wR-xodPQG0KKZ2PK_t9U,10790
18
18
  scruby/mixins/update.py,sha256=TyxvxB-gNijlfzTmhwrq0ydvu0C3R-RihW5h5tJ96bM,4964
19
- scruby-2.3.0.dist-info/METADATA,sha256=mtGCSIcs5Ah_xokLG3OnmnjDJGeDGBSFp0iNNT8DxUk,13382
20
- scruby-2.3.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
21
- scruby-2.3.0.dist-info/licenses/GPL-3.0-LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
22
- scruby-2.3.0.dist-info/licenses/MIT-LICENSE,sha256=mS0Wz0yGNB63gEcWEnuIb_lldDYV0sjRaO-o_GL6CWE,1074
23
- scruby-2.3.0.dist-info/RECORD,,
19
+ scruby-2.3.2.dist-info/METADATA,sha256=MdIGXw69UNrbUb6I-2lecMGvekaPun_-Bf9ksHkV0us,13434
20
+ scruby-2.3.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
21
+ scruby-2.3.2.dist-info/licenses/GPL-3.0-LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
22
+ scruby-2.3.2.dist-info/licenses/MIT-LICENSE,sha256=mS0Wz0yGNB63gEcWEnuIb_lldDYV0sjRaO-o_GL6CWE,1074
23
+ scruby-2.3.2.dist-info/RECORD,,
File without changes