ratify 0.1.0__tar.gz
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.
- ratify-0.1.0/PKG-INFO +12 -0
- ratify-0.1.0/README.md +3 -0
- ratify-0.1.0/ratify/__init__.py +0 -0
- ratify-0.1.0/ratify/ratify.py +402 -0
- ratify-0.1.0/ratify.egg-info/PKG-INFO +12 -0
- ratify-0.1.0/ratify.egg-info/SOURCES.txt +8 -0
- ratify-0.1.0/ratify.egg-info/dependency_links.txt +1 -0
- ratify-0.1.0/ratify.egg-info/top_level.txt +1 -0
- ratify-0.1.0/setup.cfg +4 -0
- ratify-0.1.0/setup.py +10 -0
ratify-0.1.0/PKG-INFO
ADDED
ratify-0.1.0/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""A Validator Class"""
|
|
3
|
+
|
|
4
|
+
from jsonschema.exceptions import ValidationError
|
|
5
|
+
import re
|
|
6
|
+
import datetime
|
|
7
|
+
|
|
8
|
+
class Ratify:
|
|
9
|
+
|
|
10
|
+
def __init__(self) -> None:
|
|
11
|
+
self.__errors:dict = dict()
|
|
12
|
+
|
|
13
|
+
def make(self, fields, rules):
|
|
14
|
+
self.__errors = dict()
|
|
15
|
+
"""creates a new validation request"""
|
|
16
|
+
for key, value in rules.items():
|
|
17
|
+
for val in value:
|
|
18
|
+
# check if val has ':'
|
|
19
|
+
if ":" in val:
|
|
20
|
+
vals = val.rsplit(":")
|
|
21
|
+
self.call_functions()[vals[0]](fields, key, vals[1])
|
|
22
|
+
else:
|
|
23
|
+
self.call_functions()[val](fields, key)
|
|
24
|
+
if len(self.__errors) > 0:
|
|
25
|
+
raise ValidationError(str(self.__errors))
|
|
26
|
+
else:
|
|
27
|
+
return fields
|
|
28
|
+
|
|
29
|
+
def call_functions(self):
|
|
30
|
+
"""maps rules to functions"""
|
|
31
|
+
map = {
|
|
32
|
+
"required" : self.is_required,
|
|
33
|
+
"email" : self.is_email,
|
|
34
|
+
"min" : self.is_min,
|
|
35
|
+
"max" : self.is_max,
|
|
36
|
+
"string" : self.is_string,
|
|
37
|
+
"integer" : self.is_integer,
|
|
38
|
+
"list" : self.is_list,
|
|
39
|
+
"dict" : self.is_dict,
|
|
40
|
+
"boolean" : self.is_boolean,
|
|
41
|
+
"float" : self.is_float,
|
|
42
|
+
"after" : self.is_after,
|
|
43
|
+
"before" : self.is_before,
|
|
44
|
+
"after_or_equal" : self.is_after_or_equal,
|
|
45
|
+
"before_or_equal" : self.is_before_or_equal,
|
|
46
|
+
"size" : self.is_size,
|
|
47
|
+
"contains" : self.is_contains,
|
|
48
|
+
"confirm_password" : self.is_confirm_password,
|
|
49
|
+
"less_than" : self.is_less_than,
|
|
50
|
+
"less_than_or_equal" : self.is_less_than_or_equal,
|
|
51
|
+
"greater_than" : self.is_greater_than,
|
|
52
|
+
"greater_than_or_equal" : self.is_greater_than_or_equal,
|
|
53
|
+
"mimes" : self.is_mimes,
|
|
54
|
+
"url" : self.is_url,
|
|
55
|
+
"file": self.is_file,
|
|
56
|
+
"ends_with": self.is_ends_with,
|
|
57
|
+
"starts_with": self.is_starts_with,
|
|
58
|
+
"in": self.is_in,
|
|
59
|
+
"not_in": self.is_not_in,
|
|
60
|
+
"in_array": self.is_in_array,
|
|
61
|
+
"not_in_array": self.is_not_in_array,
|
|
62
|
+
"alpha": self.is_alpha,
|
|
63
|
+
"alpha_num": self.is_alpha_num,
|
|
64
|
+
"uppercase": self.is_uppercase,
|
|
65
|
+
"lowercase": self.is_lowercase,
|
|
66
|
+
"same": self.is_same,
|
|
67
|
+
"required_if": self.is_required_if,
|
|
68
|
+
"date": self.is_date,
|
|
69
|
+
"datetime": self.is_datetime,
|
|
70
|
+
"date_format": self.is_date_format
|
|
71
|
+
}
|
|
72
|
+
return map
|
|
73
|
+
|
|
74
|
+
def is_required(self, fields, key)->None:
|
|
75
|
+
"""Validates if a field is required"""
|
|
76
|
+
value = fields[key]
|
|
77
|
+
if value is None or value == '':
|
|
78
|
+
error = "The {} field is required".format(key)
|
|
79
|
+
self.__logError(key, error)
|
|
80
|
+
|
|
81
|
+
def is_email(self, fields, key)->None:
|
|
82
|
+
"""checks if the field is a valid email"""
|
|
83
|
+
value = fields[key]
|
|
84
|
+
check = re.fullmatch("^[a-zA-Z0-9_.±]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$", value)
|
|
85
|
+
if not check:
|
|
86
|
+
error = "This is an invalid email"
|
|
87
|
+
self.__logError(key, error)
|
|
88
|
+
|
|
89
|
+
def is_min(self, fields, key, min=3):
|
|
90
|
+
"""check the min length of the value"""
|
|
91
|
+
value = fields[key]
|
|
92
|
+
if isinstance(value, str):
|
|
93
|
+
if len(value) < int(min):
|
|
94
|
+
error = "The {} length should not be less than {}".format(key, min)
|
|
95
|
+
self.__logError(key, error)
|
|
96
|
+
if isinstance(value, int):
|
|
97
|
+
if value < int(min):
|
|
98
|
+
error = "The {} value should not be less than {}".format(key, min)
|
|
99
|
+
self.__logError(key, error)
|
|
100
|
+
|
|
101
|
+
def is_max(self, fields, key, max=20):
|
|
102
|
+
"""check the max length of the value"""
|
|
103
|
+
value = fields[key]
|
|
104
|
+
if isinstance(value, str):
|
|
105
|
+
if len(value) > int(max):
|
|
106
|
+
error = "The {} length should not be more than {}".format(key, max)
|
|
107
|
+
self.__logError(key, error)
|
|
108
|
+
if isinstance(value, int):
|
|
109
|
+
if value > int(max):
|
|
110
|
+
error = "The {} value should not be more than {}".format(key, max)
|
|
111
|
+
self.__logError(key, error)
|
|
112
|
+
|
|
113
|
+
def __logError(self, key, error):
|
|
114
|
+
"""logs the validation errors"""
|
|
115
|
+
if key in self.__errors:
|
|
116
|
+
self.__errors[key].append(error)
|
|
117
|
+
else:
|
|
118
|
+
self.__errors[key] = []
|
|
119
|
+
self.__errors[key].append(error)
|
|
120
|
+
|
|
121
|
+
def is_string(self, fields, key):
|
|
122
|
+
"""checks if the field is a string"""
|
|
123
|
+
value = fields[key]
|
|
124
|
+
if not isinstance(value, str):
|
|
125
|
+
error = "The {} field should be a string".format(key)
|
|
126
|
+
self.__logError(key, error)
|
|
127
|
+
|
|
128
|
+
def is_integer(self, fields, key):
|
|
129
|
+
"""checks if the field is an integer"""
|
|
130
|
+
value = fields[key]
|
|
131
|
+
if not isinstance(value, int):
|
|
132
|
+
error = "The {} field should be an integer".format(key)
|
|
133
|
+
self.__logError(key, error)
|
|
134
|
+
|
|
135
|
+
def is_list(self, fields, key):
|
|
136
|
+
"""checks if the field is a list"""
|
|
137
|
+
value = fields[key]
|
|
138
|
+
if not isinstance(value, list):
|
|
139
|
+
error = "The {} field should be a list".format(key)
|
|
140
|
+
self.__logError(key, error)
|
|
141
|
+
|
|
142
|
+
def is_dict(self, fields, key):
|
|
143
|
+
"""checks if the field is a dictionary"""
|
|
144
|
+
value = fields[key]
|
|
145
|
+
if not isinstance(value, dict):
|
|
146
|
+
error = "The {} field should be a dictionary".format(key)
|
|
147
|
+
self.__logError(key, error)
|
|
148
|
+
|
|
149
|
+
def is_boolean(self, fields, key):
|
|
150
|
+
"""checks if the field is a boolean"""
|
|
151
|
+
value = fields[key]
|
|
152
|
+
if not isinstance(value, bool):
|
|
153
|
+
error = "The {} field should be a boolean".format(key)
|
|
154
|
+
self.__logError(key, error)
|
|
155
|
+
|
|
156
|
+
def is_float(self, fields, key):
|
|
157
|
+
"""checks if the field is a float"""
|
|
158
|
+
value = fields[key]
|
|
159
|
+
if not isinstance(value, float):
|
|
160
|
+
error = "The {} field should be a float".format(key)
|
|
161
|
+
self.__logError(key, error)
|
|
162
|
+
|
|
163
|
+
def is_after(self, fields, key, date):
|
|
164
|
+
"""checks if the date is after the given date"""
|
|
165
|
+
value = fields[key]
|
|
166
|
+
if value <= date:
|
|
167
|
+
error = "The {} field should be after {}".format(key, date)
|
|
168
|
+
self.__logError(key, error)
|
|
169
|
+
|
|
170
|
+
def is_before(self, fields, key, date):
|
|
171
|
+
"""checks if the date is before the given date"""
|
|
172
|
+
value = fields[key]
|
|
173
|
+
if value >= date:
|
|
174
|
+
error = "The {} field should be before {}".format(key, date)
|
|
175
|
+
self.__logError(key, error)
|
|
176
|
+
|
|
177
|
+
def is_after_or_equal(self, fields, key, date):
|
|
178
|
+
"""checks if the date is after or equal to the given date"""
|
|
179
|
+
value = fields[key]
|
|
180
|
+
if value < date:
|
|
181
|
+
error = "The {} field should be after or equal to {}".format(key, date)
|
|
182
|
+
self.__logError(key, error)
|
|
183
|
+
|
|
184
|
+
def is_before_or_equal(self, fields, key, date):
|
|
185
|
+
"""checks if the date is before or equal to the given date"""
|
|
186
|
+
value = fields[key]
|
|
187
|
+
if value > date:
|
|
188
|
+
error = "The {} field should be before or equal to {}".format(key, date)
|
|
189
|
+
self.__logError(key, error)
|
|
190
|
+
|
|
191
|
+
def is_size(self, fields, key, size):
|
|
192
|
+
"""checks the size of the value"""
|
|
193
|
+
value = fields[key]
|
|
194
|
+
if isinstance(value, int):
|
|
195
|
+
if value != int(size):
|
|
196
|
+
error = "The {} field must be {}".format(key, size)
|
|
197
|
+
self.__logError(key, error)
|
|
198
|
+
elif isinstance(value, str):
|
|
199
|
+
if len(value) != int(size):
|
|
200
|
+
error = "The {} field must be {} characters".format(key, size)
|
|
201
|
+
self.__logError(key, error)
|
|
202
|
+
elif isinstance(value, list):
|
|
203
|
+
if len(value) != int(size):
|
|
204
|
+
error = "The {} field must contain {} items".format(key, size)
|
|
205
|
+
self.__logError(key, error)
|
|
206
|
+
|
|
207
|
+
def is_contains(self, fields, key, needle):
|
|
208
|
+
"""checks if the value contains the given value"""
|
|
209
|
+
self.is_list(fields, key)
|
|
210
|
+
value = list(map(str, fields[key]))
|
|
211
|
+
if needle not in value:
|
|
212
|
+
error = "The {} field must contain {}".format(key, needle)
|
|
213
|
+
self.__logError(key, error)
|
|
214
|
+
|
|
215
|
+
def is_confirm_password(self, fields, key, password_field):
|
|
216
|
+
"""checks if the value is the same as the password"""
|
|
217
|
+
value = fields[key]
|
|
218
|
+
if password_field not in fields.keys():
|
|
219
|
+
error = "The {} field is missing".format(password_field)
|
|
220
|
+
self.__logError(key, error)
|
|
221
|
+
elif value != fields[password_field]:
|
|
222
|
+
error = "The {} field must be the same as the {}".format(key, password_field)
|
|
223
|
+
self.__logError(key, error)
|
|
224
|
+
|
|
225
|
+
def is_less_than(self, fields, key, reference):
|
|
226
|
+
"""checks if the value is less than the reference"""
|
|
227
|
+
value = fields[key]
|
|
228
|
+
if value >= fields[reference]:
|
|
229
|
+
error = "The {} field must be less than {}".format(key, reference)
|
|
230
|
+
self.__logError(key,error)
|
|
231
|
+
|
|
232
|
+
def is_less_than_or_equal(self, fields, key, reference):
|
|
233
|
+
"""checks if the value is less than or equal to the reference"""
|
|
234
|
+
value = fields[key]
|
|
235
|
+
if value > fields[reference]:
|
|
236
|
+
error = "The {} field must be less than or equal to {}".format(key, reference)
|
|
237
|
+
self.__logError(key, error)
|
|
238
|
+
|
|
239
|
+
def is_greater_than(self, fields, key, reference):
|
|
240
|
+
"""checks if the value is greater than the reference"""
|
|
241
|
+
value = fields[key]
|
|
242
|
+
if value <= fields[reference]:
|
|
243
|
+
error = "The {} field must be greater than {}".format(key, reference)
|
|
244
|
+
self.__logError(key, error)
|
|
245
|
+
|
|
246
|
+
def is_greater_than_or_equal(self, fields, key, reference):
|
|
247
|
+
"""checks if the value is greater than or equal to the reference"""
|
|
248
|
+
value = fields[key]
|
|
249
|
+
if value < fields[reference]:
|
|
250
|
+
error = "The {} field must be greater than or equal to {}".format(key, reference)
|
|
251
|
+
self.__logError(key, error)
|
|
252
|
+
|
|
253
|
+
def is_mimes(self, fields, key, mimes):
|
|
254
|
+
"""checks the file type"""
|
|
255
|
+
value = fields.files[key]
|
|
256
|
+
if value.split(".")[1] not in mimes.split(","):
|
|
257
|
+
error = "The {} field format is not allowed".format(key)
|
|
258
|
+
self.__logError(key, error)
|
|
259
|
+
|
|
260
|
+
def is_url(self, fields, key):
|
|
261
|
+
"""checks if the value is a valid url"""
|
|
262
|
+
value = fields[key]
|
|
263
|
+
check = re.fullmatch("^(http|https)://[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+", value)
|
|
264
|
+
if not check:
|
|
265
|
+
error = "The {} field must be a valid url".format(key)
|
|
266
|
+
self.__logError(key, error)
|
|
267
|
+
|
|
268
|
+
def is_file(self, fields, key, allowable_file_extensions):
|
|
269
|
+
"""checks if the value is a file"""
|
|
270
|
+
value = fields.files[key]
|
|
271
|
+
filename = value.filename
|
|
272
|
+
if filename.split(".")[1] not in allowable_file_extensions.split(","):
|
|
273
|
+
error = "The {} field format is not allowed".format(key)
|
|
274
|
+
self.__logError(key, error)
|
|
275
|
+
|
|
276
|
+
def is_ends_with(self, fields, key, ends_with):
|
|
277
|
+
"""checks if the value ends with some characters"""
|
|
278
|
+
value = fields[key]
|
|
279
|
+
options = ends_with.split(",")
|
|
280
|
+
match = 0
|
|
281
|
+
for option in options:
|
|
282
|
+
if value.endswith(option):
|
|
283
|
+
match += 1
|
|
284
|
+
if match == 0:
|
|
285
|
+
error = "The {} field must end with {}".format(key, ends_with)
|
|
286
|
+
self.__logError(key, error)
|
|
287
|
+
|
|
288
|
+
def is_starts_with(self, fields, key, starts_with):
|
|
289
|
+
"""checks if the value starts with some characters"""
|
|
290
|
+
value = fields[key]
|
|
291
|
+
options = starts_with.split(",")
|
|
292
|
+
match = 0
|
|
293
|
+
for option in options:
|
|
294
|
+
if value.startswith(option):
|
|
295
|
+
match += 1
|
|
296
|
+
if match == 0:
|
|
297
|
+
error = "The {} field must start with {}".format(key, starts_with)
|
|
298
|
+
self.__logError(key, error)
|
|
299
|
+
|
|
300
|
+
def is_in(self, fields, key, options):
|
|
301
|
+
"""checks if the value is in the options"""
|
|
302
|
+
value = fields[key]
|
|
303
|
+
options = options.split(",")
|
|
304
|
+
if value not in options:
|
|
305
|
+
error = "The {} field must be in {}".format(key, options)
|
|
306
|
+
self.__logError(key, error)
|
|
307
|
+
|
|
308
|
+
def is_not_in(self, fields, key, options):
|
|
309
|
+
"""checks if the value is not in the options"""
|
|
310
|
+
value = fields[key]
|
|
311
|
+
options = options.split(",")
|
|
312
|
+
if value in options:
|
|
313
|
+
error = "The {} field must not be in {}".format(key, options)
|
|
314
|
+
self.__logError(key, error)
|
|
315
|
+
|
|
316
|
+
def is_in_array(self, fields, key, array_field):
|
|
317
|
+
"""checks if the value is in the array"""
|
|
318
|
+
value = fields[key]
|
|
319
|
+
array = fields[array_field]
|
|
320
|
+
if value not in array:
|
|
321
|
+
error = "The {} field must be in the {} field".format(key, array_field)
|
|
322
|
+
self.__logError(key, error)
|
|
323
|
+
|
|
324
|
+
def is_not_in_array(self, fields, key, array_field):
|
|
325
|
+
"""checks if the value is not in the array"""
|
|
326
|
+
value = fields[key]
|
|
327
|
+
array = fields[array_field]
|
|
328
|
+
if value in array:
|
|
329
|
+
error = "The {} field must not be in the {} field".format(key, array_field)
|
|
330
|
+
self.__logError(key, error)
|
|
331
|
+
|
|
332
|
+
def is_alpha(self, fields, key):
|
|
333
|
+
"""checks if the value is alphabetic"""
|
|
334
|
+
value = fields[key]
|
|
335
|
+
if not value.isalpha():
|
|
336
|
+
error = "The {} field must be alphabetic".format(key)
|
|
337
|
+
self.__logError(key, error)
|
|
338
|
+
|
|
339
|
+
def is_alpha_num(self, fields, key):
|
|
340
|
+
"""checks if the value is alphanumeric"""
|
|
341
|
+
value = fields[key]
|
|
342
|
+
if not value.isalnum():
|
|
343
|
+
error = "The {} field must be alphanumeric".format(key)
|
|
344
|
+
self.__logError(key, error)
|
|
345
|
+
|
|
346
|
+
def is_uppercase(self, fields, key):
|
|
347
|
+
"""checks if the value is uppercase"""
|
|
348
|
+
value = fields[key]
|
|
349
|
+
if not value.isupper():
|
|
350
|
+
error = "The {} field must be uppercase".format(key)
|
|
351
|
+
self.__logError(key, error)
|
|
352
|
+
|
|
353
|
+
def is_lowercase(self, fields, key):
|
|
354
|
+
"""checks if the value is lowercase"""
|
|
355
|
+
value = fields[key]
|
|
356
|
+
if not value.islower():
|
|
357
|
+
error = "The {} field must be lowercase".format(key)
|
|
358
|
+
self.__logError(key, error)
|
|
359
|
+
|
|
360
|
+
def is_same(self, fields, key, other_field):
|
|
361
|
+
"""checks if the value is the same as another field"""
|
|
362
|
+
value = fields[key]
|
|
363
|
+
if value != fields[other_field]:
|
|
364
|
+
error = "The {} field must be the same as the {} field".format(key, other_field)
|
|
365
|
+
self.__logError(key, error)
|
|
366
|
+
|
|
367
|
+
def is_required_if(self, fields, key, other_field):
|
|
368
|
+
"""checks if the value is required if another field is present"""
|
|
369
|
+
value = fields[key]
|
|
370
|
+
reference = other_field.split(",")
|
|
371
|
+
reference_value = fields[reference[0]]
|
|
372
|
+
reference.remove(reference[0])
|
|
373
|
+
if reference_value in reference and value is None:
|
|
374
|
+
error = "The {} field is required".format(key)
|
|
375
|
+
self.__logError(key, error)
|
|
376
|
+
|
|
377
|
+
def is_date(self, fields, key):
|
|
378
|
+
"""checks if the value is a date"""
|
|
379
|
+
value = fields[key]
|
|
380
|
+
try:
|
|
381
|
+
datetime.datetime.strptime(value, "%Y-%m-%d")
|
|
382
|
+
except ValueError:
|
|
383
|
+
error = "The {} field must be a date".format(key)
|
|
384
|
+
self.__logError(key, error)
|
|
385
|
+
|
|
386
|
+
def is_datetime(self, fields, key):
|
|
387
|
+
"""checks if the value is a datetime"""
|
|
388
|
+
value = fields[key]
|
|
389
|
+
try:
|
|
390
|
+
datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
|
|
391
|
+
except ValueError:
|
|
392
|
+
error = "The {} field must be a datetime".format(key)
|
|
393
|
+
self.__logError(key, error)
|
|
394
|
+
|
|
395
|
+
def is_date_format(self, fields, key, date_format):
|
|
396
|
+
"""checks if the value is in the given date format"""
|
|
397
|
+
value = fields[key]
|
|
398
|
+
try:
|
|
399
|
+
datetime.datetime.strptime(value, date_format)
|
|
400
|
+
except ValueError:
|
|
401
|
+
error = "The {} field must be in the {} format".format(key, date_format)
|
|
402
|
+
self.__logError(key, error)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ratify
|
ratify-0.1.0/setup.cfg
ADDED
ratify-0.1.0/setup.py
ADDED