diff --git a/src/prefect/agent.py b/src/prefect/agent.py index 4a8846c1c60d..e4c3f6c428c2 100644 --- a/src/prefect/agent.py +++ b/src/prefect/agent.py @@ -1,7 +1,7 @@ """ DEPRECATION WARNING: -This module, is deprecated as of version March 2024 and not be available after September 2024. +This module is deprecated as of March 2024 and will not be available after September 2024. Agents have been replaced by workers, which offer enhanced functionality and better performance. For upgrade instructions, see https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/. diff --git a/src/prefect/infrastructure/base.py b/src/prefect/infrastructure/base.py index c4ac70036d14..789e6686464f 100644 --- a/src/prefect/infrastructure/base.py +++ b/src/prefect/infrastructure/base.py @@ -1,3 +1,11 @@ +""" +DEPRECATION WARNING: + +This module is deprecated as of March 2024 and will not be available after September 2024. +Infrastructure blocks have been replaced by workers, which offer enhanced functionality and better performance. + +For upgrade instructions, see https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/. +""" import abc import shlex import warnings @@ -5,6 +13,7 @@ import anyio.abc +from prefect._internal.compatibility.deprecated import deprecated_class from prefect._internal.compatibility.experimental import ( EXPERIMENTAL_WARNING, ExperimentalFeature, @@ -48,6 +57,12 @@ def __bool__(self): return self.status_code == 0 +@deprecated_class( + start_date="Mar 2024", + help="Use the `BaseWorker` class to create custom infrastructure integrations instead." + " Refer to the upgrade guide for more information:" + " https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/.", +) class Infrastructure(Block, abc.ABC): _block_schema_capabilities = ["run-infrastructure"] diff --git a/src/prefect/infrastructure/container.py b/src/prefect/infrastructure/container.py index 0f0e23e4d0bf..838101858c3e 100644 --- a/src/prefect/infrastructure/container.py +++ b/src/prefect/infrastructure/container.py @@ -1,3 +1,11 @@ +""" +DEPRECATION WARNING: + +This module is deprecated as of March 2024 and will not be available after September 2024. +It has been replaced by the Docker worker from the prefect-docker package, which offers enhanced functionality and better performance. + +For upgrade instructions, see https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/. +""" import json import re import shlex @@ -10,6 +18,7 @@ import anyio.abc import packaging.version +from prefect._internal.compatibility.deprecated import deprecated_class from prefect._internal.pydantic import HAS_PYDANTIC_V2 if HAS_PYDANTIC_V2: @@ -54,6 +63,10 @@ class ImagePullPolicy(AutoEnum): NEVER = AutoEnum.auto() +@deprecated_class( + start_date="Mar 2024", + help="Use the `DockerRegistryCredentials` class from prefect-docker instead.", +) class BaseDockerLogin(Block, ABC): _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/14a315b79990200db7341e42553e23650b34bb96-250x250.png" _block_schema_capabilities = ["docker-login"] @@ -105,6 +118,10 @@ def _get_docker_client(): return docker_client +@deprecated_class( + start_date="Mar 2024", + help="Use the `DockerRegistryCredentials` class from prefect-docker instead.", +) class DockerRegistry(BaseDockerLogin): """ Connects to a Docker registry. @@ -170,6 +187,12 @@ class DockerContainerResult(InfrastructureResult): """Contains information about a completed Docker container""" +@deprecated_class( + start_date="Mar 2024", + help="Use the Docker worker from prefect-docker instead." + " Refer to the upgrade guide for more information:" + " https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/.", +) class DockerContainer(Infrastructure): """ Runs a command in a container. diff --git a/src/prefect/infrastructure/kubernetes.py b/src/prefect/infrastructure/kubernetes.py index 45418134507c..41167a8130c1 100644 --- a/src/prefect/infrastructure/kubernetes.py +++ b/src/prefect/infrastructure/kubernetes.py @@ -1,3 +1,11 @@ +""" +DEPRECATION WARNING: + +This module is deprecated as of March 2024 and will not be available after September 2024. +It has been replaced by the Kubernetes worker from the prefect-kubernetes package, which offers enhanced functionality and better performance. + +For upgrade instructions, see https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/. +""" import copy import enum import json @@ -11,6 +19,9 @@ import anyio.abc import yaml +from prefect._internal.compatibility.deprecated import ( + deprecated_class, +) from prefect._internal.pydantic import HAS_PYDANTIC_V2 if HAS_PYDANTIC_V2: @@ -58,6 +69,12 @@ class KubernetesJobResult(InfrastructureResult): """Contains information about the final state of a completed Kubernetes Job""" +@deprecated_class( + start_date="Mar 2024", + help="Use the Kubernetes worker from prefect-kubernetes instead." + " Refer to the upgrade guide for more information:" + " https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/.", +) class KubernetesJob(Infrastructure): """ Runs a command as a Kubernetes Job. diff --git a/src/prefect/infrastructure/process.py b/src/prefect/infrastructure/process.py index c600778ba7cb..0ee8079f0097 100644 --- a/src/prefect/infrastructure/process.py +++ b/src/prefect/infrastructure/process.py @@ -1,3 +1,12 @@ +""" +DEPRECATION WARNING: + +This module is deprecated as of March 2024 and will not be available after September 2024. +It has been replaced by the process worker from the `prefect.workers` module, which offers enhanced functionality and better performance. + +For upgrade instructions, see https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/. +""" + import asyncio import contextlib import os @@ -14,6 +23,7 @@ import anyio.abc import sniffio +from prefect._internal.compatibility.deprecated import deprecated_class from prefect._internal.pydantic import HAS_PYDANTIC_V2 if HAS_PYDANTIC_V2: @@ -57,6 +67,12 @@ def _parse_infrastructure_pid(infrastructure_pid: str) -> Tuple[str, int]: return hostname, int(pid) +@deprecated_class( + start_date="Mar 2024", + help="Use the process worker instead." + " Refer to the upgrade guide for more information:" + " https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/.", +) class Process(Infrastructure): """ Run a command in a new process. diff --git a/src/prefect/testing/utilities.py b/src/prefect/testing/utilities.py index 33ec298e5904..8eccb5ae2d89 100644 --- a/src/prefect/testing/utilities.py +++ b/src/prefect/testing/utilities.py @@ -1,6 +1,7 @@ -"""" +""" Internal utilities for tests. """ + import sys import warnings from contextlib import ExitStack, contextmanager @@ -119,12 +120,19 @@ def kubernetes_environments_equal( @contextmanager -def assert_does_not_warn(): +def assert_does_not_warn(ignore_warnings=[]): """ - Converts warnings to errors within this context to assert warnings are not raised. + Converts warnings to errors within this context to assert warnings are not raised, + except for those specified in ignore_warnings. + + Parameters: + - ignore_warnings: List of warning types to ignore. Example: [DeprecationWarning, UserWarning] """ with warnings.catch_warnings(): warnings.simplefilter("error") + for warning_type in ignore_warnings: + warnings.filterwarnings("ignore", category=warning_type) + try: yield except Warning as warning: diff --git a/tests/conftest.py b/tests/conftest.py index 0136d2ecb6c3..8ec04ffb2505 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,6 +16,7 @@ fixture, a sync fixture must be defined that consumes the async fixture to perform the settings context change. See `test_database_connection_url` for example. """ + import asyncio import logging import pathlib diff --git a/tests/infrastructure/test_docker_container.py b/tests/infrastructure/test_docker_container.py index d73a346cbb1f..647d7dae1b6e 100644 --- a/tests/infrastructure/test_docker_container.py +++ b/tests/infrastructure/test_docker_container.py @@ -8,6 +8,7 @@ import docker import pytest +from prefect._internal.compatibility.deprecated import PrefectDeprecationWarning from prefect.exceptions import InfrastructureNotAvailable, InfrastructureNotFound from prefect.infrastructure.container import ( CONTAINER_LABELS, @@ -499,7 +500,7 @@ def test_warns_at_runtime_when_using_host_network_mode_on_non_linux_platform( ): monkeypatch.setattr("sys.platform", "darwin") - with assert_does_not_warn(): + with assert_does_not_warn(ignore_warnings=[PrefectDeprecationWarning]): runner = DockerContainer( command=["echo", "hello"], network_mode="host", @@ -697,7 +698,7 @@ def test_does_not_warn_about_gateway_if_user_has_provided_nonlocal_api_url( monkeypatch.setattr("sys.platform", "linux") mock_docker_client.version.return_value = {"Version": "19.1.1"} - with assert_does_not_warn(): + with assert_does_not_warn(ignore_warnings=[PrefectDeprecationWarning]): DockerContainer( command=["echo", "hello"], env={"PREFECT_API_URL": "http://my-domain.test/api"}, @@ -736,7 +737,7 @@ def test_does_not_warn_about_gateway_if_not_using_linux( monkeypatch.setattr("sys.platform", platform) mock_docker_client.version.return_value = {"Version": "19.1.1"} - with assert_does_not_warn(): + with assert_does_not_warn(ignore_warnings=[PrefectDeprecationWarning]): DockerContainer( command=["echo", "hello"], ).run() diff --git a/tests/infrastructure/test_infra_block_deprecation.py b/tests/infrastructure/test_infra_block_deprecation.py new file mode 100644 index 000000000000..ab2eb913249a --- /dev/null +++ b/tests/infrastructure/test_infra_block_deprecation.py @@ -0,0 +1,74 @@ +import pytest +from anyio.abc._tasks import TaskStatus + +from prefect._internal.compatibility.deprecated import PrefectDeprecationWarning +from prefect.infrastructure.base import Infrastructure, InfrastructureResult +from prefect.infrastructure.container import ( + DockerContainer, + DockerRegistry, +) +from prefect.infrastructure.kubernetes import KubernetesJob +from prefect.infrastructure.process import Process + + +class PretendInfrastructure(Infrastructure): + type = "Pretend" + + async def run(self, task_status: TaskStatus = None) -> InfrastructureResult: + return await super().run(task_status) + + async def kill_infrastructure(self) -> None: + await super().kill_infrastructure() + + def preview(self) -> str: + return super().preview() + + +@pytest.mark.parametrize( + "InfraBlock, expected_message", + [ + ( + PretendInfrastructure, + "prefect.infrastructure.base.Infrastructure has been deprecated." + " It will not be available after Sep 2024." + " Use the `BaseWorker` class to create custom infrastructure integrations instead." + " Refer to the upgrade guide for more information", + ), + ( + KubernetesJob, + "prefect.infrastructure.kubernetes.KubernetesJob has been deprecated." + " It will not be available after Sep 2024." + " Use the Kubernetes worker from prefect-kubernetes instead." + " Refer to the upgrade guide for more information", + ), + ( + DockerContainer, + "prefect.infrastructure.container.DockerContainer has been deprecated." + " It will not be available after Sep 2024." + " Use the Docker worker from prefect-docker instead." + " Refer to the upgrade guide for more information", + ), + ( + Process, + "prefect.infrastructure.process.Process has been deprecated." + " It will not be available after Sep 2024." + " Use the process worker instead." + " Refer to the upgrade guide for more information", + ), + ], +) +def test_infra_blocks_emit_a_deprecation_warning(InfraBlock, expected_message): + with pytest.warns(PrefectDeprecationWarning, match=expected_message): + InfraBlock() + + +def test_docker_registry_emits_a_deprecation_warning(): + with pytest.warns( + PrefectDeprecationWarning, + match=( + "prefect.infrastructure.container.DockerRegistry has been deprecated." + " It will not be available after Sep 2024." + " Use the `DockerRegistryCredentials` class from prefect-docker instead." + ), + ): + DockerRegistry(username="foo", password="bar", registry_url="baz") diff --git a/tests/infrastructure/test_process.py b/tests/infrastructure/test_process.py index a914bdbf60bb..307d53d050b5 100644 --- a/tests/infrastructure/test_process.py +++ b/tests/infrastructure/test_process.py @@ -488,11 +488,11 @@ def test_unix_process_run_does_not_set_creation_flag(monkeypatch): @pytest.mark.parametrize( - "process,expected_template", + "kwargs,expected_template", [ - (Process(), default_base_job_template), + ({}, default_base_job_template), ( - Process( + dict( command=["python", "my_script.py"], env={"VAR1": "value1", "VAR2": "value2"}, labels={"label1": "value1", "label2": "value2"}, @@ -504,7 +504,7 @@ def test_unix_process_run_does_not_set_creation_flag(monkeypatch): ), ], ) -async def test_generate_work_pool_base_job_template(process, expected_template): - template = await process.generate_work_pool_base_job_template() +async def test_generate_work_pool_base_job_template(kwargs, expected_template): + template = await Process(**kwargs).generate_work_pool_base_job_template() assert template == expected_template