additory 0.1.0a1__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 (87) hide show
  1. additory/__init__.py +15 -0
  2. additory/analysis/__init__.py +48 -0
  3. additory/analysis/cardinality.py +126 -0
  4. additory/analysis/correlations.py +124 -0
  5. additory/analysis/distributions.py +376 -0
  6. additory/analysis/quality.py +158 -0
  7. additory/analysis/scan.py +400 -0
  8. additory/augment/__init__.py +24 -0
  9. additory/augment/augmentor.py +653 -0
  10. additory/augment/builtin_lists.py +430 -0
  11. additory/augment/distributions.py +22 -0
  12. additory/augment/forecast.py +1132 -0
  13. additory/augment/list_registry.py +177 -0
  14. additory/augment/smote.py +320 -0
  15. additory/augment/strategies.py +883 -0
  16. additory/common/__init__.py +157 -0
  17. additory/common/backend.py +355 -0
  18. additory/common/column_utils.py +191 -0
  19. additory/common/distributions.py +737 -0
  20. additory/common/exceptions.py +62 -0
  21. additory/common/lists.py +229 -0
  22. additory/common/patterns.py +240 -0
  23. additory/common/resolver.py +567 -0
  24. additory/common/sample_data.py +182 -0
  25. additory/common/validation.py +197 -0
  26. additory/core/__init__.py +27 -0
  27. additory/core/ast_builder.py +165 -0
  28. additory/core/backends/__init__.py +23 -0
  29. additory/core/backends/arrow_bridge.py +476 -0
  30. additory/core/backends/cudf_bridge.py +355 -0
  31. additory/core/column_positioning.py +358 -0
  32. additory/core/compiler_polars.py +166 -0
  33. additory/core/config.py +342 -0
  34. additory/core/enhanced_cache_manager.py +1119 -0
  35. additory/core/enhanced_matchers.py +473 -0
  36. additory/core/enhanced_version_manager.py +325 -0
  37. additory/core/executor.py +59 -0
  38. additory/core/integrity_manager.py +477 -0
  39. additory/core/loader.py +190 -0
  40. additory/core/logging.py +24 -0
  41. additory/core/memory_manager.py +547 -0
  42. additory/core/namespace_manager.py +657 -0
  43. additory/core/parser.py +176 -0
  44. additory/core/polars_expression_engine.py +551 -0
  45. additory/core/registry.py +176 -0
  46. additory/core/sample_data_manager.py +492 -0
  47. additory/core/user_namespace.py +751 -0
  48. additory/core/validator.py +27 -0
  49. additory/dynamic_api.py +308 -0
  50. additory/expressions/__init__.py +26 -0
  51. additory/expressions/engine.py +551 -0
  52. additory/expressions/parser.py +176 -0
  53. additory/expressions/proxy.py +546 -0
  54. additory/expressions/registry.py +313 -0
  55. additory/expressions/samples.py +492 -0
  56. additory/synthetic/__init__.py +101 -0
  57. additory/synthetic/api.py +220 -0
  58. additory/synthetic/common_integration.py +314 -0
  59. additory/synthetic/config.py +262 -0
  60. additory/synthetic/engines.py +529 -0
  61. additory/synthetic/exceptions.py +180 -0
  62. additory/synthetic/file_managers.py +518 -0
  63. additory/synthetic/generator.py +702 -0
  64. additory/synthetic/generator_parser.py +68 -0
  65. additory/synthetic/integration.py +319 -0
  66. additory/synthetic/models.py +241 -0
  67. additory/synthetic/pattern_resolver.py +573 -0
  68. additory/synthetic/performance.py +469 -0
  69. additory/synthetic/polars_integration.py +464 -0
  70. additory/synthetic/proxy.py +60 -0
  71. additory/synthetic/schema_parser.py +685 -0
  72. additory/synthetic/validator.py +553 -0
  73. additory/utilities/__init__.py +53 -0
  74. additory/utilities/encoding.py +600 -0
  75. additory/utilities/games.py +300 -0
  76. additory/utilities/keys.py +8 -0
  77. additory/utilities/lookup.py +103 -0
  78. additory/utilities/matchers.py +216 -0
  79. additory/utilities/resolvers.py +286 -0
  80. additory/utilities/settings.py +167 -0
  81. additory/utilities/units.py +746 -0
  82. additory/utilities/validators.py +153 -0
  83. additory-0.1.0a1.dist-info/METADATA +293 -0
  84. additory-0.1.0a1.dist-info/RECORD +87 -0
  85. additory-0.1.0a1.dist-info/WHEEL +5 -0
  86. additory-0.1.0a1.dist-info/licenses/LICENSE +21 -0
  87. additory-0.1.0a1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,342 @@
