Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate PrefectAgent and prefect agent command group #12273

Merged
merged 4 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/prefect/_internal/compatibility/deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,34 @@ def wrapper(*args, **kwargs):
return decorator


def deprecated_class(
*,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
stacklevel: int = 2,
help: str = "",
) -> Callable[[T], T]:
def decorator(cls: T):
message = generate_deprecation_message(
name=to_qualified_name(cls),
start_date=start_date,
end_date=end_date,
help=help,
)

original_init = cls.__init__

@functools.wraps(original_init)
def new_init(self, *args, **kwargs):
warnings.warn(message, PrefectDeprecationWarning, stacklevel=stacklevel)
original_init(self, *args, **kwargs)

cls.__init__ = new_init
return cls

return decorator


def deprecated_parameter(
name: str,
*,
Expand Down
20 changes: 14 additions & 6 deletions src/prefect/agent.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
"""
The agent is responsible for checking for flow runs that are ready to run and starting
their execution.
DEPRECATION WARNING:

This module, is deprecated as of version March 2024 and 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/.
Comment on lines +2 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏

"""

import inspect
from typing import AsyncIterator, List, Optional, Set, Union
from uuid import UUID
Expand All @@ -11,7 +16,9 @@
import anyio.to_process
import pendulum

from prefect._internal.compatibility.experimental import experimental_parameter
from prefect._internal.compatibility.deprecated import (
deprecated_class,
)
from prefect.blocks.core import Block
from prefect.client.orchestration import PrefectClient, get_client
from prefect.client.schemas.filters import (
Expand Down Expand Up @@ -44,10 +51,11 @@
from prefect.states import Crashed, Pending, StateType, exception_to_failed_state


@deprecated_class(
start_date="Mar 2024",
help="Use a worker instead. Refer to the upgrade guide for more information: https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/.",
)
class PrefectAgent:
@experimental_parameter(
"work_pool_name", group="work_pools", when=lambda y: y is not None
)
serinamarie marked this conversation as resolved.
Show resolved Hide resolved
def __init__(
self,
work_queues: List[str] = None,
Expand Down
8 changes: 7 additions & 1 deletion src/prefect/cli/agent.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Command line interface for working with agent services
"""

import os
from functools import partial
from typing import List
Expand All @@ -25,7 +26,12 @@
from prefect.utilities.services import critical_service_loop

agent_app = PrefectTyper(
name="agent", help="Commands for starting and interacting with agent processes."
name="agent",
help="Commands for starting and interacting with agent processes.",
deprecated=True,
deprecated_name="agent",
deprecated_start_date="Mar 2024",
deprecated_help="Use `prefect worker start` instead. Refer to the upgrade guide for more information: https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/. ",
)
app.add_typer(agent_app)

Expand Down
18 changes: 18 additions & 0 deletions tests/_internal/compatibility/test_deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from prefect._internal.compatibility.deprecated import (
PrefectDeprecationWarning,
deprecated_callable,
deprecated_class,
deprecated_field,
deprecated_parameter,
generate_deprecation_message,
Expand Down Expand Up @@ -173,3 +174,20 @@ class Foo(pydantic.BaseModel):
),
):
Foo(x=10)


def test_deprecated_class():
@deprecated_class(start_date="Jan 2022", help="test help")
class MyClass:
def __init__(self):
pass

with pytest.warns(
PrefectDeprecationWarning,
match=(
"MyClass has been deprecated. It will not be available after Jul 2022."
" test help"
),
):
obj = MyClass()
assert isinstance(obj, MyClass)
14 changes: 14 additions & 0 deletions tests/agent/test_agent_deprecation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest

from prefect._internal.compatibility.deprecated import PrefectDeprecationWarning
from prefect.agent import PrefectAgent


def test_agent_emits_deprecation_warning():
with pytest.warns(
PrefectDeprecationWarning,
match=(
"prefect.agent.PrefectAgent has been deprecated. It will not be available after Sep 2024. Use a worker instead. Refer to the upgrade guide for more information"
),
):
PrefectAgent()
30 changes: 29 additions & 1 deletion tests/cli/test_agent.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,45 @@
import warnings
from unittest.mock import ANY

import pytest

import prefect.cli.agent
from prefect import PrefectClient
from prefect._internal.compatibility.deprecated import PrefectDeprecationWarning
from prefect.settings import PREFECT_AGENT_PREFETCH_SECONDS, temporary_settings
from prefect.testing.cli import invoke_and_assert
from prefect.testing.utilities import MagicMock
from prefect.utilities.asyncutils import run_sync_in_worker_thread


@pytest.fixture(autouse=True)
def ignore_agent_deprecation_warnings():
"""
Ignore deprecation warnings from the agent module to avoid
test failures.
"""
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=PrefectDeprecationWarning)
yield
serinamarie marked this conversation as resolved.
Show resolved Hide resolved


def test_start_agent_emits_deprecation_warning():
invoke_and_assert(
command=["agent", "start", "--run-once", "-q", "test"],
expected_code=0,
expected_output_contains=[
"The 'agent' command group has been deprecated.",
"It will not be available after Sep 2024.",
" Use `prefect worker start` instead.",
" Refer to the upgrade guide for more information",
],
)


def test_start_agent_with_no_args():
invoke_and_assert(
command=["agent", "start"],
expected_output="No work queues provided!",
expected_output_contains="No work queues provided!",
expected_code=1,
)

Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
from .fixtures.client import *
from .fixtures.collections_registry import *
from .fixtures.database import *
from .fixtures.deprecation import *
from .fixtures.docker import *
from .fixtures.logging import *
from .fixtures.storage import *
Expand Down
22 changes: 22 additions & 0 deletions tests/fixtures/deprecation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
Fixture to ignore our own deprecation warnings.

Deprecations should be specifically tested to ensure they are emitted as expected.
"""

import warnings

import pytest

from prefect._internal.compatibility.deprecated import PrefectDeprecationWarning


@pytest.fixture(autouse=True)
def ignore_prefect_deprecation_warnings():
"""
Ignore deprecation warnings from the agent module to avoid
test failures.
"""
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=PrefectDeprecationWarning)
yield