prefect-client 3.0.4__py3-none-any.whl → 3.0.5__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/transactions.py CHANGED
@@ -284,11 +284,14 @@ class Transaction(ContextModel):
284
284
  self.children.append(transaction)
285
285
 
286
286
  def get_parent(self) -> Optional["Transaction"]:
287
- prev_var = getattr(self._token, "old_value")
288
- if prev_var != Token.MISSING:
289
- parent = prev_var
287
+ parent = None
288
+ if self._token:
289
+ prev_var = getattr(self._token, "old_value")
290
+ if prev_var != Token.MISSING:
291
+ parent = prev_var
290
292
  else:
291
- parent = None
293
+ # `_token` has been reset so we need to get the active transaction from the context var
294
+ parent = self.get_active()
292
295
  return parent
293
296
 
294
297
  def commit(self) -> bool:
prefect/types/__init__.py CHANGED
@@ -1,17 +1,23 @@
1
- from typing import Annotated, Any, Dict, List, Union
1
+ from functools import partial
2
+ from typing import Annotated, Any, Dict, List, Set, TypeVar, Union
3
+ from typing_extensions import Literal
2
4
  import orjson
3
5
  import pydantic
4
6
 
5
7
  from pydantic import (
6
8
  BeforeValidator,
7
9
  Field,
10
+ SecretStr,
8
11
  StrictBool,
9
12
  StrictFloat,
10
13
  StrictInt,
11
14
  StrictStr,
15
+ TypeAdapter,
12
16
  )
13
17
  from zoneinfo import available_timezones
14
18
 
19
+ T = TypeVar("T")
20
+
15
21
  MAX_VARIABLE_NAME_LENGTH = 255
16
22
  MAX_VARIABLE_VALUE_LENGTH = 5000
17
23
 
