prefect-client 2.20.4__py3-none-any.whl → 3.0.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/__init__.py +74 -110
- prefect/_internal/compatibility/deprecated.py +6 -115
- prefect/_internal/compatibility/experimental.py +4 -79
- prefect/_internal/compatibility/migration.py +166 -0
- prefect/_internal/concurrency/__init__.py +2 -2
- prefect/_internal/concurrency/api.py +1 -35
- prefect/_internal/concurrency/calls.py +0 -6
- prefect/_internal/concurrency/cancellation.py +0 -3
- prefect/_internal/concurrency/event_loop.py +0 -20
- prefect/_internal/concurrency/inspection.py +3 -3
- prefect/_internal/concurrency/primitives.py +1 -0
- prefect/_internal/concurrency/services.py +23 -0
- prefect/_internal/concurrency/threads.py +35 -0
- prefect/_internal/concurrency/waiters.py +0 -28
- prefect/_internal/integrations.py +7 -0
- prefect/_internal/pydantic/__init__.py +0 -45
- prefect/_internal/pydantic/annotations/pendulum.py +2 -2
- prefect/_internal/pydantic/v1_schema.py +21 -22
- prefect/_internal/pydantic/v2_schema.py +0 -2
- prefect/_internal/pydantic/v2_validated_func.py +18 -23
- prefect/_internal/pytz.py +1 -1
- prefect/_internal/retries.py +61 -0
- prefect/_internal/schemas/bases.py +45 -177
- prefect/_internal/schemas/fields.py +1 -43
- prefect/_internal/schemas/validators.py +47 -233
- prefect/agent.py +3 -695
- prefect/artifacts.py +173 -14
- prefect/automations.py +39 -4
- prefect/blocks/abstract.py +1 -1
- prefect/blocks/core.py +405 -153
- prefect/blocks/fields.py +2 -57
- prefect/blocks/notifications.py +43 -28
- prefect/blocks/redis.py +168 -0
- prefect/blocks/system.py +67 -20
- prefect/blocks/webhook.py +2 -9
- prefect/cache_policies.py +239 -0
- prefect/client/__init__.py +4 -0
- prefect/client/base.py +33 -27
- prefect/client/cloud.py +65 -20
- prefect/client/collections.py +1 -1
- prefect/client/orchestration.py +650 -442
- prefect/client/schemas/actions.py +115 -100
- prefect/client/schemas/filters.py +46 -52
- prefect/client/schemas/objects.py +228 -178
- prefect/client/schemas/responses.py +18 -36
- prefect/client/schemas/schedules.py +55 -36
- prefect/client/schemas/sorting.py +2 -0
- prefect/client/subscriptions.py +8 -7
- prefect/client/types/flexible_schedule_list.py +11 -0
- prefect/client/utilities.py +9 -6
- prefect/concurrency/asyncio.py +60 -11
- prefect/concurrency/context.py +24 -0
- prefect/concurrency/events.py +2 -2
- prefect/concurrency/services.py +46 -16
- prefect/concurrency/sync.py +51 -7
- prefect/concurrency/v1/asyncio.py +143 -0
- prefect/concurrency/v1/context.py +27 -0
- prefect/concurrency/v1/events.py +61 -0
- prefect/concurrency/v1/services.py +116 -0
- prefect/concurrency/v1/sync.py +92 -0
- prefect/context.py +246 -149
- prefect/deployments/__init__.py +33 -18
- prefect/deployments/base.py +10 -15
- prefect/deployments/deployments.py +2 -1048
- prefect/deployments/flow_runs.py +178 -0
- prefect/deployments/runner.py +72 -173
- prefect/deployments/schedules.py +31 -25
- prefect/deployments/steps/__init__.py +0 -1
- prefect/deployments/steps/core.py +7 -0
- prefect/deployments/steps/pull.py +15 -21
- prefect/deployments/steps/utility.py +2 -1
- prefect/docker/__init__.py +20 -0
- prefect/docker/docker_image.py +82 -0
- prefect/engine.py +15 -2475
- prefect/events/actions.py +17 -23
- prefect/events/cli/automations.py +20 -7
- prefect/events/clients.py +142 -80
- prefect/events/filters.py +14 -18
- prefect/events/related.py +74 -75
- prefect/events/schemas/__init__.py +0 -5
- prefect/events/schemas/automations.py +55 -46
- prefect/events/schemas/deployment_triggers.py +7 -197
- prefect/events/schemas/events.py +46 -65
- prefect/events/schemas/labelling.py +10 -14
- prefect/events/utilities.py +4 -5
- prefect/events/worker.py +23 -8
- prefect/exceptions.py +15 -0
- prefect/filesystems.py +30 -529
- prefect/flow_engine.py +827 -0
- prefect/flow_runs.py +379 -7
- prefect/flows.py +470 -360
- prefect/futures.py +382 -331
- prefect/infrastructure/__init__.py +5 -26
- prefect/infrastructure/base.py +3 -320
- prefect/infrastructure/provisioners/__init__.py +5 -3
- prefect/infrastructure/provisioners/cloud_run.py +13 -8
- prefect/infrastructure/provisioners/container_instance.py +14 -9
- prefect/infrastructure/provisioners/ecs.py +10 -8
- prefect/infrastructure/provisioners/modal.py +8 -5
- prefect/input/__init__.py +4 -0
- prefect/input/actions.py +2 -4
- prefect/input/run_input.py +9 -9
- prefect/logging/formatters.py +2 -4
- prefect/logging/handlers.py +9 -14
- prefect/logging/loggers.py +5 -5
- prefect/main.py +72 -0
- prefect/plugins.py +2 -64
- prefect/profiles.toml +16 -2
- prefect/records/__init__.py +1 -0
- prefect/records/base.py +223 -0
- prefect/records/filesystem.py +207 -0
- prefect/records/memory.py +178 -0
- prefect/records/result_store.py +64 -0
- prefect/results.py +577 -504
- prefect/runner/runner.py +117 -47
- prefect/runner/server.py +32 -34
- prefect/runner/storage.py +3 -12
- prefect/runner/submit.py +2 -10
- prefect/runner/utils.py +2 -2
- prefect/runtime/__init__.py +1 -0
- prefect/runtime/deployment.py +1 -0
- prefect/runtime/flow_run.py +40 -5
- prefect/runtime/task_run.py +1 -0
- prefect/serializers.py +28 -39
- prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
- prefect/settings.py +209 -332
- prefect/states.py +160 -63
- prefect/task_engine.py +1478 -57
- prefect/task_runners.py +383 -287
- prefect/task_runs.py +240 -0
- prefect/task_worker.py +463 -0
- prefect/tasks.py +684 -374
- prefect/transactions.py +410 -0
- prefect/types/__init__.py +72 -86
- prefect/types/entrypoint.py +13 -0
- prefect/utilities/annotations.py +4 -3
- prefect/utilities/asyncutils.py +227 -148
- prefect/utilities/callables.py +137 -45
- prefect/utilities/collections.py +134 -86
- prefect/utilities/dispatch.py +27 -14
- prefect/utilities/dockerutils.py +11 -4
- prefect/utilities/engine.py +186 -32
- prefect/utilities/filesystem.py +4 -5
- prefect/utilities/importtools.py +26 -27
- prefect/utilities/pydantic.py +128 -38
- prefect/utilities/schema_tools/hydration.py +18 -1
- prefect/utilities/schema_tools/validation.py +30 -0
- prefect/utilities/services.py +35 -9
- prefect/utilities/templating.py +12 -2
- prefect/utilities/timeout.py +20 -5
- prefect/utilities/urls.py +195 -0
- prefect/utilities/visualization.py +1 -0
- prefect/variables.py +78 -59
- prefect/workers/__init__.py +0 -1
- prefect/workers/base.py +237 -244
- prefect/workers/block.py +5 -226
- prefect/workers/cloud.py +6 -0
- prefect/workers/process.py +265 -12
- prefect/workers/server.py +29 -11
- {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/METADATA +28 -24
- prefect_client-3.0.0.dist-info/RECORD +201 -0
- {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/WHEEL +1 -1
- prefect/_internal/pydantic/_base_model.py +0 -51
- prefect/_internal/pydantic/_compat.py +0 -82
- prefect/_internal/pydantic/_flags.py +0 -20
- prefect/_internal/pydantic/_types.py +0 -8
- prefect/_internal/pydantic/utilities/config_dict.py +0 -72
- prefect/_internal/pydantic/utilities/field_validator.py +0 -150
- prefect/_internal/pydantic/utilities/model_construct.py +0 -56
- prefect/_internal/pydantic/utilities/model_copy.py +0 -55
- prefect/_internal/pydantic/utilities/model_dump.py +0 -136
- prefect/_internal/pydantic/utilities/model_dump_json.py +0 -112
- prefect/_internal/pydantic/utilities/model_fields.py +0 -50
- prefect/_internal/pydantic/utilities/model_fields_set.py +0 -29
- prefect/_internal/pydantic/utilities/model_json_schema.py +0 -82
- prefect/_internal/pydantic/utilities/model_rebuild.py +0 -80
- prefect/_internal/pydantic/utilities/model_validate.py +0 -75
- prefect/_internal/pydantic/utilities/model_validate_json.py +0 -68
- prefect/_internal/pydantic/utilities/model_validator.py +0 -87
- prefect/_internal/pydantic/utilities/type_adapter.py +0 -71
- prefect/_vendor/fastapi/__init__.py +0 -25
- prefect/_vendor/fastapi/applications.py +0 -946
- prefect/_vendor/fastapi/background.py +0 -3
- prefect/_vendor/fastapi/concurrency.py +0 -44
- prefect/_vendor/fastapi/datastructures.py +0 -58
- prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
- prefect/_vendor/fastapi/dependencies/models.py +0 -64
- prefect/_vendor/fastapi/dependencies/utils.py +0 -877
- prefect/_vendor/fastapi/encoders.py +0 -177
- prefect/_vendor/fastapi/exception_handlers.py +0 -40
- prefect/_vendor/fastapi/exceptions.py +0 -46
- prefect/_vendor/fastapi/logger.py +0 -3
- prefect/_vendor/fastapi/middleware/__init__.py +0 -1
- prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -25
- prefect/_vendor/fastapi/middleware/cors.py +0 -3
- prefect/_vendor/fastapi/middleware/gzip.py +0 -3
- prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -3
- prefect/_vendor/fastapi/middleware/trustedhost.py +0 -3
- prefect/_vendor/fastapi/middleware/wsgi.py +0 -3
- prefect/_vendor/fastapi/openapi/__init__.py +0 -0
- prefect/_vendor/fastapi/openapi/constants.py +0 -2
- prefect/_vendor/fastapi/openapi/docs.py +0 -203
- prefect/_vendor/fastapi/openapi/models.py +0 -480
- prefect/_vendor/fastapi/openapi/utils.py +0 -485
- prefect/_vendor/fastapi/param_functions.py +0 -340
- prefect/_vendor/fastapi/params.py +0 -453
- prefect/_vendor/fastapi/py.typed +0 -0
- prefect/_vendor/fastapi/requests.py +0 -4
- prefect/_vendor/fastapi/responses.py +0 -40
- prefect/_vendor/fastapi/routing.py +0 -1331
- prefect/_vendor/fastapi/security/__init__.py +0 -15
- prefect/_vendor/fastapi/security/api_key.py +0 -98
- prefect/_vendor/fastapi/security/base.py +0 -6
- prefect/_vendor/fastapi/security/http.py +0 -172
- prefect/_vendor/fastapi/security/oauth2.py +0 -227
- prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -34
- prefect/_vendor/fastapi/security/utils.py +0 -10
- prefect/_vendor/fastapi/staticfiles.py +0 -1
- prefect/_vendor/fastapi/templating.py +0 -3
- prefect/_vendor/fastapi/testclient.py +0 -1
- prefect/_vendor/fastapi/types.py +0 -3
- prefect/_vendor/fastapi/utils.py +0 -235
- prefect/_vendor/fastapi/websockets.py +0 -7
- prefect/_vendor/starlette/__init__.py +0 -1
- prefect/_vendor/starlette/_compat.py +0 -28
- prefect/_vendor/starlette/_exception_handler.py +0 -80
- prefect/_vendor/starlette/_utils.py +0 -88
- prefect/_vendor/starlette/applications.py +0 -261
- prefect/_vendor/starlette/authentication.py +0 -159
- prefect/_vendor/starlette/background.py +0 -43
- prefect/_vendor/starlette/concurrency.py +0 -59
- prefect/_vendor/starlette/config.py +0 -151
- prefect/_vendor/starlette/convertors.py +0 -87
- prefect/_vendor/starlette/datastructures.py +0 -707
- prefect/_vendor/starlette/endpoints.py +0 -130
- prefect/_vendor/starlette/exceptions.py +0 -60
- prefect/_vendor/starlette/formparsers.py +0 -276
- prefect/_vendor/starlette/middleware/__init__.py +0 -17
- prefect/_vendor/starlette/middleware/authentication.py +0 -52
- prefect/_vendor/starlette/middleware/base.py +0 -220
- prefect/_vendor/starlette/middleware/cors.py +0 -176
- prefect/_vendor/starlette/middleware/errors.py +0 -265
- prefect/_vendor/starlette/middleware/exceptions.py +0 -74
- prefect/_vendor/starlette/middleware/gzip.py +0 -113
- prefect/_vendor/starlette/middleware/httpsredirect.py +0 -19
- prefect/_vendor/starlette/middleware/sessions.py +0 -82
- prefect/_vendor/starlette/middleware/trustedhost.py +0 -64
- prefect/_vendor/starlette/middleware/wsgi.py +0 -147
- prefect/_vendor/starlette/py.typed +0 -0
- prefect/_vendor/starlette/requests.py +0 -328
- prefect/_vendor/starlette/responses.py +0 -347
- prefect/_vendor/starlette/routing.py +0 -933
- prefect/_vendor/starlette/schemas.py +0 -154
- prefect/_vendor/starlette/staticfiles.py +0 -248
- prefect/_vendor/starlette/status.py +0 -199
- prefect/_vendor/starlette/templating.py +0 -231
- prefect/_vendor/starlette/testclient.py +0 -804
- prefect/_vendor/starlette/types.py +0 -30
- prefect/_vendor/starlette/websockets.py +0 -193
- prefect/blocks/kubernetes.py +0 -119
- prefect/deprecated/__init__.py +0 -0
- prefect/deprecated/data_documents.py +0 -350
- prefect/deprecated/packaging/__init__.py +0 -12
- prefect/deprecated/packaging/base.py +0 -96
- prefect/deprecated/packaging/docker.py +0 -146
- prefect/deprecated/packaging/file.py +0 -92
- prefect/deprecated/packaging/orion.py +0 -80
- prefect/deprecated/packaging/serializers.py +0 -171
- prefect/events/instrument.py +0 -135
- prefect/infrastructure/container.py +0 -824
- prefect/infrastructure/kubernetes.py +0 -920
- prefect/infrastructure/process.py +0 -289
- prefect/manifests.py +0 -20
- prefect/new_flow_engine.py +0 -449
- prefect/new_task_engine.py +0 -423
- prefect/pydantic/__init__.py +0 -76
- prefect/pydantic/main.py +0 -39
- prefect/software/__init__.py +0 -2
- prefect/software/base.py +0 -50
- prefect/software/conda.py +0 -199
- prefect/software/pip.py +0 -122
- prefect/software/python.py +0 -52
- prefect/task_server.py +0 -322
- prefect_client-2.20.4.dist-info/RECORD +0 -294
- /prefect/{_internal/pydantic/utilities → client/types}/__init__.py +0 -0
- /prefect/{_vendor → concurrency/v1}/__init__.py +0 -0
- {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/LICENSE +0 -0
- {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/top_level.txt +0 -0
@@ -1,289 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
DEPRECATION WARNING:
|
3
|
-
|
4
|
-
This module is deprecated as of March 2024 and will not be available after September 2024.
|
5
|
-
It has been replaced by the process worker from the `prefect.workers` module, which offers enhanced functionality and better performance.
|
6
|
-
|
7
|
-
For upgrade instructions, see https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/.
|
8
|
-
"""
|
9
|
-
|
10
|
-
import contextlib
|
11
|
-
import os
|
12
|
-
import shlex
|
13
|
-
import signal
|
14
|
-
import socket
|
15
|
-
import subprocess
|
16
|
-
import sys
|
17
|
-
import tempfile
|
18
|
-
from pathlib import Path
|
19
|
-
from typing import Dict, Tuple, Union
|
20
|
-
|
21
|
-
import anyio
|
22
|
-
import anyio.abc
|
23
|
-
|
24
|
-
from prefect._internal.compatibility.deprecated import deprecated_class
|
25
|
-
from prefect._internal.pydantic import HAS_PYDANTIC_V2
|
26
|
-
|
27
|
-
if HAS_PYDANTIC_V2:
|
28
|
-
from pydantic.v1 import Field
|
29
|
-
else:
|
30
|
-
from pydantic import Field
|
31
|
-
|
32
|
-
from typing_extensions import Literal
|
33
|
-
|
34
|
-
from prefect.exceptions import InfrastructureNotAvailable, InfrastructureNotFound
|
35
|
-
from prefect.infrastructure.base import Infrastructure, InfrastructureResult
|
36
|
-
from prefect.utilities.asyncutils import sync_compatible
|
37
|
-
from prefect.utilities.processutils import get_sys_executable, run_process
|
38
|
-
|
39
|
-
if sys.platform == "win32":
|
40
|
-
# exit code indicating that the process was terminated by Ctrl+C or Ctrl+Break
|
41
|
-
STATUS_CONTROL_C_EXIT = 0xC000013A
|
42
|
-
|
43
|
-
|
44
|
-
def _infrastructure_pid_from_process(process: anyio.abc.Process) -> str:
|
45
|
-
hostname = socket.gethostname()
|
46
|
-
return f"{hostname}:{process.pid}"
|
47
|
-
|
48
|
-
|
49
|
-
def _parse_infrastructure_pid(infrastructure_pid: str) -> Tuple[str, int]:
|
50
|
-
hostname, pid = infrastructure_pid.split(":")
|
51
|
-
return hostname, int(pid)
|
52
|
-
|
53
|
-
|
54
|
-
@deprecated_class(
|
55
|
-
start_date="Mar 2024",
|
56
|
-
help="Use the process worker instead."
|
57
|
-
" Refer to the upgrade guide for more information:"
|
58
|
-
" https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/.",
|
59
|
-
)
|
60
|
-
class Process(Infrastructure):
|
61
|
-
"""
|
62
|
-
Run a command in a new process.
|
63
|
-
|
64
|
-
Current environment variables and Prefect settings will be included in the created
|
65
|
-
process. Configured environment variables will override any current environment
|
66
|
-
variables.
|
67
|
-
|
68
|
-
Attributes:
|
69
|
-
command: A list of strings specifying the command to run in the container to
|
70
|
-
start the flow run. In most cases you should not override this.
|
71
|
-
env: Environment variables to set for the new process.
|
72
|
-
labels: Labels for the process. Labels are for metadata purposes only and
|
73
|
-
cannot be attached to the process itself.
|
74
|
-
name: A name for the process. For display purposes only.
|
75
|
-
stream_output: Whether to stream output to local stdout.
|
76
|
-
working_dir: Working directory where the process should be opened. If not set,
|
77
|
-
a tmp directory will be used.
|
78
|
-
"""
|
79
|
-
|
80
|
-
_logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/356e6766a91baf20e1d08bbe16e8b5aaef4d8643-48x48.png"
|
81
|
-
_documentation_url = "https://docs.prefect.io/concepts/infrastructure/#process"
|
82
|
-
|
83
|
-
type: Literal["process"] = Field(
|
84
|
-
default="process", description="The type of infrastructure."
|
85
|
-
)
|
86
|
-
stream_output: bool = Field(
|
87
|
-
default=True,
|
88
|
-
description=(
|
89
|
-
"If set, output will be streamed from the process to local standard output."
|
90
|
-
),
|
91
|
-
)
|
92
|
-
working_dir: Union[str, Path, None] = Field(
|
93
|
-
default=None,
|
94
|
-
description=(
|
95
|
-
"If set, the process will open within the specified path as the working"
|
96
|
-
" directory. Otherwise, a temporary directory will be created."
|
97
|
-
),
|
98
|
-
) # Underlying accepted types are str, bytes, PathLike[str], None
|
99
|
-
|
100
|
-
@sync_compatible
|
101
|
-
async def run(
|
102
|
-
self,
|
103
|
-
task_status: anyio.abc.TaskStatus = None,
|
104
|
-
) -> "ProcessResult":
|
105
|
-
if not self.command:
|
106
|
-
raise ValueError("Process cannot be run with empty command.")
|
107
|
-
|
108
|
-
display_name = f" {self.name!r}" if self.name else ""
|
109
|
-
|
110
|
-
# Open a subprocess to execute the flow run
|
111
|
-
self.logger.info(f"Opening process{display_name}...")
|
112
|
-
working_dir_ctx = (
|
113
|
-
tempfile.TemporaryDirectory(suffix="prefect")
|
114
|
-
if not self.working_dir
|
115
|
-
else contextlib.nullcontext(self.working_dir)
|
116
|
-
)
|
117
|
-
with working_dir_ctx as working_dir:
|
118
|
-
self.logger.debug(
|
119
|
-
f"Process{display_name} running command: {' '.join(self.command)} in"
|
120
|
-
f" {working_dir}"
|
121
|
-
)
|
122
|
-
|
123
|
-
# We must add creationflags to a dict so it is only passed as a function
|
124
|
-
# parameter on Windows, because the presence of creationflags causes
|
125
|
-
# errors on Unix even if set to None
|
126
|
-
kwargs: Dict[str, object] = {}
|
127
|
-
if sys.platform == "win32":
|
128
|
-
kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP
|
129
|
-
|
130
|
-
process = await run_process(
|
131
|
-
self.command,
|
132
|
-
stream_output=self.stream_output,
|
133
|
-
task_status=task_status,
|
134
|
-
task_status_handler=_infrastructure_pid_from_process,
|
135
|
-
env=self._get_environment_variables(),
|
136
|
-
cwd=working_dir,
|
137
|
-
**kwargs,
|
138
|
-
)
|
139
|
-
|
140
|
-
# Use the pid for display if no name was given
|
141
|
-
display_name = display_name or f" {process.pid}"
|
142
|
-
|
143
|
-
if process.returncode:
|
144
|
-
help_message = None
|
145
|
-
if process.returncode == -9:
|
146
|
-
help_message = (
|
147
|
-
"This indicates that the process exited due to a SIGKILL signal. "
|
148
|
-
"Typically, this is either caused by manual cancellation or "
|
149
|
-
"high memory usage causing the operating system to "
|
150
|
-
"terminate the process."
|
151
|
-
)
|
152
|
-
if process.returncode == -15:
|
153
|
-
help_message = (
|
154
|
-
"This indicates that the process exited due to a SIGTERM signal. "
|
155
|
-
"Typically, this is caused by manual cancellation."
|
156
|
-
)
|
157
|
-
elif process.returncode == 247:
|
158
|
-
help_message = (
|
159
|
-
"This indicates that the process was terminated due to high "
|
160
|
-
"memory usage."
|
161
|
-
)
|
162
|
-
elif (
|
163
|
-
sys.platform == "win32" and process.returncode == STATUS_CONTROL_C_EXIT
|
164
|
-
):
|
165
|
-
help_message = (
|
166
|
-
"Process was terminated due to a Ctrl+C or Ctrl+Break signal. "
|
167
|
-
"Typically, this is caused by manual cancellation."
|
168
|
-
)
|
169
|
-
|
170
|
-
self.logger.error(
|
171
|
-
f"Process{display_name} exited with status code: {process.returncode}"
|
172
|
-
+ (f"; {help_message}" if help_message else "")
|
173
|
-
)
|
174
|
-
else:
|
175
|
-
self.logger.info(f"Process{display_name} exited cleanly.")
|
176
|
-
|
177
|
-
return ProcessResult(
|
178
|
-
status_code=process.returncode, identifier=str(process.pid)
|
179
|
-
)
|
180
|
-
|
181
|
-
async def kill(self, infrastructure_pid: str, grace_seconds: int = 30):
|
182
|
-
hostname, pid = _parse_infrastructure_pid(infrastructure_pid)
|
183
|
-
|
184
|
-
if hostname != socket.gethostname():
|
185
|
-
raise InfrastructureNotAvailable(
|
186
|
-
f"Unable to kill process {pid!r}: The process is running on a different"
|
187
|
-
f" host {hostname!r}."
|
188
|
-
)
|
189
|
-
|
190
|
-
# In a non-windows environment first send a SIGTERM, then, after
|
191
|
-
# `grace_seconds` seconds have passed subsequent send SIGKILL. In
|
192
|
-
# Windows we use CTRL_BREAK_EVENT as SIGTERM is useless:
|
193
|
-
# https://bugs.python.org/issue26350
|
194
|
-
if sys.platform == "win32":
|
195
|
-
try:
|
196
|
-
os.kill(pid, signal.CTRL_BREAK_EVENT)
|
197
|
-
except (ProcessLookupError, WindowsError):
|
198
|
-
raise InfrastructureNotFound(
|
199
|
-
f"Unable to kill process {pid!r}: The process was not found."
|
200
|
-
)
|
201
|
-
else:
|
202
|
-
try:
|
203
|
-
os.kill(pid, signal.SIGTERM)
|
204
|
-
except ProcessLookupError:
|
205
|
-
raise InfrastructureNotFound(
|
206
|
-
f"Unable to kill process {pid!r}: The process was not found."
|
207
|
-
)
|
208
|
-
|
209
|
-
# Throttle how often we check if the process is still alive to keep
|
210
|
-
# from making too many system calls in a short period of time.
|
211
|
-
check_interval = max(grace_seconds / 10, 1)
|
212
|
-
|
213
|
-
with anyio.move_on_after(grace_seconds):
|
214
|
-
while True:
|
215
|
-
await anyio.sleep(check_interval)
|
216
|
-
|
217
|
-
# Detect if the process is still alive. If not do an early
|
218
|
-
# return as the process respected the SIGTERM from above.
|
219
|
-
try:
|
220
|
-
os.kill(pid, 0)
|
221
|
-
except ProcessLookupError:
|
222
|
-
return
|
223
|
-
|
224
|
-
try:
|
225
|
-
os.kill(pid, signal.SIGKILL)
|
226
|
-
except OSError:
|
227
|
-
# We shouldn't ever end up here, but it's possible that the
|
228
|
-
# process ended right after the check above.
|
229
|
-
return
|
230
|
-
|
231
|
-
def preview(self):
|
232
|
-
environment = self._get_environment_variables(include_os_environ=False)
|
233
|
-
return " \\\n".join(
|
234
|
-
[f"{key}={value}" for key, value in environment.items()]
|
235
|
-
+ [" ".join(self.command)]
|
236
|
-
)
|
237
|
-
|
238
|
-
def _get_environment_variables(self, include_os_environ: bool = True):
|
239
|
-
os_environ = os.environ if include_os_environ else {}
|
240
|
-
# The base environment must override the current environment or
|
241
|
-
# the Prefect settings context may not be respected
|
242
|
-
env = {**os_environ, **self._base_environment(), **self.env}
|
243
|
-
|
244
|
-
# Drop null values allowing users to "unset" variables
|
245
|
-
return {key: value for key, value in env.items() if value is not None}
|
246
|
-
|
247
|
-
def _base_flow_run_command(self):
|
248
|
-
return [get_sys_executable(), "-m", "prefect.engine"]
|
249
|
-
|
250
|
-
def get_corresponding_worker_type(self):
|
251
|
-
return "process"
|
252
|
-
|
253
|
-
async def generate_work_pool_base_job_template(self):
|
254
|
-
from prefect.workers.utilities import (
|
255
|
-
get_default_base_job_template_for_infrastructure_type,
|
256
|
-
)
|
257
|
-
|
258
|
-
base_job_template = await get_default_base_job_template_for_infrastructure_type(
|
259
|
-
self.get_corresponding_worker_type(),
|
260
|
-
)
|
261
|
-
assert (
|
262
|
-
base_job_template is not None
|
263
|
-
), "Failed to generate default base job template for Process worker."
|
264
|
-
for key, value in self.dict(exclude_unset=True, exclude_defaults=True).items():
|
265
|
-
if key == "command":
|
266
|
-
base_job_template["variables"]["properties"]["command"][
|
267
|
-
"default"
|
268
|
-
] = shlex.join(value)
|
269
|
-
elif key in [
|
270
|
-
"type",
|
271
|
-
"block_type_slug",
|
272
|
-
"_block_document_id",
|
273
|
-
"_block_document_name",
|
274
|
-
"_is_anonymous",
|
275
|
-
]:
|
276
|
-
continue
|
277
|
-
elif key in base_job_template["variables"]["properties"]:
|
278
|
-
base_job_template["variables"]["properties"][key]["default"] = value
|
279
|
-
else:
|
280
|
-
self.logger.warning(
|
281
|
-
f"Variable {key!r} is not supported by Process work pools."
|
282
|
-
" Skipping."
|
283
|
-
)
|
284
|
-
|
285
|
-
return base_job_template
|
286
|
-
|
287
|
-
|
288
|
-
class ProcessResult(InfrastructureResult):
|
289
|
-
"""Contains information about the final state of a completed process"""
|
prefect/manifests.py
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Manifests are portable descriptions of one or more workflows within a given directory structure.
|
3
|
-
|
4
|
-
They are the foundational building blocks for defining Flow Deployments.
|
5
|
-
"""
|
6
|
-
|
7
|
-
from prefect.pydantic import BaseModel, Field
|
8
|
-
from prefect.utilities.callables import ParameterSchema
|
9
|
-
|
10
|
-
|
11
|
-
class Manifest(BaseModel):
|
12
|
-
"""A JSON representation of a flow."""
|
13
|
-
|
14
|
-
flow_name: str = Field(default=..., description="The name of the flow.")
|
15
|
-
import_path: str = Field(
|
16
|
-
default=..., description="The relative import path for the flow."
|
17
|
-
)
|
18
|
-
parameter_openapi_schema: ParameterSchema = Field(
|
19
|
-
default=..., description="The OpenAPI schema of the flow's parameters."
|
20
|
-
)
|