moose-lib 0.6.148.dev3442438466__py3-none-any.whl → 0.6.283__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 (59) hide show
  1. moose_lib/__init__.py +34 -3
  2. moose_lib/blocks.py +416 -52
  3. moose_lib/clients/redis_client.py +26 -14
  4. moose_lib/commons.py +37 -30
  5. moose_lib/config/config_file.py +5 -1
  6. moose_lib/config/runtime.py +73 -34
  7. moose_lib/data_models.py +331 -61
  8. moose_lib/dmv2/__init__.py +69 -73
  9. moose_lib/dmv2/_registry.py +2 -1
  10. moose_lib/dmv2/_source_capture.py +37 -0
  11. moose_lib/dmv2/consumption.py +55 -32
  12. moose_lib/dmv2/ingest_api.py +9 -2
  13. moose_lib/dmv2/ingest_pipeline.py +35 -16
  14. moose_lib/dmv2/life_cycle.py +3 -1
  15. moose_lib/dmv2/materialized_view.py +24 -14
  16. moose_lib/dmv2/moose_model.py +165 -0
  17. moose_lib/dmv2/olap_table.py +299 -151
  18. moose_lib/dmv2/registry.py +18 -3
  19. moose_lib/dmv2/sql_resource.py +16 -8
  20. moose_lib/dmv2/stream.py +75 -23
  21. moose_lib/dmv2/types.py +14 -8
  22. moose_lib/dmv2/view.py +13 -6
  23. moose_lib/dmv2/web_app.py +11 -6
  24. moose_lib/dmv2/web_app_helpers.py +5 -1
  25. moose_lib/dmv2/workflow.py +37 -9
  26. moose_lib/internal.py +340 -56
  27. moose_lib/main.py +87 -56
  28. moose_lib/query_builder.py +18 -5
  29. moose_lib/query_param.py +54 -20
  30. moose_lib/secrets.py +122 -0
  31. moose_lib/streaming/streaming_function_runner.py +233 -117
  32. moose_lib/utilities/sql.py +0 -1
  33. {moose_lib-0.6.148.dev3442438466.dist-info → moose_lib-0.6.283.dist-info}/METADATA +18 -1
  34. moose_lib-0.6.283.dist-info/RECORD +63 -0
  35. tests/__init__.py +1 -1
  36. tests/conftest.py +6 -5
  37. tests/test_backward_compatibility.py +85 -0
  38. tests/test_cluster_validation.py +85 -0
  39. tests/test_codec.py +75 -0
  40. tests/test_column_formatting.py +80 -0
  41. tests/test_fixedstring.py +43 -0
  42. tests/test_iceberg_config.py +105 -0
  43. tests/test_int_types.py +211 -0
  44. tests/test_kafka_config.py +141 -0
  45. tests/test_materialized.py +74 -0
  46. tests/test_metadata.py +37 -0
  47. tests/test_moose.py +21 -30
  48. tests/test_moose_model.py +153 -0
  49. tests/test_olap_table_moosemodel.py +89 -0
  50. tests/test_olap_table_versioning.py +52 -58
  51. tests/test_query_builder.py +97 -9
  52. tests/test_redis_client.py +10 -3
  53. tests/test_s3queue_config.py +211 -110
  54. tests/test_secrets.py +239 -0
  55. tests/test_simple_aggregate.py +42 -40
  56. tests/test_web_app.py +11 -5
  57. moose_lib-0.6.148.dev3442438466.dist-info/RECORD +0 -47
  58. {moose_lib-0.6.148.dev3442438466.dist-info → moose_lib-0.6.283.dist-info}/WHEEL +0 -0
  59. {moose_lib-0.6.148.dev3442438466.dist-info → moose_lib-0.6.283.dist-info}/top_level.txt +0 -0