1
+ # config.py
2
+ # Central configuration for additory engine
3
+
4
+ import os
5
+ import yaml
6
+ from pathlib import Path
7
+ from typing import Optional, Dict, Any
8
+ from dataclasses import dataclass, field
9
+
10
+ from .logging import log_info, log_warning
11
+
12
+
13
+ # ------------------------------------------------------------
14
+ # Expression Configuration
15
+ # ------------------------------------------------------------
16
+
17
+ @dataclass
18
+ class ExpressionConfig:
19
+ """Configuration for expression namespaces"""
20
+
21
+ # Built-in expressions
22
+ builtin_path: str = "reference/expressions_definitions/"
23
+ builtin_remote_url: Optional[str] = None
24
+
25
+ # User expressions
26
+ user_path: str = "user_expressions/"
27
+ user_remote_url: Optional[str] = None
28
+
29
+ # Mode
30
+ mode: str = "development" # "development" or "production"
31
+
32
+ # Cache settings
33
+ cache_enabled: bool = True
34
+ cache_ttl: int = 3600 # seconds
35
+
36
+ def is_production(self) -> bool:
37
+ """Check if running in production mode"""
38
+ return self.mode == "production"
39
+
40
+ def get_builtin_source(self) -> str:
41
+ """Get built-in expressions source (local or remote)"""
42
+ if self.is_production() and self.builtin_remote_url:
43
+ return self.builtin_remote_url
44
+ return self.builtin_path
45
+
46
+ def get_user_source(self) -> str:
47
+ """Get user expressions source (local or remote)"""
48
+ if self.user_remote_url:
49
+ return self.user_remote_url
50
+ return self.user_path
51
+
52
+ def to_dict(self) -> Dict[str, Any]:
53
+ """Convert to dictionary for serialization"""
54
+ return {
55
+ 'builtin_path': self.builtin_path,
56
+ 'builtin_remote_url': self.builtin_remote_url,
57
+ 'user_path': self.user_path,
58
+ 'user_remote_url': self.user_remote_url,
59
+ 'mode': self.mode,
60
+ 'cache_enabled': self.cache_enabled,
61
+ 'cache_ttl': self.cache_ttl,
62
+ }
63
+
64
+ @classmethod
65
+ def from_dict(cls, data: Dict[str, Any]) -> 'ExpressionConfig':
66
+ """Create from dictionary"""
67
+ return cls(
68
+ builtin_path=data.get('builtin_path', 'reference/expressions_definitions/'),
69
+ builtin_remote_url=data.get('builtin_remote_url'),
70
+ user_path=data.get('user_path', 'user_expressions/'),
71
+ user_remote_url=data.get('user_remote_url'),
72
+ mode=data.get('mode', 'development'),
73
+ cache_enabled=data.get('cache_enabled', True),
74
+ cache_ttl=data.get('cache_ttl', 3600),
75
+ )
76
+
77
+
78
+ # Global expression config instance
79
+ _expression_config: Optional[ExpressionConfig] = None
80
+
81
+
82
+ def get_expression_config() -> ExpressionConfig:
83
+ """
84
+ Get current expression configuration
85
+
86
+ Returns:
87
+ ExpressionConfig instance
88
+ """
89
+ global _expression_config
90
+
91
+ if _expression_config is None:
92
+ # Try to load from config file
93
+ _expression_config = load_expression_config()
94
+
95
+ return _expression_config
96
+
97
+
98
+ def set_expression_config(config: ExpressionConfig):
99
+ """
100
+ Set expression configuration
101
+
102
+ Args:
103
+ config: ExpressionConfig instance
104
+ """
105
+ global _expression_config
106
+ _expression_config = config
107
+ log_info(f"[config] Expression config set: mode={config.mode}")
108
+
109
+
110
+ def get_config_file_path() -> str:
111
+ """
112
+ Get path to configuration file
113
+
114
+ Returns:
115
+ Path to ~/.additory/config.yaml
116
+ """
117
+ home = Path.home()
118
+ config_dir = home / '.additory'
119
+ return str(config_dir / 'config.yaml')
120
+
121
+
122
+ def load_expression_config() -> ExpressionConfig:
123
+ """
124
+ Load expression configuration from file
125
+
126
+ Returns:
127
+ ExpressionConfig instance (default if file doesn't exist)
128
+ """
129
+ config_path = get_config_file_path()
130
+
131
+ if not os.path.exists(config_path):
132
+ log_info(f"[config] No config file found, using defaults")
133
+ return ExpressionConfig()
134
+
135
+ try:
136
+ with open(config_path, 'r', encoding='utf-8') as f:
137
+ data = yaml.safe_load(f)
138
+
139
+ if not data or 'expressions' not in data:
140
+ log_warning(f"[config] Invalid config file, using defaults")
141
+ return ExpressionConfig()
142
+
143
+ expr_data = data['expressions']
144
+ config = ExpressionConfig.from_dict(expr_data)
145
+
146
+ log_info(f"[config] Loaded expression config from {config_path}")
147
+ log_info(f"[config] Mode: {config.mode}")
148
+ log_info(f"[config] Built-in source: {config.get_builtin_source()}")
149
+ log_info(f"[config] User source: {config.get_user_source()}")
150
+
151
+ return config
152
+
153
+ except Exception as e:
154
+ log_warning(f"[config] Failed to load config file: {e}")
155
+ return ExpressionConfig()
156
+
157
+
158
+ def save_expression_config(config: Optional[ExpressionConfig] = None):
159
+ """
160
+ Save expression configuration to file
161
+
162
+ Args:
163
+ config: ExpressionConfig to save (uses current if None)
164
+ """
165
+ if config is None:
166
+ config = get_expression_config()
167
+
168
+ config_path = get_config_file_path()
169
+ config_dir = os.path.dirname(config_path)
170
+
171
+ # Ensure directory exists
172
+ os.makedirs(config_dir, exist_ok=True)
173
+
174
+ # Prepare config data
175
+ config_data = {
176
+ 'expressions': config.to_dict()
177
+ }
178
+
179
+ try:
180
+ with open(config_path, 'w', encoding='utf-8') as f:
181
+ yaml.dump(config_data, f, default_flow_style=False, sort_keys=False)
182
+
183
+ log_info(f"[config] Saved expression config to {config_path}")
184
+
185
+ except Exception as e:
186
+ log_warning(f"[config] Failed to save config file: {e}")
187
+
188
+
189
+ def set_production_mode(
190
+ builtin_remote_url: str,
191
+ user_remote_url: Optional[str] = None
192
+ ):
193
+ """
194
+ Configure for production mode with remote URLs
195
+
196
+ Args:
197
+ builtin_remote_url: Remote URL for built-in expressions
198
+ user_remote_url: Optional remote URL for user expressions
199
+ """
200
+ config = ExpressionConfig(
201
+ builtin_remote_url=builtin_remote_url,
202
+ user_remote_url=user_remote_url,
203
+ mode="production"
204
+ )
205
+
206
+ set_expression_config(config)
207
+ save_expression_config(config)
208
+
209
+ log_info(f"[config] Configured for production mode")
210
+ log_info(f"[config] Built-in URL: {builtin_remote_url}")
211
+ if user_remote_url:
212
+ log_info(f"[config] User URL: {user_remote_url}")
213
+
214
+
215
+ def set_development_mode(
216
+ builtin_path: str = "reference/expressions_definitions/",
217
+ user_path: str = "user_expressions/"
218
+ ):
219
+ """
220
+ Configure for development mode with local paths
221
+
222
+ Args:
223
+ builtin_path: Local path for built-in expressions
224
+ user_path: Local path for user expressions
225
+ """
226
+ config = ExpressionConfig(
227
+ builtin_path=builtin_path,
228
+ user_path=user_path,
229
+ mode="development"
230
+ )
231
+
232
+ set_expression_config(config)
233
+ save_expression_config(config)
234
+
235
+ log_info(f"[config] Configured for development mode")
236
+ log_info(f"[config] Built-in path: {builtin_path}")
237
+ log_info(f"[config] User path: {user_path}")
238
+
239
+
240
+ # ------------------------------------------------------------
241
+ # Engine version
242
+ # ------------------------------------------------------------
243
+
244
+ def get_engine_version():
245
+ return "0.0.1"
246
+
247
+
248
+ # ------------------------------------------------------------
249
+ # Built‑in expression roots
250
+ # ------------------------------------------------------------
251
+ # These are optional. If you later ship built‑in formulas inside the package,
252
+ # add their paths here.
253
+
254
+ _BUILTIN_ROOTS = [] # e.g., ["builtin/expressions"]
255
+
256
+ def get_builtin_roots():
257
+ return _BUILTIN_ROOTS
258
+
259
+
260
+ # ------------------------------------------------------------
261
+ # Default version
262
+ # ------------------------------------------------------------
263
+
264
+ def get_default_version():
265
+ """
266
+ The version used when the user does not specify one.
267
+ """
268
+ return "v1"
269
+
270
+
271
+ # ------------------------------------------------------------
272
+ # User overrides
273
+ # ------------------------------------------------------------
274
+
275
+ _user_version_override = None
276
+ _user_formula_root_override = None
277
+ _custom_formula_path = None
278
+
279
+
280
+ def get_user_version_override():
281
+ """
282
+ Returns a user‑set version override, if any.
283
+ """
284
+ return _user_version_override
285
+
286
+
287
+ def set_user_version_override(v):
288
+ """
289
+ Allows the user to force a specific version globally.
290
+ """
291
+ global _user_version_override
292
+ _user_version_override = v
293
+
294
+
295
+ def get_user_formula_root_override():
296
+ """
297
+ Returns the folder where versioned expressions live.
298
+ Example:
299
+ expressions/
300
+ v1/
301
+ v2/
302
+ """
303
+ return _user_formula_root_override
304
+
305
+
306
+ def set_user_formula_root_override(path):
307
+ """
308
+ Sets the root folder for all versioned expressions.
309
+ """
310
+ global _user_formula_root_override
311
+ _user_formula_root_override = path
312
+
313
+
314
+ def get_custom_formula_path():
315
+ """
316
+ Returns a direct override path for a single formula file.
317
+ If set, this bypasses versioning entirely.
318
+ """
319
+ return _custom_formula_path
320
+
321
+
322
+ def set_custom_formula_path(path):
323
+ """
324
+ Allows the user to point directly to a single .add file.
325
+ """
326
+ global _custom_formula_path
327
+ _custom_formula_path = path
328
+
329
+
330
+ # backend preference setting
331
+
332
+ _backend_preference: str | None = None # "cpu", "gpu", or None
333
+
334
+ def set_backend_preference(mode: str | None):
335
+ global _backend_preference
336
+ if mode not in (None, "cpu", "gpu"):
337
+ raise ValueError("backend must be 'cpu', 'gpu', or None")
338
+ _backend_preference = mode
339
+
340
+ def get_backend_preference() -> str | None:
341
+ return _backend_preference
342
+