Skip to content

feat: expose user publish preflight endpoint via workflow client (HYP-829)#950

Closed
rupeshatlan wants to merge 1 commit into
mainfrom
rupesh/hyp-829-user-publish-preflight
Closed

feat: expose user publish preflight endpoint via workflow client (HYP-829)#950
rupeshatlan wants to merge 1 commit into
mainfrom
rupesh/hyp-829-user-publish-preflight

Conversation

@rupeshatlan

Copy link
Copy Markdown
Collaborator

Summary

Adds client.workflow.user_publish_preflight(user_id, connection_qualified_name) to the v9 sync and async workflow clients, wrapping Heracles' POST /workflows/preflight/user-publish-check.

The endpoint verifies the workflow creator's account is enabled and that they may publish (ENTITY_CREATE/UPDATE/DELETE) to the target connection. All checks — including the Keycloak impersonation/token-exchange — run server-side in Heracles, so callers only need their own service-account token; the endpoint is restricted to service-account-* callers on the Heracles side (x-endpoint-type: service-account).

Why

Per @cmgrote's review on atlanhq/application-sdk#1966 ("New Heracles endpoints should be exposed via pyatlan, and then the existing pyatlan bits used for the actual interactions"): the application-sdk's run_publish_preflight Temporal activity — the first activity of every extract workflow (HYP-829) — currently calls this endpoint with raw httpx. With this wrapper the SDK switches to the pyatlan client and inherits its auth handling, observability headers, retries, and pooling.

Deliberately not done client-side via client.impersonate.user + /evaluates: that would require distributing impersonate-any-user credentials (CLIENT_ID/CLIENT_SECRET) to every connector app, including customer-deployed SDR runtimes. Keeping impersonation server-side in Heracles is the security boundary this design preserves (discussion: HYP-829).

Changes (house pattern, +111/-0)

File Change
pyatlan/client/constants.py USER_PUBLISH_PREFLIGHT API constant (EndPoint.HERACLES)
pyatlan/client/common/workflow.py WorkflowUserPublishPreflight shared prepare/process
pyatlan/client/common/__init__.py re-export
pyatlan_v9/client/workflow.py sync user_publish_preflight()
pyatlan_v9/client/aio/workflow.py async user_publish_preflight()
tests/unit/test_workflow_client.py 3 unit tests for the shared logic

Related

Notes for reviewers

  • Files compile; unit tests are pure (no client mock needed) — but I could not execute the suite locally (local Python 3.14 can't import pyatlan's pydantic-v1 models), so relying on CI.
  • v9-only by design (the SDK consumes pyatlan_v9); happy to mirror onto the legacy v1 WorkflowClient if wanted.
  • Method returns the raw verdict dict ({passed, failed_checks, message}); can switch to a typed response model if preferred.

🤖 Generated with Claude Code

…-829)

Adds client.workflow.user_publish_preflight(user_id, connection_qualified_name)
to the v9 sync and async workflow clients, wrapping Heracles'
POST /workflows/preflight/user-publish-check. The endpoint verifies the
workflow creator's account is enabled and that they may publish
(ENTITY_CREATE/UPDATE/DELETE) to the target connection; all checks —
including the Keycloak impersonation — run server-side in Heracles, so
callers only need their own service-account token (the endpoint is
restricted to service-account callers).

Follows the house pattern: API constant in pyatlan/client/constants.py,
shared prepare/process logic in pyatlan/client/common/workflow.py, thin
methods in pyatlan_v9 sync + aio clients. Unit tests cover the shared
prepare_request/process_response logic.

Consumer: atlanhq/application-sdk run_publish_preflight Temporal activity
(first activity of every extract workflow) — per review feedback on
atlanhq/application-sdk#1966 that new Heracles endpoints be exposed via
pyatlan rather than called with raw httpx.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rupeshatlan

Copy link
Copy Markdown
Collaborator Author

Closing for now per HYP-829 final decision: the SDK will not call this endpoint — the Automation Engine calls Heracles directly (own client stack). Can be reopened if a pyatlan consumer appears.

@linear

linear Bot commented Jun 10, 2026

Copy link
Copy Markdown

HYP-829

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant