safeshield 1.6.1__py3-none-any.whl → 1.6.4__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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: safeshield
3
- Version: 1.6.1
3
+ Version: 1.6.4
4
4
  Summary: Library for Help Validation Control
5
5
  Home-page: https://github.com/WunsunTarniho/py-guard
6
6
  Author: Wunsun Tarniho
@@ -20,12 +20,23 @@ Requires-Dist: mysql-connector-python==8.0.33
20
20
  Requires-Dist: Pillow==11.2.1
21
21
  Requires-Dist: psycopg2-binary==2.9.9
22
22
  Requires-Dist: python-dotenv==1.1.1
23
- Requires-Dist: python-dateutil==2.9.0.post0
24
- Requires-Dist: setuptools==63.2.0
23
+ Requires-Dist: python_dateutil==2.9.0.post0
24
+ Requires-Dist: setuptools==75.8.2
25
25
  Requires-Dist: SQLAlchemy==2.0.41
26
26
  Requires-Dist: Werkzeug==1.0.1
27
27
  Requires-Dist: dnspython==2.4.2
28
28
  Requires-Dist: idna==3.4
29
+ Dynamic: author
30
+ Dynamic: author-email
31
+ Dynamic: classifier
32
+ Dynamic: description
33
+ Dynamic: description-content-type
34
+ Dynamic: home-page
35
+ Dynamic: license-file
36
+ Dynamic: project-url
37
+ Dynamic: requires-dist
38
+ Dynamic: requires-python
39
+ Dynamic: summary
29
40
 
30
41
  # Safe Shield
31
42
  Safe Shield is a robust Python library designed to validating HTTP requests and input data.
@@ -153,7 +164,10 @@ validator.validate()
153
164
 
154
165
  """
155
166
  validator.has_errors -> True
156
- validator.errors -> {"name": ["The name field is required.", "The name must be a string"]}
167
+ validator.errors:
168
+ {
169
+ "name": ["The name field is required.", "The name must be a string"]
170
+ }
157
171
  """
158
172
  ```
159
173
 
@@ -191,10 +205,11 @@ validator.validate()
191
205
 
192
206
  """
193
207
  validator.has_errors -> True
194
- validator.errors -> {
195
- "user.contact.email": ["The email must be a valid email with valid DNS records."],
196
- "orders.0.price": ["The price must be a number"]
197
- }
208
+ validator.errors:
209
+ {
210
+ "user.contact.email": ["The email must be a valid email with valid DNS records."],
211
+ "orders.0.price": ["The price must be a number"]
212
+ }
198
213
  """
199
214
  ```
200
215
 
@@ -217,9 +232,10 @@ validator.validate()
217
232
 
218
233
  """
219
234
  validator.has_errors -> True
220
- validator.errors -> {
221
- "user.contact.email": ["This email is invalid"],
222
- "orders.0.price": ["The price must be a number"]
223
- }
235
+ validator.errors:
236
+ {
237
+ "user.contact.email": ["This email is invalid"],
238
+ "orders.0.price": ["The price must be a number"]
239
+ }
224
240
  """