@@ -82,11 +88,54 @@ StrictVariableValue = Annotated[VariableValue, BeforeValidator(check_variable_va
82
88
  LaxUrl = Annotated[str, BeforeValidator(lambda x: str(x).strip())]
83
89
 
84
90
 
91
+ StatusCode = Annotated[int, Field(ge=100, le=599)]
92
+
93
+
85
94
  class SecretDict(pydantic.Secret[Dict[str, Any]]):
86
95
  pass
87
96
 
88
97
 
98
+ def validate_set_T_from_delim_string(
99
+ value: Union[str, T, Set[T], None], type_, delim=None
100
+ ) -> Set[T]:
101
+ """
102
+ "no-info" before validator useful in scooping env vars
103
+
104
+ e.g. `PREFECT_CLIENT_RETRY_EXTRA_CODES=429,502,503` -> `{429, 502, 503}`
105
+ e.g. `PREFECT_CLIENT_RETRY_EXTRA_CODES=429` -> `{429}`
106
+ """
107
+ if not value:
108
+ return set()
109
+
110
+ T_adapter = TypeAdapter(type_)
111
+ delim = delim or ","
112
+ if isinstance(value, str):
113
+ return {T_adapter.validate_strings(s) for s in value.split(delim)}
114
+ errors = []
115
+ try:
116
+ return {T_adapter.validate_python(value)}
117
+ except pydantic.ValidationError as e:
118
+ errors.append(e)
119
+ try:
120
+ return TypeAdapter(Set[type_]).validate_python(value)
121
+ except pydantic.ValidationError as e:
122
+ errors.append(e)
123
+ raise ValueError(f"Invalid set[{type_}]: {errors}")
124
+
125
+
126
+ ClientRetryExtraCodes = Annotated[
127
+ Union[str, StatusCode, Set[StatusCode], None],
128
+ BeforeValidator(partial(validate_set_T_from_delim_string, type_=StatusCode)),
129
+ ]
130
+
131
+ LogLevel = Annotated[
132
+ Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
133
+ BeforeValidator(lambda x: x.upper()),
134
+ ]
135
+
89
136
  __all__ = [
137
+ "ClientRetryExtraCodes",
138
+ "LogLevel",
90
139
  "NonNegativeInteger",
91
140
  "PositiveInteger",
92
141
  "NonNegativeFloat",
@@ -94,5 +143,6 @@ __all__ = [
94
143
  "NameOrEmpty",
95
144
  "NonEmptyishName",
96
145
  "SecretDict",
146
+ "StatusCode",
97
147
  "StrictVariableValue",
98
148
  ]
@@ -26,6 +26,7 @@ from typing_extensions import Literal
26
26
 
27
27
  from prefect.utilities.dispatch import get_dispatch_key, lookup_type, register_base_type
28
28
  from prefect.utilities.importtools import from_qualified_name, to_qualified_name
29
+ from prefect.utilities.names import obfuscate
29
30
 
30
31
  D = TypeVar("D", bound=Any)
31
32
  M = TypeVar("M", bound=BaseModel)
@@ -371,7 +372,7 @@ def handle_secret_render(value: object, context: dict[str, Any]) -> object:
371
372
  return (
372
373
  cast(Secret[object], value).get_secret_value()
373
374
  if context.get("include_secrets", False)
374
- else "**********"
375
+ else obfuscate(value)
375
376
  )
376
377
  elif isinstance(value, BaseModel):
377
378
  return value.model_dump(context=context)
prefect/utilities/text.py CHANGED
@@ -1,4 +1,5 @@
1
- from typing import Optional
1
+ import difflib
2
+ from typing import Iterable, Optional
2
3
 
3
4
 
4
5
  def truncated_to(length: int, value: Optional[str]) -> str:
@@ -17,3 +18,14 @@ def truncated_to(length: int, value: Optional[str]) -> str:
17
18
  proposed = f"{beginning}...{omitted} additional characters...{end}"
18
19
 
19
20
  return proposed if len(proposed) < len(value) else value
21
+
22
+
23
+ def fuzzy_match_string(
24
+ word: str,
25
+ possibilities: Iterable[str],
26
+ *,
27
+ n: int = 1,
28
+ cutoff: float = 0.6,
29
+ ) -> Optional[str]:
30
+ match = difflib.get_close_matches(word, possibilities, n=n, cutoff=cutoff)
31
+ return match[0] if match else None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 3.0.4
3
+ Version: 3.0.5
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -4,29 +4,29 @@ prefect/_version.py,sha256=I9JsXwt7BjAAbMEZgtmE3a6dJ2jqV-wqWto9D6msb3k,24597
4
4
  prefect/agent.py,sha256=BOVVY5z-vUIQ2u8LwMTXDaNys2fjOZSS5YGDwJmTQjI,230
5
5
  prefect/artifacts.py,sha256=dsxFWmdg2r9zbHM3KgKOR5YbJ29_dXUYF9kipJpbxkE,13009
6
6
  prefect/automations.py,sha256=NlQ62GPJzy-gnWQqX7c6CQJKw7p60WLGDAFcy82vtg4,5613
7
- prefect/cache_policies.py,sha256=thYNj0CcJjM4TJQvXsLKTIQl7t0qjEnSWzxPWPONcRw,9118
8
- prefect/context.py,sha256=J4GS70ZG_dkJ2v_dQWkdbuiN88iumFpoJhTu3hg7d60,21821
7
+ prefect/cache_policies.py,sha256=PWUzyJue4h5XHVeIVolfPKhRGrx1hyWJt58AJyHbcqU,9104
8
+ prefect/context.py,sha256=4CsGsfn8Kt8SHcTor5vhfcSIRm3qcQkO9vb9rfsKD3E,21571
9
9
  prefect/engine.py,sha256=BpmDbe6miZcTl1vRkxfCPYcWSXADLigGPCagFwucMz0,1976
10
- prefect/exceptions.py,sha256=ondjUe0fIXXjhoFnqg8twqgLoPMR02HuQv5Az-kSG50,11348
10
+ prefect/exceptions.py,sha256=V_nRpS2Z93PvJMoQdXbx8zepVaFb-pWanCqVi7T1ngI,11803
11
11
  prefect/filesystems.py,sha256=CxwMmKY8LBUed_9IqE2jUqxVCWhXa1r2fjKgLbIC2Vg,17893
12
- prefect/flow_engine.py,sha256=Z6xOO1ONAGwVNcvyvEIkJv_LB0VE5iBptV4ZWgTFqbc,30000
12
+ prefect/flow_engine.py,sha256=p1IoMa5okV0l-0KGjDxNDsR1N74K5oP_Lb3V0z7v49U,30076
13
13
  prefect/flow_runs.py,sha256=EaXRIQTOnwnA0fO7_EjwafFRmS57K_CRy0Xsz3JDIhc,16070
14
- prefect/flows.py,sha256=zgTnzasA8a1PiOGRRSUB1P2kIz5kNgaKMkPEI81TXcQ,89588
14
+ prefect/flows.py,sha256=UxcyRGZElO4_ZwWUa5oa5POL6CL2N5M8FvrPUZrsOX4,89591
15
15
  prefect/futures.py,sha256=1Uq-Q3ommCHSku_lsASuP1s3yFuYoL980fGcHdCFg30,16298
16
16
  prefect/main.py,sha256=IdtnJR5-IwP8EZsfhMFKj92ylMhNyau9X_eMcTP2ZjM,2336
17
17
  prefect/plugins.py,sha256=HY7Z7OJlltqzsUiPMEL1Y_hQbHw0CeZKayWiK-k8DP4,2435
18
18
  prefect/profiles.toml,sha256=kTvqDNMzjH3fsm5OEI-NKY4dMmipor5EvQXRB6rPEjY,522
19
19
  prefect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- prefect/results.py,sha256=dHaS_sHHi9CcHk5DmwONey2OQnVJkj7cLqoYmHaUB58,47377
20
+ prefect/results.py,sha256=-V_JRaWeY2WXWhY2d_zL7KVIro660mIU6F3heNaih0o,47391
21
21
  prefect/serializers.py,sha256=Lo41EM0_qGzcfB_63390Izeo3DdK6cY6VZfxa9hpSGQ,8712
22
- prefect/settings.py,sha256=9T_JY0VIpnFly_BtDDihPT9ppukUQrOdUkqwEtJQa60,73501
22
+ prefect/settings.py,sha256=032alJnUkrWxXnHFyZD-p6cPN09x9bIoK7q7qi1VSxs,73558
23
23
  prefect/states.py,sha256=2lysq6X5AvqPfE3eD3D0HYt-KpFA2OUgA0c4ZQ22A_U,24906
24
24
  prefect/task_engine.py,sha256=rcCPPrX01CxiOPhnf_7WcN0wGHbmB5VV7_OG7PKYOrY,57943
25
25
  prefect/task_runners.py,sha256=W1n0yMwbDIqnvffFVJADo9MGEbLaYkzWk52rqgnkMY4,15019
26
26
  prefect/task_runs.py,sha256=jkaQOkRKOHS8fgHUijteriFpjMSKv4zldn1D8tZHkUI,8777
27
27
  prefect/task_worker.py,sha256=a8Uw78Ms4p3ikt_la50lENmPLIa-jjbuvunvjVXvRKQ,16785
28
28
  prefect/tasks.py,sha256=35eOv7VfhziiC3hL9FxB3spYtG6tpxZBLzk5KP_8Ux8,68371
29
- prefect/transactions.py,sha256=oJKP4w5KjV1PSmN-ByyHN3bagSiKiTKvMVtLvAAfpAg,16387
29
+ prefect/transactions.py,sha256=NTzflkehGQ5jKmuChpvsUv1-ZPBqLI7OmUeq-nZJGHQ,16558
30
30
  prefect/variables.py,sha256=023cfSj_ydwvz6lyChRKnjHFfkdoYZKK_zdTtuSxrYo,4665
31
31
  prefect/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  prefect/_internal/_logging.py,sha256=HvNHY-8P469o5u4LYEDBTem69XZEt1QUeUaLToijpak,810
@@ -35,7 +35,6 @@ prefect/_internal/pytz.py,sha256=WWl9x16rKFWequGmcOGs_ljpCDPf2LDHMyZp_4D8e6c,137
35
35
  prefect/_internal/retries.py,sha256=xtgj6oPSvYQLbyk451LR6swcRQvRVWEzCxY6GMK7qA4,2284
36
36
  prefect/_internal/compatibility/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  prefect/_internal/compatibility/deprecated.py,sha256=PVME2C3Oe4_8tKIGufx1W4EpGkz5IQY8gFohPVOjNcM,7533
38
- prefect/_internal/compatibility/experimental.py,sha256=nrIeeAe1vZ0yMb1cPw5AroVR6_msx-bzTeBLzY4au6o,5634
39
38
  prefect/_internal/compatibility/migration.py,sha256=oifIj6mKwVUfrUO13ODLKOCwLON4YqaTXzhBFh8AK6E,6797
40
39
  prefect/_internal/concurrency/__init__.py,sha256=YlTwU9ryjPNwbJa45adLJY00t_DGCh1QrdtY9WdVFfw,2140
41
40
  prefect/_internal/concurrency/api.py,sha256=mOajv_f9ms2u3O4sgegJDV2kLeCg9lBavlEZzPw5kr4,7126
@@ -72,13 +71,13 @@ prefect/client/base.py,sha256=2K8UiWzorZNNM4c8c-OiGeZ5i5ViUfZ_Q31oPobbOO0,24956
72
71
  prefect/client/cloud.py,sha256=Wjm27jUG1K8UHb8sIamOqyAGlM26Oe9_OFpCO6x5s2E,6191
73
72
  prefect/client/collections.py,sha256=u-96saqu0RALAazRI0YaZCJahnuafMppY21KN6ggx80,1059
74
73
  prefect/client/constants.py,sha256=Z_GG8KF70vbbXxpJuqW5pLnwzujTVeHbcYYRikNmGH0,29
75
- prefect/client/orchestration.py,sha256=XImn-8TKOYJ8LBAZ83FEC4DOf0RP6WE9BeLpDXfYX4A,149371
74
+ prefect/client/orchestration.py,sha256=qJp29dPR9OE6uSH3Tkl5uD4IKzQRsYv6dj3Ku-I-sSQ,150555
76
75
  prefect/client/subscriptions.py,sha256=oqF2MJsgN3psJg-MePfvwMtEWjromfP9StWF00xc1eg,3403
77
76
  prefect/client/utilities.py,sha256=89fmza0cRMOayxgXRdO51TKb11TczJ0ByOZmcZVrt44,3286
78
77
  prefect/client/schemas/__init__.py,sha256=KlyqFV-hMulMkNstBn_0ijoHoIwJZaBj6B1r07UmgvE,607
79
78
  prefect/client/schemas/actions.py,sha256=GT1VlvwV5koV690H7ViGFH3tpW7_PvDf0QJoYTcOLDg,28862
80
79
  prefect/client/schemas/filters.py,sha256=oYUBj59SC6keYHaQ8-qFaVynEAcHV8BABrQaob2mI6c,35864
81
- prefect/client/schemas/objects.py,sha256=zJGTbmFYiAORxJ3PB4EcRkOIVcQlxH4O91aOtjKBkyU,56149
80
+ prefect/client/schemas/objects.py,sha256=hlFnM04FzH3HaKm_gcvu7AC1CZsTzVALCajIzosgQCg,56198
82
81
  prefect/client/schemas/responses.py,sha256=tV06W8npA8oCjV9d0ZNvjro4QcbHxayb8PC4LmanXjo,15467
83
82
  prefect/client/schemas/schedules.py,sha256=8rpqjOYtknu2-1n5_WD4cOplgu93P3mCyX86B22LfL4,13070
84
83
  prefect/client/schemas/sorting.py,sha256=L-2Mx-igZPtsUoRUguTcG3nIEstMEMPD97NwPM2Ox5s,2579
@@ -99,7 +98,7 @@ prefect/concurrency/v1/sync.py,sha256=qKE0YzNbrmYooTwP7pz4m1BUz61THCUIF45_PE5IyY
99
98
  prefect/deployments/__init__.py,sha256=_wb7NxDKhq11z9MjYsPckmT3o6MRhGLRgCV9TmvYtew,1002
100
99
  prefect/deployments/base.py,sha256=OyaKZ1Uk16XtvABh5byO6I3jp_1FYG301ryjDq00qJE,16688
101
100
  prefect/deployments/deployments.py,sha256=EvC9qBdvJRc8CHJqRjFTqtzx75SE8bpZOl5C-2eULyA,109
102
- prefect/deployments/flow_runs.py,sha256=tH6lpEkgHhQ5Ipr0bhVAjN6AeOoDwY7UKrkbJihJ6D0,6567
101
+ prefect/deployments/flow_runs.py,sha256=Pz6KYDKNPkgOnh4M2VhkiPhNtDQfuKBmqSjmYGaucbs,6812
103
102
  prefect/deployments/runner.py,sha256=b7jD1DHL7y2jeBXgdBfSsnBMJPHShs4Tt1c5jAeG5Dk,41823
104
103
  prefect/deployments/schedules.py,sha256=KCYA6dOmLAoElHZuoWqdJn4Yno4TtOZtXfPOpTLb1cE,2046
105
104
  prefect/deployments/steps/__init__.py,sha256=Dlz9VqMRyG1Gal8dj8vfGpPr0LyQhZdvcciozkK8WoY,206
@@ -137,10 +136,10 @@ prefect/locking/filesystem.py,sha256=GiZlLLj51cLH6QQgq7IeU6jUK6vGi0wMnOG0zaO95-c
137
136
  prefect/locking/memory.py,sha256=Y1fsMSUAk3jUILzRivbxlrE9Xv8OcVbaylVf-aiEGNc,7495
138
137
  prefect/locking/protocol.py,sha256=o5-48SxvEDAdVwW8RIn7rCN32CmvIsaVHTztESUXuHU,4232
139
138
  prefect/logging/__init__.py,sha256=zx9f5_dWrR4DbcTOFBpNGOPoCZ1QcPFudr7zxb2XRpA,148
140
- prefect/logging/configuration.py,sha256=bYqFJm0QgLz92Dub1Lbl3JONjjm0lTK149pNAGbxPdM,3467
139
+ prefect/logging/configuration.py,sha256=5kOYdd4Hi6t-wJhxEncYS9bUAMEMTRKy_i22pepjDrw,3343
141
140
  prefect/logging/filters.py,sha256=9keHLN4-cpnsWcii1qU0RITNi9-m7pOhkJ_t0MtCM4k,1117
142
141
  prefect/logging/formatters.py,sha256=3nBWgawvD48slT0zgkKeus1gIyf0OjmDKdLwMEe5mPU,3923
143
- prefect/logging/handlers.py,sha256=w532IhEH6890X3jlfwX3iYIxwJIM0WXDIHTT0K5e-U8,10453
142
+ prefect/logging/handlers.py,sha256=8Ey7jJuhwYq1TG3lvsdMqWL_k7F-aL9DBFCkTUKLRSc,10417
144
143
  prefect/logging/highlighters.py,sha256=BpSXOy0n3lFVvlKWa7jC-HetAiClFi9jnQtEq5-rgok,1681
145
144
  prefect/logging/loggers.py,sha256=9fN5iTXQwBAHwKfE9iBo-90f2SyGs9Z3OKmkLPG91VY,10995
146
145
  prefect/logging/logging.yml,sha256=ALNY_E1i3E7tkagCB3Qg35IvuRBHt-t9QqVJvsSq5xA,3185
@@ -161,7 +160,7 @@ prefect/runtime/flow_run.py,sha256=33XsudriajxIRJtebPpqF8cWCRsUpmvb9V0CSipG4J0,9
161
160
  prefect/runtime/task_run.py,sha256=B6v_nZiHy9nKZfnKFQF7izZjAjaiZOT0j80m-VcLxmY,3403
162
161
  prefect/server/api/collections_data/views/aggregate-worker-metadata.json,sha256=gqrwGyylzBEzlFSPOJcMuUwdoK_zojpU0SZaBDgK5FE,79748
163
162
  prefect/server/api/static/prefect-logo-mark-gradient.png,sha256=ylRjJkI_JHCw8VbQasNnXQHwZW-sH-IQiUGSD3aWP1E,73430
164
- prefect/types/__init__.py,sha256=SAHJDtWEGidTKXQACJ38nj6fq8r57Gj0Pwo4Gy7pVWs,2234
163
+ prefect/types/__init__.py,sha256=A714iHFE9makA5LiAKd0Y5wfdb7m13gBwvrpQzdLVgs,3647
165
164
  prefect/types/entrypoint.py,sha256=2FF03-wLPgtnqR_bKJDB2BsXXINPdu8ptY9ZYEZnXg8,328
166
165
  prefect/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
167
166
  prefect/utilities/annotations.py,sha256=Ocj2s5zhnGr8uXUBnOli-OrybXVJdu4-uZvCRpKpV_Q,2820
@@ -179,12 +178,12 @@ prefect/utilities/importtools.py,sha256=aO-xhf2h2KzsLGvSKwRAZLB4ITeW9rsV0Ys-gwq3
179
178
  prefect/utilities/math.py,sha256=wLwcKVidpNeWQi1TUIWWLHGjlz9UgboX9FUGhx_CQzo,2821
180
179
  prefect/utilities/names.py,sha256=x-stHcF7_tebJPvB1dz-5FvdXJXNBTg2kFZXSnIBBmk,1657
181
180
  prefect/utilities/processutils.py,sha256=yo_GO48pZzgn4A0IK5irTAoqyUCYvWKDSqHXCrtP8c4,14547
182
- prefect/utilities/pydantic.py,sha256=YEY7hp5ptaYqOzsZJC4dXf9d2g37aOdepoH8FBPg7uw,12394
181
+ prefect/utilities/pydantic.py,sha256=GElM_h4Mk6nBZsN7l60c-7JeipCnG99akl-e2hbHhVE,12444
183
182
  prefect/utilities/render_swagger.py,sha256=h2UrORVN3f7gM4zurtMnySjQXZIOWbji3uMinpbkl8U,3717
184
183
  prefect/utilities/services.py,sha256=pan_cq-REq2TfTCevdj0OC58qqQFOcetkPN_VV7nDRw,7622
185
184
  prefect/utilities/slugify.py,sha256=57Vb14t13F3zm1P65KAu8nVeAz0iJCd1Qc5eMG-R5y8,169
186
185
  prefect/utilities/templating.py,sha256=nAiOGMMHGbIDFkGYy-g-dzcbY311WfycdgAhsM3cLpY,13298
187
- prefect/utilities/text.py,sha256=eXGIsCcZ7h_6hy8T5GDQjL8GiKyktoOqavYub0QjgO4,445
186
+ prefect/utilities/text.py,sha256=JRs6WNUn07i5oRP_jyTUYD6I0hdVwyMI0JmJc8f9gFw,731
188
187
  prefect/utilities/timeout.py,sha256=BRDIOWnqcw3B7X9tIk83Y3n9nQrJzZgduDQ63z-ns8w,1286
189
188
  prefect/utilities/urls.py,sha256=tKB7Bmbhbe3lBpiAIp7Idb_TWDmmDZI6nNTnDkwDKKI,8207
190
189
  prefect/utilities/visualization.py,sha256=Lum4IvLQ0nHsdLt6GGzS3Wwo-828u1rmOKc5mmWu994,6502
@@ -198,8 +197,8 @@ prefect/workers/cloud.py,sha256=BOVVY5z-vUIQ2u8LwMTXDaNys2fjOZSS5YGDwJmTQjI,230
198
197
  prefect/workers/process.py,sha256=tcJ3fbiraLCfpVGpv8dOHwMSfVzeD_kyguUOvPuIz6I,19796
199
198
  prefect/workers/server.py,sha256=lgh2FfSuaNU7b6HPxSFm8JtKvAvHsZGkiOo4y4tW1Cw,2022
200
199
  prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
201
- prefect_client-3.0.4.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
202
- prefect_client-3.0.4.dist-info/METADATA,sha256=ylM5VSYd7hcLhlSEVyvOk4Pmp5LuAfj7Fae0wdGUB0o,7332
203
- prefect_client-3.0.4.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
204
- prefect_client-3.0.4.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
205
- prefect_client-3.0.4.dist-info/RECORD,,
200
+ prefect_client-3.0.5.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
201
+ prefect_client-3.0.5.dist-info/METADATA,sha256=z2Y18sxgwZTvdzyz5EzjKqyunbZ1riu3hS17perRosE,7332
202
+ prefect_client-3.0.5.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
203
+ prefect_client-3.0.5.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
204
+ prefect_client-3.0.5.dist-info/RECORD,,
@@ -1,195 +0,0 @@
1
- """
2
- Utilities for experimental features.
3
-
4
- Experimental features have a group, feature name, and optional help string.
5
-
6
- When an experimental feature is used, a warning will be displayed. Warnings may be
7
- disabled per feature group with the setting `PREFECT_EXPERIMENTAL_WARN_<GROUP>`.
8
- Warnings may also be disabled globally with the setting `PREFECT_EXPERIMENTAL_WARN`.
9
-
10
- Some experimental features require opt-in to enable any usage. These require the setting
11
- `PREFECT_EXPERIMENTAL_ENABLE_<GROUP>` to be set or an error will be thrown on use.
12
- """
13
-
14
- import functools
15
- import warnings
16
- from typing import Any, Callable, Optional, Set, TypeVar
17
-
18
- import pydantic
19
-
20
- from prefect.settings import PREFECT_EXPERIMENTAL_WARN, SETTING_VARIABLES, Setting
21
- from prefect.utilities.callables import get_call_parameters
22
-
23
- T = TypeVar("T", bound=Callable[..., Any])
24
- M = TypeVar("M", bound=pydantic.BaseModel)
25
-
26
-
27
- EXPERIMENTAL_WARNING = (
28
- "{feature} is experimental. {help}The interface or behavior may change without"
29
- " warning, we recommend pinning versions to prevent unexpected changes. To disable"
30
- " warnings for this group of experiments, disable"
31
- " PREFECT_EXPERIMENTAL_WARN_{group}."
32
- )
33
-
34
- EXPERIMENTAL_ERROR = (
35
- "{feature} is experimental and requires opt-in for usage. {help}"
36
- "To use this feature, enable PREFECT_EXPERIMENTAL_ENABLE_{group}."
37
- )
38
-
39
-
40
- class ExperimentalWarning(Warning):
41
- """
42
- A warning related to experimental code.
43
- """
44
-
45
-
46
- class ExperimentalFeature(ExperimentalWarning):
47
- """
48
- A warning displayed on use of an experimental feature.
49
-
50
- These can be globally disabled by the PREFECT_EXPIRIMENTAL_WARN setting.
51
- """
52
-
53
-
54
- class ExperimentalError(Exception):
55
- """
56
- An exception related to experimental code.
57
- """
58
-
59
-
60
- class ExperimentalFeatureDisabled(ExperimentalError):
61
- """
62
- An error displayed on use of a disabled experimental feature that requires opt-in.
63
- """
64
-
65
-
66
- def _opt_in_setting_for_group(group: str) -> Setting[bool]:
67
- group_opt_in_setting_name = f"PREFECT_EXPERIMENTAL_ENABLE_{group.upper()}"
68
- group_opt_in = SETTING_VARIABLES.get(group_opt_in_setting_name)
69
- if group_opt_in is None:
70
- raise ValueError(
71
- f"A opt-in setting for experimental feature {group!r} does not exist yet. "
72
- f"{group_opt_in_setting_name!r} must be created before the group can be "
73
- "used."
74
- )
75
- return group_opt_in
76
-
77
-
78
- def _warn_setting_for_group(group: str) -> Setting[bool]:
79
- group_warn_setting_name = f"PREFECT_EXPERIMENTAL_WARN_{group.upper()}"
80
- group_warn = SETTING_VARIABLES.get(group_warn_setting_name)
81
- if group_warn is None:
82
- raise ValueError(
83
- f"A warn setting for experimental feature {group!r} does not exist yet. "
84
- f"{group_warn_setting_name!r} must be created before the group can be used."
85
- )
86
- return group_warn
87
-
88
-
89
- def experimental(
90
- feature: str,
91
- *,
92
- group: str,
93
- help: str = "",
94
- stacklevel: int = 2,
95
- opt_in: bool = False,
96
- ) -> Callable[[T], T]:
97
- group = group.upper()
98
-
99
- if help:
100
- # Ensure help ends in a trailing space
101
- help = help.rstrip() + " "
102
-
103
- warn_message = EXPERIMENTAL_WARNING.format(feature=feature, group=group, help=help)
104
- error_message = EXPERIMENTAL_ERROR.format(feature=feature, group=group, help=help)
105
-
106
- if opt_in:
107
- group_opt_in = _opt_in_setting_for_group(group)
108
-
109
- group_warn = _warn_setting_for_group(group)
110
-
111
- def decorator(fn: T) -> T:
112
- @functools.wraps(fn)
113
- def wrapper(*args, **kwargs):
114
- if opt_in and not group_opt_in:
115
- raise ExperimentalFeatureDisabled(error_message)
116
-
117
- if PREFECT_EXPERIMENTAL_WARN and group_warn:
118
- warnings.warn(
119
- warn_message,
120
- ExperimentalFeature,
121
- stacklevel=stacklevel,
122
- )
123
- return fn(*args, **kwargs)
124
-
125
- return wrapper
126
-
127
- return decorator
128
-
129
-
130
- def experiment_enabled(group: str) -> bool:
131
- group_opt_in = _opt_in_setting_for_group(group)
132
- return group_opt_in.value()
133
-
134
-
135
- def experimental_parameter(
136
- name: str,
137
- *,
138
- group: str,
139
- help: str = "",
140
- stacklevel: int = 2,
141
- opt_in: bool = False,
142
- when: Optional[Callable[[Any], bool]] = None,
143
- ) -> Callable[[T], T]:
144
- """
145
- Mark a parameter in a callable as experimental.
146
-
147
- Example:
148
-
149
- ```python
150
-
151
- @experimental_parameter("y", group="example", when=lambda y: y is not None)
152
- def foo(x, y = None):
153
- return x + 1 + (y or 0)
154
- ```
155
- """
156
-
157
- when = when or (lambda _: True)
158
-
159
- @experimental(
160
- group=group,
161
- feature=f"The parameter {name!r}",
162
- help=help,
163
- opt_in=opt_in,
164
- stacklevel=stacklevel + 2,
165
- )
166
- def experimental_check():
167
- pass
168
-
169
- def decorator(fn: T):
170
- @functools.wraps(fn)
171
- def wrapper(*args, **kwargs):
172
- try:
173
- parameters = get_call_parameters(fn, args, kwargs, apply_defaults=False)
174
- except Exception:
175
- # Avoid raising any parsing exceptions here
176
- parameters = kwargs
177
-
178
- if name in parameters and when(parameters[name]):
179
- experimental_check()
180
- return fn(*args, **kwargs)
181
-
182
- return wrapper
183
-
184
- return decorator
185
-
186
-
187
- def enabled_experiments() -> Set[str]:
188
- """
189
- Return the set of all enabled experiments.
190
- """
191
- return {
192
- name[len("PREFECT_EXPERIMENTAL_ENABLE_") :].lower()
193
- for name, setting in SETTING_VARIABLES.items()
194
- if name.startswith("PREFECT_EXPERIMENTAL_ENABLE_") and setting.value()
195
- }