ramifice 0.8.26__py3-none-any.whl → 0.8.28__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.
Files changed (53) hide show
  1. ramifice/commons/many.py +4 -8
  2. ramifice/commons/one.py +1 -3
  3. ramifice/commons/tools.py +1 -5
  4. ramifice/commons/unit_manager.py +2 -4
  5. ramifice/fields/choice_float_field.py +2 -5
  6. ramifice/fields/choice_float_mult_field.py +3 -8
  7. ramifice/fields/choice_int_field.py +2 -5
  8. ramifice/fields/choice_int_mult_field.py +3 -8
  9. ramifice/fields/choice_text_field.py +3 -8
  10. ramifice/fields/choice_text_mult_field.py +3 -8
  11. ramifice/fields/color_field.py +1 -3
  12. ramifice/fields/date_field.py +1 -3
  13. ramifice/fields/date_time_field.py +1 -3
  14. ramifice/fields/email_field.py +2 -4
  15. ramifice/fields/file_field.py +4 -6
  16. ramifice/fields/float_field.py +3 -5
  17. ramifice/fields/general/choice_group.py +1 -3
  18. ramifice/fields/general/date_group.py +1 -2
  19. ramifice/fields/general/field.py +2 -4
  20. ramifice/fields/general/file_group.py +1 -3
  21. ramifice/fields/general/number_group.py +1 -3
  22. ramifice/fields/general/text_group.py +1 -3
  23. ramifice/fields/image_field.py +6 -12
  24. ramifice/fields/integer_field.py +3 -5
  25. ramifice/fields/ip_field.py +2 -4
  26. ramifice/fields/phone_field.py +2 -4
  27. ramifice/fields/slug_field.py +1 -1
  28. ramifice/fields/url_field.py +1 -3
  29. ramifice/models/decorator.py +3 -5
  30. ramifice/models/model.py +5 -7
  31. ramifice/paladins/add_valid.py +3 -2
  32. ramifice/paladins/check.py +6 -8
  33. ramifice/paladins/groups/date_group.py +1 -3
  34. ramifice/paladins/groups/file_group.py +1 -3
  35. ramifice/paladins/groups/img_group.py +1 -3
  36. ramifice/paladins/groups/num_group.py +2 -6
  37. ramifice/paladins/groups/slug_group.py +1 -1
  38. ramifice/paladins/groups/text_group.py +2 -2
  39. ramifice/paladins/hooks.py +8 -2
  40. ramifice/paladins/indexing.py +3 -2
  41. ramifice/paladins/save.py +4 -10
  42. ramifice/paladins/validation.py +9 -9
  43. ramifice/utils/constants.py +1 -1
  44. ramifice/utils/fixtures.py +4 -4
  45. ramifice/utils/migration.py +10 -21
  46. ramifice/utils/tools.py +1 -1
  47. ramifice/utils/translations.py +1 -1
  48. ramifice/utils/unit.py +3 -6
  49. {ramifice-0.8.26.dist-info → ramifice-0.8.28.dist-info}/METADATA +2 -1
  50. ramifice-0.8.28.dist-info/RECORD +83 -0
  51. ramifice-0.8.26.dist-info/RECORD +0 -83
  52. {ramifice-0.8.26.dist-info → ramifice-0.8.28.dist-info}/WHEEL +0 -0
  53. {ramifice-0.8.26.dist-info → ramifice-0.8.28.dist-info}/licenses/LICENSE +0 -0
ramifice/models/model.py CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  __all__ = ("Model",)
4
4
 
5
- from abc import ABCMeta, abstractmethod
6
- from typing import Any
5
+ from abc import abstractmethod
6
+ from typing import Any, ClassVar
7
7
 
8
8
  import orjson
9
9
  from babel.dates import format_date, format_datetime
@@ -15,10 +15,10 @@ from ramifice.fields import DateTimeField, IDField
15
15
  from ramifice.utils import translations
16
16
 
17
17
 
18
- class Model(metaclass=ABCMeta):
18
+ class Model:
19
19
  """Converting Python Class into Ramifice Model."""
20
20
 
21
- META: dict[str, Any] = {}
21
+ META: ClassVar[dict[str, Any]] = {}
22
22
 
23
23
  def __init__(self) -> None: # noqa: D107
24
24
  _ = translations._
@@ -81,9 +81,7 @@ class Model(metaclass=ABCMeta):
81
81
  if "Dyn" in f_type.field_type:
82
82
  dyn_data = data_dynamic_fields[f_name]
83
83
  if dyn_data is not None:
84
- f_type.choices = [
85
- [item["value"], item["title"][lang]] for item in dyn_data
86
- ]
84
+ f_type.choices = [[item["value"], item["title"][lang]] for item in dyn_data]
87
85
  else:
88
86
  # This is necessary for
89
87
  # `paladins > refrash > RefrashMixin > refrash_from_db`.
@@ -2,14 +2,15 @@
2
2
 
3
3
  __all__ = ("AddValidMixin",)
4
4
 
5
- from abc import ABCMeta
5
+ from abc import abstractmethod
6
6
 
7
7
  from xloft import NamedTuple
