prefect-client 3.0.0rc20__py3-none-any.whl → 3.0.1__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.
@@ -60,7 +60,7 @@ MOVED_IN_V3 = {
60
60
  "prefect.client:get_client": "prefect.client.orchestration:get_client",
61
61
  }
62
62
 
63
- upgrade_guide_msg = "Refer to the upgrade guide for more information: https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/."
63
+ upgrade_guide_msg = "Refer to the upgrade guide for more information: https://docs.prefect.io/latest/resources/upgrade-agents-to-workers."
64
64
 
65
65
  REMOVED_IN_V3 = {
66
66
  "prefect.client.schemas.objects:MinimalDeploymentSchedule": "Use `prefect.client.schemas.actions.DeploymentScheduleCreate` instead.",
prefect/artifacts.py CHANGED
@@ -31,7 +31,7 @@ if TYPE_CHECKING:
31
31
  class Artifact(ArtifactRequest):
32
32
  """
33
33
  An artifact is a piece of data that is created by a flow or task run.
34
- https://docs.prefect.io/latest/concepts/artifacts/
34
+ https://docs.prefect.io/latest/develop/artifacts
35
35
 
36
36
  Arguments:
37
37
  type: A string identifying the type of artifact.
prefect/blocks/core.py CHANGED
@@ -555,10 +555,9 @@ class Block(BaseModel, ABC):
555
555
  `<module>:11: No type or annotation for parameter 'write_json'`
556
556
  because griffe is unable to parse the types from pydantic.BaseModel.
557
557
  """
558
- with disable_logger("griffe.docstrings.google"):
559
- with disable_logger("griffe.agents.nodes"):
560
- docstring = Docstring(cls.__doc__)
561
- parsed = parse(docstring, Parser.google)
558
+ with disable_logger("griffe"):
559
+ docstring = Docstring(cls.__doc__)
560
+ parsed = parse(docstring, Parser.google)
562
561
  return parsed
563
562
 
564
563
  @classmethod
@@ -73,7 +73,7 @@ class AppriseNotificationBlock(AbstractAppriseNotificationBlock, ABC):
73
73
  A base class for sending notifications using Apprise, through webhook URLs.
74
74
  """
75
75
 
76
- _documentation_url = "https://docs.prefect.io/ui/notifications/"
76
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
77
77
  url: SecretStr = Field(
78
78
  default=...,
79
79
  title="Webhook URL",
@@ -100,7 +100,7 @@ class SlackWebhook(AppriseNotificationBlock):
100
100
 
101
101
  _block_type_name = "Slack Webhook"
102
102
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/c1965ecbf8704ee1ea20d77786de9a41ce1087d1-500x500.png"
103
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.SlackWebhook"
103
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
104
104
 
105
105
  url: SecretStr = Field(
106
106
  default=...,
@@ -126,7 +126,7 @@ class MicrosoftTeamsWebhook(AppriseNotificationBlock):
126
126
  _block_type_name = "Microsoft Teams Webhook"
127
127
  _block_type_slug = "ms-teams-webhook"
128
128
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/817efe008a57f0a24f3587414714b563e5e23658-250x250.png"
129
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.MicrosoftTeamsWebhook"
129
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
130
130
 
131
131
  url: SecretStr = Field(
132
132
  default=...,
@@ -181,7 +181,7 @@ class PagerDutyWebHook(AbstractAppriseNotificationBlock):
181
181
  _block_type_name = "Pager Duty Webhook"
182
182
  _block_type_slug = "pager-duty-webhook"
183
183
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/8dbf37d17089c1ce531708eac2e510801f7b3aee-250x250.png"
184
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.PagerDutyWebHook"
184
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
185
185
 
186
186
  # The default cannot be prefect_default because NotifyPagerDuty's
187
187
  # PAGERDUTY_SEVERITY_MAP only has these notify types defined as keys
@@ -291,7 +291,7 @@ class TwilioSMS(AbstractAppriseNotificationBlock):
291
291
  _block_type_name = "Twilio SMS"
292
292
  _block_type_slug = "twilio-sms"
293
293
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/8bd8777999f82112c09b9c8d57083ac75a4a0d65-250x250.png" # noqa
294
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.TwilioSMS"
294
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
295
295
 
296
296
  account_sid: str = Field(
297
297
  default=...,
@@ -360,7 +360,7 @@ class OpsgenieWebhook(AbstractAppriseNotificationBlock):
360
360
  _block_type_name = "Opsgenie Webhook"
361
361
  _block_type_slug = "opsgenie-webhook"
362
362
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/d8b5bc6244ae6cd83b62ec42f10d96e14d6e9113-280x280.png"
363
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.OpsgenieWebhook"
363
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
364
364
 
365
365
  apikey: SecretStr = Field(
366
366
  default=...,
@@ -478,7 +478,7 @@ class MattermostWebhook(AbstractAppriseNotificationBlock):
478
478
  _block_type_name = "Mattermost Webhook"
479
479
  _block_type_slug = "mattermost-webhook"
480
480
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/1350a147130bf82cbc799a5f868d2c0116207736-250x250.png"
481
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.MattermostWebhook"
481
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
482
482
 
483
483
  hostname: str = Field(
484
484
  default=...,
@@ -559,7 +559,7 @@ class DiscordWebhook(AbstractAppriseNotificationBlock):
559
559
  _block_type_name = "Discord Webhook"
560
560
  _block_type_slug = "discord-webhook"
561
561
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/9e94976c80ef925b66d24e5d14f0d47baa6b8f88-250x250.png"
562
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.DiscordWebhook"
562
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
563
563
 
564
564
  webhook_id: SecretStr = Field(
565
565
  default=...,
@@ -658,7 +658,7 @@ class CustomWebhookNotificationBlock(NotificationBlock):
658
658
 
659
659
  _block_type_name = "Custom Webhook"
660
660
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/c7247cb359eb6cf276734d4b1fbf00fb8930e89e-250x250.png"
661
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.CustomWebhookNotificationBlock"
661
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
662
662
 
663
663
  name: str = Field(title="Name", description="Name of the webhook.")
664
664
 
@@ -789,7 +789,7 @@ class SendgridEmail(AbstractAppriseNotificationBlock):
789
789
  _block_type_name = "Sendgrid Email"
790
790
  _block_type_slug = "sendgrid-email"
791
791
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/82bc6ed16ca42a2252a5512c72233a253b8a58eb-250x250.png"
792
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.SendgridEmail"
792
+ _documentation_url = "https://docs.prefect.io/latest/automate/events/automations-triggers#sending-notifications-with-automations"
793
793
 
794
794
  api_key: SecretStr = Field(
795
795
  default=...,
prefect/blocks/system.py CHANGED
@@ -44,7 +44,7 @@ class JSON(Block):
44
44
  """
45
45
 
46
46
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/4fcef2294b6eeb423b1332d1ece5156bf296ff96-48x48.png"
47
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/system/#prefect.blocks.system.JSON"
47
+ _documentation_url = "https://docs.prefect.io/latest/develop/blocks"
48
48
 
49
49
  value: Any = Field(default=..., description="A JSON-compatible value.")
50
50
 
@@ -71,7 +71,7 @@ class String(Block):
71
71
  """
72
72
 
73
73
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/c262ea2c80a2c043564e8763f3370c3db5a6b3e6-48x48.png"
74
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/system/#prefect.blocks.system.String"
74
+ _documentation_url = "https://docs.prefect.io/latest/develop/blocks"
75
75
 
76
76
  value: str = Field(default=..., description="A string value.")
77
77
 
@@ -99,7 +99,7 @@ class DateTime(Block):
99
99
 
100
100
  _block_type_name = "Date Time"
101
101
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/8b3da9a6621e92108b8e6a75b82e15374e170ff7-48x48.png"
102
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/system/#prefect.blocks.system.DateTime"
102
+ _documentation_url = "https://docs.prefect.io/latest/develop/blocks"
103
103
 
104
104
  value: PydanticDateTime = Field(
105
105
  default=...,
@@ -129,7 +129,7 @@ class Secret(Block, Generic[T]):
129
129
  """
130
130
 
131
131
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/c6f20e556dd16effda9df16551feecfb5822092b-48x48.png"
132
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/system/#prefect.blocks.system.Secret"
132
+ _documentation_url = "https://docs.prefect.io/latest/develop/blocks"
133
133
 
134
134
  value: Union[SecretStr, PydanticSecret[T]] = Field(
135
135
  default=...,
prefect/blocks/webhook.py CHANGED
@@ -19,7 +19,9 @@ class Webhook(Block):
19
19
 
20
20
  _block_type_name = "Webhook"
21
21
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/c7247cb359eb6cf276734d4b1fbf00fb8930e89e-250x250.png" # type: ignore
22
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/webhook/#prefect.blocks.webhook.Webhook"
22
+ _documentation_url = (
23
+ "https://docs.prefect.io/latest/automate/events/webhook-triggers"
24
+ )
23
25
 
24
26
  method: Literal["GET", "POST", "PUT", "PATCH", "DELETE"] = Field(
25
27
  default="POST", description="The webhook request method. Defaults to `POST`."
prefect/client/cloud.py CHANGED
@@ -73,9 +73,10 @@ class CloudClient:
73
73
  **httpx_settings, enable_csrf_support=False
74
74
  )
75
75
 
76
+ api_url = prefect.settings.PREFECT_API_URL.value() or ""
76
77
  if match := (
77
78
  re.search(PARSE_API_URL_REGEX, host)
78
- or re.search(PARSE_API_URL_REGEX, prefect.settings.PREFECT_API_URL.value())
79
+ or re.search(PARSE_API_URL_REGEX, api_url)
79
80
  ):
80
81
  self.account_id, self.workspace_id = match.groups()
81
82
 
@@ -24,6 +24,7 @@ import httpx
24
24
  import pendulum
25
25
  import pydantic
26
26
  from asgi_lifespan import LifespanManager
27
+ from packaging import version
27
28
  from starlette import status
28
29
  from typing_extensions import ParamSpec
29
30
 
@@ -3329,6 +3330,32 @@ class PrefectClient:
3329
3330
  async def delete_resource_owned_automations(self, resource_id: str):
3330
3331
  await self._client.delete(f"/automations/owned-by/{resource_id}")
3331
3332
 
3333
+ async def api_version(self) -> str:
3334
+ res = await self._client.get("/admin/version")
3335
+ return res.json()
3336
+
3337
+ def client_version(self) -> str:
3338
+ return prefect.__version__
3339
+
3340
+ async def raise_for_api_version_mismatch(self):
3341
+ # Cloud is always compatible as a server
3342
+ if self.server_type == ServerType.CLOUD:
3343
+ return
3344
+
3345
+ try:
3346
+ api_version = await self.api_version()
3347
+ except Exception as e:
3348
+ raise RuntimeError(f"Failed to reach API at {self.api_url}") from e
3349
+
3350
+ api_version = version.parse(api_version)
3351
+ client_version = version.parse(self.client_version())
3352
+
3353
+ if api_version.major != client_version.major:
3354
+ raise RuntimeError(
3355
+ f"Found incompatible versions: client: {client_version}, server: {api_version}. "
3356
+ f"Major versions must match."
3357
+ )
3358
+
3332
3359
  async def __aenter__(self):
3333
3360
  """
3334
3361
  Start the client.
@@ -3622,6 +3649,32 @@ class SyncPrefectClient:
3622
3649
  """
3623
3650
  return self._client.get("/hello")
3624
3651
 
3652
+ def api_version(self) -> str:
3653
+ res = self._client.get("/admin/version")
3654
+ return res.json()
3655
+
3656
+ def client_version(self) -> str:
3657
+ return prefect.__version__
3658
+
3659
+ def raise_for_api_version_mismatch(self):
3660
+ # Cloud is always compatible as a server
3661
+ if self.server_type == ServerType.CLOUD:
3662
+ return
3663
+
3664
+ try:
3665
+ api_version = self.api_version()
3666
+ except Exception as e:
3667
+ raise RuntimeError(f"Failed to reach API at {self.api_url}") from e
3668
+
3669
+ api_version = version.parse(api_version)
3670
+ client_version = version.parse(self.client_version())
3671
+
3672
+ if api_version.major != client_version.major:
3673
+ raise RuntimeError(
3674
+ f"Found incompatible versions: client: {client_version}, server: {api_version}. "
3675
+ f"Major versions must match."
3676
+ )
3677
+
3625
3678
  def create_flow(self, flow: "FlowObject") -> UUID:
3626
3679
  """
3627
3680
  Create a flow in the Prefect API.
@@ -4147,7 +4200,7 @@ class SyncPrefectClient:
4147
4200
 
4148
4201
  response = self._client.post(
4149
4202
  "/artifacts/",
4150
- json=artifact.model_dump_json(exclude_unset=True),
4203
+ json=artifact.model_dump(mode="json", exclude_unset=True),
4151
4204
  )
4152
4205
 
4153
4206
  return Artifact.model_validate(response.json())
prefect/context.py CHANGED
@@ -40,11 +40,10 @@ from prefect.client.orchestration import PrefectClient, SyncPrefectClient, get_c
40
40
  from prefect.client.schemas import FlowRun, TaskRun
41
41
  from prefect.events.worker import EventsWorker
42
42
  from prefect.exceptions import MissingContextError
43
- from prefect.results import ResultFactory
43
+ from prefect.results import ResultStore
44
44
  from prefect.settings import PREFECT_HOME, Profile, Settings
45
45
  from prefect.states import State
46
46
  from prefect.task_runners import TaskRunner
47
- from prefect.utilities.asyncutils import run_coro_as_sync
48
47
  from prefect.utilities.services import start_client_metrics_server
49
48
 
50
49
  T = TypeVar("T")
@@ -95,20 +94,15 @@ def hydrated_context(
95
94
  flow_run_context = FlowRunContext(
96
95
  **flow_run_context,
97
96
  client=client,
98
- result_factory=run_coro_as_sync(ResultFactory.from_flow(flow)),
99
97
  task_runner=task_runner,
100
98
  detached=True,
101
99
  )
102
100
  stack.enter_context(flow_run_context)
103
101
  # Set up parent task run context
104
102
  if parent_task_run_context := serialized_context.get("task_run_context"):
105
- parent_task = parent_task_run_context["task"]
106
103
  task_run_context = TaskRunContext(
107
104
  **parent_task_run_context,
108
105
  client=client,
109
- result_factory=run_coro_as_sync(
110
- ResultFactory.from_autonomous_task(parent_task)
111
- ),
112
106
  )
113
107
  stack.enter_context(task_run_context)
114
108
  # Set up tags context
@@ -216,6 +210,7 @@ class SyncClientContext(ContextModel):
216
210
  self._context_stack += 1
217
211
  if self._context_stack == 1:
218
212
  self.client.__enter__()
213
+ self.client.raise_for_api_version_mismatch()
219
214
  return super().__enter__()
220
215
  else:
221
216
  return self
@@ -273,6 +268,7 @@ class AsyncClientContext(ContextModel):
273
268
  self._context_stack += 1
274
269
  if self._context_stack == 1:
275
270
  await self.client.__aenter__()
271
+ await self.client.raise_for_api_version_mismatch()
276
272
  return super().__enter__()
277
273
  else:
278
274
  return self
@@ -346,7 +342,7 @@ class EngineContext(RunContext):
346
342
  detached: bool = False
347
343
 
348
344
  # Result handling
349
- result_factory: ResultFactory
345
+ result_store: ResultStore
350
346
 
351
347
  # Counter for task calls allowing unique
352
348
  task_run_dynamic_keys: Dict[str, int] = Field(default_factory=dict)
@@ -375,6 +371,7 @@ class EngineContext(RunContext):
375
371
  "log_prints",
376
372
  "start_time",
377
373
  "input_keyset",
374
+ "result_store",
378
375
  },
379
376
  exclude_unset=True,
380
377
  )
@@ -399,7 +396,7 @@ class TaskRunContext(RunContext):
399
396
  parameters: Dict[str, Any]
400
397
 
401
398
  # Result handling
402
- result_factory: ResultFactory
399
+ result_store: ResultStore
403
400
 
404
401
  __var__ = ContextVar("task_run")
405
402
 
@@ -412,6 +409,7 @@ class TaskRunContext(RunContext):
412
409
  "log_prints",
413
410
  "start_time",
414
411
  "input_keyset",
412
+ "result_store",
415
413
  },
416
414
  exclude_unset=True,
417
415
  )
@@ -508,7 +508,7 @@ class RunnerDeployment(BaseModel):
508
508
  no_file_location_error = (
509
509
  "Flows defined interactively cannot be deployed. Check out the"
510
510
  " quickstart guide for help getting started:"
511
- " https://docs.prefect.io/latest/getting-started/quickstart"
511
+ " https://docs.prefect.io/latest/get-started/quickstart"
512
512
  )
513
513
  ## first see if an entrypoint can be determined
514
514
  flow_file = getattr(flow, "__globals__", {}).get("__file__")
@@ -851,14 +851,14 @@ async def deploy(
851
851
  " or specify a remote storage location for the flow with `.from_source`."
852
852
  " If you are attempting to deploy a flow to a local process work pool,"
853
853
  " consider using `flow.serve` instead. See the documentation for more"
854
- " information: https://docs.prefect.io/latest/concepts/flows/#serving-a-flow"
854
+ " information: https://docs.prefect.io/latest/deploy/run-flows-in-local-processes"
855
855
  )
856
856
  elif work_pool.type == "process" and not ignore_warnings:
857
857
  console.print(
858
858
  "Looks like you're deploying to a process work pool. If you're creating a"
859
859
  " deployment for local development, calling `.serve` on your flow is a great"
860
860
  " way to get started. See the documentation for more information:"
861
- " https://docs.prefect.io/latest/concepts/flows/#serving-a-flow. "
861
+ " https://docs.prefect.io/latest/deploy/run-flows-in-local-processes "
862
862
  " Set `ignore_warnings=True` to suppress this message.",
863
863
  style="yellow",
864
864
  )
prefect/exceptions.py CHANGED
@@ -418,3 +418,9 @@ class SerializationError(PrefectException):
418
418
  """
419
419
  Raised when an object cannot be serialized.
420
420
  """
421
+
422
+
423
+ class ConfigurationError(PrefectException):
424
+ """
425
+ Raised when a configuration is invalid.
426
+ """
prefect/filesystems.py CHANGED
@@ -84,7 +84,7 @@ class LocalFileSystem(WritableFileSystem, WritableDeploymentStorage):
84
84
  _block_type_name = "Local File System"
85
85
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/ad39089fa66d273b943394a68f003f7a19aa850e-48x48.png"
86
86
  _documentation_url = (
87
- "https://docs.prefect.io/concepts/filesystems/#local-filesystem"
87
+ "https://docs.prefect.io/latest/develop/results#specifying-a-default-filesystem"
88
88
  )
89
89
 
90
90
  basepath: Optional[str] = Field(
@@ -260,7 +260,7 @@ class RemoteFileSystem(WritableFileSystem, WritableDeploymentStorage):
260
260
  _block_type_name = "Remote File System"
261
261
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/e86b41bc0f9c99ba9489abeee83433b43d5c9365-48x48.png"
262
262
  _documentation_url = (
263
- "https://docs.prefect.io/concepts/filesystems/#remote-file-system"
263
+ "https://docs.prefect.io/latest/develop/results#specifying-a-default-filesystem"
264
264
  )
265
265
 
266
266
  basepath: str = Field(
@@ -433,7 +433,9 @@ class SMB(WritableFileSystem, WritableDeploymentStorage):
433
433
 
434
434
  _block_type_name = "SMB"
435
435
  _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/3f624663f7beb97d011d011bffd51ecf6c499efc-195x195.png"
436
- _documentation_url = "https://docs.prefect.io/concepts/filesystems/#smb"
436
+ _documentation_url = (
437
+ "https://docs.prefect.io/latest/develop/results#specifying-a-default-filesystem"
438
+ )
437
439
 
438
440
  share_path: str = Field(
439
441
  default=...,
prefect/flow_engine.py CHANGED
@@ -47,7 +47,7 @@ from prefect.logging.loggers import (
47
47
  get_run_logger,
48
48
  patch_print,
49
49
  )
50
- from prefect.results import BaseResult, ResultFactory
50
+ from prefect.results import BaseResult, ResultStore, get_current_result_store
51
51
  from prefect.settings import PREFECT_DEBUG_MODE
52
52
  from prefect.states import (
53
53
  Failed,
@@ -202,7 +202,9 @@ class FlowRunEngine(Generic[P, R]):
202
202
  self.handle_exception(
203
203
  exc,
204
204
  msg=message,
205
- result_factory=run_coro_as_sync(ResultFactory.from_flow(self.flow)),
205
+ result_store=get_current_result_store().update_for_flow(
206
+ self.flow, _sync=True
207
+ ),
206
208
  )
207
209
  self.short_circuit = True
208
210
  self.call_hooks()
@@ -261,14 +263,14 @@ class FlowRunEngine(Generic[P, R]):
261
263
  return _result
262
264
 
263
265
  def handle_success(self, result: R) -> R:
264
- result_factory = getattr(FlowRunContext.get(), "result_factory", None)
265
- if result_factory is None:
266
- raise ValueError("Result factory is not set")
266
+ result_store = getattr(FlowRunContext.get(), "result_store", None)
267
+ if result_store is None:
268
+ raise ValueError("Result store is not set")
267
269
  resolved_result = resolve_futures_to_states(result)
268
270
  terminal_state = run_coro_as_sync(
269
271
  return_value_to_state(
270
272
  resolved_result,
271
- result_factory=result_factory,
273
+ result_store=result_store,
272
274
  write_result=True,
273
275
  )
274
276
  )
@@ -280,15 +282,14 @@ class FlowRunEngine(Generic[P, R]):
280
282
  self,
281
283
  exc: Exception,
282
284
  msg: Optional[str] = None,
283
- result_factory: Optional[ResultFactory] = None,
285
+ result_store: Optional[ResultStore] = None,
284
286
  ) -> State:
285
287
  context = FlowRunContext.get()
286
288
  terminal_state = run_coro_as_sync(
287
289
  exception_to_failed_state(
288
290
  exc,
289
291
  message=msg or "Flow run encountered an exception:",
290
- result_factory=result_factory
291
- or getattr(context, "result_factory", None),
292
+ result_store=result_store or getattr(context, "result_store", None),
292
293
  write_result=True,
293
294
  )
294
295
  )
@@ -506,7 +507,9 @@ class FlowRunEngine(Generic[P, R]):
506
507
  flow_run=self.flow_run,
507
508
  parameters=self.parameters,
508
509
  client=client,
509
- result_factory=run_coro_as_sync(ResultFactory.from_flow(self.flow)),
510
+ result_store=get_current_result_store().update_for_flow(
511
+ self.flow, _sync=True
512
+ ),
510
513
  task_runner=task_runner,
511
514
  )
512
515
  )
prefect/flows.py CHANGED
@@ -1032,8 +1032,6 @@ class Flow(Generic[P, R]):
1032
1032
  if not isinstance(storage, LocalStorage):
1033
1033
  storage.set_base_path(Path(tmpdir))
1034
1034
  await storage.pull_code()
1035
- storage.set_base_path(Path(tmpdir))
1036
- await storage.pull_code()
1037
1035
 
1038
1036
  full_entrypoint = str(storage.destination / entrypoint)
1039
1037
  flow: Flow = await from_async.wait_for_call_in_new_thread(
prefect/futures.py CHANGED
@@ -179,7 +179,8 @@ class PrefectConcurrentFuture(PrefectWrappedFuture[R, concurrent.futures.Future]
179
179
  local_logger = logger
180
180
  local_logger.warning(
181
181
  "A future was garbage collected before it resolved."
182
- " Please call `.wait()` or `.result()` on futures to ensure they resolve.",
182
+ " Please call `.wait()` or `.result()` on futures to ensure they resolve."
183
+ "\nSee https://docs.prefect.io/latest/develop/task-runners for more details.",
183
184
  )
184
185
 
185
186
 
File without changes