fraiseql-confiture 0.3.7__cp311-cp311-macosx_11_0_arm64.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 (124) hide show
  1. confiture/__init__.py +48 -0
  2. confiture/_core.cpython-311-darwin.so +0 -0
  3. confiture/cli/__init__.py +0 -0
  4. confiture/cli/dry_run.py +116 -0
  5. confiture/cli/lint_formatter.py +193 -0
  6. confiture/cli/main.py +1893 -0
  7. confiture/config/__init__.py +0 -0
  8. confiture/config/environment.py +263 -0
  9. confiture/core/__init__.py +51 -0
  10. confiture/core/anonymization/__init__.py +0 -0
  11. confiture/core/anonymization/audit.py +485 -0
  12. confiture/core/anonymization/benchmarking.py +372 -0
  13. confiture/core/anonymization/breach_notification.py +652 -0
  14. confiture/core/anonymization/compliance.py +617 -0
  15. confiture/core/anonymization/composer.py +298 -0
  16. confiture/core/anonymization/data_subject_rights.py +669 -0
  17. confiture/core/anonymization/factory.py +319 -0
  18. confiture/core/anonymization/governance.py +737 -0
  19. confiture/core/anonymization/performance.py +1092 -0
  20. confiture/core/anonymization/profile.py +284 -0
  21. confiture/core/anonymization/registry.py +195 -0
  22. confiture/core/anonymization/security/kms_manager.py +547 -0
  23. confiture/core/anonymization/security/lineage.py +888 -0
  24. confiture/core/anonymization/security/token_store.py +686 -0
  25. confiture/core/anonymization/strategies/__init__.py +41 -0
  26. confiture/core/anonymization/strategies/address.py +359 -0
  27. confiture/core/anonymization/strategies/credit_card.py +374 -0
  28. confiture/core/anonymization/strategies/custom.py +161 -0
  29. confiture/core/anonymization/strategies/date.py +218 -0
  30. confiture/core/anonymization/strategies/differential_privacy.py +398 -0
  31. confiture/core/anonymization/strategies/email.py +141 -0
  32. confiture/core/anonymization/strategies/format_preserving_encryption.py +310 -0
  33. confiture/core/anonymization/strategies/hash.py +150 -0
  34. confiture/core/anonymization/strategies/ip_address.py +235 -0
  35. confiture/core/anonymization/strategies/masking_retention.py +252 -0
  36. confiture/core/anonymization/strategies/name.py +298 -0
  37. confiture/core/anonymization/strategies/phone.py +119 -0
  38. confiture/core/anonymization/strategies/preserve.py +85 -0
  39. confiture/core/anonymization/strategies/redact.py +101 -0
  40. confiture/core/anonymization/strategies/salted_hashing.py +322 -0
  41. confiture/core/anonymization/strategies/text_redaction.py +183 -0
  42. confiture/core/anonymization/strategies/tokenization.py +334 -0
  43. confiture/core/anonymization/strategy.py +241 -0
  44. confiture/core/anonymization/syncer_audit.py +357 -0
  45. confiture/core/blue_green.py +683 -0
  46. confiture/core/builder.py +500 -0
  47. confiture/core/checksum.py +358 -0
  48. confiture/core/connection.py +184 -0
  49. confiture/core/differ.py +522 -0
  50. confiture/core/drift.py +564 -0
  51. confiture/core/dry_run.py +182 -0
  52. confiture/core/health.py +313 -0
  53. confiture/core/hooks/__init__.py +87 -0
  54. confiture/core/hooks/base.py +232 -0
  55. confiture/core/hooks/context.py +146 -0
  56. confiture/core/hooks/execution_strategies.py +57 -0
  57. confiture/core/hooks/observability.py +220 -0
  58. confiture/core/hooks/phases.py +53 -0
  59. confiture/core/hooks/registry.py +295 -0
  60. confiture/core/large_tables.py +775 -0
  61. confiture/core/linting/__init__.py +70 -0
  62. confiture/core/linting/composer.py +192 -0
  63. confiture/core/linting/libraries/__init__.py +17 -0
  64. confiture/core/linting/libraries/gdpr.py +168 -0
  65. confiture/core/linting/libraries/general.py +184 -0
  66. confiture/core/linting/libraries/hipaa.py +144 -0
  67. confiture/core/linting/libraries/pci_dss.py +104 -0
  68. confiture/core/linting/libraries/sox.py +120 -0
  69. confiture/core/linting/schema_linter.py +491 -0
  70. confiture/core/linting/versioning.py +151 -0
  71. confiture/core/locking.py +389 -0
  72. confiture/core/migration_generator.py +298 -0
  73. confiture/core/migrator.py +882 -0
  74. confiture/core/observability/__init__.py +44 -0
  75. confiture/core/observability/audit.py +323 -0
  76. confiture/core/observability/logging.py +187 -0
  77. confiture/core/observability/metrics.py +174 -0
  78. confiture/core/observability/tracing.py +192 -0
  79. confiture/core/pg_version.py +418 -0
  80. confiture/core/pool.py +406 -0
  81. confiture/core/risk/__init__.py +39 -0
  82. confiture/core/risk/predictor.py +188 -0
  83. confiture/core/risk/scoring.py +248 -0
  84. confiture/core/rollback_generator.py +388 -0
  85. confiture/core/schema_analyzer.py +769 -0
  86. confiture/core/schema_to_schema.py +590 -0
  87. confiture/core/security/__init__.py +32 -0
  88. confiture/core/security/logging.py +201 -0
  89. confiture/core/security/validation.py +416 -0
  90. confiture/core/signals.py +371 -0
  91. confiture/core/syncer.py +540 -0
  92. confiture/exceptions.py +192 -0
  93. confiture/integrations/__init__.py +0 -0
  94. confiture/models/__init__.py +24 -0
  95. confiture/models/lint.py +193 -0
  96. confiture/models/migration.py +265 -0
  97. confiture/models/schema.py +203 -0
  98. confiture/models/sql_file_migration.py +225 -0
  99. confiture/scenarios/__init__.py +36 -0
  100. confiture/scenarios/compliance.py +586 -0
  101. confiture/scenarios/ecommerce.py +199 -0
  102. confiture/scenarios/financial.py +253 -0
  103. confiture/scenarios/healthcare.py +315 -0
  104. confiture/scenarios/multi_tenant.py +340 -0
  105. confiture/scenarios/saas.py +295 -0
  106. confiture/testing/FRAMEWORK_API.md +722 -0
  107. confiture/testing/__init__.py +100 -0
  108. confiture/testing/fixtures/__init__.py +11 -0
  109. confiture/testing/fixtures/data_validator.py +229 -0
  110. confiture/testing/fixtures/migration_runner.py +167 -0
  111. confiture/testing/fixtures/schema_snapshotter.py +352 -0
  112. confiture/testing/frameworks/__init__.py +10 -0
  113. confiture/testing/frameworks/mutation.py +587 -0
  114. confiture/testing/frameworks/performance.py +479 -0
  115. confiture/testing/loader.py +225 -0
  116. confiture/testing/pytest/__init__.py +38 -0
  117. confiture/testing/pytest_plugin.py +190 -0
  118. confiture/testing/sandbox.py +304 -0
  119. confiture/testing/utils/__init__.py +0 -0
  120. fraiseql_confiture-0.3.7.dist-info/METADATA +438 -0
  121. fraiseql_confiture-0.3.7.dist-info/RECORD +124 -0
  122. fraiseql_confiture-0.3.7.dist-info/WHEEL +4 -0
  123. fraiseql_confiture-0.3.7.dist-info/entry_points.txt +4 -0
  124. fraiseql_confiture-0.3.7.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,199 @@
