additory 0.1.0a4__py3-none-any.whl → 0.1.1a1__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 (121) hide show
  1. additory/__init__.py +58 -14
  2. additory/common/__init__.py +31 -147
  3. additory/common/column_selector.py +255 -0
  4. additory/common/distributions.py +286 -613
  5. additory/common/extractors.py +313 -0
  6. additory/common/knn_imputation.py +332 -0
  7. additory/common/result.py +380 -0
  8. additory/common/strategy_parser.py +243 -0
  9. additory/common/unit_conversions.py +338 -0
  10. additory/common/validation.py +283 -103
  11. additory/core/__init__.py +34 -22
  12. additory/core/backend.py +258 -0
  13. additory/core/config.py +177 -305
  14. additory/core/logging.py +230 -24
  15. additory/core/memory_manager.py +157 -495
  16. additory/expressions/__init__.py +2 -23
  17. additory/expressions/compiler.py +457 -0
  18. additory/expressions/engine.py +264 -487
  19. additory/expressions/integrity.py +179 -0
  20. additory/expressions/loader.py +263 -0
  21. additory/expressions/parser.py +363 -167
  22. additory/expressions/resolver.py +274 -0
  23. additory/functions/__init__.py +1 -0
  24. additory/functions/analyze/__init__.py +144 -0
  25. additory/functions/analyze/cardinality.py +58 -0
  26. additory/functions/analyze/correlations.py +66 -0
  27. additory/functions/analyze/distributions.py +53 -0
  28. additory/functions/analyze/duplicates.py +49 -0
  29. additory/functions/analyze/features.py +61 -0
  30. additory/functions/analyze/imputation.py +66 -0
  31. additory/functions/analyze/outliers.py +65 -0
  32. additory/functions/analyze/patterns.py +65 -0
  33. additory/functions/analyze/presets.py +72 -0
  34. additory/functions/analyze/quality.py +59 -0
  35. additory/functions/analyze/timeseries.py +53 -0
  36. additory/functions/analyze/types.py +45 -0
  37. additory/functions/expressions/__init__.py +161 -0
  38. additory/functions/snapshot/__init__.py +82 -0
  39. additory/functions/snapshot/filter.py +119 -0
  40. additory/functions/synthetic/__init__.py +113 -0
  41. additory/functions/synthetic/mode_detector.py +47 -0
  42. additory/functions/synthetic/strategies/__init__.py +1 -0
  43. additory/functions/synthetic/strategies/advanced.py +35 -0
  44. additory/functions/synthetic/strategies/augmentative.py +160 -0
  45. additory/functions/synthetic/strategies/generative.py +168 -0
  46. additory/functions/synthetic/strategies/presets.py +116 -0
  47. additory/functions/to/__init__.py +188 -0
  48. additory/functions/to/lookup.py +351 -0
  49. additory/functions/to/merge.py +189 -0
  50. additory/functions/to/sort.py +91 -0
  51. additory/functions/to/summarize.py +170 -0
  52. additory/functions/transform/__init__.py +140 -0
  53. additory/functions/transform/datetime.py +79 -0
  54. additory/functions/transform/extract.py +85 -0
  55. additory/functions/transform/harmonize.py +105 -0
  56. additory/functions/transform/knn.py +62 -0
  57. additory/functions/transform/onehotencoding.py +68 -0
  58. additory/functions/transform/transpose.py +42 -0
  59. additory-0.1.1a1.dist-info/METADATA +83 -0
  60. additory-0.1.1a1.dist-info/RECORD +62 -0
  61. additory/analysis/__init__.py +0 -48
  62. additory/analysis/cardinality.py +0 -126
  63. additory/analysis/correlations.py +0 -124
  64. additory/analysis/distributions.py +0 -376
  65. additory/analysis/quality.py +0 -158
  66. additory/analysis/scan.py +0 -400
  67. additory/common/backend.py +0 -371
  68. additory/common/column_utils.py +0 -191
  69. additory/common/exceptions.py +0 -62
  70. additory/common/lists.py +0 -229
  71. additory/common/patterns.py +0 -240
  72. additory/common/resolver.py +0 -567
  73. additory/common/sample_data.py +0 -182
  74. additory/core/ast_builder.py +0 -165
  75. additory/core/backends/__init__.py +0 -23
  76. additory/core/backends/arrow_bridge.py +0 -483
  77. additory/core/backends/cudf_bridge.py +0 -355
  78. additory/core/column_positioning.py +0 -358
  79. additory/core/compiler_polars.py +0 -166
  80. additory/core/enhanced_cache_manager.py +0 -1119
  81. additory/core/enhanced_matchers.py +0 -473
  82. additory/core/enhanced_version_manager.py +0 -325
  83. additory/core/executor.py +0 -59
  84. additory/core/integrity_manager.py +0 -477
  85. additory/core/loader.py +0 -190
  86. additory/core/namespace_manager.py +0 -657
  87. additory/core/parser.py +0 -176
  88. additory/core/polars_expression_engine.py +0 -601
  89. additory/core/registry.py +0 -177
  90. additory/core/sample_data_manager.py +0 -492
  91. additory/core/user_namespace.py +0 -751
  92. additory/core/validator.py +0 -27
  93. additory/dynamic_api.py +0 -352
  94. additory/expressions/proxy.py +0 -549
  95. additory/expressions/registry.py +0 -313
  96. additory/expressions/samples.py +0 -492
  97. additory/synthetic/__init__.py +0 -13
  98. additory/synthetic/column_name_resolver.py +0 -149
  99. additory/synthetic/deduce.py +0 -259
  100. additory/synthetic/distributions.py +0 -22
  101. additory/synthetic/forecast.py +0 -1132
  102. additory/synthetic/linked_list_parser.py +0 -415
  103. additory/synthetic/namespace_lookup.py +0 -129
  104. additory/synthetic/smote.py +0 -320
  105. additory/synthetic/strategies.py +0 -926
  106. additory/synthetic/synthesizer.py +0 -713
  107. additory/utilities/__init__.py +0 -53
  108. additory/utilities/encoding.py +0 -600
  109. additory/utilities/games.py +0 -300
  110. additory/utilities/keys.py +0 -8
  111. additory/utilities/lookup.py +0 -103
  112. additory/utilities/matchers.py +0 -216
  113. additory/utilities/resolvers.py +0 -286
  114. additory/utilities/settings.py +0 -167
  115. additory/utilities/units.py +0 -749
  116. additory/utilities/validators.py +0 -153
  117. additory-0.1.0a4.dist-info/METADATA +0 -311
  118. additory-0.1.0a4.dist-info/RECORD +0 -72
  119. additory-0.1.0a4.dist-info/licenses/LICENSE +0 -21
  120. {additory-0.1.0a4.dist-info → additory-0.1.1a1.dist-info}/WHEEL +0 -0
  121. {additory-0.1.0a4.dist-info → additory-0.1.1a1.dist-info}/top_level.txt +0 -0
