framespec 0.0.1__tar.gz → 0.0.2__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.
- {framespec-0.0.1 → framespec-0.0.2}/PKG-INFO +7 -3
- framespec-0.0.2/pyproject.toml +27 -0
- framespec-0.0.2/pyproject.toml.orig +26 -0
- framespec-0.0.2/src/framespec/core/__init__.py +0 -0
- framespec-0.0.2/src/framespec/core/types.py +225 -0
- framespec-0.0.1/pyproject.toml +0 -14
- framespec-0.0.1/pyproject.toml.orig +0 -12
- {framespec-0.0.1 → framespec-0.0.2}/README.md +0 -0
- {framespec-0.0.1 → framespec-0.0.2}/src/framespec/__init__.py +0 -0
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: framespec
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: Declarative DataFrame specifications for PySpark.
|
|
5
|
-
Author:
|
|
5
|
+
Author: RyPy
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Dist: pyspark>=4.0.0
|
|
8
|
+
Requires-Dist: packaging>=24.0
|
|
9
|
+
Requires-Dist: typing-extensions>=4.10.0
|
|
6
10
|
Requires-Python: >=3.12
|
|
7
11
|
Description-Content-Type: text/markdown
|
|
8
12
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "framespec"
|
|
3
|
+
version = "0.0.2"
|
|
4
|
+
description = "Declarative DataFrame specifications for PySpark."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"pyspark >= 4.0.0",
|
|
10
|
+
"packaging >= 24.0",
|
|
11
|
+
"typing-extensions >= 4.10.0",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[project.authors]]
|
|
15
|
+
name = "RyPy"
|
|
16
|
+
|
|
17
|
+
[dependency-groups]
|
|
18
|
+
dev = [
|
|
19
|
+
"pytest >= 8.0",
|
|
20
|
+
"pytest-cov >= 5.0",
|
|
21
|
+
"mypy >= 1.10",
|
|
22
|
+
"ruff >= 0.5.0",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[build-system]
|
|
26
|
+
requires = ["uv-build"]
|
|
27
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "framespec"
|
|
3
|
+
version = "0.0.2"
|
|
4
|
+
description = "Declarative DataFrame specifications for PySpark."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [{ name = "RyPy" }]
|
|
7
|
+
requires-python = ">=3.12"
|
|
8
|
+
license = "MIT"
|
|
9
|
+
|
|
10
|
+
dependencies = [
|
|
11
|
+
"pyspark >= 4.0.0",
|
|
12
|
+
"packaging >= 24.0",
|
|
13
|
+
"typing-extensions >= 4.10.0",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[dependency-groups]
|
|
17
|
+
dev = [
|
|
18
|
+
"pytest >= 8.0",
|
|
19
|
+
"pytest-cov >= 5.0",
|
|
20
|
+
"mypy >= 1.10",
|
|
21
|
+
"ruff >= 0.5.0",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[build-system]
|
|
25
|
+
requires = ["uv-build"]
|
|
26
|
+
build-backend = "uv_build"
|
|
File without changes
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from pyspark.sql import types as T
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# -- Base Type --------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
@dataclass(frozen=True, kw_only=True)
|
|
8
|
+
class ColumnType:
|
|
9
|
+
"""
|
|
10
|
+
Base class for all framespec column types.
|
|
11
|
+
|
|
12
|
+
Declarative only:
|
|
13
|
+
- immutable
|
|
14
|
+
- engine-agnostic except for .dtype (Spark DataType)
|
|
15
|
+
"""
|
|
16
|
+
nullable: bool = True
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def dtype(self) -> T.DataType:
|
|
20
|
+
raise NotImplementedError
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# -- Integer Types ----------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
@dataclass(frozen=True, kw_only=True)
|
|
26
|
+
class Byte(ColumnType):
|
|
27
|
+
min_value: int | None = None
|
|
28
|
+
max_value: int | None = None
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def dtype(self) -> T.ByteType:
|
|
32
|
+
return T.ByteType()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass(frozen=True, kw_only=True)
|
|
36
|
+
class Short(ColumnType):
|
|
37
|
+
min_value: int | None = None
|
|
38
|
+
max_value: int | None = None
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def dtype(self) -> T.ShortType:
|
|
42
|
+
return T.ShortType()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass(frozen=True, kw_only=True)
|
|
46
|
+
class Int(ColumnType):
|
|
47
|
+
min_value: int | None = None
|
|
48
|
+
max_value: int | None = None
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def dtype(self) -> T.IntegerType:
|
|
52
|
+
return T.IntegerType()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass(frozen=True, kw_only=True)
|
|
56
|
+
class Long(ColumnType):
|
|
57
|
+
min_value: int | None = None
|
|
58
|
+
max_value: int | None = None
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def dtype(self) -> T.LongType:
|
|
62
|
+
return T.LongType()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# -- Floating Types ---------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
@dataclass(frozen=True, kw_only=True)
|
|
68
|
+
class Float(ColumnType):
|
|
69
|
+
min_value: float | None = None
|
|
70
|
+
max_value: float | None = None
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def dtype(self) -> T.FloatType:
|
|
74
|
+
return T.FloatType()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass(frozen=True, kw_only=True)
|
|
78
|
+
class Double(ColumnType):
|
|
79
|
+
min_value: float | None = None
|
|
80
|
+
max_value: float | None = None
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def dtype(self) -> T.DoubleType:
|
|
84
|
+
return T.DoubleType()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# -- Decimal Type -----------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
@dataclass(frozen=True, kw_only=True)
|
|
90
|
+
class Decimal(ColumnType):
|
|
91
|
+
precision: int
|
|
92
|
+
scale: int = 0
|
|
93
|
+
min_value: float | None = None
|
|
94
|
+
max_value: float | None = None
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def dtype(self) -> T.DecimalType:
|
|
98
|
+
return T.DecimalType(self.precision, self.scale)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# -- String & Binary Types --------------------------------------------------
|
|
102
|
+
|
|
103
|
+
@dataclass(frozen=True, kw_only=True)
|
|
104
|
+
class String(ColumnType):
|
|
105
|
+
min_length: int | None = None
|
|
106
|
+
max_length: int | None = None
|
|
107
|
+
pattern: str | None = None
|
|
108
|
+
allowed_values: list[str] | None = None
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def dtype(self) -> T.StringType:
|
|
112
|
+
return T.StringType()
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@dataclass(frozen=True, kw_only=True)
|
|
116
|
+
class Binary(ColumnType):
|
|
117
|
+
min_length: int | None = None
|
|
118
|
+
max_length: int | None = None
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def dtype(self) -> T.BinaryType:
|
|
122
|
+
return T.BinaryType()
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# -- Boolean Type -----------------------------------------------------------
|
|
126
|
+
|
|
127
|
+
@dataclass(frozen=True, kw_only=True)
|
|
128
|
+
class Boolean(ColumnType):
|
|
129
|
+
@property
|
|
130
|
+
def dtype(self) -> T.BooleanType:
|
|
131
|
+
return T.BooleanType()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# -- Date & Timestamp Types -------------------------------------------------
|
|
135
|
+
|
|
136
|
+
@dataclass(frozen=True, kw_only=True)
|
|
137
|
+
class Date(ColumnType):
|
|
138
|
+
@property
|
|
139
|
+
def dtype(self) -> T.DateType:
|
|
140
|
+
return T.DateType()
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@dataclass(frozen=True, kw_only=True)
|
|
144
|
+
class Timestamp(ColumnType):
|
|
145
|
+
@property
|
|
146
|
+
def dtype(self) -> T.TimestampType:
|
|
147
|
+
return T.TimestampType()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@dataclass(frozen=True, kw_only=True)
|
|
151
|
+
class TimestampNTZ(ColumnType):
|
|
152
|
+
@property
|
|
153
|
+
def dtype(self) -> T.TimestampNTZType:
|
|
154
|
+
return T.TimestampNTZType()
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
# -- Complex Types: Array, Map, Struct -------------------------------------
|
|
158
|
+
|
|
159
|
+
@dataclass(frozen=True, kw_only=True)
|
|
160
|
+
class Array(ColumnType):
|
|
161
|
+
element_type: ColumnType
|
|
162
|
+
min_items: int | None = None
|
|
163
|
+
max_items: int | None = None
|
|
164
|
+
unique_items: bool = False
|
|
165
|
+
|
|
166
|
+
@property
|
|
167
|
+
def dtype(self) -> T.ArrayType:
|
|
168
|
+
return T.ArrayType(
|
|
169
|
+
elementType=self.element_type.dtype,
|
|
170
|
+
containsNull=self.element_type.nullable,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@dataclass(frozen=True, kw_only=True)
|
|
175
|
+
class Map(ColumnType):
|
|
176
|
+
key_type: ColumnType
|
|
177
|
+
value_type: ColumnType
|
|
178
|
+
min_properties: int | None = None
|
|
179
|
+
max_properties: int | None = None
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def dtype(self) -> T.MapType:
|
|
183
|
+
return T.MapType(
|
|
184
|
+
keyType=self.key_type.dtype,
|
|
185
|
+
valueType=self.value_type.dtype,
|
|
186
|
+
valueContainsNull=self.value_type.nullable,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@dataclass(frozen=True, kw_only=True)
|
|
191
|
+
class Struct(ColumnType):
|
|
192
|
+
fields: dict[str, ColumnType]
|
|
193
|
+
required: list[str] | None = None
|
|
194
|
+
min_properties: int | None = None
|
|
195
|
+
max_properties: int | None = None
|
|
196
|
+
|
|
197
|
+
@property
|
|
198
|
+
def dtype(self) -> T.StructType:
|
|
199
|
+
return T.StructType([
|
|
200
|
+
T.StructField(name, type_.dtype, type_.nullable)
|
|
201
|
+
for name, type_ in self.fields.items()
|
|
202
|
+
])
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
# -- Special Spark Types ----------------------------------------------------
|
|
206
|
+
|
|
207
|
+
@dataclass(frozen=True, kw_only=True)
|
|
208
|
+
class Null(ColumnType):
|
|
209
|
+
@property
|
|
210
|
+
def dtype(self) -> T.NullType:
|
|
211
|
+
return T.NullType()
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
@dataclass(frozen=True, kw_only=True)
|
|
215
|
+
class CalendarInterval(ColumnType):
|
|
216
|
+
@property
|
|
217
|
+
def dtype(self) -> T.CalendarIntervalType:
|
|
218
|
+
return T.CalendarIntervalType()
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
@dataclass(frozen=True, kw_only=True)
|
|
222
|
+
class DayTimeInterval(ColumnType):
|
|
223
|
+
@property
|
|
224
|
+
def dtype(self) -> T.DayTimeIntervalType:
|
|
225
|
+
return T.DayTimeIntervalType()
|
framespec-0.0.1/pyproject.toml
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
[project]
|
|
2
|
-
name = "framespec"
|
|
3
|
-
version = "0.0.1"
|
|
4
|
-
description = "Declarative DataFrame specifications for PySpark."
|
|
5
|
-
readme = "README.md"
|
|
6
|
-
requires-python = ">=3.12"
|
|
7
|
-
dependencies = []
|
|
8
|
-
|
|
9
|
-
[[project.authors]]
|
|
10
|
-
name = "Ryan"
|
|
11
|
-
|
|
12
|
-
[build-system]
|
|
13
|
-
requires = ["uv_build>=0.12.5,<0.13.0"]
|
|
14
|
-
build-backend = "uv_build"
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
[project]
|
|
2
|
-
name = "framespec"
|
|
3
|
-
version = "0.0.1"
|
|
4
|
-
description = "Declarative DataFrame specifications for PySpark."
|
|
5
|
-
readme = "README.md"
|
|
6
|
-
authors = [{ name = "Ryan" }]
|
|
7
|
-
requires-python = ">=3.12"
|
|
8
|
-
dependencies = []
|
|
9
|
-
|
|
10
|
-
[build-system]
|
|
11
|
-
requires = ["uv_build>=0.12.5,<0.13.0"]
|
|
12
|
-
build-backend = "uv_build"
|
|
File without changes
|
|
File without changes
|