altcodepro-polydb-python 2.1.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.
Files changed (51) hide show
  1. altcodepro_polydb_python-2.1.0.dist-info/METADATA +378 -0
  2. altcodepro_polydb_python-2.1.0.dist-info/RECORD +51 -0
  3. altcodepro_polydb_python-2.1.0.dist-info/WHEEL +5 -0
  4. altcodepro_polydb_python-2.1.0.dist-info/licenses/LICENSE +21 -0
  5. altcodepro_polydb_python-2.1.0.dist-info/top_level.txt +1 -0
  6. polydb/__init__.py +64 -0
  7. polydb/adapters/AzureBlobStorageAdapter.py +77 -0
  8. polydb/adapters/AzureFileStorageAdapter.py +79 -0
  9. polydb/adapters/AzureQueueAdapter.py +61 -0
  10. polydb/adapters/AzureTableStorageAdapter.py +182 -0
  11. polydb/adapters/DynamoDBAdapter.py +216 -0
  12. polydb/adapters/EFSAdapter.py +50 -0
  13. polydb/adapters/FirestoreAdapter.py +193 -0
  14. polydb/adapters/GCPStorageAdapter.py +81 -0
  15. polydb/adapters/MongoDBAdapter.py +136 -0
  16. polydb/adapters/PostgreSQLAdapter.py +453 -0
  17. polydb/adapters/PubSubAdapter.py +83 -0
  18. polydb/adapters/S3Adapter.py +86 -0
  19. polydb/adapters/S3CompatibleAdapter.py +90 -0
  20. polydb/adapters/SQSAdapter.py +84 -0
  21. polydb/adapters/VercelKVAdapter.py +327 -0
  22. polydb/adapters/__init__.py +0 -0
  23. polydb/advanced_query.py +147 -0
  24. polydb/audit/AuditStorage.py +136 -0
  25. polydb/audit/__init__.py +7 -0
  26. polydb/audit/context.py +53 -0
  27. polydb/audit/manager.py +47 -0
  28. polydb/audit/models.py +86 -0
  29. polydb/base/NoSQLKVAdapter.py +301 -0
  30. polydb/base/ObjectStorageAdapter.py +42 -0
  31. polydb/base/QueueAdapter.py +27 -0
  32. polydb/base/SharedFilesAdapter.py +32 -0
  33. polydb/base/__init__.py +0 -0
  34. polydb/batch.py +163 -0
  35. polydb/cache.py +204 -0
  36. polydb/databaseFactory.py +748 -0
  37. polydb/decorators.py +21 -0
  38. polydb/errors.py +82 -0
  39. polydb/factory.py +107 -0
  40. polydb/models.py +39 -0
  41. polydb/monitoring.py +313 -0
  42. polydb/multitenancy.py +197 -0
  43. polydb/py.typed +0 -0
  44. polydb/query.py +150 -0
  45. polydb/registry.py +71 -0
  46. polydb/retry.py +76 -0
  47. polydb/schema.py +205 -0
  48. polydb/security.py +458 -0
  49. polydb/types.py +127 -0
  50. polydb/utils.py +61 -0
  51. polydb/validation.py +131 -0
