prefect-client 3.1.7__py3-none-any.whl → 3.1.9__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 (40) hide show
  1. prefect/__init__.py +53 -59
  2. prefect/_internal/concurrency/services.py +6 -4
  3. prefect/_version.py +3 -3
  4. prefect/agent.py +3 -1
  5. prefect/client/cloud.py +0 -21
  6. prefect/client/orchestration.py +18 -0
  7. prefect/client/schemas/objects.py +11 -0
  8. prefect/client/utilities.py +1 -15
  9. prefect/deployments/deployments.py +4 -2
  10. prefect/deployments/runner.py +3 -1
  11. prefect/engine.py +2 -1
  12. prefect/events/filters.py +2 -8
  13. prefect/exceptions.py +31 -41
  14. prefect/filesystems.py +2 -2
  15. prefect/flow_engine.py +2 -2
  16. prefect/flows.py +228 -185
  17. prefect/infrastructure/__init__.py +3 -1
  18. prefect/infrastructure/base.py +3 -1
  19. prefect/results.py +76 -19
  20. prefect/runner/runner.py +131 -21
  21. prefect/settings/__init__.py +1 -0
  22. prefect/settings/base.py +3 -2
  23. prefect/settings/models/api.py +4 -0
  24. prefect/settings/models/runner.py +8 -0
  25. prefect/settings/models/server/api.py +7 -1
  26. prefect/states.py +22 -10
  27. prefect/task_engine.py +1 -1
  28. prefect/telemetry/instrumentation.py +9 -10
  29. prefect/telemetry/services.py +67 -0
  30. prefect/utilities/engine.py +15 -1
  31. prefect/utilities/importtools.py +28 -21
  32. prefect/variables.py +2 -2
  33. prefect/workers/base.py +6 -12
  34. prefect/workers/block.py +3 -1
  35. prefect/workers/cloud.py +3 -1
  36. {prefect_client-3.1.7.dist-info → prefect_client-3.1.9.dist-info}/METADATA +1 -1
  37. {prefect_client-3.1.7.dist-info → prefect_client-3.1.9.dist-info}/RECORD +40 -39
  38. {prefect_client-3.1.7.dist-info → prefect_client-3.1.9.dist-info}/LICENSE +0 -0
  39. {prefect_client-3.1.7.dist-info → prefect_client-3.1.9.dist-info}/WHEEL +0 -0
  40. {prefect_client-3.1.7.dist-info → prefect_client-3.1.9.dist-info}/top_level.txt +0 -0
prefect/__init__.py CHANGED
@@ -2,29 +2,14 @@
2
2
 
3
3
  # Setup version and path constants
4
4
 
5
+ import sys
5
6
  from . import _version
6
7
  import importlib
7
8
  import pathlib
8
- from typing import TYPE_CHECKING, Any
9
-
10
- __version_info__ = _version.get_versions()
11
- __version__ = __version_info__["version"]
12
-
13
- # The absolute path to this module
14
- __module_path__ = pathlib.Path(__file__).parent
15
- # The absolute path to the root of the repository, only valid for use during development
16
- __development_base_path__ = __module_path__.parents[1]
17
-
18
- # The absolute path to the built UI within the Python module, used by
19
- # `prefect server start` to serve a dynamic build of the UI
20
- __ui_static_subpath__ = __module_path__ / "server" / "ui_build"
21
-
22
- # The absolute path to the built UI within the Python module
23
- __ui_static_path__ = __module_path__ / "server" / "ui"
24
-
25
- del _version, pathlib
9
+ from typing import TYPE_CHECKING, Any, Optional, TypedDict, cast
26
10
 
27
11
  if TYPE_CHECKING:
12
+ from importlib.machinery import ModuleSpec
28
13
  from .main import (
29
14
  allow_failure,
30
15
  flow,
@@ -45,80 +30,89 @@ if TYPE_CHECKING:
45
30
  suspend_flow_run,
46
31
  )