tests/test_secrets.py ADDED
@@ -0,0 +1,239 @@
1
+ """Tests for the moose_lib.secrets module.
2
+
3
+ This module tests the runtime environment variable marker functionality,
4
+ which allows users to defer secret resolution until runtime rather than
5
+ embedding secrets at build time.
6
+ """
7
+
8
+ import os
9
+ import pytest
10
+ from moose_lib.secrets import moose_runtime_env, get, MOOSE_RUNTIME_ENV_PREFIX
11
+
12
+
13
+ @pytest.fixture(scope="module", autouse=True)
14
+ def set_infra_map_loading_for_secrets_tests():
15
+ """Set IS_LOADING_INFRA_MAP=true for secrets tests so moose_runtime_env.get() returns markers."""
16
+ os.environ["IS_LOADING_INFRA_MAP"] = "true"
17
+ yield
18
+ # Clean up after all tests in this module
19
+ os.environ.pop("IS_LOADING_INFRA_MAP", None)
20
+
21
+
22
+ class TestMooseRuntimeEnvGet:
23
+ """Tests for the moose_runtime_env.get() method."""
24
+
25
+ def test_creates_marker_with_correct_prefix(self):
26
+ """Should create a marker string with the correct prefix."""
27
+ var_name = "AWS_ACCESS_KEY_ID"
28
+ result = moose_runtime_env.get(var_name)
29
+
30
+ assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
31
+ assert result == "__MOOSE_RUNTIME_ENV__:AWS_ACCESS_KEY_ID"
32
+
33
+ def test_handles_different_variable_names(self):
34
+ """Should handle different environment variable names correctly."""
35
+ test_cases = [
36
+ "AWS_SECRET_ACCESS_KEY",
37
+ "DATABASE_PASSWORD",
38
+ "API_KEY",
39
+ "MY_CUSTOM_SECRET",
40
+ ]
41
+
42
+ for var_name in test_cases:
43
+ result = moose_runtime_env.get(var_name)
44
+ assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
45
+ assert var_name in result
46
+
47
+ def test_raises_error_for_empty_string(self):
48
+ """Should raise ValueError for empty string."""
49
+ with pytest.raises(
50
+ ValueError, match="Environment variable name cannot be empty"
51
+ ):
52
+ moose_runtime_env.get("")
53
+
54
+ def test_raises_error_for_whitespace_only(self):
55
+ """Should raise ValueError for whitespace-only string."""
56
+ with pytest.raises(
57
+ ValueError, match="Environment variable name cannot be empty"
58
+ ):
59
+ moose_runtime_env.get(" ")
60
+
61
+ def test_raises_error_for_tabs_only(self):
62
+ """Should raise ValueError for string with only tabs."""
63
+ with pytest.raises(
64
+ ValueError, match="Environment variable name cannot be empty"
65
+ ):
66
+ moose_runtime_env.get("\t\t")
67
+
68
+ def test_allows_underscores_in_variable_names(self):
69
+ """Should allow variable names with underscores."""
70
+ var_name = "MY_LONG_VAR_NAME"
71
+ result = moose_runtime_env.get(var_name)
72
+
73
+ assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
74
+
75
+ def test_allows_numbers_in_variable_names(self):
76
+ """Should allow variable names with numbers."""
77
+ var_name = "API_KEY_123"
78
+ result = moose_runtime_env.get(var_name)
79
+
80
+ assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
81
+
82
+ def test_preserves_exact_casing(self):
83
+ """Should preserve exact variable name casing."""
84
+ var_name = "MixedCase_VarName"
85
+ result = moose_runtime_env.get(var_name)
86
+
87
+ assert var_name in result
88
+ assert var_name.lower() not in result # Ensure casing wasn't changed
89
+
90
+ def test_can_be_used_in_s3queue_config(self):
91
+ """Should create markers that can be used in S3Queue configuration."""
92
+ access_key_marker = moose_runtime_env.get("AWS_ACCESS_KEY_ID")
93
+ secret_key_marker = moose_runtime_env.get("AWS_SECRET_ACCESS_KEY")
94
+
95
+ config = {
96
+ "aws_access_key_id": access_key_marker,
97
+ "aws_secret_access_key": secret_key_marker,
98
+ }
99
+
100
+ assert "AWS_ACCESS_KEY_ID" in config["aws_access_key_id"]
101
+ assert "AWS_SECRET_ACCESS_KEY" in config["aws_secret_access_key"]
102
+
103
+
104
+ class TestModuleLevelGetFunction:
105
+ """Tests for the module-level get() function."""
106
+
107
+ def test_module_level_get_creates_marker(self):
108
+ """The module-level get function should create markers."""
109
+ var_name = "TEST_SECRET"
110
+ result = get(var_name)
111
+
112
+ assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
113
+
114
+ def test_module_level_get_matches_class_method(self):
115
+ """Module-level get should produce same result as class method."""
116
+ var_name = "MY_SECRET"
117
+
118
+ result_module = get(var_name)
119
+ result_class = moose_runtime_env.get(var_name)
120
+
121
+ assert result_module == result_class
122
+
123
+ def test_module_level_get_raises_error_for_empty(self):
124
+ """Module-level get should raise ValueError for empty string."""
125
+ with pytest.raises(
126
+ ValueError, match="Environment variable name cannot be empty"
127
+ ):
128
+ get("")
129
+
130
+
131
+ class TestMooseRuntimeEnvPrefix:
132
+ """Tests for the MOOSE_RUNTIME_ENV_PREFIX constant."""
133
+
134
+ def test_has_expected_value(self):
135
+ """Should have the expected prefix value."""
136
+ assert MOOSE_RUNTIME_ENV_PREFIX == "__MOOSE_RUNTIME_ENV__:"
137
+
138
+ def test_is_string(self):
139
+ """Should be a string."""
140
+ assert isinstance(MOOSE_RUNTIME_ENV_PREFIX, str)
141
+
142
+ def test_is_not_empty(self):
143
+ """Should not be empty."""
144
+ assert len(MOOSE_RUNTIME_ENV_PREFIX) > 0
145
+
146
+
147
+ class TestMarkerFormatValidation:
148
+ """Tests for marker format validation and parsing."""
149
+
150
+ def test_creates_easily_detectable_markers(self):
151
+ """Should create markers that are easily detectable."""
152
+ marker = moose_runtime_env.get("TEST_VAR")
153
+
154
+ assert marker.startswith("__MOOSE_RUNTIME_ENV__:")
155
+
156
+ def test_markers_can_be_split_to_extract_variable_name(self):
157
+ """Should create markers that can be split to extract variable name."""
158
+ var_name = "MY_SECRET"
159
+ marker = moose_runtime_env.get(var_name)
160
+
161
+ parts = marker.split(MOOSE_RUNTIME_ENV_PREFIX)
162
+ assert len(parts) == 2
163
+ assert parts[1] == var_name
164
+
165
+ def test_markers_are_json_serializable(self):
166
+ """Should create markers that are JSON serializable."""
167
+ import json
168
+
169
+ marker = moose_runtime_env.get("TEST_VAR")
170
+ json_str = json.dumps({"secret": marker})
171
+ parsed = json.loads(json_str)
172
+
173
+ assert parsed["secret"] == marker
174
+
175
+ def test_markers_work_with_dict_serialization(self):
176
+ """Should work correctly with dictionary serialization."""
177
+ marker = moose_runtime_env.get("DATABASE_PASSWORD")
178
+
179
+ config = {"password": marker, "other_field": "value"}
180
+
181
+ # Verify the marker is preserved in the dict
182
+ assert config["password"] == marker
183
+ assert MOOSE_RUNTIME_ENV_PREFIX in config["password"]
184
+
185
+
186
+ class TestIntegrationScenarios:
187
+ """Integration tests for real-world usage scenarios."""
188
+
189
+ def test_s3queue_engine_with_secrets(self):
190
+ """Should work correctly in S3Queue engine configuration."""
191
+ from moose_lib.blocks import S3QueueEngine
192
+
193
+ engine = S3QueueEngine(
194
+ s3_path="s3://my-bucket/data/*.json",
195
+ format="JSONEachRow",
196
+ aws_access_key_id=moose_runtime_env.get("AWS_ACCESS_KEY_ID"),
197
+ aws_secret_access_key=moose_runtime_env.get("AWS_SECRET_ACCESS_KEY"),
198
+ )
199
+
200
+ # Verify markers were set correctly
201
+ assert engine.aws_access_key_id == "__MOOSE_RUNTIME_ENV__:AWS_ACCESS_KEY_ID"
202
+ assert (
203
+ engine.aws_secret_access_key
204
+ == "__MOOSE_RUNTIME_ENV__:AWS_SECRET_ACCESS_KEY"
205
+ )
206
+
207
+ def test_multiple_secrets_in_same_config(self):
208
+ """Should handle multiple secrets in the same configuration."""
209
+ config = {
210
+ "username": moose_runtime_env.get("DB_USERNAME"),
211
+ "password": moose_runtime_env.get("DB_PASSWORD"),
212
+ "api_key": moose_runtime_env.get("API_KEY"),
213
+ }
214
+
215
+ # All should have the correct prefix
216
+ for value in config.values():
217
+ assert value.startswith(MOOSE_RUNTIME_ENV_PREFIX)
218
+
219
+ # Each should have the correct variable name
220
+ assert "DB_USERNAME" in config["username"]
221
+ assert "DB_PASSWORD" in config["password"]
222
+ assert "API_KEY" in config["api_key"]
223
+
224
+ def test_mixed_secret_and_plain_values(self):
225
+ """Should handle mix of secret markers and plain values."""
226
+ config = {
227
+ "region": "us-east-1", # Plain value
228
+ "access_key": moose_runtime_env.get("AWS_ACCESS_KEY_ID"), # Secret
229
+ "bucket": "my-bucket", # Plain value
230
+ "secret_key": moose_runtime_env.get("AWS_SECRET_ACCESS_KEY"), # Secret
231
+ }
232
+
233
+ # Plain values should be unchanged
234
+ assert config["region"] == "us-east-1"
235
+ assert config["bucket"] == "my-bucket"
236
+
237
+ # Secrets should have markers
238
+ assert MOOSE_RUNTIME_ENV_PREFIX in config["access_key"]
239
+ assert MOOSE_RUNTIME_ENV_PREFIX in config["secret_key"]
@@ -7,106 +7,108 @@ from moose_lib.data_models import SimpleAggregateFunction, _to_columns
7
7
 
8
8
  def test_simple_aggregated_helper():
9
9
  """Test that simple_aggregated helper creates correct annotation"""
10
- annotated_type = simple_aggregated('sum', int)
10
+ annotated_type = simple_aggregated("sum", int)
11
11
 
12
12
  # Check that it's annotated
13
- assert hasattr(annotated_type, '__metadata__')
13
+ assert hasattr(annotated_type, "__metadata__")
14
14
  metadata = annotated_type.__metadata__[0]
15
15
 
16
16
  # Check metadata is SimpleAggregateFunction instance
17
17
  assert isinstance(metadata, SimpleAggregateFunction)
18
- assert metadata.agg_func == 'sum'
18
+ assert metadata.agg_func == "sum"
19
19
  assert metadata.arg_type == int
20
20
 
21
21
 
22
22
  def test_simple_aggregate_function_to_dict():
23
23
  """Test that SimpleAggregateFunction.to_dict() creates correct structure"""
24
- func = SimpleAggregateFunction(agg_func='sum', arg_type=int)
24
+ func = SimpleAggregateFunction(agg_func="sum", arg_type=int)
25
25
  result = func.to_dict()
26
26
 
27
- assert result['functionName'] == 'sum'
28
- assert 'argumentType' in result
29
- # Python int maps to "Int" by default (not "Int64")
30
- assert result['argumentType'] == 'Int'
27
+ assert result["functionName"] == "sum"
28
+ assert "argumentType" in result
29
+ # unless Annotated, Python int becomes `Int64`
30
+ assert result["argumentType"] == "Int64"
31
31
 
