prefect-client 2.14.21__py3-none-any.whl → 2.15.0__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/concurrency/api.py +37 -2
- prefect/_internal/concurrency/calls.py +9 -0
- prefect/_internal/concurrency/cancellation.py +3 -1
- prefect/_internal/concurrency/event_loop.py +2 -2
- prefect/_internal/concurrency/threads.py +3 -2
- prefect/_internal/pydantic/annotations/pendulum.py +4 -4
- prefect/_internal/pydantic/v2_schema.py +2 -2
- prefect/_vendor/fastapi/__init__.py +1 -1
- prefect/_vendor/fastapi/applications.py +13 -13
- prefect/_vendor/fastapi/background.py +3 -1
- prefect/_vendor/fastapi/concurrency.py +7 -3
- prefect/_vendor/fastapi/datastructures.py +9 -7
- prefect/_vendor/fastapi/dependencies/utils.py +12 -7
- prefect/_vendor/fastapi/encoders.py +1 -1
- prefect/_vendor/fastapi/exception_handlers.py +7 -4
- prefect/_vendor/fastapi/exceptions.py +4 -2
- prefect/_vendor/fastapi/middleware/__init__.py +1 -1
- prefect/_vendor/fastapi/middleware/asyncexitstack.py +1 -1
- prefect/_vendor/fastapi/middleware/cors.py +3 -1
- prefect/_vendor/fastapi/middleware/gzip.py +3 -1
- prefect/_vendor/fastapi/middleware/httpsredirect.py +1 -1
- prefect/_vendor/fastapi/middleware/trustedhost.py +1 -1
- prefect/_vendor/fastapi/middleware/wsgi.py +3 -1
- prefect/_vendor/fastapi/openapi/docs.py +1 -1
- prefect/_vendor/fastapi/openapi/utils.py +3 -3
- prefect/_vendor/fastapi/requests.py +4 -2
- prefect/_vendor/fastapi/responses.py +13 -7
- prefect/_vendor/fastapi/routing.py +15 -15
- prefect/_vendor/fastapi/security/api_key.py +3 -3
- prefect/_vendor/fastapi/security/http.py +2 -2
- prefect/_vendor/fastapi/security/oauth2.py +2 -2
- prefect/_vendor/fastapi/security/open_id_connect_url.py +3 -3
- prefect/_vendor/fastapi/staticfiles.py +1 -1
- prefect/_vendor/fastapi/templating.py +3 -1
- prefect/_vendor/fastapi/testclient.py +1 -1
- prefect/_vendor/fastapi/utils.py +3 -3
- prefect/_vendor/fastapi/websockets.py +7 -3
- prefect/_vendor/starlette/__init__.py +1 -0
- prefect/_vendor/starlette/_compat.py +28 -0
- prefect/_vendor/starlette/_exception_handler.py +80 -0
- prefect/_vendor/starlette/_utils.py +88 -0
- prefect/_vendor/starlette/applications.py +261 -0
- prefect/_vendor/starlette/authentication.py +159 -0
- prefect/_vendor/starlette/background.py +43 -0
- prefect/_vendor/starlette/concurrency.py +59 -0
- prefect/_vendor/starlette/config.py +151 -0
- prefect/_vendor/starlette/convertors.py +87 -0
- prefect/_vendor/starlette/datastructures.py +707 -0
- prefect/_vendor/starlette/endpoints.py +130 -0
- prefect/_vendor/starlette/exceptions.py +60 -0
- prefect/_vendor/starlette/formparsers.py +276 -0
- prefect/_vendor/starlette/middleware/__init__.py +17 -0
- prefect/_vendor/starlette/middleware/authentication.py +52 -0
- prefect/_vendor/starlette/middleware/base.py +220 -0
- prefect/_vendor/starlette/middleware/cors.py +176 -0
- prefect/_vendor/starlette/middleware/errors.py +265 -0
- prefect/_vendor/starlette/middleware/exceptions.py +74 -0
- prefect/_vendor/starlette/middleware/gzip.py +113 -0
- prefect/_vendor/starlette/middleware/httpsredirect.py +19 -0
- prefect/_vendor/starlette/middleware/sessions.py +82 -0
- prefect/_vendor/starlette/middleware/trustedhost.py +64 -0
- prefect/_vendor/starlette/middleware/wsgi.py +147 -0
- prefect/_vendor/starlette/requests.py +328 -0
- prefect/_vendor/starlette/responses.py +347 -0
- prefect/_vendor/starlette/routing.py +933 -0
- prefect/_vendor/starlette/schemas.py +154 -0
- prefect/_vendor/starlette/staticfiles.py +248 -0
- prefect/_vendor/starlette/status.py +199 -0
- prefect/_vendor/starlette/templating.py +231 -0
- prefect/_vendor/starlette/testclient.py +805 -0
- prefect/_vendor/starlette/types.py +30 -0
- prefect/_vendor/starlette/websockets.py +193 -0
- prefect/blocks/core.py +3 -3
- prefect/blocks/notifications.py +8 -8
- prefect/client/base.py +1 -1
- prefect/client/cloud.py +1 -1
- prefect/client/orchestration.py +1 -1
- prefect/client/subscriptions.py +2 -6
- prefect/concurrency/services.py +1 -1
- prefect/context.py +3 -3
- prefect/deployments/deployments.py +3 -3
- prefect/engine.py +69 -9
- prefect/events/clients.py +1 -1
- prefect/filesystems.py +9 -9
- prefect/flow_runs.py +5 -1
- prefect/futures.py +1 -1
- prefect/infrastructure/container.py +3 -3
- prefect/infrastructure/kubernetes.py +4 -6
- prefect/infrastructure/process.py +3 -3
- prefect/input/run_input.py +1 -1
- prefect/logging/formatters.py +1 -1
- prefect/runner/server.py +3 -3
- prefect/settings.py +3 -4
- prefect/software/pip.py +1 -1
- prefect/task_engine.py +4 -0
- prefect/task_server.py +35 -17
- prefect/utilities/asyncutils.py +1 -1
- prefect/utilities/collections.py +1 -1
- {prefect_client-2.14.21.dist-info → prefect_client-2.15.0.dist-info}/METADATA +4 -2
- {prefect_client-2.14.21.dist-info → prefect_client-2.15.0.dist-info}/RECORD +103 -68
- {prefect_client-2.14.21.dist-info → prefect_client-2.15.0.dist-info}/LICENSE +0 -0
- {prefect_client-2.14.21.dist-info → prefect_client-2.15.0.dist-info}/WHEEL +0 -0
- {prefect_client-2.14.21.dist-info → prefect_client-2.15.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,231 @@
|
|
1
|
+
import typing
|
2
|
+
import warnings
|
3
|
+
from os import PathLike
|
4
|
+
|
5
|
+
from prefect._vendor.starlette.background import BackgroundTask
|
6
|
+
from prefect._vendor.starlette.datastructures import URL
|
7
|
+
from prefect._vendor.starlette.requests import Request
|
8
|
+
from prefect._vendor.starlette.responses import HTMLResponse
|
9
|
+
from prefect._vendor.starlette.types import Receive, Scope, Send
|
10
|
+
|
11
|
+
try:
|
12
|
+
import jinja2
|
13
|
+
|
14
|
+
# @contextfunction was renamed to @pass_context in Jinja 3.0, and was removed in 3.1
|
15
|
+
# hence we try to get pass_context (most installs will be >=3.1)
|
16
|
+
# and fall back to contextfunction,
|
17
|
+
# adding a type ignore for mypy to let us access an attribute that may not exist
|
18
|
+
if hasattr(jinja2, "pass_context"):
|
19
|
+
pass_context = jinja2.pass_context
|
20
|
+
else: # pragma: nocover
|
21
|
+
pass_context = jinja2.contextfunction # type: ignore[attr-defined]
|
22
|
+
except ModuleNotFoundError: # pragma: nocover
|
23
|
+
jinja2 = None # type: ignore[assignment]
|
24
|
+
|
25
|
+
|
26
|
+
class _TemplateResponse(HTMLResponse):
|
27
|
+
def __init__(
|
28
|
+
self,
|
29
|
+
template: typing.Any,
|
30
|
+
context: typing.Dict[str, typing.Any],
|
31
|
+
status_code: int = 200,
|
32
|
+
headers: typing.Optional[typing.Mapping[str, str]] = None,
|
33
|
+
media_type: typing.Optional[str] = None,
|
34
|
+
background: typing.Optional[BackgroundTask] = None,
|
35
|
+
):
|
36
|
+
self.template = template
|
37
|
+
self.context = context
|
38
|
+
content = template.render(context)
|
39
|
+
super().__init__(content, status_code, headers, media_type, background)
|
40
|
+
|
41
|
+
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
|
42
|
+
request = self.context.get("request", {})
|
43
|
+
extensions = request.get("extensions", {})
|
44
|
+
if "http.response.debug" in extensions:
|
45
|
+
await send(
|
46
|
+
{
|
47
|
+
"type": "http.response.debug",
|
48
|
+
"info": {
|
49
|
+
"template": self.template,
|
50
|
+
"context": self.context,
|
51
|
+
},
|
52
|
+
}
|
53
|
+
)
|
54
|
+
await super().__call__(scope, receive, send)
|
55
|
+
|
56
|
+
|
57
|
+
class Jinja2Templates:
|
58
|
+
"""
|
59
|
+
templates = Jinja2Templates("templates")
|
60
|
+
|
61
|
+
return templates.TemplateResponse("index.html", {"request": request})
|
62
|
+
"""
|
63
|
+
|
64
|
+
@typing.overload
|
65
|
+
def __init__(
|
66
|
+
self,
|
67
|
+
directory: "typing.Union[str, PathLike[typing.AnyStr], typing.Sequence[typing.Union[str, PathLike[typing.AnyStr]]]]", # noqa: E501
|
68
|
+
*,
|
69
|
+
context_processors: typing.Optional[
|
70
|
+
typing.List[typing.Callable[[Request], typing.Dict[str, typing.Any]]]
|
71
|
+
] = None,
|
72
|
+
**env_options: typing.Any,
|
73
|
+
) -> None:
|
74
|
+
...
|
75
|
+
|
76
|
+
@typing.overload
|
77
|
+
def __init__(
|
78
|
+
self,
|
79
|
+
*,
|
80
|
+
env: "jinja2.Environment",
|
81
|
+
context_processors: typing.Optional[
|
82
|
+
typing.List[typing.Callable[[Request], typing.Dict[str, typing.Any]]]
|
83
|
+
] = None,
|
84
|
+
) -> None:
|
85
|
+
...
|
86
|
+
|
87
|
+
def __init__(
|
88
|
+
self,
|
89
|
+
directory: "typing.Union[str, PathLike[typing.AnyStr], typing.Sequence[typing.Union[str, PathLike[typing.AnyStr]]], None]" = None, # noqa: E501
|
90
|
+
*,
|
91
|
+
context_processors: typing.Optional[
|
92
|
+
typing.List[typing.Callable[[Request], typing.Dict[str, typing.Any]]]
|
93
|
+
] = None,
|
94
|
+
env: typing.Optional["jinja2.Environment"] = None,
|
95
|
+
**env_options: typing.Any,
|
96
|
+
) -> None:
|
97
|
+
if env_options:
|
98
|
+
warnings.warn(
|
99
|
+
"Extra environment options are deprecated. Use a preconfigured jinja2.Environment instead.", # noqa: E501
|
100
|
+
DeprecationWarning,
|
101
|
+
)
|
102
|
+
assert jinja2 is not None, "jinja2 must be installed to use Jinja2Templates"
|
103
|
+
assert directory or env, "either 'directory' or 'env' arguments must be passed"
|
104
|
+
self.context_processors = context_processors or []
|
105
|
+
if directory is not None:
|
106
|
+
self.env = self._create_env(directory, **env_options)
|
107
|
+
elif env is not None:
|
108
|
+
self.env = env
|
109
|
+
|
110
|
+
self._setup_env_defaults(self.env)
|
111
|
+
|
112
|
+
def _create_env(
|
113
|
+
self,
|
114
|
+
directory: "typing.Union[str, PathLike[typing.AnyStr], typing.Sequence[typing.Union[str, PathLike[typing.AnyStr]]]]", # noqa: E501
|
115
|
+
**env_options: typing.Any,
|
116
|
+
) -> "jinja2.Environment":
|
117
|
+
loader = jinja2.FileSystemLoader(directory)
|
118
|
+
env_options.setdefault("loader", loader)
|
119
|
+
env_options.setdefault("autoescape", True)
|
120
|
+
|
121
|
+
return jinja2.Environment(**env_options)
|
122
|
+
|
123
|
+
def _setup_env_defaults(self, env: "jinja2.Environment") -> None:
|
124
|
+
@pass_context
|
125
|
+
def url_for(
|
126
|
+
context: typing.Dict[str, typing.Any],
|
127
|
+
name: str,
|
128
|
+
/,
|
129
|
+
**path_params: typing.Any,
|
130
|
+
) -> URL:
|
131
|
+
request: Request = context["request"]
|
132
|
+
return request.url_for(name, **path_params)
|
133
|
+
|
134
|
+
env.globals.setdefault("url_for", url_for)
|
135
|
+
|
136
|
+
def get_template(self, name: str) -> "jinja2.Template":
|
137
|
+
return self.env.get_template(name)
|
138
|
+
|
139
|
+
@typing.overload
|
140
|
+
def TemplateResponse(
|
141
|
+
self,
|
142
|
+
request: Request,
|
143
|
+
name: str,
|
144
|
+
context: typing.Optional[typing.Dict[str, typing.Any]] = None,
|
145
|
+
status_code: int = 200,
|
146
|
+
headers: typing.Optional[typing.Mapping[str, str]] = None,
|
147
|
+
media_type: typing.Optional[str] = None,
|
148
|
+
background: typing.Optional[BackgroundTask] = None,
|
149
|
+
) -> _TemplateResponse:
|
150
|
+
...
|
151
|
+
|
152
|
+
@typing.overload
|
153
|
+
def TemplateResponse(
|
154
|
+
self,
|
155
|
+
name: str,
|
156
|
+
context: typing.Optional[typing.Dict[str, typing.Any]] = None,
|
157
|
+
status_code: int = 200,
|
158
|
+
headers: typing.Optional[typing.Mapping[str, str]] = None,
|
159
|
+
media_type: typing.Optional[str] = None,
|
160
|
+
background: typing.Optional[BackgroundTask] = None,
|
161
|
+
) -> _TemplateResponse:
|
162
|
+
# Deprecated usage
|
163
|
+
...
|
164
|
+
|
165
|
+
def TemplateResponse(
|
166
|
+
self, *args: typing.Any, **kwargs: typing.Any
|
167
|
+
) -> _TemplateResponse:
|
168
|
+
if args:
|
169
|
+
if isinstance(
|
170
|
+
args[0], str
|
171
|
+
): # the first argument is template name (old style)
|
172
|
+
warnings.warn(
|
173
|
+
"The `name` is not the first parameter anymore. "
|
174
|
+
"The first parameter should be the `Request` instance.\n"
|
175
|
+
'Replace `TemplateResponse(name, {"request": request})` by `TemplateResponse(request, name)`.', # noqa: E501
|
176
|
+
DeprecationWarning,
|
177
|
+
)
|
178
|
+
|
179
|
+
name = args[0]
|
180
|
+
context = args[1] if len(args) > 1 else kwargs.get("context", {})
|
181
|
+
status_code = (
|
182
|
+
args[2] if len(args) > 2 else kwargs.get("status_code", 200)
|
183
|
+
)
|
184
|
+
headers = args[2] if len(args) > 2 else kwargs.get("headers")
|
185
|
+
media_type = args[3] if len(args) > 3 else kwargs.get("media_type")
|
186
|
+
background = args[4] if len(args) > 4 else kwargs.get("background")
|
187
|
+
|
188
|
+
if "request" not in context:
|
189
|
+
raise ValueError('context must include a "request" key')
|
190
|
+
request = context["request"]
|
191
|
+
else: # the first argument is a request instance (new style)
|
192
|
+
request = args[0]
|
193
|
+
name = args[1] if len(args) > 1 else kwargs["name"]
|
194
|
+
context = args[2] if len(args) > 2 else kwargs.get("context", {})
|
195
|
+
status_code = (
|
196
|
+
args[3] if len(args) > 3 else kwargs.get("status_code", 200)
|
197
|
+
)
|
198
|
+
headers = args[4] if len(args) > 4 else kwargs.get("headers")
|
199
|
+
media_type = args[5] if len(args) > 5 else kwargs.get("media_type")
|
200
|
+
background = args[6] if len(args) > 6 else kwargs.get("background")
|
201
|
+
else: # all arguments are kwargs
|
202
|
+
if "request" not in kwargs:
|
203
|
+
warnings.warn(
|
204
|
+
"The `TemplateResponse` now requires the `request` argument.\n"
|
205
|
+
'Replace `TemplateResponse(name, {"context": context})` by `TemplateResponse(request, name)`.', # noqa: E501
|
206
|
+
DeprecationWarning,
|
207
|
+
)
|
208
|
+
if "request" not in kwargs.get("context", {}):
|
209
|
+
raise ValueError('context must include a "request" key')
|
210
|
+
|
211
|
+
context = kwargs.get("context", {})
|
212
|
+
request = kwargs.get("request", context.get("request"))
|
213
|
+
name = typing.cast(str, kwargs["name"])
|
214
|
+
status_code = kwargs.get("status_code", 200)
|
215
|
+
headers = kwargs.get("headers")
|
216
|
+
media_type = kwargs.get("media_type")
|
217
|
+
background = kwargs.get("background")
|
218
|
+
|
219
|
+
context.setdefault("request", request)
|
220
|
+
for context_processor in self.context_processors:
|
221
|
+
context.update(context_processor(request))
|
222
|
+
|
223
|
+
template = self.get_template(name)
|
224
|
+
return _TemplateResponse(
|
225
|
+
template,
|
226
|
+
context,
|
227
|
+
status_code=status_code,
|
228
|
+
headers=headers,
|
229
|
+
media_type=media_type,
|
230
|
+
background=background,
|
231
|
+
)
|