prefect-client 3.0.0rc5__py3-none-any.whl → 3.0.0rc7__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.
@@ -8,6 +8,10 @@ from prefect.utilities.hashing import hash_objects
8
8
 
9
9
  @dataclass
10
10
  class CachePolicy:
11
+ """
12
+ Base class for all cache policies.
13
+ """
14
+
11
15
  @classmethod
12
16
  def from_cache_key_fn(
13
17
  cls, cache_key_fn: Callable[["TaskRunContext", Dict[str, Any]], Optional[str]]
@@ -59,6 +63,11 @@ class CachePolicy:
59
63
 
60
64
  @dataclass
61
65
  class CacheKeyFnPolicy(CachePolicy):
66
+ """
67
+ This policy accepts a custom function with signature f(task_run_context, task_parameters, flow_parameters) -> str
68
+ and uses it to compute a task run cache key.
69
+ """
70
+
62
71
  # making it optional for tests
63
72
  cache_key_fn: Optional[
64
73
  Callable[["TaskRunContext", Dict[str, Any]], Optional[str]]
@@ -77,6 +86,13 @@ class CacheKeyFnPolicy(CachePolicy):
77
86
 
78
87
  @dataclass
79
88
  class CompoundCachePolicy(CachePolicy):
89
+ """
90
+ This policy is constructed from two or more other cache policies and works by computing the keys
91
+ for each policy individually, and then hashing a sorted tuple of all computed keys.
92
+
93
+ Any keys that return `None` will be ignored.
94
+ """
95
+
80
96
  policies: Optional[list] = None
81
97
 
82
98
  def compute_key(
@@ -88,20 +104,25 @@ class CompoundCachePolicy(CachePolicy):
88
104
  ) -> Optional[str]:
89
105
  keys = []
90
106
  for policy in self.policies or []:
91
- keys.append(
92
- policy.compute_key(
93
- task_ctx=task_ctx,
94
- inputs=inputs,
95
- flow_parameters=flow_parameters,
96
- **kwargs,
97
- )
107
+ policy_key = policy.compute_key(
108
+ task_ctx=task_ctx,
109
+ inputs=inputs,
110
+ flow_parameters=flow_parameters,
111
+ **kwargs,
98
112
  )
113
+ if policy_key is not None:
114
+ keys.append(policy_key)
115
+ if not keys:
116
+ return None
99
117
  return hash_objects(*keys)
100
118
 
101
119
 
102
120
  @dataclass
103
- class Default(CachePolicy):
104
- "Execution run ID only"
121
+ class _None(CachePolicy):
122
+ """
123
+ Policy that always returns `None` for the computed cache key.
124
+ This policy prevents persistence.
125
+ """
105
126
 
106
127
  def compute_key(
107
128
  self,
@@ -110,12 +131,14 @@ class Default(CachePolicy):
110
131
  flow_parameters: Dict[str, Any],
111
132
  **kwargs,
112
133
  ) -> Optional[str]:
113
- return str(task_ctx.task_run.id)
134
+ return None
114
135
 
115
136
 
116
137
  @dataclass
117
- class _None(CachePolicy):
118
- "ignore key policies altogether, always run - prevents persistence"
138
+ class TaskSource(CachePolicy):
139
+ """
140
+ Policy for computing a cache key based on the source code of the task.
141
+ """
119
142
 
120
143
  def compute_key(
121
144
  self,
@@ -124,11 +147,22 @@ class _None(CachePolicy):
124
147
  flow_parameters: Dict[str, Any],
125
148
  **kwargs,
126
149
  ) -> Optional[str]:
127
- return None
150
+ if not task_ctx:
151
+ return None
152
+ try:
153
+ lines = inspect.getsource(task_ctx.task)
154
+ except TypeError:
155
+ lines = inspect.getsource(task_ctx.task.fn.__class__)
156
+
157
+ return hash_objects(lines)
128
158
 
129
159
 
130
160
  @dataclass
131
- class TaskDef(CachePolicy):
161
+ class FlowParameters(CachePolicy):
162
+ """
163
+ Policy that computes the cache key based on a hash of the flow parameters.
164
+ """
165
+
132
166
  def compute_key(
133
167
  self,
134
168
  task_ctx: TaskRunContext,
@@ -136,21 +170,37 @@ class TaskDef(CachePolicy):
136
170
  flow_parameters: Dict[str, Any],
137
171
  **kwargs,
138
172
  ) -> Optional[str]:
139
- lines = inspect.getsource(task_ctx.task)
140
- return hash_objects(lines)
173
+ if not flow_parameters:
174
+ return None
175
+ return hash_objects(flow_parameters)
141
176
 
142
177
 
143
178
  @dataclass
144
- class FlowParameters(CachePolicy):
145
- pass
179
+ class RunId(CachePolicy):
180
+ """
181
+ Returns either the prevailing flow run ID, or if not found, the prevailing task
182
+ run ID.
183
+ """
184
+
185
+ def compute_key(
186
+ self,
187
+ task_ctx: TaskRunContext,
188
+ inputs: Dict[str, Any],
189
+ flow_parameters: Dict[str, Any],
190
+ **kwargs,
191
+ ) -> Optional[str]:
192
+ if not task_ctx:
193
+ return None
194
+ run_id = task_ctx.task_run.flow_run_id
195
+ if run_id is None:
196
+ run_id = task_ctx.task_run.id
197
+ return str(run_id)
146
198
 
147
199
 
148
200
  @dataclass
149
201
  class Inputs(CachePolicy):
150
202
  """
151
- Exposes flag for whether to include flow parameters as well.
152
-
153
- And exclude/include config.
203
+ Policy that computes a cache key based on a hash of the runtime inputs provided to the task..
154
204
  """
155
205
 
156
206
  exclude: Optional[list] = None
@@ -166,6 +216,9 @@ class Inputs(CachePolicy):
166
216
  inputs = inputs or {}
167
217
  exclude = self.exclude or []
168
218
 
219
+ if not inputs:
220
+ return None
221
+
169
222
  for key, val in inputs.items():
170
223
  if key not in exclude:
171
224
  hashed_inputs[key] = val
@@ -173,7 +226,9 @@ class Inputs(CachePolicy):
173
226
  return hash_objects(hashed_inputs)
174
227
 
175
228
 
176
- DEFAULT = Default()
177
229
  INPUTS = Inputs()
178
230
  NONE = _None()
179
- TASKDEF = TaskDef()
231
+ TASK_SOURCE = TaskSource()
232
+ FLOW_PARAMETERS = FlowParameters()
233
+ RUN_ID = RunId()
234
+ DEFAULT = INPUTS + TASK_SOURCE + RUN_ID
prefect/task_engine.py CHANGED
@@ -174,11 +174,18 @@ class TaskRunEngine(Generic[P, R]):
174
174
  def compute_transaction_key(self) -> str:
175
175
  key = None
176
176
  if self.task.cache_policy:
177
+ flow_run_context = FlowRunContext.get()
177
178
  task_run_context = TaskRunContext.get()
179
+
180
+ if flow_run_context:
181
+ parameters = flow_run_context.parameters
182
+ else:
183
+ parameters = None
184
+
178
185
  key = self.task.cache_policy.compute_key(
179
186
  task_ctx=task_run_context,
180
187
  inputs=self.parameters,
181
- flow_parameters=None,
188
+ flow_parameters=parameters,
182
189
  )
183
190
  elif self.task.result_storage_key is not None:
184
191
  key = _format_user_supplied_storage_key(self.task.result_storage_key)
prefect/task_runners.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import abc
2
2
  import asyncio
3
+ import sys
3
4
  import uuid
4
5
  from concurrent.futures import ThreadPoolExecutor
5
6
  from contextvars import copy_context
@@ -205,7 +206,7 @@ class ThreadPoolTaskRunner(TaskRunner[PrefectConcurrentFuture]):
205
206
  def __init__(self, max_workers: Optional[int] = None):
206
207
  super().__init__()
207
208
  self._executor: Optional[ThreadPoolExecutor] = None
208
- self._max_workers = max_workers
209
+ self._max_workers = sys.maxsize if max_workers is None else max_workers
209
210
 
210
211
  def duplicate(self) -> "ThreadPoolTaskRunner":
211
212
  return type(self)(max_workers=self._max_workers)
prefect/tasks.py CHANGED
@@ -32,6 +32,7 @@ from uuid import UUID, uuid4
32
32
 
33
33
  from typing_extensions import Literal, ParamSpec
34
34
 
35
+ from prefect.cache_policies import DEFAULT, NONE, CachePolicy
35
36
  from prefect.client.orchestration import get_client
36
37
  from prefect.client.schemas import TaskRun
37
38
  from prefect.client.schemas.objects import TaskRunInput, TaskRunResult
@@ -43,7 +44,6 @@ from prefect.context import (
43
44
  )
44
45
  from prefect.futures import PrefectDistributedFuture, PrefectFuture
45
46
  from prefect.logging.loggers import get_logger
46
- from prefect.records.cache_policies import DEFAULT, NONE, CachePolicy
47
47
  from prefect.results import ResultFactory, ResultSerializer, ResultStorage
48
48
  from prefect.settings import (
49
49
  PREFECT_TASK_DEFAULT_RETRIES,
@@ -51,7 +51,10 @@ from prefect.settings import (
51
51
  )
52
52
  from prefect.states import Pending, Scheduled, State
53
53
  from prefect.utilities.annotations import NotSet
54
- from prefect.utilities.asyncutils import run_coro_as_sync
54
+ from prefect.utilities.asyncutils import (
55
+ run_coro_as_sync,
56
+ sync_compatible,
57
+ )
55
58
  from prefect.utilities.callables import (
56
59
  expand_mapping_parameters,
57
60
  get_call_parameters,
@@ -1284,7 +1287,8 @@ class Task(Generic[P, R]):
1284
1287
  """
1285
1288
  return self.apply_async(args=args, kwargs=kwargs)
1286
1289
 
1287
- def serve(self) -> "Task":
1290
+ @sync_compatible
1291
+ async def serve(self) -> NoReturn:
1288
1292
  """Serve the task using the provided task runner. This method is used to
1289
1293
  establish a websocket connection with the Prefect server and listen for
1290
1294
  submitted task runs to execute.
@@ -1303,7 +1307,7 @@ class Task(Generic[P, R]):
1303
1307
  """
1304
1308
  from prefect.task_worker import serve
1305
1309
 
1306
- serve(self)
1310
+ await serve(self)
1307
1311
 
1308
1312
 
1309
1313
  @overload
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 3.0.0rc5
3
+ Version: 3.0.0rc7
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -3,6 +3,7 @@ prefect/__init__.py,sha256=YmPor6iCXeKOr8jfH08qD9CBiRsEY6pXs4mRSQRo6ro,2873
3
3
  prefect/_version.py,sha256=I9JsXwt7BjAAbMEZgtmE3a6dJ2jqV-wqWto9D6msb3k,24597
4
4
  prefect/artifacts.py,sha256=G-jCyce3XGtTyQpCk_s3L7e-TWFyJY8Dcnk_i4_CsY4,12647
5
5
  prefect/automations.py,sha256=NlQ62GPJzy-gnWQqX7c6CQJKw7p60WLGDAFcy82vtg4,5613
6
+ prefect/cache_policies.py,sha256=uEKNGO-PJ3N35B2tjhRDtQULN6ok72D9raIoJaUyXk0,6365
6
7
  prefect/context.py,sha256=OEmbC61D3l0E50HIaMlVNNJShhYC6I1-4TQhpP321tw,19480
7
8
  prefect/engine.py,sha256=asH7iMb1IfEOOIVIxM3ZalfvCe9PUp7f9ceKyT6isa8,2019
8
9
  prefect/exceptions.py,sha256=kRiEX6qpT9errs0SuYJDYG7ioMNddTvqK7gT8RVFajk,11076
@@ -19,11 +20,11 @@ prefect/results.py,sha256=qG-5mAlZTRV7GneuQVS7GpHHt3QXcZbwLwn03fHAi4M,27326
19
20
  prefect/serializers.py,sha256=8ON--RmaLX3Td3Rpd1lshGcqWyjlCFkmO3sblxsdT_c,8699
20
21
  prefect/settings.py,sha256=JkCgcFO7Zw0Kv_azK9XLabx08ypVgL76E6r8nD-HZLM,74598
21
22
  prefect/states.py,sha256=JdN01UMYFelFybPoAEKbiPJNuPaj6pksLJ3o0_oNz5Q,20690
22
- prefect/task_engine.py,sha256=dzMID0AhbRlJnrm7U-PjJ8DxvW2J0j2jStOvDRuZDJs,32317
23
- prefect/task_runners.py,sha256=TQHyQATPkZE6BNVJ_JQBNmiL1kdgZRjY_Fjs3-N1UiE,11869
23
+ prefect/task_engine.py,sha256=wGN-jFfiLROth8pA8be9Y9_ghi5VS3T2Zpu4ZxTtHSk,32519
24
+ prefect/task_runners.py,sha256=fjOWg2-ds_bE-x5O5Eshr25IS7EMxcEvo7NSmRRtdm8,11920
24
25
  prefect/task_runs.py,sha256=eDWYH5H1K4SyduhKmn3GzO6vM3fZSwOZxAb8KhkMGsk,7798
25
26
  prefect/task_worker.py,sha256=iawQZn4hNcrXR-CHtM4jzhlnotqeNHiRuHc-eumJ9Oc,16788
26
- prefect/tasks.py,sha256=-j9ZCxvfvgHkyUsaRuj9EhEWmfO4NLN76Pg2_yGCaL0,60243
27
+ prefect/tasks.py,sha256=rA7FAqcb58hwhrju7ocxL-e982vXEKx86Zl8G-LYcQY,60300
27
28
  prefect/transactions.py,sha256=XhEXdhid1457m5V7VTz1U8JCek6U6jSFD7EffGhCLag,9149
28
29
  prefect/variables.py,sha256=-t5LVY0N-K4f0fa6YwruVVQqwnU3fGWBMYXXE32XPkA,4821
29
30
  prefect/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -129,7 +130,6 @@ prefect/logging/highlighters.py,sha256=BpSXOy0n3lFVvlKWa7jC-HetAiClFi9jnQtEq5-rg
129
130
  prefect/logging/loggers.py,sha256=qWM-5IxN3U5MlK7srfALOC9sCpGqt20Vu9WSxpU2zIs,11527
130
131
  prefect/logging/logging.yml,sha256=UkEewf0c3_dURI2uCU4RrxkhI5Devoa1s93fl7hilcg,3160
131
132
  prefect/records/__init__.py,sha256=7q-lwyevfVgb5S7K9frzawmiJmpZ5ET0m5yXIHBYcVA,31
132
- prefect/records/cache_policies.py,sha256=2R6tQioujG2qr5rQgg7kPK-SLMM1lUHplEKcOfJbrh0,4761
133
133
  prefect/records/result_store.py,sha256=6Yh9zqqXMWjn0qWSfcjQBSfXCM7jVg9pve5TVsOodDc,1734
134
134
  prefect/records/store.py,sha256=eQM1p2vZDshXZYg6SkJwL-DP3kUehL_Zgs8xa2-0DZs,224
135
135
  prefect/runner/__init__.py,sha256=7U-vAOXFkzMfRz1q8Uv6Otsvc0OrPYLLP44srwkJ_8s,89
@@ -179,8 +179,8 @@ prefect/workers/base.py,sha256=62E0Q41pPr3eQdSBSUBfiR4WYx01OfuqUp5INRqHGgo,46942
179
179
  prefect/workers/process.py,sha256=vylkSSswaSCew-V65YW0HcxIxyKI-uqWkbSKpkkLamQ,9372
180
180
  prefect/workers/server.py,sha256=EfPiMxI7TVgkqpHkdPwSaYG-ydi99sG7jwXhkAcACbI,1519
181
181
  prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
182
- prefect_client-3.0.0rc5.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
183
- prefect_client-3.0.0rc5.dist-info/METADATA,sha256=fGHLD4XaLt3FzjMoZxnEJcK-rByrMfxN-Bpu27Y66Ao,7392
184
- prefect_client-3.0.0rc5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
185
- prefect_client-3.0.0rc5.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
186
- prefect_client-3.0.0rc5.dist-info/RECORD,,
182
+ prefect_client-3.0.0rc7.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
183
+ prefect_client-3.0.0rc7.dist-info/METADATA,sha256=XGHFsFT4rRszItqxIOYgPy9KGgecgj7YZSVN0tZB-OE,7392
184
+ prefect_client-3.0.0rc7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
185
+ prefect_client-3.0.0rc7.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
186
+ prefect_client-3.0.0rc7.dist-info/RECORD,,