32
32
 
33
33
  def test_simple_aggregate_function_to_dict_with_different_types():
34
34
  """Test SimpleAggregateFunction.to_dict() with various types"""
35
35
  # Test with float
36
- func_float = SimpleAggregateFunction(agg_func='max', arg_type=float)
36
+ func_float = SimpleAggregateFunction(agg_func="max", arg_type=float)
37
37
  result_float = func_float.to_dict()
38
- assert result_float['functionName'] == 'max'
39
- assert result_float['argumentType'] == 'Float64'
38
+ assert result_float["functionName"] == "max"
39
+ assert result_float["argumentType"] == "Float64"
40
40
 
41
41
  # Test with str
42
- func_str = SimpleAggregateFunction(agg_func='anyLast', arg_type=str)
42
+ func_str = SimpleAggregateFunction(agg_func="anyLast", arg_type=str)
43
43
  result_str = func_str.to_dict()
44
- assert result_str['functionName'] == 'anyLast'
45
- assert result_str['argumentType'] == 'String'
44
+ assert result_str["functionName"] == "anyLast"
45
+ assert result_str["argumentType"] == "String"
46
46
 
47
47
 
48
48
  def test_dataclass_with_simple_aggregated():
49
49
  """Test that BaseModel with simple_aggregated field converts correctly"""
