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.
- prefect/_internal/compatibility/migration.py +1 -1
- prefect/artifacts.py +1 -1
- prefect/blocks/core.py +3 -4
- prefect/blocks/notifications.py +10 -10
- prefect/blocks/system.py +4 -4
- prefect/blocks/webhook.py +3 -1
- prefect/client/cloud.py +2 -1
- prefect/client/orchestration.py +54 -1
- prefect/context.py +7 -9
- prefect/deployments/runner.py +3 -3
- prefect/exceptions.py +6 -0
- prefect/filesystems.py +5 -3
- prefect/flow_engine.py +13 -10
- prefect/flows.py +0 -2
- prefect/futures.py +2 -1
- prefect/locking/__init__.py +0 -0
- prefect/locking/memory.py +213 -0
- prefect/locking/protocol.py +122 -0
- prefect/records/filesystem.py +4 -2
- prefect/records/result_store.py +12 -6
- prefect/results.py +559 -206
- prefect/settings.py +10 -3
- prefect/states.py +12 -12
- prefect/task_engine.py +28 -20
- prefect/task_worker.py +6 -4
- prefect/tasks.py +24 -6
- prefect/transactions.py +35 -28
- prefect/utilities/callables.py +1 -3
- prefect/variables.py +34 -24
- prefect/workers/process.py +1 -3
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/METADATA +2 -2
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/RECORD +35 -32
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/LICENSE +0 -0
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/WHEEL +0 -0
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/top_level.txt +0 -0
@@ -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/
|
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/
|
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
|
559
|
-
|
560
|
-
|
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
|
prefect/blocks/notifications.py
CHANGED
@@ -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/
|
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/
|
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/
|
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/
|
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/
|
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/
|
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/
|
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/
|
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/
|
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/
|
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/
|
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/
|
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/
|
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/
|
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 =
|
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,
|
79
|
+
or re.search(PARSE_API_URL_REGEX, api_url)
|
79
80
|
):
|
80
81
|
self.account_id, self.workspace_id = match.groups()
|
81
82
|
|
prefect/client/orchestration.py
CHANGED
@@ -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.
|
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
|
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
|
-
|
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
|
-
|
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
|
)
|
prefect/deployments/runner.py
CHANGED
@@ -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/
|
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/
|
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/
|
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
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/
|
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/
|
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 =
|
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,
|
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
|
-
|
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
|
-
|
265
|
-
if
|
266
|
-
raise ValueError("Result
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|