47
32
 
48
- _slots: dict[str, Any] = {
49
- "__version_info__": __version_info__,
50
- "__version__": __version__,
51
- "__module_path__": __module_path__,
52
- "__development_base_path__": __development_base_path__,
53
- "__ui_static_subpath__": __ui_static_subpath__,
54
- "__ui_static_path__": __ui_static_path__,
55
- }
33
+ __spec__: ModuleSpec
34
+
35
+ # Versioneer provides version information as dictionaries
36
+ # with these keys
37
+ class VersionInfo(TypedDict("_FullRevisionId", {"full-revisionid": str})):
38
+ version: str
39
+ dirty: Optional[bool]
40
+ error: Optional[str]
41
+ date: Optional[str]
56
42
 
57
- _public_api: dict[str, tuple[str, str]] = {
43
+
44
+ __version_info__: "VersionInfo" = cast("VersionInfo", _version.get_versions())
45
+ __version__ = __version_info__["version"]
46
+
47
+ # The absolute path to this module
48
+ __module_path__: pathlib.Path = pathlib.Path(__file__).parent
49
+ # The absolute path to the root of the repository, only valid for use during development
50
+ __development_base_path__: pathlib.Path = __module_path__.parents[1]
51
+
52
+ # The absolute path to the built UI within the Python module, used by
53
+ # `prefect server start` to serve a dynamic build of the UI
54
+ __ui_static_subpath__: pathlib.Path = __module_path__ / "server" / "ui_build"
55
+
56
+ # The absolute path to the built UI within the Python module
57
+ __ui_static_path__: pathlib.Path = __module_path__ / "server" / "ui"
58
+
59
+ del _version, pathlib
60
+
61
+ _public_api: dict[str, tuple[Optional[str], str]] = {
58
62
  "allow_failure": (__spec__.parent, ".main"),
63
+ "aserve": (__spec__.parent, ".main"),
64
+ "deploy": (__spec__.parent, ".main"),
59
65
  "flow": (__spec__.parent, ".main"),
60
66
  "Flow": (__spec__.parent, ".main"),
61
67
  "get_client": (__spec__.parent, ".main"),
62
68
  "get_run_logger": (__spec__.parent, ".main"),
69
+ "pause_flow_run": (__spec__.parent, ".main"),
70
+ "resume_flow_run": (__spec__.parent, ".main"),
71
+ "serve": (__spec__.parent, ".main"),
63
72
  "State": (__spec__.parent, ".main"),
73
+ "suspend_flow_run": (__spec__.parent, ".main"),
64
74
  "tags": (__spec__.parent, ".main"),
65
75
  "task": (__spec__.parent, ".main"),
66
76
  "Task": (__spec__.parent, ".main"),
67
77
  "Transaction": (__spec__.parent, ".main"),
68
78
  "unmapped": (__spec__.parent, ".main"),
69
- "serve": (__spec__.parent, ".main"),
70
- "aserve": (__spec__.parent, ".main"),
71
- "deploy": (__spec__.parent, ".main"),
72
- "pause_flow_run": (__spec__.parent, ".main"),
73
- "resume_flow_run": (__spec__.parent, ".main"),
74
- "suspend_flow_run": (__spec__.parent, ".main"),
75
79
  }
76
80
 
77
81
  # Declare API for type-checkers
78
82
  __all__ = [
83
+ "__version__",
79
84
  "allow_failure",
85
+ "aserve",
86
+ "deploy",
80
87
  "flow",
81
88
  "Flow",
82
89
  "get_client",
83
90
  "get_run_logger",
91
+ "pause_flow_run",
92
+ "resume_flow_run",
93
+ "serve",
84
94
  "State",
95
+ "suspend_flow_run",
85
96
  "tags",
86
97
  "task",
87
98
  "Task",
88
99
  "Transaction",
89
100
  "unmapped",
90
- "serve",
91
- "aserve",
92
- "deploy",
93
- "pause_flow_run",
94
- "resume_flow_run",
95
- "suspend_flow_run",
96
- "__version_info__",
97
- "__version__",
98
- "__module_path__",
99
- "__development_base_path__",
100
- "__ui_static_subpath__",
101
- "__ui_static_path__",
102
101
  ]
103
102
 
104
103
 
105
- def __getattr__(attr_name: str) -> object:
106
- if attr_name in _slots:
107
- return _slots[attr_name]
104
+ def __getattr__(attr_name: str) -> Any:
108
105
  try:
109
- dynamic_attr = _public_api.get(attr_name)
110
- if dynamic_attr is None:
106
+ if (dynamic_attr := _public_api.get(attr_name)) is None:
111
107
  return importlib.import_module(f".{attr_name}", package=__name__)
112
108
 
113
- package, module_name = dynamic_attr
114
-
115
- from importlib import import_module
116
-
117
- if module_name == "__module__":
118
- return import_module(f".{attr_name}", package=package)
109
+ package, mname = dynamic_attr
110
+ if mname == "__module__":
111
+ return importlib.import_module(f".{attr_name}", package=package)
119
112
  else:
120
- module = import_module(module_name, package=package)
113
+ module = importlib.import_module(mname, package=package)
121
114
  return getattr(module, attr_name)
122
115
  except ModuleNotFoundError as ex:
123
- module, _, attribute = ex.name.rpartition(".")
124
- raise AttributeError(f"module {module} has no attribute {attribute}") from ex
116
+ mname, _, attr = (ex.name or "").rpartition(".")
117
+ ctx = {"name": mname, "obj": attr} if sys.version_info >= (3, 10) else {}
118
+ raise AttributeError(f"module {mname} has no attribute {attr}", **ctx) from ex
@@ -225,7 +225,9 @@ class QueueService(abc.ABC, Generic[T]):
225
225
  return future.result()
226
226
 
227
227
  @classmethod
228
- def drain_all(cls, timeout: Optional[float] = None) -> Union[Awaitable, None]:
228
+ def drain_all(
229
+ cls, timeout: Optional[float] = None, at_exit=True
230
+ ) -> Union[Awaitable, None]:
229
231
  """
230
232
  Stop all instances of the service and wait for all remaining work to be
231
233
  completed.
@@ -237,7 +239,7 @@ class QueueService(abc.ABC, Generic[T]):
237
239
  instances = tuple(cls._instances.values())
238
240
 
239
241
  for instance in instances:
240
- futures.append(instance._drain())
242
+ futures.append(instance._drain(at_exit=at_exit))
241
243
 
242
244
  if get_running_loop() is not None:
243
245
  return (
@@ -376,10 +378,10 @@ class BatchedQueueService(QueueService[T]):
376
378
  @contextlib.contextmanager
377
379
  def drain_on_exit(service: QueueService):
378
380
  yield
379
- service.drain_all()
381
+ service.drain_all(at_exit=True)
380
382
 
381
383
 
382
384
  @contextlib.asynccontextmanager
383
385
  async def drain_on_exit_async(service: QueueService):
384
386
  yield
385
- await service.drain_all()
387
+ await service.drain_all(at_exit=True)
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-20T16:33:15-0500",
12
12
  "dirty": true,
13
13
  "error": null,
14
- "full-revisionid": "c05ffa6d1816f980d574b42119dffb9f8c8300a3",
15
- "version": "3.1.7"
14
+ "full-revisionid": "e1fe79439b319ce5478aa5f8bd4e836ed4f8a0f5",
15
+ "version": "3.1.9"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
prefect/agent.py CHANGED
@@ -1,6 +1,8 @@
1
1
  """
2
2
  2024-06-27: This surfaces an actionable error message for moved or removed objects in Prefect 3.0 upgrade.
3
3
  """
4
+ from typing import Any, Callable
5
+
4
6
  from prefect._internal.compatibility.migration import getattr_migration
5
7
 
6
- __getattr__ = getattr_migration(__name__)
8
+ __getattr__: Callable[[str], Any] = getattr_migration(__name__)
prefect/client/cloud.py CHANGED
@@ -1,6 +1,5 @@
1
1
  import re
2
2
  from typing import Any, NoReturn, Optional, cast
3
- from uuid import UUID
4
3
 
5
4
  import anyio
6
5
  import httpx
@@ -23,7 +22,6 @@ from prefect.settings import (
23
22
  PREFECT_CLOUD_API_URL,
24
23
  PREFECT_TESTING_UNIT_TEST_MODE,
25
24
  )
26
- from prefect.types import KeyValueLabels
27
25
 
28
26
  PARSE_API_URL_REGEX = re.compile(r"accounts/(.{36})/workspaces/(.{36})")
29
27
 
@@ -160,25 +158,6 @@ class CloudClient:
160
158
  response = await self.get(f"{self.account_base_url}/ip_allowlist/my_access")
161
159
  return IPAllowlistMyAccessResponse.model_validate(response)
162
160
 
163
- async def update_flow_run_labels(
164
- self, flow_run_id: UUID, labels: KeyValueLabels
165
- ) -> httpx.Response:
166
- """
167
- Update the labels for a flow run.
168
-
169
- Args:
170
- flow_run_id: The identifier for the flow run to update.
171
- labels: A dictionary of labels to update for the flow run.
172
-
173
- Returns:
174
- an `httpx.Response` object from the PATCH request
175
- """
176
-
177
- return await self._client.patch(
178
- f"{self.workspace_base_url}/flow_runs/{flow_run_id}/labels",
179
- json=labels,
180
- )
181
-
182
161
  async def __aenter__(self) -> Self:
183
162
  await self._client.__aenter__()
184
163
  return self
@@ -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)
@@ -190,6 +190,8 @@ class StateDetails(PrefectBaseModel):
190
190
  retriable: Optional[bool] = None
191
191
  transition_id: Optional[UUID] = None
192
192
  task_parameters_id: Optional[UUID] = None
193
+ # Captures the trace_id and span_id of the span where this state was created
194
+ traceparent: Optional[str] = None
193
195
 
194
196
 
195
197
  def data_discriminator(x: Any) -> str:
@@ -237,6 +239,15 @@ class State(ObjectBaseModel, Generic[R]):
237
239
  ) -> Union[R, Exception]:
238
240
  ...
239
241
 
242
+ @overload
243
+ def result(
244
+ self: "State[R]",
245
+ raise_on_failure: bool = ...,
246
+ fetch: bool = ...,
247
+ retry_result_failure: bool = ...,
248
+ ) -> Union[R, Exception]:
249
+ ...
250
+
240
251
  @deprecated.deprecated_parameter(
241
252
  "fetch",
242
253
  when=lambda fetch: fetch is not True,
@@ -7,7 +7,7 @@ Utilities for working with clients.
7
7
 
8
8
  from collections.abc import Awaitable, Coroutine
9
9
  from functools import wraps
10
- from typing import TYPE_CHECKING, Any, Callable, Optional, Union, overload
10
+ from typing import TYPE_CHECKING, Any, Callable, Optional, Union
11
11
 
12
12
  from typing_extensions import Concatenate, ParamSpec, TypeGuard, TypeVar
13
13
 
@@ -71,23 +71,9 @@ def client_injector(
71
71
  return wrapper
72
72
 
73
73
 
74
- @overload
75
74
  def inject_client(
76
75
  fn: Callable[P, Coroutine[Any, Any, R]],
77
76
  ) -> Callable[P, Coroutine[Any, Any, R]]:
78
- ...
79
-
80
-
81
- @overload
82
- def inject_client(
83
- fn: Callable[P, R],
84
- ) -> Callable[P, R]:
85
- ...
86
-
87
-
88
- def inject_client(
89
- fn: Callable[P, Union[Coroutine[Any, Any, R], R]],
90
- ) -> Callable[P, Union[Coroutine[Any, Any, R], R]]:
91
77
  """
92
78
  Simple helper to provide a context managed client to an asynchronous function.
93
79
 
@@ -1,3 +1,5 @@
1
- from .._internal.compatibility.migration import getattr_migration
1
+ from typing import Any, Callable
2
2
 
3
- __getattr__ = getattr_migration(__name__)
3
+ from prefect._internal.compatibility.migration import getattr_migration
4
+
5
+ __getattr__: Callable[[str], Any] = getattr_migration(__name__)
@@ -549,7 +549,9 @@ class RunnerDeployment(BaseModel):
549
549
  module = importlib.import_module(mod_name)
550
550
  flow_file = getattr(module, "__file__", None)
551
551
  except ModuleNotFoundError as exc:
552
- if "__prefect_loader__" in str(exc):
552
+ # 16458 adds an identifier to the module name, so checking
553
+ # for "__prefect_loader__" (2 underscores) will not match
554
+ if "__prefect_loader_" in str(exc):
553
555
  raise ValueError(
554
556
  "Cannot create a RunnerDeployment from a flow that has been"
555
557
  " loaded from an entrypoint. To deploy a flow via"
prefect/engine.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import sys
3
+ from typing import Any, Callable
3
4
  from uuid import UUID
4
5
 
5
6
  from prefect._internal.compatibility.migration import getattr_migration
@@ -72,4 +73,4 @@ if __name__ == "__main__":
72
73
  # Let the exit code be determined by the base exception type
73
74
  raise
74
75
 
75
- __getattr__ = getattr_migration(__name__)
76
+ __getattr__: Callable[[str], Any] = getattr_migration(__name__)
prefect/events/filters.py CHANGED
@@ -2,7 +2,7 @@ from typing import List, Optional, Tuple, cast
2
2
  from uuid import UUID
3
3
 
4
4
  import pendulum
5
- from pydantic import Field, PrivateAttr
5
+ from pydantic import Field
6
6
 
7
7
  from prefect._internal.schemas.bases import PrefectBaseModel
8
8
  from prefect.types import DateTime
@@ -41,18 +41,12 @@ class AutomationFilter(PrefectBaseModel):
41
41
  class EventDataFilter(PrefectBaseModel, extra="forbid"): # type: ignore[call-arg]
42
42
  """A base class for filtering event data."""
43
43
 
44
- _top_level_filter: Optional["EventFilter"] = PrivateAttr(None)
45
-
46
44
  def get_filters(self) -> List["EventDataFilter"]:
47
45
  filters: List["EventDataFilter"] = [
48
46
  filter
49
- for filter in [
50
- getattr(self, name) for name, field in self.model_fields.items()
51
- ]
47
+ for filter in [getattr(self, name) for name in self.model_fields]
52
48
  if isinstance(filter, EventDataFilter)
53
49
  ]
54
- for filter in filters:
55
- filter._top_level_filter = self._top_level_filter
56
50
  return filters
57
51
 
58
52
  def includes(self, event: Event) -> bool:
prefect/exceptions.py CHANGED
@@ -4,19 +4,20 @@ Prefect-specific exceptions.
4
4
 
5
5
  import inspect
6
6
  import traceback
7
+ from collections.abc import Iterable
7
8
  from types import ModuleType, TracebackType
8
- from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type
9
+ from typing import TYPE_CHECKING, Any, Callable, Optional
9
10
 
10
11
  from httpx._exceptions import HTTPStatusError
11
12
  from pydantic import ValidationError
12
- from rich.traceback import Traceback
13
13
  from typing_extensions import Self
14
14
 
15
- import prefect
15
+ if TYPE_CHECKING:
16
+ from prefect.states import State
16
17
 
17
18
 
18
19
  def _trim_traceback(
19
- tb: TracebackType, remove_modules: Iterable[ModuleType]
20
+ tb: Optional[TracebackType], remove_modules: Iterable[ModuleType]
20
21
  ) -> Optional[TracebackType]:
21
22
  """
22
23
  Utility to remove frames from specific modules from a traceback.
@@ -32,8 +33,9 @@ def _trim_traceback(
32
33
  A traceback, or `None` if all traceback frames originate from an excluded module
33
34
 
34
35
  """
35
- strip_paths = [module.__file__ for module in remove_modules]
36
-
36
+ strip_paths = [
37
+ module.__file__ for module in remove_modules if module.__file__ is not None
38
+ ]
37
39
  while tb and any(
38
40
  module_path in str(tb.tb_frame.f_globals.get("__file__", ""))
39
41
  for module_path in strip_paths
@@ -91,7 +93,9 @@ class PausedRun(PrefectException):
91
93
  Raised when the result from a paused run is retrieved.
92
94
  """
93
95
 
94
- def __init__(self, *args, state=None, **kwargs):
96
+ def __init__(
97
+ self, *args: Any, state: Optional["State[Any]"] = None, **kwargs: Any
98
+ ) -> None:
95
99
  super().__init__(*args, **kwargs)
96
100
  self.state = state
97
101
 
@@ -133,6 +137,8 @@ class ScriptError(PrefectException):
133
137
  user_exc: Exception,
134
138
  path: str,
135
139
  ) -> None:
140
+ import prefect.utilities.importtools
141
+
136
142
  message = f"Script at {str(path)!r} encountered an exception: {user_exc!r}"
137
143
  super().__init__(message)
138
144
  self.user_exc = user_exc
@@ -144,30 +150,6 @@ class ScriptError(PrefectException):
144
150
  )
145
151
 
146
152
 
147
- class FlowScriptError(PrefectException):
148
- """
149
- Raised when a script errors during evaluation while attempting to load a flow.
150
- """
151
-
152
- def __init__(
153
- self,
154
- user_exc: Exception,
155
- script_path: str,
156
- ) -> None:
157
- message = f"Flow script at {script_path!r} encountered an exception"
158
- super().__init__(message)
159
-
160
- self.user_exc = user_exc
161
-
162
- def rich_user_traceback(self, **kwargs):
163
- trace = Traceback.extract(
164
- type(self.user_exc),
165
- self.user_exc,
166
- self.user_exc.__traceback__.tb_next.tb_next.tb_next.tb_next,
167
- )
168
- return Traceback(trace, **kwargs)
169
-
170
-
171
153
  class ParameterTypeError(PrefectException):
172
154
  """
173
155
  Raised when a parameter does not pass Pydantic type validation.
@@ -196,7 +178,11 @@ class ParameterBindError(TypeError, PrefectException):
196
178
 
197
179
  @classmethod
198
180
  def from_bind_failure(
199
- cls, fn: Callable, exc: TypeError, call_args: List, call_kwargs: Dict
181
+ cls,
182
+ fn: Callable[..., Any],
183
+ exc: TypeError,
184
+ call_args: tuple[Any, ...],
185
+ call_kwargs: dict[str, Any],
200
186
  ) -> Self:
201
187
  fn_signature = str(inspect.signature(fn)).strip("()")
202
188
 
@@ -214,7 +200,9 @@ class SignatureMismatchError(PrefectException, TypeError):
214
200
  super().__init__(msg)
215
201
 
216
202
  @classmethod
217
- def from_bad_params(cls, expected_params: List[str], provided_params: List[str]):
203
+ def from_bad_params(
204
+ cls, expected_params: list[str], provided_params: list[str]
205
+ ) -> Self:
218
206
  msg = (
219
207
  f"Function expects parameters {expected_params} but was provided with"
220
208
  f" parameters {provided_params}"
@@ -231,14 +219,14 @@ class ObjectNotFound(PrefectException):
231
219
  self,
232
220
  http_exc: Exception,
233
221
  help_message: Optional[str] = None,
234
- *args,
235
- **kwargs,
236
- ):
222
+ *args: Any,
223
+ **kwargs: Any,
224
+ ) -> None:
237
225
  self.http_exc = http_exc
238
226
  self.help_message = help_message
239
227
  super().__init__(help_message, *args, **kwargs)
240
228
 
241
- def __str__(self):
229
+ def __str__(self) -> str:
242
230
  return self.help_message or super().__str__()
243
231
 
244
232
 
@@ -247,7 +235,7 @@ class ObjectAlreadyExists(PrefectException):
247
235
  Raised when the client receives a 409 (conflict) from the API.
248
236
  """
249
237
 
250
- def __init__(self, http_exc: Exception, *args, **kwargs):
238
+ def __init__(self, http_exc: Exception, *args: Any, **kwargs: Any) -> None:
251
239
  self.http_exc = http_exc
252
240
  super().__init__(*args, **kwargs)
253
241
 
@@ -304,7 +292,9 @@ class Pause(PrefectSignal):
304
292
  Raised when a flow run is PAUSED and needs to exit for resubmission.
305
293
  """
306
294
 
307
- def __init__(self, *args, state=None, **kwargs):
295
+ def __init__(
296
+ self, *args: Any, state: Optional["State[Any]"] = None, **kwargs: Any
297
+ ) -> None:
308
298
  super().__init__(*args, **kwargs)
309
299
  self.state = state
310
300
 
@@ -332,7 +322,7 @@ class PrefectHTTPStatusError(HTTPStatusError):
332
322
  """
333
323
 
334
324
  @classmethod
335
- def from_httpx_error(cls: Type[Self], httpx_error: HTTPStatusError) -> Self:
325
+ def from_httpx_error(cls: type[Self], httpx_error: HTTPStatusError) -> Self:
336
326
  """
337
327
  Generate a `PrefectHTTPStatusError` from an `httpx.HTTPStatusError`.
338
328
  """
@@ -441,7 +431,7 @@ class ProfileSettingsValidationError(PrefectException):
441
431
  Raised when a profile settings are invalid.
442
432
  """
443
433
 
444
- def __init__(self, errors: List[Tuple[Any, ValidationError]]) -> None:
434
+ def __init__(self, errors: list[tuple[Any, ValidationError]]) -> None:
445
435
  self.errors = errors
446
436
 
447
437
 
prefect/filesystems.py CHANGED
@@ -2,7 +2,7 @@ import abc
2
2
  import urllib.parse
3
3
  from pathlib import Path
4
4
  from shutil import copytree
5
- from typing import Any, Dict, Optional
5
+ from typing import Any, Callable, Dict, Optional
6
6
 
7
7
  import anyio
8
8
  import fsspec
@@ -544,4 +544,4 @@ class NullFileSystem(BaseModel):
544
544
  pass
545
545
 
546
546
 
547
- __getattr__ = getattr_migration(__name__)
547
+ __getattr__: Callable[[str], Any] = getattr_migration(__name__)
prefect/flow_engine.py CHANGED
@@ -221,7 +221,7 @@ class FlowRunEngine(BaseFlowRunEngine[P, R]):
221
221
  return_data=True,
222
222
  max_depth=-1,
223
223
  remove_annotations=True,
224
- context={},
224
+ context={"parameter_name": parameter},
225
225
  )
226
226
  except UpstreamTaskError:
227
227
  raise
@@ -784,7 +784,7 @@ class AsyncFlowRunEngine(BaseFlowRunEngine[P, R]):
784
784
  return_data=True,
785
785
  max_depth=-1,
786
786
  remove_annotations=True,
787
- context={},
787
+ context={"parameter_name": parameter},
788
788
  )
789
789
  except UpstreamTaskError:
790
790
  raise