polydb/validation.py ADDED
@@ -0,0 +1,131 @@
1
+ # src/polydb/validation.py
2
+ """
3
+ Model metadata validation and schema enforcement
4
+ """
5
+ from typing import Type, Dict, Any, List, Optional
6
+ from dataclasses import dataclass
7
+ from .errors import InvalidModelMetadataError, ValidationError
8
+
9
+ @dataclass
10
+ class ValidationResult:
11
+ valid: bool
12
+ errors: List[str]
13
+ warnings: List[str]
14
+
15
+
16
+ class ModelValidator:
17
+ """Validates model metadata and schema"""
18
+
19
+ REQUIRED_FIELDS = {'storage'}
20
+ VALID_STORAGE_TYPES = {'sql', 'nosql'}
21
+ SQL_REQUIRED_FIELDS = {'table'}
22
+ NOSQL_OPTIONAL_FIELDS = {'collection', 'pk_field', 'rk_field'}
23
+
24
+ @classmethod
25
+ def validate_model(cls, model: Type) -> ValidationResult:
26
+ """Comprehensive model validation"""
27
+ errors = []
28
+ warnings = []
29
+
30
+ # Check __polydb__ exists
31
+ if not hasattr(model, '__polydb__'):
32
+ errors.append(f"Model {model.__name__} missing __polydb__ metadata")
33
+ return ValidationResult(valid=False, errors=errors, warnings=warnings)
34
+
35
+ meta = getattr(model, '__polydb__')
36
+
37
+ # Check it's a dict
38
+ if not isinstance(meta, dict):
39
+ errors.append(f"__polydb__ must be a dict, got {type(meta)}")
40
+ return ValidationResult(valid=False, errors=errors, warnings=warnings)
41
+
42
+ # Check required fields
43
+ for field in cls.REQUIRED_FIELDS:
44
+ if field not in meta:
45
+ errors.append(f"Missing required field: {field}")
46
+
47
+ # Validate storage type
48
+ storage = meta.get('storage')
49
+ if storage and storage not in cls.VALID_STORAGE_TYPES:
50
+ errors.append(f"Invalid storage type: {storage}. Must be one of {cls.VALID_STORAGE_TYPES}")
51
+
52
+ # Storage-specific validation
53
+ if storage == 'sql':
54
+ for field in cls.SQL_REQUIRED_FIELDS:
55
+ if field not in meta:
56
+ errors.append(f"SQL storage requires field: {field}")
57
+
58
+ elif storage == 'nosql':
59
+ # NoSQL has optional fields, warn if missing common ones
60
+ if 'pk_field' not in meta:
61
+ warnings.append("No pk_field specified, will default to 'id'")
62
+
63
+ if not meta.get('collection') and not meta.get('table'):
64
+ warnings.append("No collection/table name specified, will use model name")
65
+
66
+ # Validate cache settings
67
+ if meta.get('cache') and not isinstance(meta.get('cache_ttl'), (int, type(None))):
68
+ errors.append("cache_ttl must be an integer or None")
69
+
70
+ # Validate provider
71
+ valid_providers = {'azure', 'aws', 'gcp', 'vercel', 'mongodb', 'postgresql'}
72
+ provider = meta.get('provider')
73
+ if provider and provider.lower() not in valid_providers:
74
+ warnings.append(f"Unusual provider: {provider}")
75
+
76
+ return ValidationResult(
77
+ valid=len(errors) == 0,
78
+ errors=errors,
79
+ warnings=warnings
80
+ )
81
+
82
+ @classmethod
83
+ def validate_and_raise(cls, model: Type):
84
+ """Validate and raise if invalid"""
85
+ result = cls.validate_model(model)
86
+
87
+ if not result.valid:
88
+ raise InvalidModelMetadataError(
89
+ f"Invalid model {model.__name__}: {', '.join(result.errors)}"
90
+ )
91
+
92
+ # Log warnings
93
+ if result.warnings:
94
+ import logging
95
+ logger = logging.getLogger(__name__)
96
+ for warning in result.warnings:
97
+ logger.warning(f"{model.__name__}: {warning}")
98
+
99
+
100
+ class SchemaValidator:
101
+ """Validates data against model schema"""
102
+
103
+ @staticmethod
104
+ def validate_data(model: Type, data: Dict[str, Any]) -> ValidationResult:
105
+ """Validate data against model requirements"""
106
+ errors = []
107
+ warnings = []
108
+
109
+ meta = getattr(model, '__polydb__', {})
110
+
111
+ # Check required keys exist
112
+ pk_field = meta.get('pk_field', 'id')
113
+ if pk_field not in data and not meta.get('auto_generate'):
114
+ errors.append(f"Missing required field: {pk_field}")
115
+
116
+ # Check field types if type hints available
117
+ if hasattr(model, '__annotations__'):
118
+ annotations = model.__annotations__
119
+ for field_name, expected_type in annotations.items():
120
+ if field_name in data:
121
+ actual_value = data[field_name]
122
+ if not isinstance(actual_value, expected_type):
123
+ warnings.append(
124
+ f"Field {field_name} expected {expected_type}, got {type(actual_value)}"
125
+ )
126
+
127
+ return ValidationResult(
128
+ valid=len(errors) == 0,
129
+ errors=errors,
130
+ warnings=warnings
131
+ )