flyte 0.2.0b1__py3-none-any.whl → 2.0.0b46__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 (266) hide show
  1. flyte/__init__.py +83 -30
  2. flyte/_bin/connect.py +61 -0
  3. flyte/_bin/debug.py +38 -0
  4. flyte/_bin/runtime.py +87 -19
  5. flyte/_bin/serve.py +351 -0
  6. flyte/_build.py +3 -2
  7. flyte/_cache/cache.py +6 -5
  8. flyte/_cache/local_cache.py +216 -0
  9. flyte/_code_bundle/_ignore.py +31 -5
  10. flyte/_code_bundle/_packaging.py +42 -11
  11. flyte/_code_bundle/_utils.py +57 -34
  12. flyte/_code_bundle/bundle.py +130 -27
  13. flyte/_constants.py +1 -0
  14. flyte/_context.py +21 -5
  15. flyte/_custom_context.py +73 -0
  16. flyte/_debug/constants.py +37 -0
  17. flyte/_debug/utils.py +17 -0
  18. flyte/_debug/vscode.py +315 -0
  19. flyte/_deploy.py +396 -75
  20. flyte/_deployer.py +109 -0
  21. flyte/_environment.py +94 -11
  22. flyte/_excepthook.py +37 -0
  23. flyte/_group.py +2 -1
  24. flyte/_hash.py +1 -16
  25. flyte/_image.py +544 -231
  26. flyte/_initialize.py +456 -316
  27. flyte/_interface.py +40 -5
  28. flyte/_internal/controllers/__init__.py +22 -8
  29. flyte/_internal/controllers/_local_controller.py +159 -35
  30. flyte/_internal/controllers/_trace.py +18 -10
  31. flyte/_internal/controllers/remote/__init__.py +38 -9
  32. flyte/_internal/controllers/remote/_action.py +82 -12
  33. flyte/_internal/controllers/remote/_client.py +6 -2
  34. flyte/_internal/controllers/remote/_controller.py +290 -64
  35. flyte/_internal/controllers/remote/_core.py +155 -95
  36. flyte/_internal/controllers/remote/_informer.py +40 -20
  37. flyte/_internal/controllers/remote/_service_protocol.py +2 -2
  38. flyte/_internal/imagebuild/__init__.py +2 -10
  39. flyte/_internal/imagebuild/docker_builder.py +391 -84
  40. flyte/_internal/imagebuild/image_builder.py +111 -55
  41. flyte/_internal/imagebuild/remote_builder.py +409 -0
  42. flyte/_internal/imagebuild/utils.py +79 -0
  43. flyte/_internal/resolvers/_app_env_module.py +92 -0
  44. flyte/_internal/resolvers/_task_module.py +5 -38
  45. flyte/_internal/resolvers/app_env.py +26 -0
  46. flyte/_internal/resolvers/common.py +8 -1
  47. flyte/_internal/resolvers/default.py +2 -2
  48. flyte/_internal/runtime/convert.py +319 -36
  49. flyte/_internal/runtime/entrypoints.py +106 -18
  50. flyte/_internal/runtime/io.py +71 -23
  51. flyte/_internal/runtime/resources_serde.py +21 -7
  52. flyte/_internal/runtime/reuse.py +125 -0
  53. flyte/_internal/runtime/rusty.py +196 -0
  54. flyte/_internal/runtime/task_serde.py +239 -66
  55. flyte/_internal/runtime/taskrunner.py +48 -8
  56. flyte/_internal/runtime/trigger_serde.py +162 -0
  57. flyte/_internal/runtime/types_serde.py +7 -16
  58. flyte/_keyring/file.py +115 -0
  59. flyte/_link.py +30 -0
  60. flyte/_logging.py +241 -42
  61. flyte/_map.py +312 -0
  62. flyte/_metrics.py +59 -0
  63. flyte/_module.py +74 -0
  64. flyte/_pod.py +30 -0
  65. flyte/_resources.py +296 -33
  66. flyte/_retry.py +1 -7
  67. flyte/_reusable_environment.py +72 -7
  68. flyte/_run.py +462 -132
  69. flyte/_secret.py +47 -11
  70. flyte/_serve.py +333 -0
  71. flyte/_task.py +245 -56
  72. flyte/_task_environment.py +219 -97
  73. flyte/_task_plugins.py +47 -0
  74. flyte/_tools.py +8 -8
  75. flyte/_trace.py +15 -24
  76. flyte/_trigger.py +1027 -0
  77. flyte/_utils/__init__.py +12 -1
  78. flyte/_utils/asyn.py +3 -1
  79. flyte/_utils/async_cache.py +139 -0
  80. flyte/_utils/coro_management.py +5 -4
  81. flyte/_utils/description_parser.py +19 -0
  82. flyte/_utils/docker_credentials.py +173 -0
  83. flyte/_utils/helpers.py +45 -19
  84. flyte/_utils/module_loader.py +123 -0
  85. flyte/_utils/org_discovery.py +57 -0
  86. flyte/_utils/uv_script_parser.py +8 -1
  87. flyte/_version.py +16 -3
  88. flyte/app/__init__.py +27 -0
  89. flyte/app/_app_environment.py +362 -0
  90. flyte/app/_connector_environment.py +40 -0
  91. flyte/app/_deploy.py +130 -0
  92. flyte/app/_parameter.py +343 -0
  93. flyte/app/_runtime/__init__.py +3 -0
  94. flyte/app/_runtime/app_serde.py +383 -0
  95. flyte/app/_types.py +113 -0
  96. flyte/app/extras/__init__.py +9 -0
  97. flyte/app/extras/_auth_middleware.py +217 -0
  98. flyte/app/extras/_fastapi.py +93 -0
  99. flyte/app/extras/_model_loader/__init__.py +3 -0
  100. flyte/app/extras/_model_loader/config.py +7 -0
  101. flyte/app/extras/_model_loader/loader.py +288 -0
  102. flyte/cli/__init__.py +12 -0
  103. flyte/cli/_abort.py +28 -0
  104. flyte/cli/_build.py +114 -0
  105. flyte/cli/_common.py +493 -0
  106. flyte/cli/_create.py +371 -0
  107. flyte/cli/_delete.py +45 -0
  108. flyte/cli/_deploy.py +401 -0
  109. flyte/cli/_gen.py +316 -0
  110. flyte/cli/_get.py +446 -0
  111. flyte/cli/_option.py +33 -0
  112. flyte/{_cli → cli}/_params.py +57 -17
  113. flyte/cli/_plugins.py +209 -0
  114. flyte/cli/_prefetch.py +292 -0
  115. flyte/cli/_run.py +690 -0
  116. flyte/cli/_serve.py +338 -0
  117. flyte/cli/_update.py +86 -0
  118. flyte/cli/_user.py +20 -0
  119. flyte/cli/main.py +246 -0
  120. flyte/config/__init__.py +2 -167
  121. flyte/config/_config.py +215 -163
  122. flyte/config/_internal.py +10 -1
  123. flyte/config/_reader.py +225 -0
  124. flyte/connectors/__init__.py +11 -0
  125. flyte/connectors/_connector.py +330 -0
  126. flyte/connectors/_server.py +194 -0
  127. flyte/connectors/utils.py +159 -0
  128. flyte/errors.py +134 -2
  129. flyte/extend.py +24 -0
  130. flyte/extras/_container.py +69 -56
  131. flyte/git/__init__.py +3 -0
  132. flyte/git/_config.py +279 -0
  133. flyte/io/__init__.py +8 -1
  134. flyte/io/{structured_dataset → _dataframe}/__init__.py +32 -30
  135. flyte/io/{structured_dataset → _dataframe}/basic_dfs.py +75 -68
  136. flyte/io/{structured_dataset/structured_dataset.py → _dataframe/dataframe.py} +207 -242
  137. flyte/io/_dir.py +575 -113
  138. flyte/io/_file.py +587 -141
  139. flyte/io/_hashing_io.py +342 -0
  140. flyte/io/extend.py +7 -0
  141. flyte/models.py +635 -0
  142. flyte/prefetch/__init__.py +22 -0
  143. flyte/prefetch/_hf_model.py +563 -0
  144. flyte/remote/__init__.py +14 -3
  145. flyte/remote/_action.py +879 -0
  146. flyte/remote/_app.py +346 -0
  147. flyte/remote/_auth_metadata.py +42 -0
  148. flyte/remote/_client/_protocols.py +62 -4
  149. flyte/remote/_client/auth/_auth_utils.py +19 -0
  150. flyte/remote/_client/auth/_authenticators/base.py +8 -2
  151. flyte/remote/_client/auth/_authenticators/device_code.py +4 -5
  152. flyte/remote/_client/auth/_authenticators/factory.py +4 -0
  153. flyte/remote/_client/auth/_authenticators/passthrough.py +79 -0
  154. flyte/remote/_client/auth/_authenticators/pkce.py +17 -18
  155. flyte/remote/_client/auth/_channel.py +47 -18
  156. flyte/remote/_client/auth/_client_config.py +5 -3
  157. flyte/remote/_client/auth/_keyring.py +15 -2
  158. flyte/remote/_client/auth/_token_client.py +3 -3
  159. flyte/remote/_client/controlplane.py +206 -18
  160. flyte/remote/_common.py +66 -0
  161. flyte/remote/_data.py +107 -22
  162. flyte/remote/_logs.py +116 -33
  163. flyte/remote/_project.py +21 -19
  164. flyte/remote/_run.py +164 -631
  165. flyte/remote/_secret.py +72 -29
  166. flyte/remote/_task.py +387 -46
  167. flyte/remote/_trigger.py +368 -0
  168. flyte/remote/_user.py +43 -0
  169. flyte/report/_report.py +10 -6
  170. flyte/storage/__init__.py +13 -1
  171. flyte/storage/_config.py +237 -0
  172. flyte/storage/_parallel_reader.py +289 -0
  173. flyte/storage/_storage.py +268 -59
  174. flyte/syncify/__init__.py +56 -0
  175. flyte/syncify/_api.py +414 -0
  176. flyte/types/__init__.py +39 -0
  177. flyte/types/_interface.py +22 -7
  178. flyte/{io/pickle/transformer.py → types/_pickle.py} +37 -9
  179. flyte/types/_string_literals.py +8 -9
  180. flyte/types/_type_engine.py +226 -126
  181. flyte/types/_utils.py +1 -1
  182. flyte-2.0.0b46.data/scripts/debug.py +38 -0
  183. flyte-2.0.0b46.data/scripts/runtime.py +194 -0
  184. flyte-2.0.0b46.dist-info/METADATA +352 -0
  185. flyte-2.0.0b46.dist-info/RECORD +221 -0
  186. flyte-2.0.0b46.dist-info/entry_points.txt +8 -0
  187. flyte-2.0.0b46.dist-info/licenses/LICENSE +201 -0
  188. flyte/_api_commons.py +0 -3
  189. flyte/_cli/_common.py +0 -299
  190. flyte/_cli/_create.py +0 -42
  191. flyte/_cli/_delete.py +0 -23
  192. flyte/_cli/_deploy.py +0 -140
  193. flyte/_cli/_get.py +0 -235
  194. flyte/_cli/_run.py +0 -174
  195. flyte/_cli/main.py +0 -98
  196. flyte/_datastructures.py +0 -342
  197. flyte/_internal/controllers/pbhash.py +0 -39
  198. flyte/_protos/common/authorization_pb2.py +0 -66
  199. flyte/_protos/common/authorization_pb2.pyi +0 -108
  200. flyte/_protos/common/authorization_pb2_grpc.py +0 -4
  201. flyte/_protos/common/identifier_pb2.py +0 -71
  202. flyte/_protos/common/identifier_pb2.pyi +0 -82
  203. flyte/_protos/common/identifier_pb2_grpc.py +0 -4
  204. flyte/_protos/common/identity_pb2.py +0 -48
  205. flyte/_protos/common/identity_pb2.pyi +0 -72
  206. flyte/_protos/common/identity_pb2_grpc.py +0 -4
  207. flyte/_protos/common/list_pb2.py +0 -36
  208. flyte/_protos/common/list_pb2.pyi +0 -69
  209. flyte/_protos/common/list_pb2_grpc.py +0 -4
  210. flyte/_protos/common/policy_pb2.py +0 -37
  211. flyte/_protos/common/policy_pb2.pyi +0 -27
  212. flyte/_protos/common/policy_pb2_grpc.py +0 -4
  213. flyte/_protos/common/role_pb2.py +0 -37
  214. flyte/_protos/common/role_pb2.pyi +0 -53
  215. flyte/_protos/common/role_pb2_grpc.py +0 -4
  216. flyte/_protos/common/runtime_version_pb2.py +0 -28
  217. flyte/_protos/common/runtime_version_pb2.pyi +0 -24
  218. flyte/_protos/common/runtime_version_pb2_grpc.py +0 -4
  219. flyte/_protos/logs/dataplane/payload_pb2.py +0 -96
  220. flyte/_protos/logs/dataplane/payload_pb2.pyi +0 -168
  221. flyte/_protos/logs/dataplane/payload_pb2_grpc.py +0 -4
  222. flyte/_protos/secret/definition_pb2.py +0 -49
  223. flyte/_protos/secret/definition_pb2.pyi +0 -93
  224. flyte/_protos/secret/definition_pb2_grpc.py +0 -4
  225. flyte/_protos/secret/payload_pb2.py +0 -62
  226. flyte/_protos/secret/payload_pb2.pyi +0 -94
  227. flyte/_protos/secret/payload_pb2_grpc.py +0 -4
  228. flyte/_protos/secret/secret_pb2.py +0 -38
  229. flyte/_protos/secret/secret_pb2.pyi +0 -6
  230. flyte/_protos/secret/secret_pb2_grpc.py +0 -198
  231. flyte/_protos/secret/secret_pb2_grpc_grpc.py +0 -198
  232. flyte/_protos/validate/validate/validate_pb2.py +0 -76
  233. flyte/_protos/workflow/node_execution_service_pb2.py +0 -26
  234. flyte/_protos/workflow/node_execution_service_pb2.pyi +0 -4
  235. flyte/_protos/workflow/node_execution_service_pb2_grpc.py +0 -32
  236. flyte/_protos/workflow/queue_service_pb2.py +0 -106
  237. flyte/_protos/workflow/queue_service_pb2.pyi +0 -141
  238. flyte/_protos/workflow/queue_service_pb2_grpc.py +0 -172
  239. flyte/_protos/workflow/run_definition_pb2.py +0 -128
  240. flyte/_protos/workflow/run_definition_pb2.pyi +0 -310
  241. flyte/_protos/workflow/run_definition_pb2_grpc.py +0 -4
  242. flyte/_protos/workflow/run_logs_service_pb2.py +0 -41
  243. flyte/_protos/workflow/run_logs_service_pb2.pyi +0 -28
  244. flyte/_protos/workflow/run_logs_service_pb2_grpc.py +0 -69
  245. flyte/_protos/workflow/run_service_pb2.py +0 -133
  246. flyte/_protos/workflow/run_service_pb2.pyi +0 -175
  247. flyte/_protos/workflow/run_service_pb2_grpc.py +0 -412
  248. flyte/_protos/workflow/state_service_pb2.py +0 -58
  249. flyte/_protos/workflow/state_service_pb2.pyi +0 -71
  250. flyte/_protos/workflow/state_service_pb2_grpc.py +0 -138
  251. flyte/_protos/workflow/task_definition_pb2.py +0 -72
  252. flyte/_protos/workflow/task_definition_pb2.pyi +0 -65
  253. flyte/_protos/workflow/task_definition_pb2_grpc.py +0 -4
  254. flyte/_protos/workflow/task_service_pb2.py +0 -44
  255. flyte/_protos/workflow/task_service_pb2.pyi +0 -31
  256. flyte/_protos/workflow/task_service_pb2_grpc.py +0 -104
  257. flyte/io/_dataframe.py +0 -0
  258. flyte/io/pickle/__init__.py +0 -0
  259. flyte/remote/_console.py +0 -18
  260. flyte-0.2.0b1.dist-info/METADATA +0 -179
  261. flyte-0.2.0b1.dist-info/RECORD +0 -204
  262. flyte-0.2.0b1.dist-info/entry_points.txt +0 -3
  263. /flyte/{_cli → _debug}/__init__.py +0 -0
  264. /flyte/{_protos → _keyring}/__init__.py +0 -0
  265. {flyte-0.2.0b1.dist-info → flyte-2.0.0b46.dist-info}/WHEEL +0 -0
  266. {flyte-0.2.0b1.dist-info → flyte-2.0.0b46.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,342 @@
1
+ from __future__ import annotations
2
+
3
+ import hashlib
4
+ import inspect
5
+ from typing import Any, Iterable, Optional, Protocol, Union, runtime_checkable
6
+
7
+
8
+ @runtime_checkable
9
+ class HashMethod(Protocol):
10
+ def update(self, data: memoryview, /) -> None: ...
11
+ def result(self) -> str: ...
12
+
13
+ # Optional convenience; not required by the writers.
14
+ def reset(self) -> None: ...
15
+
16
+
17
+ class PrecomputedValue(HashMethod):
18
+ def __init__(self, value: str):
19
+ self._value = value
20
+
21
+ def update(self, data: memoryview, /) -> None: ...
22
+
23
+ def result(self) -> str:
24
+ return self._value
25
+
26
+
27
+ class HashlibAccumulator(HashMethod):
28
+ """
29
+ Wrap a hashlib-like object to the Accumulator protocol.
30
+ h = hashlib.new("sha256")
31
+ acc = HashlibAccumulator(h)
32
+ """
33
+
34
+ def __init__(self, h):
35
+ self._h = h
36
+
37
+ def update(self, data: memoryview, /) -> None:
38
+ self._h.update(data)
39
+
40
+ def result(self) -> Any:
41
+ return self._h.hexdigest()
42
+
43
+ @classmethod
44
+ def from_hash_name(cls, name: str) -> HashlibAccumulator:
45
+ """
46
+ Create an accumulator from a hashlib algorithm name.
47
+ """
48
+ h = hashlib.new(name)
49
+ return cls(h)
50
+
51
+
52
+ class HashingWriter:
53
+ """
54
+ Sync writer that updates a user-supplied accumulator on every write.
55
+
56
+ Hashing covers the exact bytes you pass in. If you write str, it is encoded
57
+ using the underlying file's .encoding if available, else UTF-8 (for hashing only).
58
+ """
59
+
60
+ def __init__(
61
+ self,
62
+ fh,
63
+ accumulator: HashMethod,
64
+ *,
65
+ encoding: Optional[str] = None,
66
+ errors: str = "strict",
67
+ ):
68
+ self._fh = fh
69
+ self._acc: HashMethod = accumulator
70
+ self._encoding = encoding or getattr(fh, "encoding", None)
71
+ self._errors = errors
72
+
73
+ def result(self) -> Any:
74
+ return self._acc.result()
75
+
76
+ def _to_bytes_mv(self, data) -> memoryview:
77
+ if isinstance(data, str):
78
+ b = data.encode(self._encoding or "utf-8", self._errors)
79
+ return memoryview(b)
80
+ if isinstance(data, (bytes, bytearray, memoryview)):
81
+ return memoryview(data)
82
+ # Accept any buffer-protocol object (e.g., numpy arrays)
83
+ return memoryview(data)
84
+
85
+ def write(self, data):
86
+ mv = self._to_bytes_mv(data)
87
+ self._acc.update(mv)
88
+ return self._fh.write(data)
89
+
90
+ def writelines(self, lines: Iterable[Union[str, bytes, bytearray, memoryview]]):
91
+ for line in lines:
92
+ self.write(line)
93
+
94
+ def flush(self):
95
+ return self._fh.flush()
96
+
97
+ def close(self):
98
+ return self._fh.close()
99
+
100
+ def __getattr__(self, name):
101
+ return getattr(self._fh, name)
102
+
103
+
104
+ class AsyncHashingWriter:
105
+ """
106
+ Async version of HashingWriter with the same behavior.
107
+ """
108
+
109
+ def __init__(
110
+ self,
111
+ fh,
112
+ accumulator: HashMethod,
113
+ *,
114
+ encoding: Optional[str] = None,
115
+ errors: str = "strict",
116
+ ):
117
+ self._fh = fh
118
+ self._acc = accumulator
119
+ self._encoding = encoding or getattr(fh, "encoding", None)
120
+ self._errors = errors
121
+
122
+ def result(self) -> Any:
123
+ return self._acc.result()
124
+
125
+ def _to_bytes_mv(self, data) -> memoryview:
126
+ if isinstance(data, str):
127
+ b = data.encode(self._encoding or "utf-8", self._errors)
128
+ return memoryview(b)
129
+ if isinstance(data, (bytes, bytearray, memoryview)):
130
+ return memoryview(data)
131
+ return memoryview(data)
132
+
133
+ async def write(self, data):
134
+ mv = self._to_bytes_mv(data)
135
+ self._acc.update(mv)
136
+ return await self._fh.write(data)
137
+
138
+ async def writelines(self, lines: Iterable[Union[str, bytes, bytearray, memoryview]]):
139
+ for line in lines:
140
+ await self.write(line)
141
+
142
+ async def flush(self):
143
+ fn = getattr(self._fh, "flush", None)
144
+ if fn is None:
145
+ return None
146
+ res = fn()
147
+ if inspect.isawaitable(res):
148
+ return await res
149
+ return res
150
+
151
+ async def close(self):
152
+ fn = getattr(self._fh, "close", None)
153
+ if fn is None:
154
+ return None
155
+ res = fn()
156
+ if inspect.isawaitable(res):
157
+ return await res
158
+ return res
159
+
160
+ def __getattr__(self, name):
161
+ return getattr(self._fh, name)
162
+
163
+
164
+ class HashingReader:
165
+ """
166
+ Sync reader that updates a user-supplied accumulator on every read operation.
167
+
168
+ If the underlying handle returns str (text mode), we encode it for hashing only,
169
+ using the handle's .encoding if present, else the explicit 'encoding' arg, else UTF-8.
170
+ """
171
+
172
+ def __init__(
173
+ self,
174
+ fh,
175
+ accumulator: HashMethod,
176
+ *,
177
+ encoding: Optional[str] = None,
178
+ errors: str = "strict",
179
+ ):
180
+ self._fh = fh
181
+ self._acc = accumulator
182
+ self._encoding = encoding or getattr(fh, "encoding", None)
183
+ self._errors = errors
184
+
185
+ def result(self) -> str:
186
+ return self._acc.result()
187
+
188
+ def _to_bytes_mv(self, data) -> Optional[memoryview]:
189
+ if data is None:
190
+ return None
191
+ if isinstance(data, str):
192
+ return memoryview(data.encode(self._encoding or "utf-8", self._errors))
193
+ if isinstance(data, (bytes, bytearray, memoryview)):
194
+ return memoryview(data)
195
+ # Accept any buffer-protocol object (rare for read paths, but safe)
196
+ return memoryview(data)
197
+
198
+ def read(self, size: int = -1):
199
+ data = self._fh.read(size)
200
+ mv = self._to_bytes_mv(data)
201
+ if mv is not None and len(mv) > 0:
202
+ self._acc.update(mv)
203
+ return data
204
+
205
+ def readline(self, size: int = -1):
206
+ line = self._fh.readline(size)
207
+ mv = self._to_bytes_mv(line)
208
+ if mv is not None and len(mv) > 0:
209
+ self._acc.update(mv)
210
+ return line
211
+
212
+ def readlines(self, hint: int = -1):
213
+ lines = self._fh.readlines(hint)
214
+ # Update in order to reflect exact concatenation
215
+ for line in lines:
216
+ mv = self._to_bytes_mv(line)
217
+ if mv is not None and len(mv) > 0:
218
+ self._acc.update(mv)
219
+ return lines
220
+
221
+ def __iter__(self):
222
+ return self
223
+
224
+ def __next__(self):
225
+ # Delegate to the underlying iterator to preserve semantics (including buffering),
226
+ # but intercept the produced line to hash it.
227
+ line = next(self._fh)
228
+ mv = self._to_bytes_mv(line)
229
+ if mv is not None and len(mv) > 0:
230
+ self._acc.update(mv)
231
+ return line
232
+
233
+ # ---- passthrough ----
234
+ def __getattr__(self, name):
235
+ # Avoid leaking private lookups to the underlying object if we're missing something internal
236
+ if name.startswith("_"):
237
+ raise AttributeError(name)
238
+ return getattr(self._fh, name)
239
+
240
+
241
+ class AsyncHashingReader:
242
+ """
243
+ Async reader that updates a user-supplied accumulator on every read operation.
244
+
245
+ Works with aiofiles/fsspec async handles. `flush`/`close` may be awaitable or sync.
246
+ """
247
+
248
+ def __init__(
249
+ self,
250
+ fh,
251
+ accumulator: HashMethod,
252
+ *,
253
+ encoding: Optional[str] = None,
254
+ errors: str = "strict",
255
+ ):
256
+ self._fh = fh
257
+ self._acc = accumulator
258
+ self._encoding = encoding or getattr(fh, "encoding", None)
259
+ self._errors = errors
260
+
261
+ def result(self) -> str:
262
+ return self._acc.result()
263
+
264
+ def _to_bytes_mv(self, data) -> Optional[memoryview]:
265
+ if data is None:
266
+ return None
267
+ if isinstance(data, str):
268
+ return memoryview(data.encode(self._encoding or "utf-8", self._errors))
269
+ if isinstance(data, (bytes, bytearray, memoryview)):
270
+ return memoryview(data)
271
+ return memoryview(data)
272
+
273
+ async def read(self, size: int = -1):
274
+ data = await self._fh.read(size)
275
+ mv = self._to_bytes_mv(data)
276
+ if mv is not None and len(mv) > 0:
277
+ self._acc.update(mv)
278
+ return data
279
+
280
+ async def readline(self, size: int = -1):
281
+ line = await self._fh.readline(size)
282
+ mv = self._to_bytes_mv(line)
283
+ if mv is not None and len(mv) > 0:
284
+ self._acc.update(mv)
285
+ return line
286
+
287
+ async def readlines(self, hint: int = -1):
288
+ # Some async filehandles implement readlines(); if not, fall back to manual loop.
289
+ if hasattr(self._fh, "readlines"):
290
+ lines = await self._fh.readlines(hint)
291
+ for line in lines:
292
+ mv = self._to_bytes_mv(line)
293
+ if mv is not None and len(mv) > 0:
294
+ self._acc.update(mv)
295
+ return lines
296
+ # Fallback: read all via iteration
297
+ lines = []
298
+ async for line in self:
299
+ lines.append(line)
300
+ return lines
301
+
302
+ def __aiter__(self):
303
+ return self
304
+
305
+ async def __anext__(self):
306
+ # Prefer the underlying async iterator if present
307
+ anext_fn = getattr(self._fh, "__anext__", None)
308
+ if anext_fn is not None:
309
+ try:
310
+ line = await anext_fn()
311
+ except StopAsyncIteration:
312
+ raise
313
+ mv = self._to_bytes_mv(line)
314
+ if mv is not None and len(mv) > 0:
315
+ self._acc.update(mv)
316
+ return line
317
+
318
+ # Fallback to readline-based iteration
319
+ line = await self.readline()
320
+ if line == "" or line == b"":
321
+ raise StopAsyncIteration
322
+ return line
323
+
324
+ async def flush(self):
325
+ fn = getattr(self._fh, "flush", None)
326
+ if fn is None:
327
+ return None
328
+ res = fn()
329
+ return await res if inspect.isawaitable(res) else res
330
+
331
+ async def close(self):
332
+ fn = getattr(self._fh, "close", None)
333
+ if fn is None:
334
+ return None
335
+ res = fn()
336
+ return await res if inspect.isawaitable(res) else res
337
+
338
+ # ---- passthrough ----
339
+ def __getattr__(self, name):
340
+ if name.startswith("_"):
341
+ raise AttributeError(name)
342
+ return getattr(self._fh, name)
flyte/io/extend.py ADDED
@@ -0,0 +1,7 @@
1
+ from ._dataframe import DataFrameDecoder, DataFrameEncoder, DataFrameTransformerEngine
2
+
3
+ __all__ = [
4
+ "DataFrameDecoder",
5
+ "DataFrameEncoder",
6
+ "DataFrameTransformerEngine",
7
+ ]