1
+ """E-commerce customer data anonymization scenario.
2
+
3
+ Real-world use case: Anonymizing customer data for analytics while protecting PII.
4
+
5
+ Data Types:
6
+ - Customer names (PII)
7
+ - Email addresses (PII)
8
+ - Phone numbers (PII)
9
+ - Physical addresses (PII)
10
+ - Birth dates (sensitive)
11
+ - Payment methods (PCI-DSS)
12
+ - Order totals (safe to keep)
13
+ - Order dates (may need masking)
14
+
15
+ Strategy:
16
+ - Names: Firstname/lastname format
17
+ - Emails: Email redaction pattern
18
+ - Phone: Phone masking
19
+ - Addresses: Field preservation (city, state only)
20
+ - Dates: Month/year only
21
+ - Credit cards: Last 4 digits only
22
+ - Order totals: Preserve as-is
23
+ - Order dates: Preserve year/month
24
+ """
25
+
26
+ from confiture.core.anonymization.factory import StrategyFactory, StrategyProfile
27
+
28
+
29
+ class ECommerceScenario:
30
+ """E-commerce data anonymization scenario.
31
+
32
+ Demonstrates anonymizing customer data while preserving business analytics data.
33
+
34
+ Example:
35
+ >>> scenario = ECommerceScenario()
36
+ >>> data = {
37
+ ... "customer_id": "CUST-12345",
38
+ ... "first_name": "John",
39
+ ... "last_name": "Doe",
40
+ ... "email": "john.doe@example.com",
41
+ ... "phone": "555-123-4567",
42
+ ... "address": "123 Main St, Anytown, CA 90210",
43
+ ... "birth_date": "1985-06-15",
44
+ ... "payment_method": "Visa",
45
+ ... "card_number": "4242424242424242",
46
+ ... "order_total": 129.99,
47
+ ... "order_date": "2024-12-15",
48
+ ... }
49
+ >>> anonymized = scenario.anonymize(data)
50
+ >>> # PII masked, business data preserved
51
+ """
52
+
53
+ @staticmethod
54
+ def get_profile() -> StrategyProfile:
55
+ """Get E-commerce anonymization profile.
56
+
57
+ Returns:
58
+ StrategyProfile configured for e-commerce data.
59
+
60
+ Strategy Mapping:
61
+ - customer_id: preserve (business identifier)
62
+ - first_name: name masking (firstname only)
63
+ - last_name: name masking (lastname only)
64
+ - email: email redaction
65
+ - phone: phone masking
66
+ - address: address masking (city/state only)
67
+ - birth_date: date masking (preserve year/month)
68
+ - payment_method: preserve (business data)
69
+ - card_number: credit card masking (last 4)
70
+ - order_total: preserve (business data)
71
+ - order_date: date masking (preserve year/month)
72
+ """
73
+ return StrategyProfile(
74
+ name="ecommerce",
75
+ seed=42, # Fixed seed for reproducibility
76
+ columns={
77
+ # Identifiers - preserve
78
+ "customer_id": "preserve",
79
+ "order_id": "preserve",
80
+ # PII - mask
81
+ "first_name": "name",
82
+ "last_name": "name",
83
+ "full_name": "name",
84
+ "customer_name": "name",
85
+ # Contact - redact
86
+ "email": "text_redaction",
87
+ "phone": "text_redaction",
88
+ "phone_number": "text_redaction",
89
+ # Address - preserve with masking
90
+ "address": "address",
91
+ "street": "address",
92
+ "city": "preserve", # Often kept for analytics
93
+ "state": "preserve",
94
+ "zip": "preserve",
95
+ "postal_code": "preserve",
96
+ # Sensitive dates - mask month/year
97
+ "birth_date": "date",
98
+ "dob": "date",
99
+ "date_of_birth": "date",
100
+ # Payment - PCI-DSS compliant
101
+ "payment_method": "preserve",
102
+ "payment_type": "preserve",
103
+ "card_type": "preserve",
104
+ "card_number": "credit_card",
105
+ # Business data - preserve
106
+ "order_total": "preserve",
107
+ "order_amount": "preserve",
108
+ "subtotal": "preserve",
109
+ "tax": "preserve",
110
+ "shipping": "preserve",
111
+ "discount": "preserve",
112
+ "quantity": "preserve",
113
+ "product_id": "preserve",
114
+ "sku": "preserve",
115
+ # Dates - preserve with masking
116
+ "order_date": "date",
117
+ "purchase_date": "date",
118
+ "created_at": "date",
119
+ "updated_at": "date",
120
+ "shipped_date": "date",
121
+ "delivered_date": "date",
122
+ # Location data
123
+ "ip_address": "ip_address",
124
+ "country": "preserve",
125
+ "region": "preserve",
126
+ },
127
+ defaults="preserve",
128
+ )
129
+
130
+ @classmethod
131
+ def create_factory(cls) -> StrategyFactory:
132
+ """Create factory for e-commerce anonymization.
133
+
134
+ Returns:
135
+ Configured StrategyFactory for e-commerce data.
136
+ """
137
+ profile = cls.get_profile()
138
+ return StrategyFactory(profile)
139
+
140
+ @classmethod
141
+ def anonymize(cls, data: dict) -> dict:
142
+ """Anonymize e-commerce data.
143
+
144
+ Args:
145
+ data: Customer/order data dictionary.
146
+
147
+ Returns:
148
+ Anonymized data with PII masked and business data preserved.
149
+
150
+ Example:
151
+ >>> data = {
152
+ ... "customer_id": "CUST-12345",
153
+ ... "first_name": "John",
154
+ ... "email": "john@example.com",
155
+ ... "order_total": 129.99,
156
+ ... }
157
+ >>> result = ECommerceScenario.anonymize(data)
158
+ >>> result["customer_id"] # Preserved
159
+ 'CUST-12345'
160
+ >>> result["first_name"] # Anonymized
161
+ 'Michael'
162
+ >>> result["email"] # Redacted
163
+ '[EMAIL]'
164
+ >>> result["order_total"] # Preserved
165
+ 129.99
166
+ """
167
+ factory = cls.create_factory()
168
+ return factory.anonymize(data)
169
+
170
+ @classmethod
171
+ def anonymize_batch(cls, data_list: list[dict]) -> list[dict]:
172
+ """Anonymize batch of e-commerce data.
173
+
174
+ Args:
175
+ data_list: List of customer/order data dictionaries.
176
+
177
+ Returns:
178
+ List of anonymized data records.
179
+
180
+ Example:
181
+ >>> data = [
182
+ ... {"customer_id": "CUST-1", "first_name": "John", ...},
183
+ ... {"customer_id": "CUST-2", "first_name": "Jane", ...},
184
+ ... ]
185
+ >>> results = ECommerceScenario.anonymize_batch(data)
186
+ """
187
+ factory = cls.create_factory()
188
+ return [factory.anonymize(record) for record in data_list]
189
+
190
+ @classmethod
191
+ def get_strategy_info(cls) -> dict:
192
+ """Get information about strategies used.
193
+
194
+ Returns:
195
+ Dictionary mapping column names to strategy names.
196
+ """
197
+ profile = cls.get_profile()
198
+ factory = StrategyFactory(profile)
199
+ return factory.list_column_strategies()
@@ -0,0 +1,253 @@
1
+ """Financial services PII and sensitive data anonymization scenario.
2
+
3
+ Real-world use case: Anonymizing loan applications, credit data, and financial records.
4
+
5
+ Data Types:
6
+ - Applicant names (PII)
7
+ - Social security numbers (PII - highly sensitive)
8
+ - Email addresses (PII)
9
+ - Phone numbers (PII)
10
+ - Physical addresses (PII)
11
+ - Employment information (sensitive)
12
+ - Income data (sensitive)
13
+ - Credit scores (sensitive)
14
+ - Bank account information (PCI-DSS)
15
+ - Loan amounts (preserve for analysis)
16
+ - Interest rates (preserve for analysis)
17
+ - Credit limit (preserve for analysis)
18
+ - Dates (application, decision, disbursement)
19
+ - Employment dates (sensitive)
20
+
21
+ Strategy:
22
+ - Names: Complete masking
23
+ - SSN: Pattern redaction (###-##-XXXX)
24
+ - Email: Email redaction
25
+ - Phone: Phone masking
26
+ - Addresses: Field preservation (state/zip)
27
+ - Employment: Name masking + dates
28
+ - Income: Preserve (business data)
29
+ - Credit scores: Preserve (business data)
30
+ - Bank accounts: Hash replacement
31
+ - Loan amounts: Preserve (business data)
32
+ - Dates: Preserve year/month
33
+ """
34
+
35
+ from confiture.core.anonymization.factory import StrategyFactory, StrategyProfile
36
+
37
+
38
+ class FinancialScenario:
39
+ """Financial services data anonymization scenario.
40
+
41
+ Demonstrates anonymizing loan applications and credit data while preserving
42
+ financial analytics data.
43
+
44
+ Example:
45
+ >>> scenario = FinancialScenario()
46
+ >>> data = {
47
+ ... "application_id": "APP-2024-001",
48
+ ... "applicant_name": "John Smith",
49
+ ... "ssn": "123-45-6789",
50
+ ... "text_redaction": "john.smith@example.com",
51
+ ... "text_redaction": "555-123-4567",
52
+ ... "address": "123 Main St, Anytown, CA 90210",
53
+ ... "employment_name": "Acme Corp",
54
+ ... "employment_address": "456 Corporate Blvd",
55
+ ... "employment_start": "2015-06-01",
56
+ ... "employment_end": "2024-01-15",
57
+ ... "annual_income": 75000,
58
+ ... "credit_score": 750,
59
+ ... "bank_account": "4532194857632145",
60
+ ... "loan_amount": 250000,
61
+ ... "interest_rate": 4.5,
62
+ ... "loan_term": 30,
63
+ ... "application_date": "2024-11-01",
64
+ ... "decision_date": "2024-11-15",
65
+ ... }
66
+ >>> anonymized = scenario.anonymize(data)
67
+ >>> # PII masked, financial metrics preserved
68
+ """
69
+
70
+ @staticmethod
71
+ def get_profile() -> StrategyProfile:
72
+ """Get financial data anonymization profile.
73
+
74
+ Returns:
75
+ StrategyProfile configured for financial data anonymization.
76
+
77
+ Strategy Mapping:
78
+ - application_id: preserve (business identifier)
79
+ - applicant_name: name masking
80
+ - ssn: SSN pattern redaction
81
+ - email: email redaction
82
+ - phone: phone masking
83
+ - address: address masking (preserve state/zip)
84
+ - employment_name: name masking
85
+ - employment_address: address masking
86
+ - employment dates: date masking (preserve year/month)
87
+ - income: preserve (business data)
88
+ - credit_score: preserve (business data)
89
+ - bank_account: custom hash
90
+ - loan_amount: preserve (business data)
91
+ - interest_rate: preserve (business data)
92
+ - application_date: date masking
93
+ """
94
+ return StrategyProfile(
95
+ name="financial_services",
96
+ seed=42, # Fixed seed for reproducibility
97
+ columns={
98
+ # Application identifiers - preserve
99
+ "application_id": "preserve",
100
+ "loan_id": "preserve",
101
+ "account_id": "preserve",
102
+ "reference_number": "preserve",
103
+ # Applicant PII - mask
104
+ "applicant_name": "name",
105
+ "first_name": "name",
106
+ "last_name": "name",
107
+ "full_name": "name",
108
+ "co_applicant_name": "name",
109
+ # Sensitive identifiers - redact
110
+ "ssn": "text_redaction",
111
+ "social_security_number": "text_redaction",
112
+ "tax_id": "text_redaction",
113
+ "ein": "text_redaction",
114
+ # Contact - redact
115
+ "email": "text_redaction",
116
+ "phone": "text_redaction",
117
+ "phone_number": "text_redaction",
118
+ "cell_phone": "text_redaction",
119
+ "work_phone": "text_redaction",
120
+ # Address - preserve with masking
121
+ "address": "address",
122
+ "street_address": "address",
123
+ "city": "preserve",
124
+ "state": "preserve",
125
+ "zip": "preserve",
126
+ "postal_code": "preserve",
127
+ "country": "preserve",
128
+ # Employment - mask employer name but preserve dates
129
+ "employer_name": "name",
130
+ "employment_name": "name",
131
+ "job_title": "preserve",
132
+ "position": "preserve",
133
+ "employment_address": "address",
134
+ "employment_start_date": "date",
135
+ "employment_end_date": "date",
136
+ "employment_duration": "preserve",
137
+ "years_employed": "preserve",
138
+ # Financial metrics - preserve
139
+ "annual_income": "preserve",
140
+ "income": "preserve",
141
+ "gross_income": "preserve",
142
+ "net_income": "preserve",
143
+ "monthly_income": "preserve",
144
+ "other_income": "preserve",
145
+ "total_assets": "preserve",
146
+ "total_liabilities": "preserve",
147
+ # Credit data - preserve
148
+ "credit_score": "preserve",
149
+ "fico_score": "preserve",
150
+ "credit_limit": "preserve",
151
+ "available_credit": "preserve",
152
+ "outstanding_balance": "preserve",
153
+ "debt_to_income": "preserve",
154
+ "payment_history": "preserve",
155
+ # Bank/Payment - hash accounts
156
+ "bank_account": "custom",
157
+ "bank_account_number": "custom",
158
+ "routing_number": "custom",
159
+ "card_number": "credit_card",
160
+ "account_number": "custom",
161
+ # Loan details - preserve
162
+ "loan_amount": "preserve",
163
+ "principal": "preserve",
164
+ "interest_rate": "preserve",
165
+ "apr": "preserve",
166
+ "loan_term": "preserve",
167
+ "monthly_payment": "preserve",
168
+ "loan_type": "preserve",
169
+ "loan_purpose": "preserve",
170
+ "collateral": "preserve",
171
+ # Dates - mask to year/month
172
+ "application_date": "date",
173
+ "decision_date": "date",
174
+ "approval_date": "date",
175
+ "disbursement_date": "date",
176
+ "closing_date": "date",
177
+ "maturity_date": "date",
178
+ "payment_due_date": "preserve",
179
+ # Document references
180
+ "document_id": "preserve",
181
+ "document_type": "preserve",
182
+ "verification_status": "preserve",
183
+ # IP/technical - mask
184
+ "ip_address": "ip_address",
185
+ "device_id": "preserve",
186
+ },
187
+ defaults="preserve",
188
+ )
189
+
190
+ @classmethod
191
+ def create_factory(cls) -> StrategyFactory:
192
+ """Create factory for financial data anonymization.
193
+
194
+ Returns:
195
+ Configured StrategyFactory for financial services.
196
+ """
197
+ profile = cls.get_profile()
198
+ return StrategyFactory(profile)
199
+
200
+ @classmethod
201
+ def anonymize(cls, data: dict) -> dict:
202
+ """Anonymize financial services data.
203
+
204
+ Args:
205
+ data: Loan application or account data dictionary.
206
+
207
+ Returns:
208
+ Anonymized data with PII masked and financial metrics preserved.
209
+
210
+ Example:
211
+ >>> data = {
212
+ ... "application_id": "APP-2024-001",
213
+ ... "applicant_name": "John Smith",
214
+ ... "ssn": "123-45-6789",
215
+ ... "annual_income": 75000,
216
+ ... "credit_score": 750,
217
+ ... }
218
+ >>> result = FinancialScenario.anonymize(data)
219
+ >>> result["application_id"] # Preserved
220
+ 'APP-2024-001'
221
+ >>> result["applicant_name"] # Anonymized
222
+ 'Michael Johnson'
223
+ >>> result["ssn"] # Redacted
224
+ '[REDACTED]'
225
+ >>> result["annual_income"] # Preserved
226
+ 75000
227
+ """
228
+ factory = cls.create_factory()
229
+ return factory.anonymize(data)
230
+
231
+ @classmethod
232
+ def anonymize_batch(cls, data_list: list[dict]) -> list[dict]:
233
+ """Anonymize batch of financial records.
234
+
235
+ Args:
236
+ data_list: List of loan/account records.
237
+
238
+ Returns:
239
+ List of anonymized financial records.
240
+ """
241
+ factory = cls.create_factory()
242
+ return [factory.anonymize(record) for record in data_list]
243
+
244
+ @classmethod
245
+ def get_strategy_info(cls) -> dict:
246
+ """Get information about strategies used.
247
+
248
+ Returns:
249
+ Dictionary mapping column names to strategy names.
250
+ """
251
+ profile = cls.get_profile()
252
+ factory = StrategyFactory(profile)
253
+ return factory.list_column_strategies()