50
+
50
51
  class TestModel(BaseModel):
51
52
  date_stamp: Key[datetime.datetime]
52
53
  table_name: Key[str]
53
- row_count: simple_aggregated('sum', int)
54
+ row_count: simple_aggregated("sum", int)
54
55
 
55
56
  columns = _to_columns(TestModel)
56
57
 
57
58
  # Find the row_count column
58
- row_count_col = next(c for c in columns if c.name == 'row_count')
59
+ row_count_col = next(c for c in columns if c.name == "row_count")
59
60
 
60
- # Check basic type - Python int maps to "Int"
61
- assert row_count_col.data_type == 'Int'
61
+ # Check basic type - Python int maps to "Int64" by default
62
+ assert row_count_col.data_type == "Int64"
62
63
 
63
64
  # Check annotation
64
65
  simple_agg_annotation = next(
65
- (a for a in row_count_col.annotations if a[0] == 'simpleAggregationFunction'),
66
- None
66
+ (a for a in row_count_col.annotations if a[0] == "simpleAggregationFunction"),
67
+ None,
67
68
  )
68
69
  assert simple_agg_annotation is not None
69
- assert simple_agg_annotation[1]['functionName'] == 'sum'
70
- assert simple_agg_annotation[1]['argumentType'] == 'Int'
70
+ assert simple_agg_annotation[1]["functionName"] == "sum"
71
+ assert simple_agg_annotation[1]["argumentType"] == "Int64"
71
72
 
72
73
 
73
74
  def test_multiple_simple_aggregated_fields():
74
75
  """Test BaseModel with multiple SimpleAggregateFunction fields"""
76
+
75
77
  class StatsModel(BaseModel):
76
78
  timestamp: Key[datetime.datetime]
77
- total_count: simple_aggregated('sum', int)
78
- max_value: simple_aggregated('max', int)
79
- min_value: simple_aggregated('min', int)
80
- last_seen: simple_aggregated('anyLast', datetime.datetime)
79
+ total_count: simple_aggregated("sum", int)
80
+ max_value: simple_aggregated("max", int)
81
+ min_value: simple_aggregated("min", int)
82
+ last_seen: simple_aggregated("anyLast", datetime.datetime)
81
83
 
82
84
  columns = _to_columns(StatsModel)
83
85
 
