moose-lib 0.6.174__tar.gz → 0.6.185__tar.gz

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 (56) hide show
  1. {moose_lib-0.6.174 → moose_lib-0.6.185}/PKG-INFO +1 -1
  2. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/__init__.py +19 -1
  3. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/data_models.py +14 -0
  4. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib.egg-info/PKG-INFO +1 -1
  5. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib.egg-info/SOURCES.txt +1 -0
  6. moose_lib-0.6.185/tests/test_int_types.py +204 -0
  7. {moose_lib-0.6.174 → moose_lib-0.6.185}/README.md +0 -0
  8. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/blocks.py +0 -0
  9. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/clients/__init__.py +0 -0
  10. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/clients/redis_client.py +0 -0
  11. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/commons.py +0 -0
  12. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/config/__init__.py +0 -0
  13. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/config/config_file.py +0 -0
  14. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/config/runtime.py +0 -0
  15. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/__init__.py +0 -0
  16. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/_registry.py +0 -0
  17. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/consumption.py +0 -0
  18. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/ingest_api.py +0 -0
  19. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/ingest_pipeline.py +0 -0
  20. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/life_cycle.py +0 -0
  21. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/materialized_view.py +0 -0
  22. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/olap_table.py +0 -0
  23. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/registry.py +0 -0
  24. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/sql_resource.py +0 -0
  25. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/stream.py +0 -0
  26. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/types.py +0 -0
  27. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/view.py +0 -0
  28. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/web_app.py +0 -0
  29. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/web_app_helpers.py +0 -0
  30. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2/workflow.py +0 -0
  31. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/dmv2_serializer.py +0 -0
  32. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/internal.py +0 -0
  33. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/main.py +0 -0
  34. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/query_builder.py +0 -0
  35. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/query_param.py +0 -0
  36. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/secrets.py +0 -0
  37. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/streaming/__init__.py +0 -0
  38. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/streaming/streaming_function_runner.py +0 -0
  39. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/utilities/__init__.py +0 -0
  40. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib/utilities/sql.py +0 -0
  41. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib.egg-info/dependency_links.txt +0 -0
  42. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib.egg-info/requires.txt +0 -0
  43. {moose_lib-0.6.174 → moose_lib-0.6.185}/moose_lib.egg-info/top_level.txt +0 -0
  44. {moose_lib-0.6.174 → moose_lib-0.6.185}/setup.cfg +0 -0
  45. {moose_lib-0.6.174 → moose_lib-0.6.185}/setup.py +0 -0
  46. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/__init__.py +0 -0
  47. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/conftest.py +0 -0
  48. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/test_fixedstring.py +0 -0
  49. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/test_moose.py +0 -0
  50. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/test_olap_table_versioning.py +0 -0
  51. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/test_query_builder.py +0 -0
  52. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/test_redis_client.py +0 -0
  53. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/test_s3queue_config.py +0 -0
  54. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/test_secrets.py +0 -0
  55. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/test_simple_aggregate.py +0 -0
  56. {moose_lib-0.6.174 → moose_lib-0.6.185}/tests/test_web_app.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: moose_lib
3
- Version: 0.6.174
3
+ Version: 0.6.185
4
4
  Home-page: https://www.fiveonefour.com/moose
5
5
  Author: Fiveonefour Labs Inc.
6
6
  Author-email: support@fiveonefour.com
@@ -30,7 +30,25 @@ from .blocks import (
30
30
  # Legacy enum (already exported via .blocks import, but explicit for clarity)
31
31
  ClickHouseEngines
32
32
  )
33
- from .data_models import Key, AggregateFunction, StringToEnumMixin, FixedString, ClickhouseFixedStringSize
33
+ from .data_models import (
34
+ Key,
35
+ AggregateFunction,
36
+ StringToEnumMixin,
37
+ FixedString,
38
+ ClickhouseFixedStringSize,
39
+ # Integer types
40
+ Int8,
41
+ Int16,
42
+ Int32,
43
+ Int64,
44
+ UInt8,
45
+ UInt16,
46
+ UInt32,
47
+ UInt64,
48
+ # Float types
49
+ Float32,
50
+ Float64,
51
+ )
34
52
  from .commons import Logger
35
53
 
36
54
  from .query_builder import *
@@ -15,6 +15,20 @@ import ipaddress
15
15
  type Key[T: (str, int)] = T
16
16
  type JWT[T] = T
17
17
 
