prefect-client 2.20.9__py3-none-any.whl → 2.20.11__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.
@@ -9,6 +9,8 @@ import pydantic
9
9
  from pydantic import BaseModel as V2BaseModel
10
10
  from pydantic import ConfigDict, PydanticUndefinedAnnotation, create_model
11
11
  from pydantic.type_adapter import TypeAdapter
12
+ from pydantic.v1 import BaseModel as V1BaseModel
13
+ from pydantic.v1 import SecretStr as V1SecretStr
12
14
 
13
15
  from prefect._internal.pydantic.annotations.pendulum import (
14
16
  PydanticPendulumDateTimeType,
@@ -30,6 +32,18 @@ def is_v2_model(v) -> bool:
30
32
  return False
31
33
 
32
34
 
35
+ def is_v1_model(v) -> bool:
36
+ if isinstance(v, V1BaseModel):
37
+ return True
38
+ try:
39
+ if inspect.isclass(v) and issubclass(v, V1BaseModel):
40
+ return True
41
+ except TypeError:
42
+ pass
43
+
44
+ return False
45
+
46
+
33
47
  def is_v2_type(v) -> bool:
34
48
  if is_v2_model(v):
35
49
  return True
@@ -40,6 +54,18 @@ def is_v2_type(v) -> bool:
40
54
  return False
41
55
 
42
56
 
57
+ def is_v1_type(v) -> bool:
58
+ if is_v1_model(v):
59
+ return True
60
+
61
+ try:
62
+ return v.__module__.startswith("pydantic.v1.types") or isinstance(
63
+ v, V1SecretStr
64
+ )
65
+ except AttributeError:
66
+ return False
67
+
68
+
43
69
  def has_v2_type_as_param(signature: inspect.Signature) -> bool:
44
70
  parameters = signature.parameters.values()
45
71
  for p in parameters:
File without changes
File without changes
@@ -4,6 +4,7 @@ from typing import Dict, List, Optional
4
4
 
5
5
  from prefect._internal.pydantic import HAS_PYDANTIC_V2
6
6
  from prefect.logging import LogEavesdropper
7
+ from prefect.utilities.urls import validate_restricted_url
7
8
 
8
9
  if HAS_PYDANTIC_V2:
9
10
  from pydantic.v1 import AnyHttpUrl, Field, SecretStr
@@ -88,6 +89,26 @@ class AppriseNotificationBlock(AbstractAppriseNotificationBlock, ABC):
88
89
  description="Incoming webhook URL used to send notifications.",
89
90
  examples=["https://hooks.example.com/XXX"],
90
91
  )
92
+ allow_private_urls: bool = Field(
93
+ default=True,
94
+ description="Whether to allow notifications to private URLs. Defaults to True.",
95
+ )
96
+
97
+ @sync_compatible
98
+ async def notify(
99
+ self,
100
+ body: str,
101
+ subject: Optional[str] = None,
102
+ ):
103
+ if not self.allow_private_urls:
104
+ try:
105
+ validate_restricted_url(self.url.get_secret_value())
106
+ except ValueError as exc:
107
+ if self._raise_on_failure:
108
+ raise NotificationError(str(exc))
109
+ raise
110
+
111
+ await super().notify(body, subject)
91
112
 
92
113
 
93
114
  # TODO: Move to prefect-slack once collection block auto-registration is
@@ -281,6 +302,27 @@ class PagerDutyWebHook(AbstractAppriseNotificationBlock):
281
302
  )
282
303
  self._start_apprise_client(url)
283
304
 
305
+ @sync_compatible
306
+ async def notify(
307
+ self,
308
+ body: str,
309
+ subject: Optional[str] = None,
310
+ ):
311
+ """
312
+ Apprise will combine subject and body by default, so we need to move
313
+ the body into the custom_details field. custom_details is part of the
314
+ webhook url, so we need to update the url and restart the client.
315
+ """
316
+ if subject:
317
+ self.custom_details = self.custom_details or {}
318
+ self.custom_details.update(
319
+ {"Prefect Notification Body": body.replace(" ", "%20")}
320
+ )
321
+ body = " "
322
+ self.block_initialization()
323
+
324
+ await super().notify(body, subject)
325
+
284
326
 
285
327
  class TwilioSMS(AbstractAppriseNotificationBlock):