84
86
  # Test sum
85
- sum_col = next(c for c in columns if c.name == 'total_count')
87
+ sum_col = next(c for c in columns if c.name == "total_count")
86
88
  sum_annotation = next(
87
- a for a in sum_col.annotations if a[0] == 'simpleAggregationFunction'
89
+ a for a in sum_col.annotations if a[0] == "simpleAggregationFunction"
88
90
  )
89
- assert sum_annotation[1]['functionName'] == 'sum'
91
+ assert sum_annotation[1]["functionName"] == "sum"
90
92
 
91
93
  # Test max
92
- max_col = next(c for c in columns if c.name == 'max_value')
94
+ max_col = next(c for c in columns if c.name == "max_value")
93
95
  max_annotation = next(
94
- a for a in max_col.annotations if a[0] == 'simpleAggregationFunction'
96
+ a for a in max_col.annotations if a[0] == "simpleAggregationFunction"
95
97
  )
96
- assert max_annotation[1]['functionName'] == 'max'
98
+ assert max_annotation[1]["functionName"] == "max"
97
99
 
98
100
  # Test min
99
- min_col = next(c for c in columns if c.name == 'min_value')
101
+ min_col = next(c for c in columns if c.name == "min_value")
100
102
  min_annotation = next(
101
- a for a in min_col.annotations if a[0] == 'simpleAggregationFunction'
103
+ a for a in min_col.annotations if a[0] == "simpleAggregationFunction"
102
104
  )
103
- assert min_annotation[1]['functionName'] == 'min'
105
+ assert min_annotation[1]["functionName"] == "min"
104
106
 
105
107
  # Test anyLast with datetime
106
- last_col = next(c for c in columns if c.name == 'last_seen')
107
- assert last_col.data_type == 'DateTime'
108
+ last_col = next(c for c in columns if c.name == "last_seen")
109
+ assert last_col.data_type == "DateTime"
108
110
  last_annotation = next(
109
- a for a in last_col.annotations if a[0] == 'simpleAggregationFunction'
111
+ a for a in last_col.annotations if a[0] == "simpleAggregationFunction"
110
112
  )