18
+ # Integer type aliases for ClickHouse integer types
19
+ type Int8 = Annotated[int, "int8"]
20
+ type Int16 = Annotated[int, "int16"]
21
+ type Int32 = Annotated[int, "int32"]
22
+ type Int64 = Annotated[int, "int64"]
23
+ type UInt8 = Annotated[int, "uint8"]
24
+ type UInt16 = Annotated[int, "uint16"]
25
+ type UInt32 = Annotated[int, "uint32"]
26
+ type UInt64 = Annotated[int, "uint64"]
27
+
28
+ # Float type aliases for ClickHouse float types
29
+ type Float32 = Annotated[float, "float32"]
30
+ type Float64 = Annotated[float, "float64"]
31
+
18
32
 
19
33
  @dataclasses.dataclass(frozen=True) # a BaseModel in the annotations will confuse pydantic
20
34
  class ClickhousePrecision:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: moose_lib
3
- Version: 0.6.174
3
+ Version: 0.6.185
4
4
  Home-page: https://www.fiveonefour.com/moose
5
5
  Author: Fiveonefour Labs Inc.
6
6
  Author-email: support@fiveonefour.com
@@ -43,6 +43,7 @@ moose_lib/utilities/sql.py
43
43
  tests/__init__.py
44
44
  tests/conftest.py
45
45
  tests/test_fixedstring.py
46
+ tests/test_int_types.py
46
47
  tests/test_moose.py
47
48
  tests/test_olap_table_versioning.py
48
49
  tests/test_query_builder.py