8
8
 
9
9
 
10
- class AddValidMixin(metaclass=ABCMeta):
10
+ class AddValidMixin:
11
11
  """Contains an abstract method for additional validation of fields."""
12
12
 
13
+ @abstractmethod
13
14
  async def add_validation(self) -> NamedTuple:
14
15
  """Additional validation of fields."""
15
16
  return NamedTuple()
@@ -80,9 +80,7 @@ class CheckMixin(
80
80
  "field_data": None,
81
81
  "full_model_name": cls_model.META["full_model_name"],
82
82
  "is_migration_process": is_migration_process,
83
- "curr_doc": (
84
- await collection.find_one({"_id": doc_id}) if is_save and is_update else None
85
- ),
83
+ "curr_doc": (await collection.find_one({"_id": doc_id}) if is_save and is_update else None),
86
84
  }
87
85
 
88
86
  # Run checking fields.
@@ -168,8 +166,8 @@ class CheckMixin(
168
166
  if img_data is not None:
169
167
  img_data["is_new_img"] = False
170
168
  #
171
- return dict(
172
- data=result_map,
173
- is_valid=not params["is_error_symptom"],
174
- is_update=is_update,
175
- )
169
+ return {
170
+ "data": result_map,
171
+ "is_valid": not params["is_error_symptom"],
172
+ "is_update": is_update,
173
+ }
@@ -105,9 +105,7 @@ class DateGroupMixin:
105
105
  locale=translations.CURRENT_LOCALE,
106
106
  )
107
107
  )
108
- err_msg = translations._(
109
- "The date %s must not be less than min=%s !" % value_str, min_date_str
110
- )
108
+ err_msg = translations._("The date %s must not be less than min=%s !" % value_str, min_date_str)
111
109
  accumulate_error(err_msg, params)
112
110
  # Insert result.
113
111
  if params["is_save"]:
@@ -66,9 +66,7 @@ class FileGroupMixin:
66
66
  return
67
67
  # Accumulate an error if the file size exceeds the maximum value.
68
68
  if value["size"] > field.max_size:
69
- err_msg = translations._(
70
- "File size exceeds the maximum value %s !" % to_human_size(field.max_size)
71
- )
69
+ err_msg = translations._("File size exceeds the maximum value %s !" % to_human_size(field.max_size))
72
70
  accumulate_error(err_msg, params)
73
71
  return
74
72
  # Insert result.
@@ -66,9 +66,7 @@ class ImgGroupMixin:
66
66
  return
67
67
  # Accumulate an error if the file size exceeds the maximum value.
68
68
  if value["size"] > field.max_size:
69
- err_msg = translations._(
70
- "Image size exceeds the maximum value %s !" % to_human_size(field.max_size)
71
- )
69
+ err_msg = translations._("Image size exceeds the maximum value %s !" % to_human_size(field.max_size))
72
70
  accumulate_error(err_msg, params)
73
71
  return
74
72
  # Create thumbnails.
@@ -49,16 +49,12 @@ class NumGroupMixin:
49
49
  # Validation the `max_number` field attribute.
50
50
  max_number = field.max_number
51
51
  if max_number is not None and value > max_number:
52
- err_msg = translations._(
53
- "The value %d must not be greater than max=%d !" % value, max_number
54
- )
52
+ err_msg = translations._("The value %d must not be greater than max=%d !" % value, max_number)
55
53
  accumulate_error(err_msg, params)
56
54
  # Validation the `min_number` field attribute.
57
55
  min_number = field.min_number
58
56
  if min_number is not None and value < min_number:
59
- err_msg = translations._(
60
- "The value %d must not be less than min=%d !" % value, min_number
61
- )
57
+ err_msg = translations._("The value %d must not be less than min=%d !" % value, min_number)
62
58
  accumulate_error(err_msg, params)
63
59
  # Validation the `unique` field attribute.
64
60
  if field.unique and not await check_uniqueness(value, params, field_name):
@@ -66,7 +66,7 @@ class SlugGroupMixin:
66
66
  err_msg = (
67
67
  f"Model: `{params['full_model_name']}` > "
68
68
  + f"Field: `{field_name}` > "
69
- + f"Parameter: `slug_sources` => "
69
+ + "Parameter: `slug_sources` => "
70
70
  + "At least one field should be unique!"
71
71
  )
72
72
  logger.critical(err_msg)
@@ -102,11 +102,11 @@ class TextGroupMixin:
102
102
  # Insert result.
103
103
  if params["is_save"]:
104
104
  if is_multi_language:
105
- mult_lang_text: dict[str, str] = (
105
+ mult_lang_text = (
106
106
  params["curr_doc"][field_name]
107
107
  if params["is_update"]
108
108
  else (
109
- {lang: value for lang in translations.LANGUAGES}
109
+ dict.fromkeys(translations.LANGUAGES)
110
110
  if isinstance(value, str)
111
111
  else {lang: value.get(lang, "- -") for lang in translations.LANGUAGES}
112
112
  )
@@ -2,26 +2,32 @@
2
2
 
3
3
  __all__ = ("HooksMixin",)
4
4
 
5
- from abc import ABCMeta
5
+ from abc import abstractmethod
6
6
 
7
7
 
8
- class HooksMixin(metaclass=ABCMeta):
8
+ class HooksMixin:
9
9
  """A set of abstract methods for creating hooks."""
10
10
 
11
+ @abstractmethod
11
12
  async def pre_create(self) -> None:
12
13
  """Called before a new document is created in the database."""
13
14
 
15
+ @abstractmethod
14
16
  async def post_create(self) -> None:
15
17
  """Called after a new document has been created in the database."""
16
18
 
19
+ @abstractmethod
17
20
  async def pre_update(self) -> None:
18
21
  """Called before updating an existing document in the database."""
19
22
 
23
+ @abstractmethod
20
24
  async def post_update(self) -> None:
21
25
  """Called after an existing document in the database is updated."""
22
26
 
27
+ @abstractmethod
23
28
  async def pre_delete(self) -> None:
24
29
  """Called before deleting an existing document in the database."""
25
30
 
31
+ @abstractmethod
26
32
  async def post_delete(self) -> None:
27
33
  """Called after an existing document in the database has been deleted."""
@@ -2,12 +2,13 @@
2
2
 
3
3
  __all__ = ("IndexMixin",)
4
4
 
5
- from abc import ABCMeta
5
+ from abc import abstractmethod
6
6
 
7
7
 
8
- class IndexMixin(metaclass=ABCMeta):
8
+ class IndexMixin:
9
9
  """Contains the method for indexing the model in the database."""
10
10
 
11
11
  @classmethod
12
+ @abstractmethod
12
13
  async def indexing(cls) -> None:
13
14
  """Set up and start indexing."""
ramifice/paladins/save.py CHANGED
@@ -46,7 +46,7 @@ class SaveMixin:
46
46
  # Create or update a document in database.
47
47
  if result_check["is_update"]:
48
48
  # Update date and time.
49
- checked_data["updated_at"] = datetime.now()
49
+ checked_data["updated_at"] = datetime.now() # noqa: DTZ005
50
50
  # Run hook.
51
51
  await self.pre_update()
52
52
  # Update doc.
@@ -54,9 +54,7 @@ class SaveMixin:
54
54
  # Run hook.
55
55
  await self.post_update()
56
56
  # Refresh Model.
57
- mongo_doc: dict[str, Any] | None = await collection.find_one(
58
- {"_id": checked_data["_id"]}
59
- )
57
+ mongo_doc: dict[str, Any] | None = await collection.find_one({"_id": checked_data["_id"]})
60
58
  if mongo_doc is None:
61
59
  msg = (
62
60
  f"Model: `{self.full_model_name()}` > "
@@ -68,7 +66,7 @@ class SaveMixin:
68
66
  refresh_from_mongo_doc(self, mongo_doc)
69
67
  else:
70
68
  # Add date and time.
71
- today = datetime.now()
69
+ today = datetime.now() # noqa: DTZ005
72
70
  checked_data["created_at"] = today
73
71
  checked_data["updated_at"] = today
74
72
  # Run hook.
@@ -80,11 +78,7 @@ class SaveMixin:
80
78
  # Refresh Model.
81
79
  mongo_doc = await collection.find_one({"_id": checked_data["_id"]})
82
80
  if mongo_doc is None:
83
- msg = (
84
- f"Model: `{self.full_model_name()}` > "
85
- + "Method: `save` => "
86
- + "The document was not created."
87
- )
81
+ msg = f"Model: `{self.full_model_name()}` > " + "Method: `save` => " + "The document was not created."
88
82
  logger.critical(msg)
89
83
  raise PanicError(msg)
90
84
  refresh_from_mongo_doc(self, mongo_doc)
@@ -31,19 +31,19 @@ class ValidationMixin:
31
31
  if len(field_data.errors) > 0:
32
32
  # title
33
33
  if not is_err:
34
- print(colored("\nERRORS:", "red", attrs=["bold"]))
35
- print(colored("Model: ", "blue", attrs=["bold"]), end="")
36
- print(colored(f"`{self.full_model_name()}`", "blue"))
34
+ print(colored("\nERRORS:", "red", attrs=["bold"])) # noqa: T201
35
+ print(colored("Model: ", "blue", attrs=["bold"]), end="") # noqa: T201
36
+ print(colored(f"`{self.full_model_name()}`", "blue")) # noqa: T201
37
37
  is_err = True
38
38
  # field name
39
- print(colored("Field: ", "green", attrs=["bold"]), end="")
40
- print(colored(f"`{field_name}`:", "green"))
39
+ print(colored("Field: ", "green", attrs=["bold"]), end="") # noqa: T201
40
+ print(colored(f"`{field_name}`:", "green")) # noqa: T201
41
41
  # error messages
42
- print(colored("\n".join(field_data.errors), "red"))
42
+ print(colored("\n".join(field_data.errors), "red")) # noqa: T201
43
43
  if len(self._id.alerts) > 0:
44
44
  # title
45
- print(colored("AlERTS:", "yellow", attrs=["bold"]))
45
+ print(colored("AlERTS:", "yellow", attrs=["bold"])) # noqa: T201
46
46
  # messages
47
- print(colored("\n".join(self._id.alerts), "yellow"), end="\n\n")
47
+ print(colored("\n".join(self._id.alerts), "yellow"), end="\n\n") # noqa: T201
48
48
  else:
49
- print(end="\n\n")
49
+ print(end="\n\n") # noqa: T201
@@ -64,7 +64,7 @@ REGEX: dict[str, re.Pattern] = {
64
64
  "model_name": re.compile(r"^[A-Z][a-zA-Z0-9]{0,24}$"),
65
65
  "color_code": re.compile(
66
66
  r"^(?:#|0x)(?:[a-f0-9]{3}|[a-f0-9]{6}|[a-f0-9]{8})\b|(?:rgb|hsl)a?\([^\)]*\)$",
67
- re.I,
67
+ re.I, # noqa: FURB167
68
68
  ),
69
69
  "password": re.compile(r'^[-._!"`\'#%&,:;<>=@{}~\$\(\)\*\+\/\\\?\[\]\^\|a-zA-Z0-9]{8,256}$'),
70
70
  }
@@ -31,7 +31,7 @@ async def apply_fixture(
31
31
  fixture_path: str = f"config/fixtures/{fixture_name}.yml"
32
32
  data_yaml: dict[str, Any] | list[dict[str, Any]] | None = None
33
33
 
34
- with open(fixture_path, "r") as file:
34
+ with open(fixture_path) as file:
35
35
  data_yaml = yaml.safe_load(file)
36
36
 
37
37
  if not bool(data_yaml):
@@ -71,8 +71,8 @@ async def apply_fixture(
71
71
  # If the check fails.
72
72
  if not result_check["is_valid"]:
73
73
  await collection.database.drop_collection(collection.name)
74
- print(colored("\nFIXTURE:", "red", attrs=["bold"]))
75
- print(colored(fixture_path, "blue", attrs=["bold"]))
74
+ print(colored("\nFIXTURE:", "red", attrs=["bold"])) # noqa: T201
75
+ print(colored(fixture_path, "blue", attrs=["bold"])) # noqa: T201
76
76
  inst_model.print_err()
77
77
  msg = f"Fixture `{fixture_name}` failed."
78
78
  logger.critical(msg)
@@ -80,7 +80,7 @@ async def apply_fixture(
80
80
  # Get data for document.
81
81
  checked_data: dict[str, Any] = result_check["data"]
82
82
  # Add date and time.
83
- today = datetime.now()
83
+ today = datetime.now() # noqa: DTZ005
84
84
  checked_data["created_at"] = today
85
85
  checked_data["updated_at"] = today
86
86
  # Run hook.
@@ -52,9 +52,7 @@ class Migration:
52
52
  """
53
53
  # Get access to super collection.
54
54
  # (Contains Model state and dynamic field data.)
55
- super_collection: AsyncCollection = constants.MONGO_DATABASE[
56
- constants.SUPER_COLLECTION_NAME
57
- ]
55
+ super_collection: AsyncCollection = constants.MONGO_DATABASE[constants.SUPER_COLLECTION_NAME]
58
56
  # Switch the `is_model_exist` parameter in `False`.
59
57
  async for model_state in super_collection.find():
60
58
  q_filter = {"collection_name": model_state["collection_name"]}
@@ -65,12 +63,10 @@ class Migration:
65
63
  """Get the state of the current model from a super collection."""
66
64
  # Get access to super collection.
67
65
  # (Contains Model state and dynamic field data.)
68
- super_collection: AsyncCollection = constants.MONGO_DATABASE[
69
- constants.SUPER_COLLECTION_NAME
70
- ]
66
+ super_collection: AsyncCollection = constants.MONGO_DATABASE[constants.SUPER_COLLECTION_NAME]
71
67
  # Get state of current Model.
72
68
  model_state: dict[str, Any] | None = await super_collection.find_one(
73
- {"collection_name": metadata["collection_name"]}
69
+ {"collection_name": metadata["collection_name"]},
74
70
  )
75
71
  if model_state is not None:
76
72
  model_state["is_model_exist"] = True
@@ -102,9 +98,7 @@ class Migration:
102
98
  database = constants.MONGO_DATABASE
103
99
  # Get access to super collection.
104
100
  # (Contains Model state and dynamic field data.)
105
- super_collection: AsyncCollection = constants.MONGO_DATABASE[
106
- constants.SUPER_COLLECTION_NAME
107
- ]
101
+ super_collection: AsyncCollection = constants.MONGO_DATABASE[constants.SUPER_COLLECTION_NAME]
108
102
  # Delete data for non-existent Models.
109
103
  async for model_state in super_collection.find():
110
104
  if model_state["is_model_exist"] is False:
@@ -172,7 +166,7 @@ class Migration:
172
166
  is_migration_process=True,
173
167
  )
174
168
  if not result_check["is_valid"]:
175
- print(colored("\n!!!>>MIGRATION<<!!!", "red", attrs=["bold"]))
169
+ print(colored("\n!!!>>MIGRATION<<!!!", "red", attrs=["bold"])) # noqa: T201
176
170
  inst_model.print_err()
177
171
  msg: str = "Migration failed."
178
172
  logger.critical(msg)
@@ -183,12 +177,11 @@ class Migration:
183
177
  for field_name, field_type in metadata["field_name_and_type"].items():
184
178
  if (
185
179
  field_type == "PasswordField"
186
- and model_state["field_name_and_type"].get(field_name)
187
- == "PasswordField"
180
+ and model_state["field_name_and_type"].get(field_name) == "PasswordField"
188
181
  ):
189
182
  checked_data[field_name] = mongo_doc[field_name]
190
183
  # Update date and time.
191
- checked_data["updated_at"] = datetime.now()
184
+ checked_data["updated_at"] = datetime.now() # noqa: DTZ005
192
185
  # Update the document in the database.
193
186
  await model_collection.replace_one(
194
187
  filter={"_id": checked_data["_id"]},
@@ -197,12 +190,10 @@ class Migration:
197
190
  #
198
191
  # Refresh the dynamic fields data for the current model.
199
192
  for field_name, field_data in metadata["data_dynamic_fields"].items():
200
- if model_state["data_dynamic_fields"].get(field_name, False) == False:
193
+ if model_state["data_dynamic_fields"].get(field_name, False) == False: # noqa: E712
201
194
  model_state["data_dynamic_fields"][field_name] = field_data
202
195
  else:
203
- metadata["data_dynamic_fields"][field_name] = model_state[
204
- "data_dynamic_fields"
205
- ][field_name]
196
+ metadata["data_dynamic_fields"][field_name] = model_state["data_dynamic_fields"][field_name]
206
197
  # Refresh state of current Model.
207
198
  model_state["data_dynamic_fields"] = metadata["data_dynamic_fields"]
208
199
  model_state["field_name_and_type"] = metadata["field_name_and_type"]
@@ -224,9 +215,7 @@ class Migration:
224
215
  # Apply fixture to current Model.
225
216
  fixture_name: str | None = cls_model.META["fixture_name"]
226
217
  if fixture_name is not None:
227
- collection: AsyncCollection = constants.MONGO_DATABASE[
228
- cls_model.META["collection_name"]
229
- ]
218
+ collection: AsyncCollection = constants.MONGO_DATABASE[cls_model.META["collection_name"]]
230
219
  if await collection.estimated_document_count() == 0:
231
220
  await apply_fixture(
232
221
  fixture_name=fixture_name,
ramifice/utils/tools.py CHANGED
@@ -37,7 +37,7 @@ def is_password(password: str | None) -> bool:
37
37
 
38
38
  def to_human_size(size: int) -> str:
39
39
  """Convert number of bytes to readable format."""
40
- idx = int(math.floor(math.log(size) / math.log(1024)))
40
+ idx = int(math.floor(math.log(size) / math.log(1024))) # noqa: RUF046
41
41
  size = size if size < 1024 else abs(round(size / pow(1024, idx), 2))
42
42
  order = ["bytes", "KB", "MB", "GB", "TB"][idx]
43
43
  return f"{size} {order}"
@@ -57,7 +57,7 @@ def add_languages(
57
57
  ) -> None:
58
58
  """Add languages."""
59
59
  global DEFAULT_LOCALE, LANGUAGES
60
- if not default_locale in languages:
60
+ if default_locale not in languages:
61
61
  msg = "DEFAULT_LOCALE is not included in the LANGUAGES!"
62
62
  logger.critical(msg)
63
63
  raise PanicError(msg)
ramifice/utils/unit.py CHANGED
@@ -32,16 +32,13 @@ class Unit(JsonMixin):
32
32
  msg = "Class: `Unit` > Field: `field` => Not а `str` type!"
33
33
  raise PanicError(msg)
34
34
  if not isinstance(title, dict):
35
- msg = (
36
- "Class: `Unit` > Field: `title` => Not а `str` type! "
37
- + 'Example: {"en": "Title", "ru": "Заголовок"}'
38
- )
35
+ msg = "Class: `Unit` > Field: `title` => Not а `str` type! " + 'Example: {"en": "Title", "ru": "Заголовок"}'
39
36
  raise PanicError(msg)
40
37
  if not isinstance(value, (float, int, str)):
41
- msg = "Class: `Unit` > Field: `value` => Not а `float | int | str` type!"
38
+ msg = "Class: `Unit` > Field: `value` => Not a `float | int | str` type!"
42
39
  raise PanicError(msg)
43
40
  if not isinstance(is_delete, bool):
44
- msg = "Class: `Unit` > Field: `is_delete` => Not а `bool` type!"
41
+ msg = "Class: `Unit` > Field: `is_delete` => Not a `bool` type!"
45
42
  raise PanicError(msg)
46
43
 
47
44
  JsonMixin.__init__(self)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramifice
3
- Version: 0.8.26
3
+ Version: 0.8.28
4
4
  Summary: ORM-pseudo-like API MongoDB for Python language.
5
5
  Project-URL: Homepage, https://github.com/kebasyaty/ramifice
6
6
  Project-URL: Documentation, https://kebasyaty.github.io/ramifice/
@@ -60,6 +60,7 @@ Description-Content-Type: text/markdown
60
60
  <a href="https://github.com/kebasyaty/ramifice/issues"><img src="https://img.shields.io/github/issues/kebasyaty/ramifice.svg" alt="GitHub issues"></a>
61
61
  <a href="https://pepy.tech/projects/ramifice"><img src="https://static.pepy.tech/badge/ramifice" alt="PyPI Downloads"></a>
62
62
  <a href="https://github.com/kebasyaty/ramifice/blob/main/LICENSE" alt="GitHub license"><img src="https://img.shields.io/github/license/kebasyaty/ramifice" alt="GitHub license"></a>
63
+ <a href="https://mypy-lang.org/" alt="Types: Mypy"><img src="https://img.shields.io/badge/types-Mypy-202235.svg?color=0c7ebf" alt="Types: Mypy"></a>
63
64
  <a href="https://docs.astral.sh/ruff/" alt="Code style: Ruff"><img src="https://img.shields.io/badge/code%20style-Ruff-FDD835.svg" alt="Code style: Ruff"></a>
64
65
  <a href="https://github.com/kebasyaty/ramifice" alt="PyPI implementation"><img src="https://img.shields.io/pypi/implementation/ramifice" alt="PyPI implementation"></a>
65
66
  <a href="https://github.com/kebasyaty/ramifice" alt="GitHub repository"><img src="https://img.shields.io/badge/--ecebeb?logo=github&logoColor=000000" alt="GitHub repository"></a>
@@ -0,0 +1,83 @@
1
+ ramifice/__init__.py,sha256=rTkA9TUWsis-q056oslAcalr3rwNChMUcpQX5Q43Pzs,1520
2
+ ramifice/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ ramifice/commons/__init__.py,sha256=HwOckqlNkt4OzFbYqnLw9x0VXLbwO_mJaJ9MLYgSvtI,545
4
+ ramifice/commons/general.py,sha256=ZryiRH-qf_cH9HCul7EP11UU-k4YO_rp_kku2FWAwj4,5433
5
+ ramifice/commons/indexes.py,sha256=dBPVYeJGbEyENLEzGjQmQ2XYOr3qqzjonj6zyH4rl54,3696
6
+ ramifice/commons/many.py,sha256=sirqV6oEPMaBlYc8UvReLUQtwvbhr5d2V1kYQ-xpK8o,9378
7
+ ramifice/commons/one.py,sha256=Ppq7vZpmvcfnpurgH3rXSix1KUUwDHYeJQqKkqedE14,6955
8
+ ramifice/commons/tools.py,sha256=o0o-0W7VDAMPiEOWF9Du7W7py94fCLFx8KJc7LM6HP4,2423
9
+ ramifice/commons/unit_manager.py,sha256=OCDh8Ms-zCYgHEwwyXp83qYDmRBSgkkAnZiJHSuEGm8,4945
10
+ ramifice/fields/__init__.py,sha256=hjqCZG_kKsHdHtSd05vHn9SiFpk-YSvKEsVFaXim5Sw,2360
11
+ ramifice/fields/bool_field.py,sha256=d3sKQWMAfEycgtBIhIIov2XVoqLbN8th8i3H7YLrNdg,2769
12
+ ramifice/fields/choice_float_dyn_field.py,sha256=e-i7CtmDVqWzRJJ5Pq4PmI69riHDPx9NX51h2qFsjEE,3912
13
+ ramifice/fields/choice_float_field.py,sha256=2XyMkRa6uxc9q5cxB89upoCqaUaUqZ39BLLYcE9Hmc8,4811
14
+ ramifice/fields/choice_float_mult_dyn_field.py,sha256=45nr0FoY9roO2pJ0FfzBIMu6ih5cl7_3NyKVwtUAHrA,3979
15
+ ramifice/fields/choice_float_mult_field.py,sha256=lvcSWEwYFOuxpPect3kRh6QnDGfzB2Y0JkODmhfurQo,5121
16
+ ramifice/fields/choice_int_dyn_field.py,sha256=qUAZivbZSmGYhoPo-vu9P0psEjj-ZtUWjmjYv9GY6yc,3904
17
+ ramifice/fields/choice_int_field.py,sha256=e0E2P1s21918KeYaKQrMsYb64QXztdcBiHzH7J6cLEw,4797
18
+ ramifice/fields/choice_int_mult_dyn_field.py,sha256=QajFttWuw5Z_S_ik48zev83tVIiPOgHjzPFnxmkO_e4,3973
19
+ ramifice/fields/choice_int_mult_field.py,sha256=Aet8kmD8tmHk0IF13P4LTTpAQwKX8f7YwhkJSMVf3TI,5113
20
+ ramifice/fields/choice_text_dyn_field.py,sha256=H_BGtTuNNGJdXDZmGGPpi-7c0GtDGJwkyNFbKScLs28,3895
21
+ ramifice/fields/choice_text_field.py,sha256=Kkm_CZCNXlMH9_brp0bR93ByPUU0R8MKsleVvdrc6nc,4957
22
+ ramifice/fields/choice_text_mult_dyn_field.py,sha256=OrPZ-y2ihcJeLkTWJrcPgMijedq_5czbPEmISg1HdWU,3964
23
+ ramifice/fields/choice_text_mult_field.py,sha256=H3qp6B4Rw81FEycmBJ9wiwhTQc_hlE5TmRZJNj_Z-yc,5104
24
+ ramifice/fields/color_field.py,sha256=Q1ZezPW6Jl-9olKCx47pMdHTCauBY_lwoudxIhZpAgw,4449
25
+ ramifice/fields/date_field.py,sha256=svJjb6KgsmpW4RO8y3Opkh2uFwwSVfzyeb7nd5tNXLs,6267
26
+ ramifice/fields/date_time_field.py,sha256=jINGK1VrRt1boXmjJb6_WU7G7h_qnbUSolKNFOtVXFg,6324
27
+ ramifice/fields/email_field.py,sha256=joReU6YV-ViewMiRVvHozVjIhXuPMwxA-cmqwR5kkHY,4389
28
+ ramifice/fields/file_field.py,sha256=dAsOYXPjMNwC_t8jCyoNEwlRAsGEd9V_tiuix0qTukU,9476
29
+ ramifice/fields/float_field.py,sha256=0OjoR9nwDs-Isv_lJoAT_jtdKmnd7-MqltCUiCViups,5796
30
+ ramifice/fields/id_field.py,sha256=36VroZIgCH6uKuYjjWTXIycZ06ZGy4reLX6FhMUphCI,4757
31
+ ramifice/fields/image_field.py,sha256=dZOB8ctt-7KeB-ePDwgeIgpNP6tLfnxWBU_E5_6dApc,12855
32
+ ramifice/fields/integer_field.py,sha256=WKzmy-v2uLmIYlrTwcmuoUGfjWQhGD9wHukfQ0fUipk,5770
33
+ ramifice/fields/ip_field.py,sha256=GjDo1g5PEolqb8_AcDqgE_BnTITqew2rZcqmEn3S5WA,4293
34
+ ramifice/fields/password_field.py,sha256=lKELnyIjlAIJWeCR_3BCa0ZL5R0L73cf9zimigIgN3g,3902
35
+ ramifice/fields/phone_field.py,sha256=neaa9sCLtQR5zr0eiF6CkoSHIif2h2j01DY_VDgpNzk,4580
36
+ ramifice/fields/slug_field.py,sha256=wJtyf5LWP5pxw6G91_sYSs02QY7kvLYyB1_99_6gz5o,3552
37
+ ramifice/fields/text_field.py,sha256=fBVxBzHwj7R0TiSXnidqA5XHJdEz16WShT6TGjC-B6g,5299
38
+ ramifice/fields/url_field.py,sha256=MbaXUVbmYIaYHN4sldaSIsojqxUjT0zHDpuzGC1pHrY,4292
39
+ ramifice/fields/general/__init__.py,sha256=JzgIDseNQLB_IDwY9-JSiT_bONxvhJmbKl5PhQzTnpE,40
40
+ ramifice/fields/general/choice_group.py,sha256=fdxfUEKavnW3SahtmyXNDsIJ1O67wCqZb0g-qnNc9cc,896
41
+ ramifice/fields/general/date_group.py,sha256=0Y4njV6AboQKCpSpjNRWiO8iJF4EdnVWOvmRz_M_7MY,1185
42
+ ramifice/fields/general/field.py,sha256=8P_k66rSGpY9qfiyRvRcH4VcqmzCy6fphr_BLrf-2N0,1360
43
+ ramifice/fields/general/file_group.py,sha256=HjCww3B6eS9gUmr6AGZTXhHVhS_VBvn0XpbrViWA8a8,986
44
+ ramifice/fields/general/number_group.py,sha256=QvJnnpvWvU5J-99mWk7h-00hW7busClv1eSR_DPll4A,753
45
+ ramifice/fields/general/text_group.py,sha256=y5j_7I-TzOpr6vJpbEFHN1JRc6s0wa6BVSqnHMMmX-4,1077
46
+ ramifice/models/__init__.py,sha256=I4p5Y_oHG9ZLZ3vR44PpCGGvB-C2W7fSQPb5qJsm-VQ,178
47
+ ramifice/models/decorator.py,sha256=bFUN62UXLKSVteyd8GRZGEK-u-IgJQq1U_HrCrws5ZU,6350
48
+ ramifice/models/model.py,sha256=kexnWtfmQaiGZU2qKeAhuHLxmuIFFe-xHwCULzLs9bc,7639
49
+ ramifice/paladins/__init__.py,sha256=bFr12UzadCCpuIkGSd6reeIeQ5td8W7LfckduP84WXc,1517
50
+ ramifice/paladins/add_valid.py,sha256=c-vIkbbIBC94T4czxkQC40uwNEe6w8wQgNVgu4cjeoY,439
51
+ ramifice/paladins/check.py,sha256=7zRYKzaa2tXJq8OVNe52SEFt9YFkrElsf4-mvhVD_B0,6908
52
+ ramifice/paladins/delete.py,sha256=k3N2qlaHZLWtFUTqWvtkYaqW9h3uK7ecpLjKr5gfoGE,3690
53
+ ramifice/paladins/hooks.py,sha256=jTOcz5eb3WUpIy21h-CcnsISDDsTgDCWjitszcFxZFE,1057
54
+ ramifice/paladins/indexing.py,sha256=ep6iSUhnH70eaNASr0Kx3yeuRE_i9BEdVUUiJBo4hZE,363
55
+ ramifice/paladins/password.py,sha256=7lZmsl-bBely5zlVz0aCYlC5yf8nHp1YswoFF4CZWBI,3297
56
+ ramifice/paladins/refrash.py,sha256=oS-N1QVwQGwt5lSxS01bpM6ETGuMLV_RFt1u5v2uEds,1221
57
+ ramifice/paladins/save.py,sha256=ahuPKo6qh9MHPXs_QNo9RbeBvN74uWtuI27k84gx5f4,3631
58
+ ramifice/paladins/tools.py,sha256=8rkWPGrVMJiYN97EZuX52nVFVfB6qa08avYT4v8ohLA,2918
59
+ ramifice/paladins/validation.py,sha256=vJ55g4al-V_aGxFSrnXDwAxjJXWv00Z8ZGexFipRD1c,1890
60
+ ramifice/paladins/groups/__init__.py,sha256=GdIBJaMKz7L8pBKMAA__a4m-p0g0_RlzCcvDLDMMiec,958
61
+ ramifice/paladins/groups/bool_group.py,sha256=X8P4YDh02gNzxTo9rgeCnmnV88jApUPqPLYIkpf5vGg,841
62
+ ramifice/paladins/groups/choice_group.py,sha256=NkD2sKqBkdUMHY36pFdvL4uQ-81LXByRHF_lhCEAI6Y,1848
63
+ ramifice/paladins/groups/date_group.py,sha256=3i6U2mwFMxW8s5rRi7RtSr7my6a5Cdy5MRWe601hjGA,3780
64
+ ramifice/paladins/groups/file_group.py,sha256=vDeW5JCqKHWa43LILcVWJSU1TG-CrwKXQZhchWsZgM8,2975
65
+ ramifice/paladins/groups/id_group.py,sha256=9iurBTOuhG1_8Wmxc5piTMcUNxAW3H0ZavA1sW7uopY,1321
66
+ ramifice/paladins/groups/img_group.py,sha256=xSrDYqviuMt7mxOZiO0jKll1WnVlWRaSynk7ZvdEJ4c,6131
67
+ ramifice/paladins/groups/num_group.py,sha256=oiBqm9lFsyHBKZgxfWvcQUpePPIT_0TBGPVrt0ae57s,2285
68
+ ramifice/paladins/groups/pass_group.py,sha256=54kvAyoUCEjujTw0Dh6oUrtv3RU80sWEem_b-3Ytv0k,1920
69
+ ramifice/paladins/groups/slug_group.py,sha256=sf-9CebDLoCDsaxyPVJKMhi6D_tWFeg3ET8Qk5E8pU8,2505
70
+ ramifice/paladins/groups/text_group.py,sha256=TWvUxFctwDtXSJQL_E4TvHX1Yh-cDx5MJLGLAJyC6Xc,4478
71
+ ramifice/utils/__init__.py,sha256=lAD90nw2VfGSuf0SLjOkeFScBPmc48XFvecueAfq73w,468
72
+ ramifice/utils/constants.py,sha256=zDVG2D8u0UMNl1Ik90PhZCdxjmK81uwqxosorersbXE,2630
73
+ ramifice/utils/errors.py,sha256=eEV7-aVR0U19vKqTd9JRHFJXcOv6N1HtXSzqeQpdciE,2796
74
+ ramifice/utils/fixtures.py,sha256=0hdJGu895zDvVg5HUmRVUqDLZbvM-7BlhwTF6vhRqJI,3374
75
+ ramifice/utils/migration.py,sha256=rA6RMIB7xrLNGUJHPuvxA5O0B3NkmG155et82kOtu7g,11316
76
+ ramifice/utils/mixins.py,sha256=XSkxJllqsMxN7xcP_9kn3-GRS4a1l_QQpFOlD3e-tIM,1123
77
+ ramifice/utils/tools.py,sha256=EKNJAV9Ch17IrmghLcu7-I69gDNkDSqPepG9GKU7WkA,3163
78
+ ramifice/utils/translations.py,sha256=EWITTDd4uXukRubOchqGwNjmZWt5HxoxRgq_kKeGsR8,4646
79
+ ramifice/utils/unit.py,sha256=fxeWGWh5GkI8E9lxsf80HOh-NihSrqEmIQAQlUKMIaE,2497
80
+ ramifice-0.8.28.dist-info/METADATA,sha256=X_XGDUwRgnmu1K2qcI9zlEzKoKQSWbbquGD1DMsT28Q,21236
81
+ ramifice-0.8.28.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
82
+ ramifice-0.8.28.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
83
+ ramifice-0.8.28.dist-info/RECORD,,