DataOpsHub 6.2.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.
- DataOpsHub/__init__.py +48 -0
- DataOpsHub/constants/__init__.py +29 -0
- DataOpsHub/constants/error_messages.py +30 -0
- DataOpsHub/constants/table_mappings.py +15 -0
- DataOpsHub/data_entry_forms/__init__.py +34 -0
- DataOpsHub/data_entry_forms/forms/__init__.py +13 -0
- DataOpsHub/data_entry_forms/forms/forms.py +27 -0
- DataOpsHub/data_entry_forms/validators/__init__.py +53 -0
- DataOpsHub/data_entry_forms/validators/form_field_validations.py +513 -0
- DataOpsHub/databases/__init__.py +10 -0
- DataOpsHub/databases/database_handler.py +878 -0
- DataOpsHub/databases/upload_data.py +118 -0
- DataOpsHub/models/__init__.py +17 -0
- DataOpsHub/models/base.py +82 -0
- DataOpsHub/models/user.py +110 -0
- DataOpsHub/security/__init__.py +15 -0
- DataOpsHub/security/automated_passwords.py +54 -0
- DataOpsHub/security/config.py +86 -0
- DataOpsHub/security/exceptions.py +56 -0
- DataOpsHub/services/__init__.py +14 -0
- DataOpsHub/services/user_service.py +213 -0
- dataopshub-6.2.0.dist-info/METADATA +160 -0
- dataopshub-6.2.0.dist-info/RECORD +25 -0
- dataopshub-6.2.0.dist-info/WHEEL +5 -0
- dataopshub-6.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Full-Stack Form Field Validation Module
|
|
6
|
+
|
|
7
|
+
This module provides comprehensive validation functionality for form fields in full-stack applications.
|
|
8
|
+
It combines backend-oriented validation with frontend-friendly features for user registration and other forms.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
#----------------#
|
|
12
|
+
# Import modules #
|
|
13
|
+
#----------------#
|
|
14
|
+
|
|
15
|
+
from email_validator import validate_email, EmailNotValidError
|
|
16
|
+
|
|
17
|
+
#------------------------#
|
|
18
|
+
# Import project modules #
|
|
19
|
+
#------------------------#
|
|
20
|
+
|
|
21
|
+
from DataOpsHub import (
|
|
22
|
+
INVALID_AGE_ERROR,
|
|
23
|
+
INVALID_DATE_FORMAT_ERROR,
|
|
24
|
+
INVALID_DATE_RANGE_ERROR,
|
|
25
|
+
INVALID_DATE_RANGE_FORMAT_ERROR,
|
|
26
|
+
INVALID_EMAIL_ERROR,
|
|
27
|
+
INVALID_FIRST_NAME_ERROR,
|
|
28
|
+
INVALID_FIRST_SURNAME_ERROR,
|
|
29
|
+
INVALID_ID_FORMAT_ERROR,
|
|
30
|
+
INVALID_ID_TYPE_ERROR,
|
|
31
|
+
INVALID_PASSWORD_ERROR,
|
|
32
|
+
INVALID_SECOND_SURNAME_ERROR,
|
|
33
|
+
INVALID_TEL_ERROR,
|
|
34
|
+
INVALID_TEL_SEARCH_VALUE,
|
|
35
|
+
MISSING_DATE_VALUES_ERROR,
|
|
36
|
+
USER_EXISTS_ERROR
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
from pygenutils.strings.string_handler import find_substring_index
|
|
40
|
+
from pygenutils.time_handling.time_formatters import parse_time_string
|
|
41
|
+
|
|
42
|
+
#------------------#
|
|
43
|
+
# Define functions #
|
|
44
|
+
#------------------#
|
|
45
|
+
|
|
46
|
+
# General validation functions #
|
|
47
|
+
#------------------------------#
|
|
48
|
+
|
|
49
|
+
def validate_field(field_name, field_value, reg_exp_dict, err_str_list):
|
|
50
|
+
"""
|
|
51
|
+
Validates a field based on the provided regular expression and error string.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
field_name : str
|
|
56
|
+
The name of the field being validated.
|
|
57
|
+
field_value : str
|
|
58
|
+
The value of the field to validate.
|
|
59
|
+
reg_exp_dict : dict
|
|
60
|
+
A dictionary of field names and their corresponding regular expressions.
|
|
61
|
+
err_str_list : list
|
|
62
|
+
A list of error messages corresponding to the fields.
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
dict
|
|
67
|
+
A dictionary with `has_error` (bool) and `error_msg` (str).
|
|
68
|
+
"""
|
|
69
|
+
# Special handling for complex validations
|
|
70
|
+
if field_name == FIELD_NAME_LIST_ENG[0]: # email
|
|
71
|
+
return validate_email_field(field_value)
|
|
72
|
+
elif field_name == FIELD_NAME_LIST_ENG[-1]: # age
|
|
73
|
+
return validate_age_field(field_value)
|
|
74
|
+
elif field_name == 'id': # ID validation
|
|
75
|
+
return validate_id_field(field_value, INVALID_ID_FORMAT_ERROR, INVALID_ID_TYPE_ERROR)
|
|
76
|
+
|
|
77
|
+
# Default validation using regular expressions
|
|
78
|
+
has_error = find_substring_index(
|
|
79
|
+
field_value.strip() if field_name != FIELD_NAME_LIST_ENG[4] else field_value,
|
|
80
|
+
reg_exp_dict[field_name],
|
|
81
|
+
advanced_search=True
|
|
82
|
+
) == -1
|
|
83
|
+
|
|
84
|
+
error_msg = err_str_list[FIELD_NAME_LIST_ENG.index(field_name)] if has_error else ""
|
|
85
|
+
return {"has_error": has_error, "error_msg": error_msg}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def generate_error_dict(request_form, reg_exp_dict, err_str_list):
|
|
89
|
+
"""
|
|
90
|
+
Generates an error dictionary for all form fields.
|
|
91
|
+
|
|
92
|
+
Parameters
|
|
93
|
+
----------
|
|
94
|
+
request_form : dict
|
|
95
|
+
A dictionary containing form field data (usually from Flask `request.form`).
|
|
96
|
+
reg_exp_dict : dict
|
|
97
|
+
A dictionary of field names and their corresponding regular expressions.
|
|
98
|
+
err_str_list : list
|
|
99
|
+
A list of error messages corresponding to the fields.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
dict
|
|
104
|
+
A dictionary where each key is a field name and each value contains
|
|
105
|
+
`has_error` (bool) and `error_msg` (str).
|
|
106
|
+
"""
|
|
107
|
+
return {
|
|
108
|
+
field_name: validate_field(
|
|
109
|
+
field_name,
|
|
110
|
+
request_form.get(field_name),
|
|
111
|
+
reg_exp_dict,
|
|
112
|
+
err_str_list,
|
|
113
|
+
)
|
|
114
|
+
for field_name in FIELD_NAME_LIST_ENG
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def generate_error_dict_nonempty(request_form, reg_exp_dict, err_str_list, exclude_fields=None):
|
|
119
|
+
"""
|
|
120
|
+
Generates an error dictionary for all non-empty form fields.
|
|
121
|
+
|
|
122
|
+
Parameters
|
|
123
|
+
----------
|
|
124
|
+
request_form : dict
|
|
125
|
+
A dictionary containing form field data (usually from Flask `request.form`).
|
|
126
|
+
reg_exp_dict : dict
|
|
127
|
+
A dictionary of field names and their corresponding regular expressions.
|
|
128
|
+
err_str_list : list
|
|
129
|
+
A list of error messages corresponding to the fields.
|
|
130
|
+
exclude_fields : list
|
|
131
|
+
A list of field names to exclude from validation.
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
dict
|
|
136
|
+
A dictionary where each key is a field name and each value contains
|
|
137
|
+
`has_error` (bool) and `error_msg` (str).
|
|
138
|
+
"""
|
|
139
|
+
if exclude_fields is None:
|
|
140
|
+
exclude_fields = []
|
|
141
|
+
elif exclude_fields and not isinstance(exclude_fields, list):
|
|
142
|
+
exclude_fields = [exclude_fields]
|
|
143
|
+
|
|
144
|
+
err_dict = {
|
|
145
|
+
field_name: validate_field(
|
|
146
|
+
field_name,
|
|
147
|
+
request_form.get(field_name),
|
|
148
|
+
reg_exp_dict,
|
|
149
|
+
err_str_list,
|
|
150
|
+
)
|
|
151
|
+
for field_name in FIELD_NAME_LIST_ENG
|
|
152
|
+
if request_form.get(field_name) and field_name not in exclude_fields
|
|
153
|
+
}
|
|
154
|
+
return err_dict
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
# Specific validation functions #
|
|
158
|
+
#------------------------------#
|
|
159
|
+
|
|
160
|
+
def verify_spanish_dni(dni: str) -> bool:
|
|
161
|
+
"""
|
|
162
|
+
Verify the validity of a Spanish DNI (Documento Nacional de Identidad).
|
|
163
|
+
|
|
164
|
+
Parameters
|
|
165
|
+
----------
|
|
166
|
+
dni : str
|
|
167
|
+
The DNI (ID card) to be verified.
|
|
168
|
+
|
|
169
|
+
Returns
|
|
170
|
+
-------
|
|
171
|
+
bool
|
|
172
|
+
True if the DNI is valid, False otherwise.
|
|
173
|
+
"""
|
|
174
|
+
if len(dni) != 9:
|
|
175
|
+
return False
|
|
176
|
+
|
|
177
|
+
digits = dni[:-1]
|
|
178
|
+
control_letter = dni[-1].upper()
|
|
179
|
+
|
|
180
|
+
if not digits.isdigit():
|
|
181
|
+
return False
|
|
182
|
+
|
|
183
|
+
letters = "TRWAGMYFPDXBNJZSQVHLCKE"
|
|
184
|
+
calculated_letter = letters[int(digits) % 23]
|
|
185
|
+
|
|
186
|
+
return calculated_letter == control_letter
|
|
187
|
+
|
|
188
|
+
def validate_id_field(value, invalid_val_err_str, empty_val_err_str):
|
|
189
|
+
"""
|
|
190
|
+
Validate if the ID follows the required format (3-10 characters, alphanumeric with hyphens).
|
|
191
|
+
|
|
192
|
+
Parameters
|
|
193
|
+
----------
|
|
194
|
+
value : str
|
|
195
|
+
The ID value to validate.
|
|
196
|
+
invalid_val_err_str : str
|
|
197
|
+
The error message for invalid ID format.
|
|
198
|
+
empty_val_err_str : str
|
|
199
|
+
The error message for empty ID values.
|
|
200
|
+
|
|
201
|
+
Returns
|
|
202
|
+
-------
|
|
203
|
+
dict
|
|
204
|
+
A dictionary with the error message, if any, stored under the key `error_msg` (str).
|
|
205
|
+
"""
|
|
206
|
+
try:
|
|
207
|
+
if not isinstance(value, str):
|
|
208
|
+
return {"error_msg": empty_val_err_str}
|
|
209
|
+
|
|
210
|
+
# First check if it's a Spanish DNI
|
|
211
|
+
if len(value) == 9 and value[-1].isalpha():
|
|
212
|
+
if not verify_spanish_dni(value):
|
|
213
|
+
return {"error_msg": invalid_val_err_str}
|
|
214
|
+
return {"error_msg": ""}
|
|
215
|
+
|
|
216
|
+
# If not a DNI, check the standard ID pattern
|
|
217
|
+
pattern_match_index = find_substring_index(value, ID_PATTERN, advanced_search=True)
|
|
218
|
+
if pattern_match_index == -1:
|
|
219
|
+
return {"error_msg": invalid_val_err_str}
|
|
220
|
+
|
|
221
|
+
return {"error_msg": ""}
|
|
222
|
+
except (ValueError, TypeError):
|
|
223
|
+
return {"error_msg": empty_val_err_str}
|
|
224
|
+
|
|
225
|
+
def validate_date_range(min_value, max_value):
|
|
226
|
+
"""
|
|
227
|
+
Validate date range values, always including both edges of the range.
|
|
228
|
+
|
|
229
|
+
Parameters
|
|
230
|
+
----------
|
|
231
|
+
min_value : str
|
|
232
|
+
Start date in format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM'.
|
|
233
|
+
If only date is provided, time defaults to 00:00.
|
|
234
|
+
max_value : str
|
|
235
|
+
End date in format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM'.
|
|
236
|
+
If only date is provided, time defaults to 23:59.
|
|
237
|
+
|
|
238
|
+
Returns
|
|
239
|
+
-------
|
|
240
|
+
dict
|
|
241
|
+
A dictionary with the error message, if any, stored under the key `error_msg` (str).
|
|
242
|
+
If multiple errors are found, they will be combined with semicolons.
|
|
243
|
+
"""
|
|
244
|
+
errors = []
|
|
245
|
+
min_date = None
|
|
246
|
+
max_date = None
|
|
247
|
+
min_value_error = False
|
|
248
|
+
max_value_error = False
|
|
249
|
+
|
|
250
|
+
# Try parsing min_value
|
|
251
|
+
try:
|
|
252
|
+
# Try parsing with time first
|
|
253
|
+
try:
|
|
254
|
+
min_date = parse_time_string(min_value, '%Y-%m-%d %H:%M')
|
|
255
|
+
except ValueError:
|
|
256
|
+
# If that fails, try date-only format and set time to 00:00
|
|
257
|
+
try:
|
|
258
|
+
min_date = parse_time_string(min_value, '%Y-%m-%d')
|
|
259
|
+
min_date = min_date.replace(hour=0, minute=0)
|
|
260
|
+
except ValueError:
|
|
261
|
+
min_value_error = True
|
|
262
|
+
except Exception:
|
|
263
|
+
min_value_error = True
|
|
264
|
+
|
|
265
|
+
# Try parsing max_value
|
|
266
|
+
try:
|
|
267
|
+
# Try parsing with time first
|
|
268
|
+
try:
|
|
269
|
+
max_date = parse_time_string(max_value, '%Y-%m-%d %H:%M')
|
|
270
|
+
except ValueError:
|
|
271
|
+
# If that fails, try date-only format and set time to 23:59
|
|
272
|
+
try:
|
|
273
|
+
max_date = parse_time_string(max_value, '%Y-%m-%d')
|
|
274
|
+
max_date = max_date.replace(hour=23, minute=59)
|
|
275
|
+
except ValueError:
|
|
276
|
+
max_value_error = True
|
|
277
|
+
except Exception:
|
|
278
|
+
max_value_error = True
|
|
279
|
+
|
|
280
|
+
# Create consolidated error messages for date format issues
|
|
281
|
+
if min_value_error and max_value_error:
|
|
282
|
+
errors.append(f"Invalid date format for min_value and max_value. {INVALID_DATE_FORMAT_ERROR}")
|
|
283
|
+
elif min_value_error:
|
|
284
|
+
errors.append(f"Invalid date format for min_value: '{min_value}'. {INVALID_DATE_FORMAT_ERROR}")
|
|
285
|
+
elif max_value_error:
|
|
286
|
+
errors.append(f"Invalid date format for max_value: '{max_value}'. {INVALID_DATE_FORMAT_ERROR}")
|
|
287
|
+
|
|
288
|
+
# If both dates are valid, check if min_date is greater than max_date
|
|
289
|
+
if min_date and max_date and min_date > max_date:
|
|
290
|
+
errors.append(INVALID_DATE_RANGE_ERROR)
|
|
291
|
+
|
|
292
|
+
# Return all errors at once if any were found
|
|
293
|
+
if errors:
|
|
294
|
+
return {"error_msg": "; ".join(errors)}
|
|
295
|
+
|
|
296
|
+
return {"error_msg": ""}
|
|
297
|
+
|
|
298
|
+
def validate_email_field(email):
|
|
299
|
+
"""
|
|
300
|
+
Validates and normalizes an email address.
|
|
301
|
+
|
|
302
|
+
Parameters
|
|
303
|
+
----------
|
|
304
|
+
email: str
|
|
305
|
+
The email address to validate.
|
|
306
|
+
|
|
307
|
+
Returns
|
|
308
|
+
-------
|
|
309
|
+
dict
|
|
310
|
+
A dictionary with `has_error` (bool) and `error_msg` (str).
|
|
311
|
+
"""
|
|
312
|
+
try:
|
|
313
|
+
validate_email(email)
|
|
314
|
+
return {"has_error": False, "error_msg": ""}
|
|
315
|
+
except EmailNotValidError as e:
|
|
316
|
+
return {"has_error": True, "error_msg": f"{INVALID_EMAIL_ERROR}: {str(e)}"}
|
|
317
|
+
|
|
318
|
+
def validate_age_field(age):
|
|
319
|
+
"""
|
|
320
|
+
Validate if the age is within the range [14-120].
|
|
321
|
+
|
|
322
|
+
Parameters
|
|
323
|
+
----------
|
|
324
|
+
age : str
|
|
325
|
+
The age input value as a string.
|
|
326
|
+
|
|
327
|
+
Returns
|
|
328
|
+
-------
|
|
329
|
+
dict
|
|
330
|
+
A dictionary with `has_error` (bool) and `error_msg` (str).
|
|
331
|
+
"""
|
|
332
|
+
if not (age.isdigit() and 14 <= int(age) <= 110):
|
|
333
|
+
return {"has_error": True, "error_msg": INVALID_AGE_ERROR}
|
|
334
|
+
return {"has_error": False, "error_msg": ""}
|
|
335
|
+
|
|
336
|
+
# Hybrid validation functions #
|
|
337
|
+
#----------------------------#
|
|
338
|
+
|
|
339
|
+
def validate_form_with_json(form_data, json_data=None):
|
|
340
|
+
"""
|
|
341
|
+
Validates both form data and JSON data in a full-stack context.
|
|
342
|
+
|
|
343
|
+
This function combines the backend-oriented JSON validation with
|
|
344
|
+
the frontend-oriented form validation.
|
|
345
|
+
|
|
346
|
+
Parameters
|
|
347
|
+
----------
|
|
348
|
+
form_data : dict
|
|
349
|
+
Form data from a web form (e.g., Flask request.form).
|
|
350
|
+
json_data : dict, optional
|
|
351
|
+
JSON data for API validation.
|
|
352
|
+
|
|
353
|
+
Returns
|
|
354
|
+
-------
|
|
355
|
+
dict
|
|
356
|
+
A dictionary with validation results for both form and JSON data.
|
|
357
|
+
"""
|
|
358
|
+
results = {
|
|
359
|
+
"form_validation": {},
|
|
360
|
+
"json_validation": {}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
# Validate form data if provided
|
|
364
|
+
if form_data:
|
|
365
|
+
results["form_validation"] = generate_error_dict(
|
|
366
|
+
form_data,
|
|
367
|
+
REG_EXP_DICT,
|
|
368
|
+
ERR_STR_LIST
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
# Validate JSON data if provided
|
|
372
|
+
if json_data:
|
|
373
|
+
results["json_validation"] = generate_json_validation_response(json_data)
|
|
374
|
+
|
|
375
|
+
return results
|
|
376
|
+
|
|
377
|
+
def generate_json_validation_response(json_data):
|
|
378
|
+
"""
|
|
379
|
+
Generates a validation response for medical data fields from JSON input.
|
|
380
|
+
|
|
381
|
+
Parameters
|
|
382
|
+
----------
|
|
383
|
+
json_data : dict
|
|
384
|
+
The JSON data containing medical measurements to validate.
|
|
385
|
+
Expected fields are:
|
|
386
|
+
- id (str)
|
|
387
|
+
- created_at (dict with min_value and max_value)
|
|
388
|
+
|
|
389
|
+
Returns
|
|
390
|
+
-------
|
|
391
|
+
dict
|
|
392
|
+
JSON-formatted validation response for each field:
|
|
393
|
+
{
|
|
394
|
+
"field_name": {
|
|
395
|
+
"error_msg": str
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
"""
|
|
399
|
+
validation_results = {}
|
|
400
|
+
|
|
401
|
+
for field_name, field_specs_dict in json_data.items():
|
|
402
|
+
if field_name == 'created_at':
|
|
403
|
+
# Validate date range format and values
|
|
404
|
+
if not isinstance(field_specs_dict, dict):
|
|
405
|
+
validation_results[field_name] = {"error_msg": INVALID_DATE_RANGE_FORMAT_ERROR}
|
|
406
|
+
continue
|
|
407
|
+
|
|
408
|
+
min_value = field_specs_dict.get("min_value")
|
|
409
|
+
max_value = field_specs_dict.get("max_value")
|
|
410
|
+
|
|
411
|
+
if not min_value or not max_value:
|
|
412
|
+
validation_results[field_name] = {"error_msg": MISSING_DATE_VALUES_ERROR}
|
|
413
|
+
continue
|
|
414
|
+
|
|
415
|
+
validation_results[field_name] = validate_date_range(min_value, max_value)
|
|
416
|
+
elif field_name == 'id':
|
|
417
|
+
validation_results[field_name] = validate_id_field(field_specs_dict, INVALID_ID_FORMAT_ERROR, INVALID_ID_TYPE_ERROR)
|
|
418
|
+
|
|
419
|
+
return validation_results
|
|
420
|
+
|
|
421
|
+
#--------------------------#
|
|
422
|
+
# Parameters and constants #
|
|
423
|
+
#--------------------------#
|
|
424
|
+
|
|
425
|
+
# Field name keywords #
|
|
426
|
+
#--------------------#
|
|
427
|
+
|
|
428
|
+
# User registration fields
|
|
429
|
+
FIELD_NAME_LIST_ENG = [
|
|
430
|
+
"email",
|
|
431
|
+
"first_name",
|
|
432
|
+
"first_surname",
|
|
433
|
+
"second_surname",
|
|
434
|
+
"password",
|
|
435
|
+
"tel",
|
|
436
|
+
"age"
|
|
437
|
+
]
|
|
438
|
+
|
|
439
|
+
FIELD_NAME_LIST_ESP = [
|
|
440
|
+
"Correo electrónico",
|
|
441
|
+
"Nombre",
|
|
442
|
+
"Primer apellido",
|
|
443
|
+
"Segundo apellido",
|
|
444
|
+
"Contraseña",
|
|
445
|
+
"Teléfono",
|
|
446
|
+
"Edad"
|
|
447
|
+
]
|
|
448
|
+
|
|
449
|
+
DROPDOWN_ID_LIST = [f"{field}_dropdown" for field in FIELD_NAME_LIST_ENG]
|
|
450
|
+
FIELD_NAME_SEARCH_LIST = [f"{field}_search_value" for field in FIELD_NAME_LIST_ENG]
|
|
451
|
+
|
|
452
|
+
# Fields that can be used for filtering (WHERE clauses)
|
|
453
|
+
FILTERABLE_FIELDS = ["id", "created_at"]
|
|
454
|
+
|
|
455
|
+
# Fields to display in the response (SELECT clauses)
|
|
456
|
+
DISPLAYABLE_FIELDS = ["hl7_v2"]
|
|
457
|
+
|
|
458
|
+
# Pretty names for documentation
|
|
459
|
+
FIELD_NAME_LIST_PRETTY = [
|
|
460
|
+
"ID",
|
|
461
|
+
"Age",
|
|
462
|
+
"Body Temperature",
|
|
463
|
+
"Blood Pressure",
|
|
464
|
+
"Leucocyte Count",
|
|
465
|
+
"Neutrophil Count",
|
|
466
|
+
"Lymphocyte Count",
|
|
467
|
+
"Monocyte Count",
|
|
468
|
+
"User Registration Date",
|
|
469
|
+
"HL7 v2.X"
|
|
470
|
+
]
|
|
471
|
+
|
|
472
|
+
# ID validation regex pattern
|
|
473
|
+
ID_PATTERN = r'^P[0-9]{3}$'
|
|
474
|
+
|
|
475
|
+
# Create lists of error messages for backward compatibility
|
|
476
|
+
ERR_STR_LIST = [
|
|
477
|
+
INVALID_EMAIL_ERROR,
|
|
478
|
+
INVALID_FIRST_NAME_ERROR,
|
|
479
|
+
INVALID_FIRST_SURNAME_ERROR,
|
|
480
|
+
INVALID_SECOND_SURNAME_ERROR,
|
|
481
|
+
INVALID_PASSWORD_ERROR,
|
|
482
|
+
INVALID_TEL_ERROR,
|
|
483
|
+
INVALID_AGE_ERROR,
|
|
484
|
+
USER_EXISTS_ERROR
|
|
485
|
+
]
|
|
486
|
+
|
|
487
|
+
ERR_STR_LIST_SEARCH = ERR_STR_LIST.copy()
|
|
488
|
+
INVALID_TEL_SEARCH_VALUE = INVALID_TEL_SEARCH_VALUE
|
|
489
|
+
|
|
490
|
+
# Regular expressions #
|
|
491
|
+
#---------------------#
|
|
492
|
+
|
|
493
|
+
REG_EXP_DICT = {
|
|
494
|
+
FIELD_NAME_LIST_ENG[1]: r"^[a-zá-úà-ùâ-ûä-üA-ZÁ-ÚÀ-ÙÂ-ÛÄ-ÜçñÇÑ\s-]{3,}$",
|
|
495
|
+
FIELD_NAME_LIST_ENG[2]: r"^[a-zá-úà-ùâ-ûä-üA-ZÁ-ÚÀ-ÙÂ-ÛÄ-ÜçñÇÑ\s'-]{3,}$",
|
|
496
|
+
FIELD_NAME_LIST_ENG[3]: r"^[a-zá-úà-ùâ-ûä-üA-ZÁ-ÚÀ-ÙÂ-ÛÄ-ÜçñÇÑ\s'-]{3,}$",
|
|
497
|
+
FIELD_NAME_LIST_ENG[4]: r"^(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[_\W]).+$",
|
|
498
|
+
FIELD_NAME_LIST_ENG[5]: r"^(\+[1-9][0-9]{1,2} [0-9]{3} [0-9]{3} [0-9]{3}|\+[1-9]{1}-[0-9]{3} [0-9]{3} [0-9]{3} [0-9]{3}|[0-9]{3} [0-9]{3} [0-9]{3})$",
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
REG_EXP_DICT_SEARCH = {
|
|
502
|
+
FIELD_NAME_LIST_ENG[1]: r"^[a-zá-úà-ùâ-ûä-üA-ZÁ-ÚÀ-ÙÂ-ÛÄ-ÜçñÇÑ\s%-]*$",
|
|
503
|
+
FIELD_NAME_LIST_ENG[2]: r"^[a-zá-úà-ùâ-ûä-üA-ZÁ-ÚÀ-ÙÂ-ÛÄ-ÜçñÇÑ\s%-]*$",
|
|
504
|
+
FIELD_NAME_LIST_ENG[3]: r"^[a-zá-úà-ùâ-ûä-üA-ZÁ-ÚÀ-ÙÂ-ÛÄ-ÜçñÇÑ\s%-]*$",
|
|
505
|
+
FIELD_NAME_LIST_ENG[5]: r"^\+[0-9\s]*$",
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
# Validation mapping #
|
|
509
|
+
FIELD_VALIDATORS = {
|
|
510
|
+
"id": lambda x: validate_id_field(x, INVALID_ID_FORMAT_ERROR, INVALID_ID_TYPE_ERROR),
|
|
511
|
+
"email": validate_email_field,
|
|
512
|
+
"age": validate_age_field
|
|
513
|
+
}
|