additory/core/logging.py CHANGED
@@ -1,24 +1,230 @@
1
- def log_info(message: str):
2
- # INFO logging commented out for v0.1.0 - will be re-enabled in v0.1.1
3
- # print(f"[INFO] {message}")
4
- pass
5
-
6
- def log_warning(message: str):
7
- print(f"[WARNING] {message}")
8
-
9
- def log_error(message: str):
10
- print(f"[ERROR] {message}")
11
-
12
- # Logging control functions for v0.1.1
13
- def enable_verbose_logging():
14
- """Enable verbose INFO logging (for v0.1.1)"""
15
- global _verbose_logging_enabled
16
- _verbose_logging_enabled = True
17
-
18
- def disable_verbose_logging():
19
- """Disable verbose INFO logging"""
20
- global _verbose_logging_enabled
21
- _verbose_logging_enabled = False
22
-
23
- # Global flag for verbose logging (for future use)
24
- _verbose_logging_enabled = False
1
+ """
2
+ Transparent logging system for Additory operations.
3
+
4
+ Provides clear, actionable messages about:
5
+ - Information: Assumptions and defaults
6
+ - Warnings: Why processing stopped
7
+ - Errors: Where errors occurred
8
+
9
+ Principle: "If it feels like magic, explain it!"
10
+ """
11
+
12
+ from datetime import datetime
13
+ from typing import Dict, List, Optional
14
+ import json
15
+
16
+
17
+ class Logger:
18
+ """
19
+ Centralized logger for all additory operations.
20
+
21
+ Provides three levels of logging:
22
+ - info: Explain assumptions and defaults
23
+ - warning: Explain why processing stopped
24
+ - error: Show where error occurred
25
+ """
26
+
27
+ def __init__(self, level: str = 'info'):
28
+ """
29
+ Initialize logger with level.
30
+
31
+ Args:
32
+ level: Logging level ('info', 'warning', 'error', 'silent')
33
+ """
34
+ self.level = level
35
+ self.context: Dict = {}
36
+ self.messages: List[Dict] = []
37
+ self._validate_level(level)
38
+
39
+ def _validate_level(self, level: str) -> None:
40
+ """Validate logging level."""
41
+ valid_levels = ['info', 'warning', 'error', 'silent']
42
+ if level not in valid_levels:
43
+ raise ValueError(f"Invalid log level '{level}'. Must be one of: {valid_levels}")
44
+
45
+ def set_level(self, level: str) -> None:
46
+ """
47
+ Set logging level.
48
+
49
+ Args:
50
+ level: New logging level ('info', 'warning', 'error', 'silent')
51
+ """
52
+ self._validate_level(level)
53
+ self.level = level
54
+
55
+ def set_context(self, operation: str, details: Optional[Dict] = None) -> None:
56
+ """
57
+ Set current operation context.
58
+
59
+ Args:
60
+ operation: Operation name ('to', 'transform', 'snapshot', 'synthetic', 'analyze')
61
+ details: Optional operation details
62
+ """
63
+ self.context = {
64
+ 'operation': operation,
65
+ 'details': details or {},
66
+ 'timestamp': datetime.now().isoformat()
67
+ }
68
+
69
+ def info(self, message: str, details: Optional[Dict] = None) -> None:
70
+ """
71
+ Log information message (assumptions, defaults).
72
+
73
+ Args:
74
+ message: Information message
75
+ details: Optional additional details
76
+
77
+ Example:
78
+ logger.info("Using 'fetch if unique' mode for column 'price'")
79
+ logger.info("Detected pandas DataFrame, converting to Polars")
80
+ """
81
+ if self.level == 'info':
82
+ self._log('info', message, details)
83
+
84
+ def warning(self, message: str, details: Optional[Dict] = None) -> None:
85
+ """
86
+ Log warning message (why processing stopped).
87
+
88
+ Args:
89
+ message: Warning message
90
+ details: Optional additional details
91
+
92
+ Example:
93
+ logger.warning("Many-to-many relationship detected, cannot proceed")
94
+ logger.warning("Duplicate expression name 'bmi' found")
95
+ """
96
+ if self.level in ['info', 'warning']:
97
+ self._log('warning', message, details)
98
+
99
+ def error(self, message: str, error_location: str, details: Optional[Dict] = None) -> None:
100
+ """
101
+ Log error message (where error occurred).
102
+
103
+ Args:
104
+ message: Error message
105
+ error_location: Where error occurred ('df', 'expression', 'strategy', etc.)
106
+ details: Optional additional details
107
+
108
+ Example:
109
+ logger.error("Column 'age' not found", error_location='df')
110
+ logger.error("Division by zero", error_location='expression')
111
+ """
112
+ if self.level != 'silent':
113
+ error_details = details or {}
114
+ error_details['error_location'] = error_location
115
+ self._log('error', message, error_details)
116
+
117
+ def _log(self, level: str, message: str, details: Optional[Dict] = None) -> None:
118
+ """Internal method to log a message."""
119
+ log_entry = {
120
+ 'level': level,
121
+ 'message': message,
122
+ 'context': self.context.copy(),
123
+ 'details': details or {},
124
+ 'timestamp': datetime.now().isoformat()
125
+ }
126
+ self.messages.append(log_entry)
127
+
128
+ # Print formatted message
129
+ formatted = format_message(level, message, self.context, details or {})
130
+ print(formatted)
131
+
132
+ def get_messages(self, level: Optional[str] = None) -> List[Dict]:
133
+ """
134
+ Get logged messages.
135
+
136
+ Args:
137
+ level: Filter by level (None = all)
138
+
139
+ Returns:
140
+ List of message dictionaries
141
+ """
142
+ if level is None:
143
+ return self.messages.copy()
144
+ return [msg for msg in self.messages if msg['level'] == level]
145
+
146
+ def clear(self) -> None:
147
+ """Clear all logged messages."""
148
+ self.messages.clear()
149
+ self.context.clear()
150
+
151
+
152
+ # Global logger instance
153
+ _global_logger: Optional[Logger] = None
154
+
155
+
156
+ def get_logger() -> Logger:
157
+ """
158
+ Get the global logger instance.
159
+
160
+ Returns:
161
+ Global Logger instance
162
+
163
+ Example:
164
+ logger = get_logger()
165
+ logger.info("Processing started")
166
+ """
167
+ global _global_logger
168
+ if _global_logger is None:
169
+ _global_logger = Logger()
170
+ return _global_logger
171
+
172
+
173
+ def set_log_level(level: str) -> None:
174
+ """
175
+ Set global logging level.
176
+
177
+ Args:
178
+ level: Logging level ('info', 'warning', 'error', 'silent')
179
+
180
+ Example:
181
+ import additory
182
+ additory.add.set_log_level('warning')
183
+ """
184
+ logger = get_logger()
185
+ logger.set_level(level)
186
+
187
+
188
+ def format_message(level: str, message: str, context: Dict, details: Dict) -> str:
189
+ """
190
+ Format log message for display.
191
+
192
+ Args:
193
+ level: Message level
194
+ message: Message text
195
+ context: Operation context
196
+ details: Additional details
197
+
198
+ Returns:
199
+ Formatted message string
200
+ """
201
+ # Level prefix with emoji
202
+ level_prefix = {
203
+ 'info': 'ℹ️ INFO',
204
+ 'warning': '⚠️ WARNING',
205
+ 'error': '❌ ERROR'
206
+ }
207
+
208
+ prefix = level_prefix.get(level, level.upper())
209
+
210
+ # Build message
211
+ parts = [f"[{prefix}]"]
212
+
213
+ # Add context if available
214
+ if context and 'operation' in context:
215
+ parts.append(f"[{context['operation']}]")
216
+
217
+ # Add main message
218
+ parts.append(message)
219
+
220
+ formatted = " ".join(parts)
221
+
222
+ # Add details if available and not empty
223
+ if details and any(details.values()):
224
+ # Filter out None values and format
225
+ clean_details = {k: v for k, v in details.items() if v is not None}
226
+ if clean_details:
227
+ details_str = json.dumps(clean_details, indent=2)
228
+ formatted += f"\n Details: {details_str}"
229
+
230
+ return formatted