286
328
  """Enables sending notifications via Twilio SMS.
prefect/blocks/webhook.py CHANGED
@@ -3,6 +3,7 @@ from typing import Optional
3
3
  from httpx import AsyncClient, AsyncHTTPTransport, Response
4
4
 
5
5
  from prefect._internal.pydantic import HAS_PYDANTIC_V2
6
+ from prefect.utilities.urls import validate_restricted_url
6
7
 
7
8
  if HAS_PYDANTIC_V2:
8
9
  from pydantic.v1 import Field, SecretStr
@@ -38,7 +39,10 @@ class Webhook(Block):
38
39
  description="The webhook URL.",
39
40
  examples=["https://hooks.slack.com/XXX"],
40
41
  )
41
-
42
+ allow_private_urls: bool = Field(
43
+ default=True,
44
+ description="Whether to allow notifications to private URLs. Defaults to True.",
45
+ )
42
46
  headers: SecretDict = Field(
43
47
  default_factory=lambda: SecretDict(dict()),
44
48
  title="Webhook Headers",
@@ -55,6 +59,9 @@ class Webhook(Block):
55
59
  Args:
56
60
  payload: an optional payload to send when calling the webhook.
57
61
  """
62
+ if not self.allow_private_urls:
63
+ validate_restricted_url(self.url.get_secret_value())
64
+
58
65
  async with self._client:
59
66
  return await self._client.request(
60
67
  method=self.method,
@@ -8,12 +8,14 @@ from typing import (
8
8
  Dict,
9
9
  Iterable,
10
10
  List,
11
+ Literal,
11
12
  NoReturn,
12
13
  Optional,
13
14
  Set,
14
15
  Tuple,
15
16
  TypeVar,
16
17
  Union,
18
+ overload,
17
19
  )
18
20
  from uuid import UUID, uuid4
19
21
 
@@ -178,6 +180,20 @@ class ServerType(AutoEnum):
178
180
  return PREFECT_EXPERIMENTAL_EVENTS and PREFECT_API_SERVICES_TRIGGERS_ENABLED
179
181
 
180
182
 
183
+ @overload
184
+ def get_client(
185
+ httpx_settings: Optional[Dict[str, Any]] = None, sync_client: Literal[False] = False
186
+ ) -> "PrefectClient":
187
+ ...
188
+
189
+
190
+ @overload
191
+ def get_client(
192
+ httpx_settings: Optional[Dict[str, Any]] = None, sync_client: Literal[True] = True
193
+ ) -> "SyncPrefectClient":
194
+ ...
195
+
196
+
181
197
  def get_client(
182
198
  httpx_settings: Optional[Dict[str, Any]] = None, sync_client: bool = False
183
199
  ) -> Union["PrefectClient", "SyncPrefectClient"]:
prefect/flows.py CHANGED
@@ -45,11 +45,15 @@ from prefect._internal.pydantic import HAS_PYDANTIC_V2
45
45
 
46
46
  if HAS_PYDANTIC_V2:
47
47
  import pydantic.v1 as pydantic
48
+ from pydantic import BaseModel as V2BaseModel
48
49
  from pydantic import ValidationError as V2ValidationError
49
50
  from pydantic.v1 import BaseModel as V1BaseModel
50
51
  from pydantic.v1.decorator import ValidatedFunction as V1ValidatedFunction
51
52
 
52
- from ._internal.pydantic.v2_schema import is_v2_type
53
+ from ._internal.pydantic.v2_schema import (
54
+ is_v1_type,
55
+ is_v2_type,
56
+ )
53
57
  from ._internal.pydantic.v2_validated_func import V2ValidatedFunction
54
58
  from ._internal.pydantic.v2_validated_func import (
55
59
  V2ValidatedFunction as ValidatedFunction,
@@ -339,6 +343,16 @@ class Flow(Generic[P, R]):
339
343
  # is not picklable in some environments
340
344
  try:
341
345
  ValidatedFunction(self.fn, config={"arbitrary_types_allowed": True})
346
+ except TypeError as exc:
347
+ if (
348
+ HAS_PYDANTIC_V2
349
+ and "`__modify_schema__` method is not supported" in str(exc)
350
+ ):
351
+ V1ValidatedFunction(
352
+ self.fn, config={"arbitrary_types_allowed": True}
353
+ )
354
+ else:
355
+ raise
342
356
  except pydantic.ConfigError as exc:
343
357
  raise ValueError(
344
358
  "Flow function is not compatible with `validate_parameters`. "
@@ -510,19 +524,33 @@ class Flow(Generic[P, R]):
510
524
  args, kwargs = parameters_to_args_kwargs(self.fn, parameters)
511
525
 
512
526
  if HAS_PYDANTIC_V2:
513
- has_v1_models = any(isinstance(o, V1BaseModel) for o in args) or any(
514
- isinstance(o, V1BaseModel) for o in kwargs.values()
527
+ sig = inspect.signature(self.fn)
528
+
529
+ has_v1_types = any(
530
+ is_v1_type(param.annotation) for param in sig.parameters.values()
531
+ )
532
+ has_v1_models = any(
533
+ issubclass(param.annotation, V1BaseModel)
534
+ if isinstance(param.annotation, type)
535
+ else False
536
+ for param in sig.parameters.values()
515
537
  )
516
- has_v2_types = any(is_v2_type(o) for o in args) or any(
517
- is_v2_type(o) for o in kwargs.values()
538
+ has_v2_types = any(
539
+ is_v2_type(param.annotation) for param in sig.parameters.values()
540
+ )
541
+ has_v2_models = any(
542
+ issubclass(param.annotation, V2BaseModel)
543
+ if isinstance(param.annotation, type)
544
+ else False
545
+ for param in sig.parameters.values()
518
546
  )
519
547
 
520
- if has_v1_models and has_v2_types:
548
+ if (has_v1_types and has_v2_types) or (has_v1_models and has_v2_models):
521
549
  raise ParameterTypeError(
522
550
  "Cannot mix Pydantic v1 and v2 types as arguments to a flow."
523
551
  )
524
552
 
525
- if has_v1_models:
553
+ if has_v1_models or has_v1_types:
526
554
  validated_fn = V1ValidatedFunction(
527
555
  self.fn, config={"arbitrary_types_allowed": True}
528
556
  )
@@ -530,7 +558,6 @@ class Flow(Generic[P, R]):
530
558
  validated_fn = V2ValidatedFunction(
531
559
  self.fn, config={"arbitrary_types_allowed": True}
532
560
  )
533
-
534
561
  else:
535
562
  validated_fn = ValidatedFunction(
536
563
  self.fn, config={"arbitrary_types_allowed": True}
@@ -0,0 +1,49 @@
1
+ import ipaddress
2
+ import socket
3
+ from urllib.parse import urlparse
4
+
5
+
6
+ def validate_restricted_url(url: str):
7
+ """
8
+ Validate that the provided URL is safe for outbound requests. This prevents
9
+ attacks like SSRF (Server Side Request Forgery), where an attacker can make
10
+ requests to internal services (like the GCP metadata service, localhost addresses,
11
+ or in-cluster Kubernetes services)
12
+ Args:
13
+ url: The URL to validate.
14
+ Raises:
15
+ ValueError: If the URL is a restricted URL.
16
+ """
17
+
18
+ try:
19
+ parsed_url = urlparse(url)
20
+ except ValueError:
21
+ raise ValueError(f"{url!r} is not a valid URL.")
22
+
23
+ if parsed_url.scheme not in ("http", "https"):
24
+ raise ValueError(
25
+ f"{url!r} is not a valid URL. Only HTTP and HTTPS URLs are allowed."
26
+ )
27
+
28
+ hostname = parsed_url.hostname or ""
29
+
30
+ # Remove IPv6 brackets if present
31
+ if hostname.startswith("[") and hostname.endswith("]"):
32
+ hostname = hostname[1:-1]
33
+
34
+ if not hostname:
35
+ raise ValueError(f"{url!r} is not a valid URL.")
36
+
37
+ try:
38
+ ip_address = socket.gethostbyname(hostname)
39
+ ip = ipaddress.ip_address(ip_address)
40
+ except socket.gaierror:
41
+ try:
42
+ ip = ipaddress.ip_address(hostname)
43
+ except ValueError:
44
+ raise ValueError(f"{url!r} is not a valid URL. It could not be resolved.")
45
+
46
+ if ip.is_private:
47
+ raise ValueError(
48
+ f"{url!r} is not a valid URL. It resolves to the private address {ip}."
49
+ )
prefect/workers/base.py CHANGED
@@ -137,6 +137,12 @@ class BaseJobConfiguration(BaseModel):
137
137
  variables = cls._get_base_config_defaults(
138
138
  variables_schema.get("properties", {})
139
139
  )
140
+
141
+ # copy variable defaults for `env` to job config before they're replaced by
142
+ # deployment overrides
143
+ if variables.get("env"):
144
+ job_config["env"] = variables.get("env")
145
+
140
146
  variables.update(values)
141
147
 
142
148
  # deep merge `env`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 2.20.9
3
+ Version: 2.20.11
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -22,7 +22,7 @@ Classifier: Topic :: Software Development :: Libraries
22
22
  Requires-Python: >=3.8
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
- Requires-Dist: anyio<5.0.0,>=4.4.0
25
+ Requires-Dist: anyio<4.6.1,>=4.4.0
26
26
  Requires-Dist: asgi-lifespan<3.0,>=1.0
27
27
  Requires-Dist: cachetools<6.0,>=5.3
28
28
  Requires-Dist: cloudpickle<4.0,>=2.0
@@ -40,7 +40,7 @@ Requires-Dist: jsonschema<5.0.0,>=4.0.0
40
40
  Requires-Dist: orjson<4.0,>=3.7
41
41
  Requires-Dist: packaging<24.3,>=21.3
42
42
  Requires-Dist: pathspec>=0.8.0
43
- Requires-Dist: pydantic[email]!=2.0.0,!=2.0.1,!=2.1.0,<2.9.0,>=1.10.0
43
+ Requires-Dist: pydantic[email]!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.10.0
44
44
  Requires-Dist: pydantic-core<3.0.0,>=2.12.0
45
45
  Requires-Dist: python-dateutil<3.0.0,>=2.8.2
46
46
  Requires-Dist: python-slugify<9.0,>=5.0
@@ -9,7 +9,7 @@ prefect/engine.py,sha256=i68gM-ZZ2x9D4aIwaLmApWeHqpMb2U2QWNJjX3aPmZM,92887
9
9
  prefect/exceptions.py,sha256=ElqC81_w6XbTaxLYANLMIPK8Fz46NmJZCRKL4NZ-JIg,10907
10
10
  prefect/filesystems.py,sha256=XniPSdBAqywj43X7GyfuWJQIbz07QJ5Y3cVNLhIF3lQ,35260
11
11
  prefect/flow_runs.py,sha256=mFHLavZk1yZ62H3UazuNDBZWAF7AqKttA4rMcHgsVSw,3119
12
- prefect/flows.py,sha256=ApTY03QIH5C9i4p50vaYVPW1K1YoVqIi9n6JomfgX34,84989
12
+ prefect/flows.py,sha256=rJ2lfAFy3yff6ecKwFx9sDrjhOhdSGKQo7ocx7BasAs,85988
13
13
  prefect/futures.py,sha256=RaWfYIXtH7RsWxQ5QWTTlAzwtVV8XWpXaZT_hLq35vQ,12590
14
14
  prefect/manifests.py,sha256=sTM7j8Us5d49zaydYKWsKb7zJ96v1ChkLkLeR0GFYD8,683
15
15
  prefect/new_flow_engine.py,sha256=A1adTWTBAwPCn6ay003Jsoc2SdYgHV4AcJo1bmpa_7Y,16039
@@ -50,7 +50,7 @@ prefect/_internal/pydantic/_flags.py,sha256=h1K50GKUJx09hvGHtfQ-rnBs233jhKr8DVtJ
50
50
  prefect/_internal/pydantic/_types.py,sha256=A1WD9OHyGoIp0gujl3ozCoXEd4OcySgjgbmHsMq9RTs,275
51
51
  prefect/_internal/pydantic/schemas.py,sha256=tsRKq5yEIgiRbWMl3BPnbfNaKyDN6pq8WSs0M8SQMm4,452
52
52
  prefect/_internal/pydantic/v1_schema.py,sha256=j_DDQqpP1xFsvkNSjWeviTnnFyNPPqou9n4M2lf3K2U,1133
53
- prefect/_internal/pydantic/v2_schema.py,sha256=RE7VQaf6nefhdYU2O-gbzumMcuBk-fiH_6Rq9F7eAqg,3689
53
+ prefect/_internal/pydantic/v2_schema.py,sha256=iOIy7zgDt__uPfp03RVDvrwRMbZzHF6yWmgnjlPXEAc,4262
54
54
  prefect/_internal/pydantic/v2_validated_func.py,sha256=44I4o8jjiS7TYep-E6UYMwjpYH5F1WwJFajW81A3wts,3823
55
55
  prefect/_internal/pydantic/annotations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
56
  prefect/_internal/pydantic/annotations/pendulum.py,sha256=rWT6zzCtIqvK2_EuAkMt73ZzAvdE5tF2104e0-tIaa4,2625
@@ -86,6 +86,7 @@ prefect/_vendor/fastapi/exceptions.py,sha256=131GbKBhoKJNvkE3k2-IvKye6xH-fvNaJ20
86
86
  prefect/_vendor/fastapi/logger.py,sha256=I9NNi3ov8AcqbsbC9wl1X-hdItKgYt2XTrx1f99Zpl4,54
87
87
  prefect/_vendor/fastapi/param_functions.py,sha256=BLvSfhJqiViP-_zYQ7BL_t9IARf4EJbKZSikDNsOkfw,9130
88
88
  prefect/_vendor/fastapi/params.py,sha256=UBEVQ_EK9iIbF3DOJXfH2zcO27uvf5NeRdslMOEtIEA,13350
89
+ prefect/_vendor/fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
90
  prefect/_vendor/fastapi/requests.py,sha256=KsGwp86w95S-0wgx4pL-T4i9M_z-_KlMzX43rdUg9YU,183
90
91
  prefect/_vendor/fastapi/responses.py,sha256=M67RzoU0K91ojgHjvDIDK3iyBAvA9YKPsUJIP4FtxtY,1381
91
92
  prefect/_vendor/fastapi/routing.py,sha256=Kz1WttDcSqHkt1fW9_UmkZG-G0noRY3FAStkfw_VUNE,57083
@@ -131,6 +132,7 @@ prefect/_vendor/starlette/datastructures.py,sha256=AyApp3jfD9muXBn8EVbuAVk6ZhCDY
131
132
  prefect/_vendor/starlette/endpoints.py,sha256=00KnI8grT2xxv1jERCvAgqwVxRDOo8hrqpFHnKow9xs,5319
132
133
  prefect/_vendor/starlette/exceptions.py,sha256=ODmYfjgNKWAZwfV8TDVepoEwhv1Kl92KvvwMvEJ04AA,1840
133
134
  prefect/_vendor/starlette/formparsers.py,sha256=aNoQl0CPI7pYnvae2k0KB2jNnv6mQJL-N2FuhRhPLW4,10450
135
+ prefect/_vendor/starlette/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
134
136
  prefect/_vendor/starlette/requests.py,sha256=dytpLA1l9oVb-u98i4caDI1z4-XtPCe1jzjFajlQWa8,10899
135
137
  prefect/_vendor/starlette/responses.py,sha256=1l36hyZeTXWYCQ8dYCo-eM_I6KyGuq_qUdtM9GBT3EA,12565
136
138
  prefect/_vendor/starlette/routing.py,sha256=Y0uiRXBQ0uRWs1O63qFD6doqKeh-KhqhuiHU5ovodQs,35696
@@ -157,15 +159,15 @@ prefect/blocks/abstract.py,sha256=AiAs0MC5JKCf0Xg0yofC5Qu2TZ52AjDMP1ntMGuP2dY,16
157
159
  prefect/blocks/core.py,sha256=_NKdrHvN2f0LdgqX9MYXp0PJQW36e6cs2Za7hVfrCIw,43870
158
160
  prefect/blocks/fields.py,sha256=ANOzbNyDCBIvm6ktgbLTMs7JW2Sf6CruyATjAW61ks0,1607
159
161
  prefect/blocks/kubernetes.py,sha256=IN-hZkzIRvqjd_dzPZby3q8p7m2oUWqArBq24BU9cDg,4071
160
- prefect/blocks/notifications.py,sha256=LJd2mgV29URqItJyxtWUpdo4wswtm7KyIseuAjV3joI,28132
162
+ prefect/blocks/notifications.py,sha256=EMW38ZGkQERQHJ32zkqod_GkFIJssq5ra5_rpRZOc_c,29487
161
163
  prefect/blocks/system.py,sha256=aIRiFKlXIQ1sMaqniMXYolFsx2IVN3taBMH3KCThB2I,3089
162
- prefect/blocks/webhook.py,sha256=VzQ-qcRtW8MMuYEGYwFgt1QXtWedUtVmeTo7iE2UQ78,2008
164
+ prefect/blocks/webhook.py,sha256=iyPkhgTL04oqz7R2I0jddS2oBWVdp7qvBlRxEbbwueo,2327
163
165
  prefect/client/__init__.py,sha256=yJ5FRF9RxNUio2V_HmyKCKw5G6CZO0h8cv6xA_Hkpcc,477
164
166
  prefect/client/base.py,sha256=YSPeE7hV0NCuD6WzoAACDYGFK4Yq35d26pITZ3elNyY,24669
165
167
  prefect/client/cloud.py,sha256=E54OAFr7bY5IXhhMBdjGwLQiR0eU-WWFoEEiOq2l53I,4104
166
168
  prefect/client/collections.py,sha256=I9EgbTg4Fn57gn8vwP_WdDmgnATbx9gfkm2jjhCORjw,1037
167
169
  prefect/client/constants.py,sha256=Z_GG8KF70vbbXxpJuqW5pLnwzujTVeHbcYYRikNmGH0,29
168
- prefect/client/orchestration.py,sha256=k_0W9QP0uCamt2FXW3JwZcAEDGS_ArwZx69lKsb02Gg,140180
170
+ prefect/client/orchestration.py,sha256=0lJx6nRKyboYFf_wVdRBVXaH5nFAdFOlWJZV0AXgYYg,140503
169
171
  prefect/client/subscriptions.py,sha256=3kqPH3F-CwyrR5wygCpJMjRjM_gcQjd54Qjih6FcLlA,3372
170
172
  prefect/client/utilities.py,sha256=7V4IkfC8x_OZuPXGvtIMmwZCOW63hSY8iVQkuRYTR6g,3079
171
173
  prefect/client/schemas/__init__.py,sha256=KlyqFV-hMulMkNstBn_0ijoHoIwJZaBj6B1r07UmgvE,607
@@ -276,18 +278,19 @@ prefect/utilities/slugify.py,sha256=57Vb14t13F3zm1P65KAu8nVeAz0iJCd1Qc5eMG-R5y8,
276
278
  prefect/utilities/templating.py,sha256=t32Gcsvvm8ibzdqXwcWzY7JkwftPn73FiiLYEnQWyKM,13237
277
279
  prefect/utilities/text.py,sha256=eXGIsCcZ7h_6hy8T5GDQjL8GiKyktoOqavYub0QjgO4,445
278
280
  prefect/utilities/timeout.py,sha256=nxmuPxROIT-i8gPffpARuxnxu58H0vkmbjTVIgef0_0,805
281
+ prefect/utilities/urls.py,sha256=sxv2lG8u3tX_zPZp66qEAFgZmGreG_D_9jGAqqYqaKc,1522
279
282
  prefect/utilities/visualization.py,sha256=9Pc8ImgnBpnszWTFxYm42cmtHjNEAsGZ8ugkn8w_dJk,6501
280
283
  prefect/utilities/schema_tools/__init__.py,sha256=KsFsTEHQqgp89TkDpjggkgBBywoHQPxbx-m6YQhiNEI,322
281
284
  prefect/utilities/schema_tools/hydration.py,sha256=RNuJK4Vd__V69gdQbaWSVhSkV0AUISfGzH_xd0p6Zh0,8291
282
285
  prefect/utilities/schema_tools/validation.py,sha256=zZHL_UFxAlgaUzi-qsEOrhWtZ7EkFQvPkX_YN1EJNTo,8414
283
286
  prefect/workers/__init__.py,sha256=6el2Q856CuRPa5Hdrbm9QyAWB_ovcT2bImSFsoWI46k,66
284
- prefect/workers/base.py,sha256=LNcVu0FIDBYv2XnWH1a2uV2Yyngtlyq8_pvLC4dxbrc,45576
287
+ prefect/workers/base.py,sha256=r0kM2EbT69yQsd3L7Lq99IqaBHhZgc6tcpdh3YekSJY,45779
285
288
  prefect/workers/block.py,sha256=aYY__uq3v1eq1kkbVukxyhQNbkknaKYo6-_3tcrfKKA,8067
286
289
  prefect/workers/process.py,sha256=pPtCdA7fKQ4OsvoitT-cayZeh5HgLX4xBUYlb2Zad-Q,9475
287
290
  prefect/workers/server.py,sha256=WVZJxR8nTMzK0ov0BD0xw5OyQpT26AxlXbsGQ1OrxeQ,1551
288
291
  prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
289
- prefect_client-2.20.9.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
290
- prefect_client-2.20.9.dist-info/METADATA,sha256=XB_lbnZBAGQikh8HCxxvu1AJYMsgFVGUIa_E0aOUdaQ,7391
291
- prefect_client-2.20.9.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
292
- prefect_client-2.20.9.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
293
- prefect_client-2.20.9.dist-info/RECORD,,
292
+ prefect_client-2.20.11.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
293
+ prefect_client-2.20.11.dist-info/METADATA,sha256=YMdpw_0mas-4W0mXLs8FpuoyxKW-PlSvCxwdHPi0ArA,7392
294
+ prefect_client-2.20.11.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
295
+ prefect_client-2.20.11.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
296
+ prefect_client-2.20.11.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.44.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5