225
241
  ```
@@ -1,31 +1,31 @@
1
+ safeshield-1.6.4.dist-info/licenses/LICENSE,sha256=YxHGBtuH0Vsy-KPvW2_afKE54XIrf1eipLF4v6kaybI,35276
1
2
  validator/__init__.py,sha256=udxDzUicPfxBOAQvzsnl3pHur9VUppKbWMgg35hpiww,244
2
3
  validator/exceptions.py,sha256=y2v7CaXmeGFHWcnigtLl4U-sFta_jMiXkGKXWIIVglY,366
3
4
  validator/factory.py,sha256=SJ2iJmTnFS-4ccH-gzZl_7CAW7Z6YJkZbMImu-po80w,1163
4
5
  validator/core/__init__.py,sha256=ZcqlXJSk03i_CVzmIN-nVe1UOyvwwO5jhbEj7f62Y_o,59
5
- validator/core/validator.py,sha256=eGLV6fx4eKm7TJm_FV53lshr0zIlKtKTK4BhDfuTIVs,12695
6
+ validator/core/validator.py,sha256=cflLhGo_rS6Zh61X7lZfr0q-xR0bBHfylGudZ1uTn7o,12765
6
7
  validator/database/__init__.py,sha256=O-cB6-MhNapJ3iwe5jvifbMfr1dPjXLtEdfNTKIu0hc,171
7
8
  validator/database/detector.py,sha256=Vac7oVL26GjU6expGo01-6mgUtXqldr-jirzpYokZBM,9597
8
- validator/database/manager.py,sha256=QD_vmsE36LnTHANTPf63ICxEqfWym9cPI-uWEXYrvr4,6924
9
+ validator/database/manager.py,sha256=XJM_I0WaWfZWV710duAc32p1gtiP2or-MAj75WPw1oM,6478
9
10
  validator/rules/__init__.py,sha256=z3Vk3R5CRgjeqyDWZxdofD2tBMTgdyYVuFmo1mKOTj4,830
10
11
  validator/rules/array.py,sha256=7xwdXnthWZNDbD4lONgqtOf44OOQq1J6XexYm6BXea4,3512
11
- validator/rules/base.py,sha256=dIDT5W_KCuHsyhDL9volDcRJsRZ-1bICDr7268KyjQQ,5943
12
+ validator/rules/base.py,sha256=yhxQdGiiM-wY7VtRH-KRU-_wmw7RVJnmJcmayO1EqBk,5870
12
13
  validator/rules/basic.py,sha256=8k-REzsSyknhNuw0vPKMxtovvJBVlyZDihXXVznRQpM,6420
13
- validator/rules/boolean.py,sha256=ff5qLKOJXi08VJnENaqeEIabbXtoCQvW2fDR6vOsXl0,5452
14
+ validator/rules/boolean.py,sha256=UuSO9BdBMR5l6sB3dgZqoqOVjqu47yjFrmJ7xylTVKs,5452
14
15
  validator/rules/comparison.py,sha256=BnufmgCkSqzUjSFWvlsKN8auOCKTBs7Pxy5i9rwSQs8,15564
15
16
  validator/rules/date.py,sha256=k27U3e08OPZoXyEX0Yj86ZfjCUuhLy4eBmqYbyc4Jn4,7292
16
17
  validator/rules/files.py,sha256=3Q0KoadDKqNIiVlBR7b5b-XBs4gOg3ZFu7wU7SrdqWQ,12280
17
18
  validator/rules/format.py,sha256=u_BhPQwW30JYHwZIjHD0ZX449csgTPPCJOeoXaQr4M4,7361
18
19
  validator/rules/numeric.py,sha256=UgawwV_ZKiJ3Dano32UrSBC6Qe69zbiL69OyMDo91yY,8699
19
20
  validator/rules/string.py,sha256=3wgrqAO4V97ZPMc97mwDV6vsNvs6oyJs-ciqQX-FLBs,6268
20
- validator/rules/utilities.py,sha256=BaErsE0TPt1u342aOuSBkjh0CMD2Sq7ZwiBqM8j0GLo,16910
21
+ validator/rules/utilities.py,sha256=pwo-uhBKDkIV2ZcdVQDBFYMc5ICsKswL904AayBLeBg,17080
21
22
  validator/services/__init__.py,sha256=zzKTmqL7v4niFGWHJBfWLqgJ0iTaW_69OzYZN8uInzQ,210
22
23
  validator/services/rule_conflict.py,sha256=T3IhWLmZsRUccJ4oFO-OKRjrc5Xt7r71kktxjjj2IA8,9505
23
24
  validator/services/rule_error_handler.py,sha256=l4jA6WtTRBNGytVA_nSwJpbix_viNWhqlwKcxIKXzcY,2325
24
25
  validator/services/rule_preparer.py,sha256=7HSMuSGGgaYWv8dt_m7pL5MQkJcTwFBH9gfmCZwzt8U,5284
25
26
  validator/utils/__init__.py,sha256=Yzo-xv285Be-a233M4duDdYtscuHiuBbPSX_C8yViJI,20
26
27
  validator/utils/string.py,sha256=0YACzeEaWNEOR9_7O9A8D1ItIbtWfOJ8IfrzcB8VMYA,515
27
- safeshield-1.6.1.dist-info/LICENSE,sha256=YxHGBtuH0Vsy-KPvW2_afKE54XIrf1eipLF4v6kaybI,35276
28
- safeshield-1.6.1.dist-info/METADATA,sha256=WY8CB1VcuQqdWkNH9O-nvW_oWTVttfgka8FMwRZlVH8,6544
29
- safeshield-1.6.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
30
- safeshield-1.6.1.dist-info/top_level.txt,sha256=iUtV3dlHOIiMfLuY4pruY00lFni8JzOkQ3Nh1II19OE,10
31
- safeshield-1.6.1.dist-info/RECORD,,
28
+ safeshield-1.6.4.dist-info/METADATA,sha256=o4U6ffoKB60H_lc2k50jRS67BeECUuSHIgzRuKBR5hI,6664
29
+ safeshield-1.6.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
+ safeshield-1.6.4.dist-info/top_level.txt,sha256=iUtV3dlHOIiMfLuY4pruY00lFni8JzOkQ3Nh1II19OE,10
31
+ safeshield-1.6.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.45.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -282,7 +282,7 @@ class Validator:
282
282
  combined_rules = existing_rules + new_rules
283
283
 
284
284
  RuleConflictChecker.check_conflicts(combined_rules)
285
- self._raw_rules[field] = self.rule_preparer._deduplicate_rules(field, combined_rules)
285
+ self._raw_rules[field] = self.rule_preparer._deduplicate_rules(combined_rules)
286
286
 
287
287
  def set_stop_on_first_failure(self, value: bool) -> None:
288
288
  """Set whether to stop validation after first failure"""
@@ -293,6 +293,9 @@ class Validator:
293
293
  """Get current validation errors"""
294
294
  return self.error_handler.errors
295
295
 
296
+ def get_errors(self):
297
+ return self.error_handler.errors or {}
298
+
296
299
  @property
297
300
  def has_errors(self) -> bool:
298
301
  """Check if there are any validation errors"""
@@ -111,21 +111,8 @@ class DatabaseManager:
111
111
  return cursor.fetchall()
112
112
 
113
113
  def exists(self, table: str, column: str, value: Any) -> bool:
114
- if '.' in column:
115
- parts = column.split('.')
116
- if len(parts) != 2:
117
- raise ValueError("Foreign key reference should be in format 'foreign_key.column'")
118
-
119
- foreign_key, related_column = parts
120
- sql = f"""
121
- SELECT 1 FROM {table} t
122
- JOIN {foreign_key} r ON t.{foreign_key} = r.id
123
- WHERE r.{related_column} = %s
124
- LIMIT 1
125
- """
126
- else:
127
- sql = f"SELECT 1 FROM {table} WHERE {column} = %s LIMIT 1"
128
-
114
+ """Optimized exists check with parameterized query"""
115
+ sql = f"SELECT 1 FROM {table} WHERE {column} = %s LIMIT 1"
129
116
  result = self.query(sql, (value,))
130
117
  return bool(result)
131
118
 
validator/rules/base.py CHANGED
@@ -99,9 +99,6 @@ class Rule(ABC):
99
99
 
100
100
  attributes = []
101
101
 
102
- if isinstance(fields, bool):
103
- return None
104
-
105
102
  for field in fields:
106
103
  if field in self.validator.custom_attributes:
107
104
  attributes.append(self.validator.custom_attributes[field])
@@ -45,7 +45,7 @@ class DeclinedRule(Rule):
45
45
  return f"The :attribute must be declined."
46
46
 
47
47
  class AcceptedIfRule(AcceptedRule):
48
- _count_parameter = 1
48
+ _count_parameter = 2
49
49
 
50
50
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
51
51
  condition_met = False
@@ -99,7 +99,7 @@ class AcceptedUnlessRule(AcceptedRule):
99
99
  return replacements
100
100
 
101
101
  class DeclinedIfRule(DeclinedRule):
102
- _count_parameter = 1
102
+ _count_parameter = 2
103
103
 
104
104
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
105
105
  condition_met = False
@@ -4,7 +4,7 @@ from .basic import *
4
4
  from .boolean import AcceptedRule, DeclinedRule
5
5
 
6
6
  class RequiredIfRule(RequiredRule):
7
- _count_parameter = 2
7
+ _count_parameter = 1
8
8
  _accept_closure = True
9
9
 
10
10
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -67,7 +67,8 @@ class RequiredWithRule(RequiredRule):
67
67
  _count_parameter = 1
68
68
 
69
69
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
70
- if any(f in self.validator.data for f in params):
70
+ condition = [f in self.validator.data and not self.is_empty(self.get_field_value(f)) for f in params]
71
+ if any(condition):
71
72
  return super().validate(field, value, params)
72
73
  return True
73
74
 
@@ -84,7 +85,9 @@ class RequiredWithAllRule(RequiredRule):
84
85
  _count_parameter = 1
85
86
 
86
87
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
87
- if all(f in self.validator.data for f in params):
88
+ condition = [f in self.validator.data and not self.is_empty(self.get_field_value(f)) for f in params]
89
+
90
+ if all(condition):
88
91
  return super().validate(field, value, params)
89
92
  return True
90
93
 
@@ -170,7 +173,7 @@ class RequiredArrayKeysRule(Rule):
170
173
  return replacements
171
174
 
172
175
  class ProhibitedIfRule(ProhibitedRule):
173
- _count_parameter = 2
176
+ _count_parameter = 1
174
177
  _accept_closure = True
175
178
 
176
179
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -241,7 +244,7 @@ class ProhibitedIfDeclinedRule(ProhibitedRule, DeclinedRule):
241
244
  return True
242
245
 
243
246
  class PresentIfRule(PresentRule):
244
- _count_parameter = 2
247
+ _count_parameter = 1
245
248
  _accept_closure = True
246
249
 
247
250
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -431,7 +434,7 @@ class MissingWithAllRule(MissingRule):
431
434
  return replacements
432
435
 
433
436
  class ExcludeIfRule(ExcludeRule):
434
- _count_parameter = 2
437
+ _count_parameter = 1
435
438
  _accept_closure = True
436
439
 
437
440
  def validate(self, field: str, value: Any, params: List[str]) -> bool: