prefect-client 3.1.7__py3-none-any.whl → 3.1.8__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.
prefect/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-12-16T10:06:12-0800",
11
+ "date": "2024-12-17T10:20:43-0800",
12
12
  "dirty": true,
13
13
  "error": null,
14
- "full-revisionid": "c05ffa6d1816f980d574b42119dffb9f8c8300a3",
15
- "version": "3.1.7"
14
+ "full-revisionid": "53a83ebc4a9a26a1d7cfd91d6be7cf6bd30e7f21",
15
+ "version": "3.1.8"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ import base64
2
3
  import datetime
3
4
  import ssl
4
5
  import warnings
@@ -114,6 +115,7 @@ from prefect.events import filters
114
115
  from prefect.events.schemas.automations import Automation, AutomationCore
115
116
  from prefect.logging import get_logger
116
117
  from prefect.settings import (
118
+ PREFECT_API_AUTH_STRING,
117
119
  PREFECT_API_DATABASE_CONNECTION_URL,
118
120
  PREFECT_API_ENABLE_HTTP2,
119
121
  PREFECT_API_KEY,
@@ -228,6 +230,7 @@ def get_client(
228
230
  if sync_client:
229
231
  return SyncPrefectClient(
230
232
  api,
233
+ auth_string=PREFECT_API_AUTH_STRING.value(),
231
234
  api_key=PREFECT_API_KEY.value(),
232
235
  httpx_settings=httpx_settings,
233
236
  server_type=server_type,
@@ -235,6 +238,7 @@ def get_client(
235
238
  else:
236
239
  return PrefectClient(
237
240
  api,
241
+ auth_string=PREFECT_API_AUTH_STRING.value(),
238
242
  api_key=PREFECT_API_KEY.value(),
239
243
  httpx_settings=httpx_settings,
240
244
  server_type=server_type,
@@ -271,6 +275,7 @@ class PrefectClient:
271
275
  self,
272
276
  api: Union[str, ASGIApp],
273
277
  *,
278
+ auth_string: Optional[str] = None,
274
279
  api_key: Optional[str] = None,
275
280
  api_version: Optional[str] = None,
276
281
  httpx_settings: Optional[dict[str, Any]] = None,
@@ -299,6 +304,10 @@ class PrefectClient:
299
304
  if api_key:
300
305
  httpx_settings["headers"].setdefault("Authorization", f"Bearer {api_key}")
301
306
 
307
+ if auth_string:
308
+ token = base64.b64encode(auth_string.encode("utf-8")).decode("utf-8")
309
+ httpx_settings["headers"].setdefault("Authorization", f"Basic {token}")
310
+
302
311
  # Context management
303
312
  self._context_stack: int = 0
304
313
  self._exit_stack = AsyncExitStack()
@@ -3469,6 +3478,8 @@ class PrefectClient:
3469
3478
  try:
3470
3479
  api_version = await self.api_version()
3471
3480
  except Exception as e:
3481
+ if "Unauthorized" in str(e):
3482
+ raise e
3472
3483
  raise RuntimeError(f"Failed to reach API at {self.api_url}") from e
3473
3484
 
3474
3485
  api_version = version.parse(api_version)
@@ -3590,6 +3601,7 @@ class SyncPrefectClient:
3590
3601
  self,
3591
3602
  api: Union[str, ASGIApp],
3592
3603
  *,
3604
+ auth_string: Optional[str] = None,
3593
3605
  api_key: Optional[str] = None,
3594
3606
  api_version: Optional[str] = None,
3595
3607
  httpx_settings: Optional[dict[str, Any]] = None,
@@ -3618,6 +3630,10 @@ class SyncPrefectClient:
3618
3630
  if api_key:
3619
3631
  httpx_settings["headers"].setdefault("Authorization", f"Bearer {api_key}")
3620
3632
 
3633
+ if auth_string:
3634
+ token = base64.b64encode(auth_string.encode("utf-8")).decode("utf-8")
3635
+ httpx_settings["headers"].setdefault("Authorization", f"Basic {token}")
3636
+
3621
3637
  # Context management
3622
3638
  self._context_stack: int = 0
3623
3639
  self._ephemeral_app: Optional[ASGIApp] = None
@@ -3800,6 +3816,8 @@ class SyncPrefectClient:
3800
3816
  try:
3801
3817
  api_version = self.api_version()
3802
3818
  except Exception as e:
3819
+ if "Unauthorized" in str(e):
3820
+ raise e
3803
3821
  raise RuntimeError(f"Failed to reach API at {self.api_url}") from e
3804
3822
 
3805
3823
  api_version = version.parse(api_version)
prefect/runner/runner.py CHANGED
@@ -47,11 +47,12 @@ from typing import (
47
47
  TYPE_CHECKING,
48
48
  Any,
49
49
  Callable,
50
+ Coroutine,
50
51
  Dict,
51
52
  Iterable,
52
53
  List,
53
54
  Optional,
54
- Set,
55
+ TypedDict,
55
56
  Union,
56
57
  )
57
58
  from uuid import UUID, uuid4
@@ -59,6 +60,7 @@ from uuid import UUID, uuid4
59
60
  import anyio
60
61
  import anyio.abc
61
62
  import pendulum
63
+ from cachetools import LRUCache
62
64
 
63
65
  from prefect._internal.concurrency.api import (
64
66
  create_call,
@@ -94,8 +96,6 @@ from prefect.logging.loggers import PrefectLogAdapter, flow_run_logger, get_logg
94
96
  from prefect.runner.storage import RunnerStorage
95
97
  from prefect.settings import (
96
98
  PREFECT_API_URL,
97
- PREFECT_RUNNER_POLL_FREQUENCY,
98
- PREFECT_RUNNER_PROCESS_LIMIT,
99
99
  PREFECT_RUNNER_SERVER_ENABLE,
100
100
  get_current_settings,
101
101
  )
@@ -123,19 +123,25 @@ from prefect.utilities.services import (
123
123
  from prefect.utilities.slugify import slugify
124
124
 
125
125
  if TYPE_CHECKING:
126
- from prefect.client.schemas.objects import Deployment
126
+ from prefect.client.schemas.responses import DeploymentResponse
127
127
  from prefect.client.types.flexible_schedule_list import FlexibleScheduleList
128
128
  from prefect.deployments.runner import RunnerDeployment
129
129
 
130
130
  __all__ = ["Runner"]
131
131
 
132
132
 
133
+ class ProcessMapEntry(TypedDict):
134
+ flow_run: FlowRun
135
+ pid: int
136
+
137
+
133
138
  class Runner:
134
139
  def __init__(
135
140
  self,
136
141
  name: Optional[str] = None,
137
142
  query_seconds: Optional[float] = None,
138
143
  prefetch_seconds: float = 10,
144
+ heartbeat_seconds: Optional[float] = None,
139
145
  limit: Optional[int] = None,
140
146
  pause_on_shutdown: bool = True,
141
147
  webserver: bool = False,
@@ -149,6 +155,9 @@ class Runner:
149
155
  query_seconds: The number of seconds to wait between querying for
150
156
  scheduled flow runs; defaults to `PREFECT_RUNNER_POLL_FREQUENCY`
151
157
  prefetch_seconds: The number of seconds to prefetch flow runs for.
158
+ heartbeat_seconds: The number of seconds to wait between emitting
159
+ flow run heartbeats. The runner will not emit heartbeats if the value is None.
160
+ Defaults to `PREFECT_RUNNER_HEARTBEAT_FREQUENCY`.
152
161
  limit: The maximum number of flow runs this runner should be running at
153
162
  pause_on_shutdown: A boolean for whether or not to automatically pause
154
163
  deployment schedules on shutdown; defaults to `True`
@@ -180,6 +189,8 @@ class Runner:
180
189
  asyncio.run(runner.start())
181
190
  ```
182
191
  """
192
+ settings = get_current_settings()
193
+
183
194
  if name and ("/" in name or "%" in name):
184
195
  raise ValueError("Runner name cannot contain '/' or '%'")
185
196
  self.name = Path(name).stem if name is not None else f"runner-{uuid4()}"
@@ -188,19 +199,24 @@ class Runner:
188
199
  self.started = False
189
200
  self.stopping = False
190
201
  self.pause_on_shutdown = pause_on_shutdown
191
- self.limit = limit or PREFECT_RUNNER_PROCESS_LIMIT.value()
202
+ self.limit = limit or settings.runner.process_limit
192
203
  self.webserver = webserver
193
204
 
194
- self.query_seconds = query_seconds or PREFECT_RUNNER_POLL_FREQUENCY.value()
205
+ self.query_seconds = query_seconds or settings.runner.poll_frequency
195
206
  self._prefetch_seconds = prefetch_seconds
207
+ self.heartbeat_seconds = (
208
+ heartbeat_seconds or settings.runner.heartbeat_frequency
209
+ )
210
+ if self.heartbeat_seconds is not None and self.heartbeat_seconds < 30:
211
+ raise ValueError("Heartbeat must be 30 seconds or greater.")
196
212
 
197
213
  self._limiter: Optional[anyio.CapacityLimiter] = None
198
214
  self._client = get_client()
199
- self._submitting_flow_run_ids = set()
200
- self._cancelling_flow_run_ids = set()
201
- self._scheduled_task_scopes = set()
202
- self._deployment_ids: Set[UUID] = set()
203
- self._flow_run_process_map: dict[UUID, dict[str, Any]] = dict()
215
+ self._submitting_flow_run_ids: set[UUID] = set()
216
+ self._cancelling_flow_run_ids: set[UUID] = set()
217
+ self._scheduled_task_scopes: set[UUID] = set()
218
+ self._deployment_ids: set[UUID] = set()
219
+ self._flow_run_process_map: dict[UUID, ProcessMapEntry] = dict()
204
220
 
205
221
  self._tmp_dir: Path = (
206
222
  Path(tempfile.gettempdir()) / "runner_storage" / str(uuid4())
@@ -210,6 +226,12 @@ class Runner:
210
226
 
211
227
  self._loop: Optional[asyncio.AbstractEventLoop] = None
212
228
 
229
+ # Caching
230
+ self._deployment_cache: LRUCache[UUID, "DeploymentResponse"] = LRUCache(
231
+ maxsize=100
232
+ )
233
+ self._flow_cache: LRUCache[UUID, "APIFlow"] = LRUCache(maxsize=100)
234
+
213
235
  @sync_compatible
214
236
  async def add_deployment(
215
237
  self,
@@ -234,7 +256,7 @@ class Runner:
234
256
  @sync_compatible
235
257
  async def add_flow(
236
258
  self,
237
- flow: Flow,
259
+ flow: Flow[Any, Any],
238
260
  name: Optional[str] = None,
239
261
  interval: Optional[
240
262
  Union[
@@ -249,7 +271,7 @@ class Runner:
249
271
  paused: Optional[bool] = None,
250
272
  schedules: Optional["FlexibleScheduleList"] = None,
251
273
  concurrency_limit: Optional[Union[int, ConcurrencyLimitConfig, None]] = None,
252
- parameters: Optional[dict] = None,
274
+ parameters: Optional[dict[str, Any]] = None,
253
275
  triggers: Optional[List[Union[DeploymentTriggerTypes, TriggerTypes]]] = None,
254
276
  description: Optional[str] = None,
255
277
  tags: Optional[List[str]] = None,
@@ -336,7 +358,7 @@ class Runner:
336
358
  else:
337
359
  return next(s for s in self._storage_objs if s == storage)
338
360
 
339
- def handle_sigterm(self, signum, frame):
361
+ def handle_sigterm(self, **kwargs: Any) -> None:
340
362
  """
341
363
  Gracefully shuts down the runner when a SIGTERM is received.
342
364
  """
@@ -441,6 +463,16 @@ class Runner:
441
463
  jitter_range=0.3,
442
464
  )
443
465
  )
466
+ if self.heartbeat_seconds is not None:
467
+ loops_task_group.start_soon(
468
+ partial(
469
+ critical_service_loop,
470
+ workload=runner._emit_flow_run_heartbeats,
471
+ interval=self.heartbeat_seconds,
472
+ run_once=run_once,
473
+ jitter_range=0.3,
474
+ )
475
+ )
444
476
 
445
477
  def execute_in_background(
446
478
  self, func: Callable[..., Any], *args: Any, **kwargs: Any
@@ -538,6 +570,15 @@ class Runner:
538
570
  jitter_range=0.3,
539
571
  )
540
572
  )
573
+ if self.heartbeat_seconds is not None:
574
+ tg.start_soon(
575
+ partial(
576
+ critical_service_loop,
577
+ workload=self._emit_flow_run_heartbeats,
578
+ interval=self.heartbeat_seconds,
579
+ jitter_range=0.3,
580
+ )
581
+ )
541
582
 
542
583
  def _get_flow_run_logger(self, flow_run: "FlowRun") -> PrefectLogAdapter:
543
584
  return flow_run_logger(flow_run=flow_run).getChild(
@@ -850,18 +891,84 @@ class Runner:
850
891
  "message": state_msg or "Flow run was cancelled successfully."
851
892
  },
852
893
  )
894
+
895
+ flow, deployment = await self._get_flow_and_deployment(flow_run)
896
+ self._emit_flow_run_cancelled_event(
897
+ flow_run=flow_run, flow=flow, deployment=deployment
898
+ )
899
+ run_logger.info(f"Cancelled flow run '{flow_run.name}'!")
900
+
901
+ async def _get_flow_and_deployment(
902
+ self, flow_run: "FlowRun"
903
+ ) -> tuple[Optional["APIFlow"], Optional["DeploymentResponse"]]:
904
+ deployment: Optional["DeploymentResponse"] = (
905
+ self._deployment_cache.get(flow_run.deployment_id)
906
+ if flow_run.deployment_id
907
+ else None
908
+ )
909
+ flow: Optional["APIFlow"] = self._flow_cache.get(flow_run.flow_id)
910
+ if not deployment and flow_run.deployment_id is not None:
853
911
  try:
854
912
  deployment = await self._client.read_deployment(flow_run.deployment_id)
913
+ self._deployment_cache[flow_run.deployment_id] = deployment
855
914
  except ObjectNotFound:
856
915
  deployment = None
916
+ if not flow:
857
917
  try:
858
918
  flow = await self._client.read_flow(flow_run.flow_id)
919
+ self._flow_cache[flow_run.flow_id] = flow
859
920
  except ObjectNotFound:
860
921
  flow = None
861
- self._emit_flow_run_cancelled_event(
862
- flow_run=flow_run, flow=flow, deployment=deployment
922
+ return flow, deployment
923
+
924
+ async def _emit_flow_run_heartbeats(self):
925
+ coros: list[Coroutine[Any, Any, Any]] = []
926
+ for entry in self._flow_run_process_map.values():
927
+ coros.append(self._emit_flow_run_heartbeat(entry["flow_run"]))
928
+ await asyncio.gather(*coros)
929
+
930
+ async def _emit_flow_run_heartbeat(self, flow_run: "FlowRun"):
931
+ from prefect import __version__
932
+
933
+ related: list[RelatedResource] = []
934
+ tags: list[str] = []
935
+
936
+ flow, deployment = await self._get_flow_and_deployment(flow_run)
937
+ if deployment:
938
+ related.append(
939
+ RelatedResource(
940
+ {
941
+ "prefect.resource.id": f"prefect.deployment.{deployment.id}",
942
+ "prefect.resource.role": "deployment",
943
+ "prefect.resource.name": deployment.name,
944
+ }
945
+ )
863
946
  )
864
- run_logger.info(f"Cancelled flow run '{flow_run.name}'!")
947
+ tags.extend(deployment.tags)
948
+ if flow:
949
+ related.append(
950
+ RelatedResource(
951
+ {
952
+ "prefect.resource.id": f"prefect.flow.{flow.id}",
953
+ "prefect.resource.role": "flow",
954
+ "prefect.resource.name": flow.name,
955
+ }
956
+ )
957
+ )
958
+ tags.extend(flow_run.tags)
959
+
960
+ related = [RelatedResource.model_validate(r) for r in related]
961
+ related += tags_as_related_resources(set(tags))
962
+
963
+ emit_event(
964
+ event="prefect.flow-run.heartbeat",
965
+ resource={
966
+ "prefect.resource.id": f"prefect.flow-run.{flow_run.id}",
967
+ "prefect.resource.name": flow_run.name,
968
+ "prefect.version": __version__,
969
+ },
970
+ related=related,
971
+ )
865
972
 
866
973
  def _event_resource(self):
867
974
  from prefect import __version__
@@ -876,7 +983,7 @@ class Runner:
876
983
  self,
877
984
  flow_run: "FlowRun",
878
985
  flow: "Optional[APIFlow]",
879
- deployment: "Optional[Deployment]",
986
+ deployment: "Optional[DeploymentResponse]",
880
987
  ):
881
988
  related: list[RelatedResource] = []
882
989
  tags: list[str] = []
@@ -920,6 +1027,7 @@ class Runner:
920
1027
  resource=self._event_resource(),
921
1028
  related=related,
922
1029
  )
1030
+ self._logger.debug(f"Emitted flow run heartbeat event for {flow_run.id}")
923
1031
 
924
1032
  async def _get_scheduled_flow_runs(
925
1033
  self,
@@ -1052,6 +1160,9 @@ class Runner:
1052
1160
  self._flow_run_process_map[flow_run.id] = dict(
1053
1161
  pid=readiness_result, flow_run=flow_run
1054
1162
  )
1163
+ # Heartbeats are opt-in and only emitted if a heartbeat frequency is set
1164
+ if self.heartbeat_seconds is not None:
1165
+ await self._emit_flow_run_heartbeat(flow_run)
1055
1166
 
1056
1167
  run_logger.info(f"Completed submission of flow run '{flow_run.id}'")
1057
1168
  else:
@@ -53,6 +53,7 @@ __all__ = [ # noqa: F822
53
53
  "temporary_settings",
54
54
  "DEFAULT_PROFILES_PATH",
55
55
  # add public settings here for auto-completion
56
+ "PREFECT_API_AUTH_STRING", # type: ignore
56
57
  "PREFECT_API_KEY", # type: ignore
57
58
  "PREFECT_API_URL", # type: ignore
58
59
  "PREFECT_UI_URL", # type: ignore
prefect/settings/base.py CHANGED
@@ -192,7 +192,7 @@ def _add_environment_variables(
192
192
 
193
193
 
194
194
  def _build_settings_config(
195
- path: Tuple[str, ...] = tuple(),
195
+ path: Tuple[str, ...] = tuple(), frozen: bool = False
196
196
  ) -> PrefectSettingsConfigDict:
197
197
  env_prefix = f"PREFECT_{'_'.join(path).upper()}_" if path else "PREFECT_"
198
198
  return PrefectSettingsConfigDict(
@@ -202,7 +202,8 @@ def _build_settings_config(
202
202
  toml_file="prefect.toml",
203
203
  prefect_toml_table_header=path,
204
204
  pyproject_toml_table_header=("tool", "prefect", *path),
205
- json_schema_extra=_add_environment_variables,
205
+ json_schema_extra=_add_environment_variables, # type: ignore
206
+ frozen=frozen,
206
207
  )
207
208
 
208
209
 
@@ -19,6 +19,10 @@ class APISettings(PrefectBaseSettings):
19
19
  default=None,
20
20
  description="The URL of the Prefect API. If not set, the client will attempt to infer it.",
21
21
  )
22
+ auth_string: Optional[SecretStr] = Field(
23
+ default=None,
24
+ description="The auth string used for basic authentication with a self-hosted Prefect API. Should be kept secret.",
25
+ )
22
26
  key: Optional[SecretStr] = Field(
23
27
  default=None,
24
28
  description="The API key used for authentication with the Prefect API. Should be kept secret.",
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from pydantic import Field
2
4
 
3
5
  from prefect.settings.base import PrefectBaseSettings, _build_settings_config
@@ -54,6 +56,12 @@ class RunnerSettings(PrefectBaseSettings):
54
56
  description="Number of seconds a runner should wait between queries for scheduled work.",
55
57
  )
56
58
 
59
+ heartbeat_frequency: Optional[int] = Field(
60
+ default=None,
61
+ description="Number of seconds a runner should wait between heartbeats for flow runs.",
62
+ ge=30,
63
+ )
64
+
57
65
  server: RunnerServerSettings = Field(
58
66
  default_factory=RunnerServerSettings,
59
67
  description="Settings for controlling runner server behavior",
@@ -1,6 +1,7 @@
1
1
  from datetime import timedelta
2
+ from typing import Optional
2
3
 
3
- from pydantic import AliasChoices, AliasPath, Field
4
+ from pydantic import AliasChoices, AliasPath, Field, SecretStr
4
5
 
5
6
  from prefect.settings.base import PrefectBaseSettings, _build_settings_config
6
7
 
@@ -12,6 +13,11 @@ class ServerAPISettings(PrefectBaseSettings):
12
13
 
13
14
  model_config = _build_settings_config(("server", "api"))
14
15
 
16
+ auth_string: Optional[SecretStr] = Field(
17
+ default=None,
18
+ description="A string to use for basic authentication with the API; typically in the form 'user:password' but can be any string.",
19
+ )
20
+
15
21
  host: str = Field(
16
22
  default="127.0.0.1",
17
23
  description="The API's host address (defaults to `127.0.0.1`).",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 3.1.7
3
+ Version: 3.1.8
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -1,6 +1,6 @@
1
1
  prefect/.prefectignore,sha256=awSprvKT0vI8a64mEOLrMxhxqcO-b0ERQeYpA2rNKVQ,390
2
2
  prefect/__init__.py,sha256=ueYVH54DQR3_ktv_s3nB0xf_45VEekMsiwVV7aSOgcM,3522
3
- prefect/_version.py,sha256=5AMwrvCH2wgaO_0FCvrmHtoVbKo0Gm1xYSvAJ1QLDX4,496
3
+ prefect/_version.py,sha256=bscv-D4ssNwrDiU3ekD7QzmIrDtnERxX5XHAG6X-rTE,496
4
4
  prefect/agent.py,sha256=BOVVY5z-vUIQ2u8LwMTXDaNys2fjOZSS5YGDwJmTQjI,230
5
5
  prefect/artifacts.py,sha256=dsxFWmdg2r9zbHM3KgKOR5YbJ29_dXUYF9kipJpbxkE,13009
6
6
  prefect/automations.py,sha256=T8sUqDriABSuFeuoKUH2OXeCK5YwFfk-mjjM0_Oflyw,5984
@@ -72,7 +72,7 @@ prefect/client/base.py,sha256=KJg-RapWjjJp64I-k7s3AlN3rXZQRVz2tYOoAQ6qdTU,25547
72
72
  prefect/client/cloud.py,sha256=-Va7ziL5ZnF0a9jz1Pinhmtl5rkw5sTpkBu5eKegSbA,7179
73
73
  prefect/client/collections.py,sha256=OdgJrUssGtuD0tHIYhtBamEN5q4oA6Uv4ZX-QueW7LI,1074
74
74
  prefect/client/constants.py,sha256=Z_GG8KF70vbbXxpJuqW5pLnwzujTVeHbcYYRikNmGH0,29
75
- prefect/client/orchestration.py,sha256=I36EOzCmpDS6ruHBqOvsy2ORywMcDs85fWFiRbHUH2U,159172
75
+ prefect/client/orchestration.py,sha256=DQBnvgFZ1jbUMfMKcoP6l5mn6lZlT_0FW2DFcP0ahds,159927
76
76
  prefect/client/subscriptions.py,sha256=TZ7Omv8yeQQIkE6EmWYM78e8p7UdvdTDzcQe91dCU4U,3838
77
77
  prefect/client/utilities.py,sha256=mfU-t5sCm5GV9dLKmUbl2ynixGZJOKXSh3_gjZfA7Vo,3703
78
78
  prefect/client/schemas/__init__.py,sha256=uQqe3HkbW3gBvsIju0ee_ybJ8uuF2z_-DXLjS_O_37w,1063
@@ -150,7 +150,7 @@ prefect/records/filesystem.py,sha256=X-h7r5deiHH5IaaDk4ugOCmR5ZKnJeU2cLgp0AkMt0E
150
150
  prefect/records/memory.py,sha256=YdzQvEfb-CX0sKxAZK5TaNxVvAlyYlZse9qdoer6Xbk,6447
151
151
  prefect/records/result_store.py,sha256=3ZUFNHCCv_qBQhmIFdvlK_GMnPZcFacaI9dVdDKWdwA,2431
152
152
  prefect/runner/__init__.py,sha256=7U-vAOXFkzMfRz1q8Uv6Otsvc0OrPYLLP44srwkJ_8s,89
153
- prefect/runner/runner.py,sha256=BTxJcviHR3_OYCg1jmyftMfk75ppMQ4n49kwLKw200k,49389
153
+ prefect/runner/runner.py,sha256=JZbZqv9hy4rp_TAeIQiLfmplfLWe0OLCRVe6vUrh0wE,54005
154
154
  prefect/runner/server.py,sha256=UXlxugqV1SiC49aTnwCDsEdQS6AXyfstaJWukuOBVO8,11171
155
155
  prefect/runner/storage.py,sha256=EkCnutcpcs4X0II81xBtZFGIwqfwRe00W9r6LLfZkQU,24754
156
156
  prefect/runner/submit.py,sha256=DGhBUUIg-N3z788ZqaCcqpIPkvCzQtZeLqjKtQNV1IA,8137
@@ -161,8 +161,8 @@ prefect/runtime/flow_run.py,sha256=lX8Y2Y1UALwt-LNuDkCcmQ8zKSMgcW2C26Sn2QMM7V4,1
161
161
  prefect/runtime/task_run.py,sha256=B6v_nZiHy9nKZfnKFQF7izZjAjaiZOT0j80m-VcLxmY,3403
162
162
  prefect/server/api/collections_data/views/aggregate-worker-metadata.json,sha256=gqrwGyylzBEzlFSPOJcMuUwdoK_zojpU0SZaBDgK5FE,79748
163
163
  prefect/server/api/static/prefect-logo-mark-gradient.png,sha256=ylRjJkI_JHCw8VbQasNnXQHwZW-sH-IQiUGSD3aWP1E,73430
164
- prefect/settings/__init__.py,sha256=NU9Qyq0DJDIS6bZcgDe_Z2xZkhNEDwdxwbL8bo6V9z8,2023
165
- prefect/settings/base.py,sha256=dB793Q53wD-qUO1yQfxad7xtluWM50XQPhcsMkj6pl8,8410
164
+ prefect/settings/__init__.py,sha256=98gr0K9ovrBz1RQsOIUvYTx2RURbFR5PFKew51Ne314,2070
165
+ prefect/settings/base.py,sha256=lTekZKFzC8IWr4MiejqroJd4Hx6Hk7xu09wn39S99Ng,8470
166
166
  prefect/settings/constants.py,sha256=5NjVLG1Km9J9I-a6wrq-qmi_dTkPdwEk3IrY9bSxWvw,281
167
167
  prefect/settings/context.py,sha256=yKxnaDJHX8e2jmAVtw1RF9o7X4V3AOcz61sVeQyPX2c,2195
168
168
  prefect/settings/legacy.py,sha256=mkd-kMjQqpsIV5zWjiSNdtZDrK2od-Gk8tzat0rh-JE,5653
@@ -170,7 +170,7 @@ prefect/settings/profiles.py,sha256=VZdzOV-KSuAkCxtdhBmSG9i84-K2QLSx6g2-vIUkfig,
170
170
  prefect/settings/profiles.toml,sha256=kTvqDNMzjH3fsm5OEI-NKY4dMmipor5EvQXRB6rPEjY,522
171
171
  prefect/settings/sources.py,sha256=qoRt-XwfDB6-rC1UeZxF08G5DzpEtIU66mtm5fI7dP8,12676
172
172
  prefect/settings/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
- prefect/settings/models/api.py,sha256=DuoBHYeMX9MlgjT6JNLWPHSj_iySo98a0uNuTVSk1r8,1511
173
+ prefect/settings/models/api.py,sha256=nAT0Szkv0cknCPjetTrKpN10x9xsHJYyQExStwN-hhs,1709
174
174
  prefect/settings/models/cli.py,sha256=mHB-BHBVO9qfQcr9uHbBmU6MMDLlLUUDxjyaRz7v1ls,958
175
175
  prefect/settings/models/client.py,sha256=Ua18wKXWrNi0Ktb6cd42kdSOQYhFnObwTHTc3QDYg2k,2985
176
176
  prefect/settings/models/cloud.py,sha256=7-WtW0rGPMOuG1O9Lwv_H_keEldXPo9YGHmoGwCXpeg,1767
@@ -181,12 +181,12 @@ prefect/settings/models/internal.py,sha256=mJ7h3d_WHw-0FBVhIbDHPjYI041YtuReD1bZO
181
181
  prefect/settings/models/logging.py,sha256=YxD8fOcWOROUrq6dH6EIadJwYL7LlLSUGWlHVLn-l3Y,4560
182
182
  prefect/settings/models/results.py,sha256=lU-3oVlgxGradSB1EYU-VZogK-rzE5LDw_wOcKhJp4M,1397
183
183
  prefect/settings/models/root.py,sha256=7PC_Oiz7SYM3Ea3rqn_XnozvdivNq3rKc2dEcjTA5L4,16377
184
- prefect/settings/models/runner.py,sha256=TOYDnmYmv6Ec5Ma6Vii-rPUTeMGszDluecLwy65Gnm4,1644
184
+ prefect/settings/models/runner.py,sha256=eDS7CrO5NpngLhPIyzZuNoR5H4egoqvHLjOQKAT-MOM,1861
185
185
  prefect/settings/models/tasks.py,sha256=qXLWJIVZT4L1GQcaCD_NUJktpB5WYOxthOq_PDLdj20,3309
186
186
  prefect/settings/models/testing.py,sha256=r6KCYi8nvflCEwRFqS2T5J9baMHtVJfW0Q8EWARu1PQ,1733
187
187
  prefect/settings/models/worker.py,sha256=EvaKk4j37QJw8o9w78kU9EF3dxx3aeHD4iT9shY3djk,1229
188
188
  prefect/settings/models/server/__init__.py,sha256=KJmffmlHb8GYnClaeYcerae-IaeNsNMucKKRRS_zG9Q,33
189
- prefect/settings/models/server/api.py,sha256=EKpt31hlX9dwrrsW-QztuJCHfUXqeWSz5xAMre1r698,4719
189
+ prefect/settings/models/server/api.py,sha256=SLnHmsuwwqOPI5kgeOZR5dP0vscD9OzU13NsXIsWN2I,4972
190
190
  prefect/settings/models/server/database.py,sha256=0eerMb05A9wD9_C4SefTzVvmba3rW18K2eteL2IcXLg,7201
191
191
  prefect/settings/models/server/deployments.py,sha256=_GcxGOsMMrCzGEnOwC2i6JQW77h2tbyAdBJzAigHDas,778
192
192
  prefect/settings/models/server/ephemeral.py,sha256=WxSpF-z9iDKAEjvcqrA5aggLEPRbl_ERocoLxPlu424,923
@@ -240,8 +240,8 @@ prefect/workers/cloud.py,sha256=BOVVY5z-vUIQ2u8LwMTXDaNys2fjOZSS5YGDwJmTQjI,230
240
240
  prefect/workers/process.py,sha256=tcJ3fbiraLCfpVGpv8dOHwMSfVzeD_kyguUOvPuIz6I,19796
241
241
  prefect/workers/server.py,sha256=lgh2FfSuaNU7b6HPxSFm8JtKvAvHsZGkiOo4y4tW1Cw,2022
242
242
  prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
243
- prefect_client-3.1.7.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
244
- prefect_client-3.1.7.dist-info/METADATA,sha256=wFhqHeI71rpP-VAGH2VkqHUFtCC_mdnh2mk_fCNbas4,7286
245
- prefect_client-3.1.7.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
246
- prefect_client-3.1.7.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
247
- prefect_client-3.1.7.dist-info/RECORD,,
243
+ prefect_client-3.1.8.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
244
+ prefect_client-3.1.8.dist-info/METADATA,sha256=4KfLwSINwbcWgsBb4RwSbu-lz7FjcGvGCoiKQ3a04_E,7286
245
+ prefect_client-3.1.8.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
246
+ prefect_client-3.1.8.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
247
+ prefect_client-3.1.8.dist-info/RECORD,,