@@ -0,0 +1,204 @@
1
+ from datetime import datetime
2
+ from typing import Annotated
3
+ from pydantic import BaseModel
4
+ from moose_lib import (
5
+ Key,
6
+ Int8, Int16, Int32, Int64,
7
+ UInt8, UInt16, UInt32, UInt64,
8
+ Float32, Float64,
9
+ )
10
+ from moose_lib.data_models import _to_columns
11
+
12
+
13
+ def test_integer_type_aliases():
14
+ """Test that integer type aliases convert to correct ClickHouse types."""
15
+
16
+ class IntegerTypesTest(BaseModel):
17
+ id: Key[str]
18
+ created_at: datetime
19
+ tiny_int: Int8
20
+ small_int: Int16
21
+ medium_int: Int32
22
+ big_int: Int64
23
+ tiny_uint: UInt8
24
+ small_uint: UInt16
25
+ medium_uint: UInt32
26
+ big_uint: UInt64
27
+
28
+ columns = _to_columns(IntegerTypesTest)
29
+ by_name = {col.name: col for col in columns}
30
+
31
+ # Verify signed integer types
32
+ assert by_name["tiny_int"].data_type == "Int8"
33
+ assert by_name["small_int"].data_type == "Int16"
34
+ assert by_name["medium_int"].data_type == "Int32"
35
+ assert by_name["big_int"].data_type == "Int64"
36
+
37
+ # Verify unsigned integer types
38
+ assert by_name["tiny_uint"].data_type == "UInt8"
39
+ assert by_name["small_uint"].data_type == "UInt16"
40
+ assert by_name["medium_uint"].data_type == "UInt32"
41
+ assert by_name["big_uint"].data_type == "UInt64"
42
+
43
+ # Verify other fields still work
44
+ assert by_name["id"].data_type == "String"
45
+ assert by_name["created_at"].data_type == "DateTime"
46
+
47
+
48
+ def test_float_type_aliases():
49
+ """Test that float type aliases convert to correct ClickHouse types."""
50
+
51
+ class FloatTypesTest(BaseModel):
52
+ id: Key[str]
53
+ precision_float: Float32
54
+ double_precision_float: Float64
55
+
56
+ columns = _to_columns(FloatTypesTest)
57
+ by_name = {col.name: col for col in columns}
58
+
59
+ assert by_name["precision_float"].data_type == "Float32"
60
+ assert by_name["double_precision_float"].data_type == "Float64"
61
+ assert by_name["id"].data_type == "String"
62
+
63
+
64
+ def test_combined_numeric_types():
65
+ """Test combining integer and float types in a single model."""
66
+
67
+ class NumericTypesTest(BaseModel):
68
+ user_id: UInt64
69
+ age: UInt8
70
+ score: Int32
71
+ latitude: Float64
72
+ longitude: Float64
73
+ precision_value: Float32
74
+
75
+ columns = _to_columns(NumericTypesTest)
76
+ by_name = {col.name: col for col in columns}
77
+
78
+ assert by_name["user_id"].data_type == "UInt64"
79
+ assert by_name["age"].data_type == "UInt8"
80
+ assert by_name["score"].data_type == "Int32"
81
+ assert by_name["latitude"].data_type == "Float64"
82
+ assert by_name["longitude"].data_type == "Float64"
83
+ assert by_name["precision_value"].data_type == "Float32"
84
+
85
+
86
+ def test_integer_types_as_keys():
87
+ """Test that integer types can be used as primary keys."""
88
+
89
+ class IntegerKeyTest(BaseModel):
90
+ user_id: Key[UInt64]
91
+ event_id: Key[Int64]
92
+ name: str
93
+
94
+ columns = _to_columns(IntegerKeyTest)
95
+ by_name = {col.name: col for col in columns}
96
+
97
+ assert by_name["user_id"].data_type == "UInt64"
98
+ assert by_name["user_id"].primary_key is True
99
+ assert by_name["event_id"].data_type == "Int64"
100
+ assert by_name["event_id"].primary_key is True
101
+ assert by_name["name"].data_type == "String"
102
+
103
+
104
+ def test_optional_integer_types():
105
+ """Test that optional integer types work correctly."""
106
+ from typing import Optional
107
+
108
+ class OptionalIntTest(BaseModel):
109
+ required_count: UInt32
110
+ optional_count: Optional[UInt32]
111
+ optional_score: Optional[Int16]
112
+
113
+ columns = _to_columns(OptionalIntTest)
114
+ by_name = {col.name: col for col in columns}
115
+
116
+ assert by_name["required_count"].data_type == "UInt32"
117
+ assert by_name["required_count"].required is True
118
+
119
+ assert by_name["optional_count"].data_type == "UInt32"
120
+ assert by_name["optional_count"].required is False
121
+
122
+ assert by_name["optional_score"].data_type == "Int16"
123
+ assert by_name["optional_score"].required is False
124
+
125
+
126
+ def test_uint_common_use_cases():
127
+ """Test common use cases for unsigned integers."""
128
+
129
+ class CommonUIntUseCases(BaseModel):
130
+ # User/entity IDs (always positive)
131
+ user_id: UInt64
132
+ # Counters (always positive or zero)
133
+ page_views: UInt32
134
+ click_count: UInt32
135
+ # Small enums/flags (0-255)
136
+ status_code: UInt8
137
+ # Port numbers (0-65535)
138
+ port: UInt16
139
+ # Timestamps as unix epoch
140
+ timestamp: UInt64
141
+
142
+ columns = _to_columns(CommonUIntUseCases)
143
+ by_name = {col.name: col for col in columns}
144
+
145
+ assert by_name["user_id"].data_type == "UInt64"
146
+ assert by_name["page_views"].data_type == "UInt32"
147
+ assert by_name["click_count"].data_type == "UInt32"
148
+ assert by_name["status_code"].data_type == "UInt8"
149
+ assert by_name["port"].data_type == "UInt16"
150
+ assert by_name["timestamp"].data_type == "UInt64"
151
+
152
+
153
+ def test_int_common_use_cases():
154
+ """Test common use cases for signed integers."""
155
+
156
+ class CommonIntUseCases(BaseModel):
157
+ # Temperature (can be negative)
158
+ temperature: Int16
159
+ # Financial amounts (can be negative for debits)
160
+ balance: Int64
161
+ # Deltas/differences
162
+ delta: Int32
163
+ # Small range values
164
+ offset: Int8
165
+
166
+ columns = _to_columns(CommonIntUseCases)
167
+ by_name = {col.name: col for col in columns}
168
+
169
+ assert by_name["temperature"].data_type == "Int16"
170
+ assert by_name["balance"].data_type == "Int64"
171
+ assert by_name["delta"].data_type == "Int32"
172
+ assert by_name["offset"].data_type == "Int8"
173
+
174
+
175
+ def test_default_int_still_works():
176
+ """Test that plain int without type annotation still works as before."""
177
+
178
+ class PlainIntTest(BaseModel):
179
+ plain_int: int
180
+ typed_int: UInt32
181
+
182
+ columns = _to_columns(PlainIntTest)
183
+ by_name = {col.name: col for col in columns}
184
+
185
+ # Plain int should still map to "Int" (default behavior)
186
+ assert by_name["plain_int"].data_type == "Int"
187
+ # Typed int should map to specific type
188
+ assert by_name["typed_int"].data_type == "UInt32"
189
+
190
+
191
+ def test_default_float_still_works():
192
+ """Test that plain float without type annotation still works as before."""
193
+
194
+ class PlainFloatTest(BaseModel):
195
+ plain_float: float
196
+ typed_float: Float32
197
+
198
+ columns = _to_columns(PlainFloatTest)
199
+ by_name = {col.name: col for col in columns}
200
+
201
+ # Plain float should still map to "Float64" (default behavior)
202
+ assert by_name["plain_float"].data_type == "Float64"
203
+ # Typed float should map to specific type
204
+ assert by_name["typed_float"].data_type == "Float32"
File without changes
File without changes
File without changes