111
- assert last_annotation[1]['functionName'] == 'anyLast'
112
- assert last_annotation[1]['argumentType'] == 'DateTime'
113
+ assert last_annotation[1]["functionName"] == "anyLast"
114
+ assert last_annotation[1]["argumentType"] == "DateTime"
tests/test_web_app.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Unit tests for WebApp SDK functionality.
3
3
  """
4
+
4
5
  import pytest
5
6
  from moose_lib.dmv2 import WebApp, WebAppConfig, WebAppMetadata
6
7
  from moose_lib.dmv2._registry import _web_apps
@@ -9,6 +10,7 @@ from moose_lib.dmv2._registry import _web_apps
9
10
  # Mock FastAPI app for testing
10
11
  class MockFastAPIApp:
11
12
  """Mock FastAPI application for testing."""
13
+
12
14
  pass
13
15
 
14
16
 
@@ -84,7 +86,10 @@ def test_webapp_root_path_rejected():
84
86
  app = MockFastAPIApp()
85
87
  config = WebAppConfig(mount_path="/")
86
88
 
87
- with pytest.raises(ValueError, match='mountPath cannot be "/" as it would allow routes to overlap with reserved paths'):
89
+ with pytest.raises(
90
+ ValueError,
91
+ match='mountPath cannot be "/" as it would allow routes to overlap with reserved paths',
92
+ ):
88
93
  WebApp("test_app", app, config)
89
94
 
90
95
 
@@ -127,7 +132,9 @@ def test_webapp_duplicate_mount_path():
127
132
  WebApp("app1", app1, config1)
128
133
 
129
134
  config2 = WebAppConfig(mount_path="/myapi")
130
- with pytest.raises(ValueError, match='WebApp with mountPath "/myapi" already exists'):
135
+ with pytest.raises(
136
+ ValueError, match='WebApp with mountPath "/myapi" already exists'
137
+ ):
131
138
  WebApp("app2", app2, config2)
132
139
 
133
140
 
@@ -178,9 +185,8 @@ def test_webapp_serialization():
178
185
  "test_app",
179
186
  app,
180
187
  WebAppConfig(
181
- mount_path="/myapi",
182
- metadata=WebAppMetadata(description="Test API")
183
- )
188
+ mount_path="/myapi", metadata=WebAppMetadata(description="Test API")
189
+ ),
184
190
  )
185
191
 
186
192
  # Verify it's in the registry
@@ -1,47 +0,0 @@
1
- moose_lib/__init__.py,sha256=swNNCec7czJO62pYKeRyonMR4QlzgCN74GLFFI3NDxs,917
2
- moose_lib/blocks.py,sha256=Cwjx7UX5qXLVpxF5eBomBLzIoxVn769jfZRJfJnqPyw,14423
3
- moose_lib/commons.py,sha256=YDMzRO3ySa_iQRknmFwwE539KgSyjWhYJ-E3jIsfSgc,6585
4
- moose_lib/data_models.py,sha256=t_RL658-l9iCau2NXdnCSbt_MFH9S-vYNCmimZfWZ_o,15509
5
- moose_lib/dmv2_serializer.py,sha256=CL_Pvvg8tJOT8Qk6hywDNzY8MYGhMVdTOw8arZi3jng,49
6
- moose_lib/internal.py,sha256=FMd4GuQ2uRXiV7_9JrTYN1xx2HFagMbEY9uu_Kb4omg,27742
7
- moose_lib/main.py,sha256=JWsgza52xEh25AyF61cO1ItJ8VXJHHz8j-4HG445Whg,20380
8
- moose_lib/query_builder.py,sha256=-L5p2dArBx3SBA-WZPkcCJPemKXnqJw60NHy-wn5wa4,6619
9
- moose_lib/query_param.py,sha256=kxcR09BMIsEg4o2qetjKrVu1YFRaLfMEzwzyGsKUpvA,6474
10
- moose_lib/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- moose_lib/clients/redis_client.py,sha256=BDYjJ582V-rW92qVQ4neZ9Pu7JtDNt8x8jBWApt1XUg,11895
12
- moose_lib/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- moose_lib/config/config_file.py,sha256=x6Gm3MkhPYLcaZefgNTpZCFnnqSWVlLz2JVoISxG7rI,3885
14
- moose_lib/config/runtime.py,sha256=zfd58p6tTIIkcjeMYtQJNMzXGVbXGBHGmq7FX7GLoXc,8130
15
- moose_lib/dmv2/__init__.py,sha256=BQf-WUA2AY0X5h6ITZ_BrTGul2vDnflbIiSl_m7thhE,3312
16
- moose_lib/dmv2/_registry.py,sha256=ACc_Cr__tZJEQfp6uTVx7O8nF62IrHt_i-X6w1s4QQA,739
17
- moose_lib/dmv2/consumption.py,sha256=sWfGwgCBQIIrhFEbx1CULfoN3rFFoy8uCBUefu4ejiw,12928
18
- moose_lib/dmv2/ingest_api.py,sha256=XhvHHgGPXp-BuRpAALth-FRhanwy-zJQ_83Cg_RLolM,2586
19
- moose_lib/dmv2/ingest_pipeline.py,sha256=R8NRrfD9zkEzwWEJKIrNL9Nk18DdGc7wdAakae_2-7o,8459
20
- moose_lib/dmv2/life_cycle.py,sha256=wl0k6yzwU1MJ_fO_UkN29buoY5G6ChYZvfwigP9fVfM,1254
21
- moose_lib/dmv2/materialized_view.py,sha256=wTam1V5CC2rExt7YrdK_Cz4rRTONm2keKOF951LlCP4,4875
22
- moose_lib/dmv2/olap_table.py,sha256=o8wNZ9qTrbNB8mz8VnQTSme7AsNQ8KofDI2erywnSa0,35763
23
- moose_lib/dmv2/registry.py,sha256=5V8HRKBJXKLIi5tdIC2tKEmsGELQ1C2fBrMjns8a3ao,2947
24
- moose_lib/dmv2/sql_resource.py,sha256=kUZoGqxhZMHMthtBZGYJBxTFjXkspXiWLXhJRYXgGUM,1864
25
- moose_lib/dmv2/stream.py,sha256=pDryS1x5zMkDSJsFlGqm8quwKTl1ctAL-a_U8ySgqQI,18043
26
- moose_lib/dmv2/types.py,sha256=3YZ5Kbz2eOn94GWMTYT6Ix69Ekwe6aoUR4DiETQjv9E,4633
27
- moose_lib/dmv2/view.py,sha256=fVbfbJgc2lvhjpGvpfKcFUqZqxKuLD4X59jdupxIe94,1350
28
- moose_lib/dmv2/web_app.py,sha256=BPJIKMGNJqezThw56maVpjLwinJ8afDaBAoRgLiTGQA,5487
29
- moose_lib/dmv2/web_app_helpers.py,sha256=3HUDTUmNwvOLQHrOcvo_ocXD6HBfyKEprPYAqT0kVnI,2895
30
- moose_lib/dmv2/workflow.py,sha256=_FY4-VRo7uWxRtoipxGSo04qzBb4pbP30iQei1W0Ios,6287
31
- moose_lib/streaming/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- moose_lib/streaming/streaming_function_runner.py,sha256=A4XrfawOR432hSfJr86-s1-aXsN6jAvwTyJcoY2Hos4,23171
33
- moose_lib/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- moose_lib/utilities/sql.py,sha256=kbg1DT5GdsIwgTsMzbsd6SAVf9aWER8DqmT_eKS3XN4,904
35
- tests/__init__.py,sha256=0Gh4yzPkkC3TzBGKhenpMIxJcRhyrrCfxLSfpTZnPMQ,53
36
- tests/conftest.py,sha256=tsBozrzGuJUO7dRGVcIxCjqi-l77I-DvYnzpbKtmGzE,1003
37
- tests/test_moose.py,sha256=mBsx_OYWmL8ppDzL_7Bd7xR6qf_i3-pCIO3wm2iQNaA,2136
38
- tests/test_olap_table_versioning.py,sha256=ffuJsO5TYKBd2aWV0GWDmosCwL4j518Y_MqYJdrfgDY,7041
39
- tests/test_query_builder.py,sha256=O3imdFSaqU13kbK1jSQaHbBgynhVmJaApT8DlRqYwJU,1116
40
- tests/test_redis_client.py,sha256=d9_MLYsJ4ecVil_jPB2gW3Q5aWnavxmmjZg2uYI3LVo,3256
41
- tests/test_s3queue_config.py,sha256=F05cnD61S2wBKPabcpEJxf55-DJGF4nLqwBb6aFbprc,9741
42
- tests/test_simple_aggregate.py,sha256=yyFSYHUXskA1aTcwC-KQ9XmgOikeQ8wKXzntsUBIC6w,4055
43
- tests/test_web_app.py,sha256=iL86sg0NS2k6nP8jIGKZvrtg0BjvaqNTRp7-4T1TTck,6557
44
- moose_lib-0.6.148.dev3442438466.dist-info/METADATA,sha256=zgGu8QHz4E6NOqio2tEqoteLxLhnf1YKTBwjWkgOvDQ,841
45
- moose_lib-0.6.148.dev3442438466.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
46
- moose_lib-0.6.148.dev3442438466.dist-info/top_level.txt,sha256=XEns2-4aCmGp2XjJAeEH9TAUcGONLnSLy6ycT9FSJh8,16
47
- moose_lib-0.6.148.dev3442438466.dist-info/RECORD,,