Skip to content
Open
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
8 changes: 4 additions & 4 deletions src/prefect/server/api/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ class BaseClient:
_http_client: PrefectHttpxAsyncClient

def __init__(self, additional_headers: dict[str, str] | None = None):
from prefect.server.api.server import create_app
from prefect.server.api.server import create_api_app

additional_headers = additional_headers or {}

# create_app caches application instances, and invoking it with no arguments
# will point it to the the currently running server instance
api_app = create_app()
# create_api_app creates only the API routes without UI or background
# services, which is all OrchestrationClient needs for in-process calls.
api_app = create_api_app()

settings = get_current_settings()

Expand Down
7 changes: 7 additions & 0 deletions src/prefect/server/events/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1811,6 +1811,13 @@ async def message_handler(message: Message):
except ActionFailed as e:
# ActionFailed errors are expected errors and will not be retried
await action.fail(triggered_action, e.reason)
except Exception:
logger.exception(
"Unexpected error executing action %s for automation %s",
triggered_action.id,
triggered_action.automation.id,
)
raise
else:
await action.succeed(triggered_action)
await record_action_happening(triggered_action.id)
Expand Down
16 changes: 15 additions & 1 deletion tests/server/api/test_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from sqlalchemy.ext.asyncio import AsyncSession

from prefect.server.api.clients import OrchestrationClient
from prefect.server.api.server import create_app
from prefect.server.api.server import create_api_app, create_app
from prefect.server.models import deployments, flow_runs, flows
from prefect.server.models.variables import create_variable
from prefect.server.schemas.actions import VariableCreate
Expand Down Expand Up @@ -260,6 +260,20 @@ async def test_read_variables_with_error(orchestration_client: OrchestrationClie
await orchestration_client.read_workspace_variables()


async def test_orchestration_client_uses_api_app():
"""
Regression test for https://github.com/PrefectHQ/prefect/issues/19317

OrchestrationClient should use create_api_app instead of create_app to avoid
UI static file creation and background services that fail in read-only containers.
"""
with mock.patch(
"prefect.server.api.server.create_api_app", wraps=create_api_app
) as mock_create_api_app:
OrchestrationClient()
mock_create_api_app.assert_called_once()


async def test_get_orchestration_client_after_create_app_final():
"""
Regression test for https://github.com/PrefectHQ/prefect/issues/17451
Expand Down
Loading