Skip to content

Commit

Permalink
[graphql] workspaceLocationEntryOrError root resolver (#21523)
Browse files Browse the repository at this point in the history
adds a way to load workspace location entries individually by name 

## How I Tested These Changes

added test
  • Loading branch information
alangenfeld authored Apr 30, 2024
1 parent b694637 commit b8ed5ba
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 54 deletions.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions js_modules/dagster-ui/packages/ui-core/src/graphql/types.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
GrapheneRepository,
GrapheneRepositoryConnection,
GrapheneWorkspace,
GrapheneWorkspaceLocationEntry,
GrapheneWorkspaceLocationStatusEntries,
)
from dagster_graphql.schema.util import ResolveInfo
Expand Down Expand Up @@ -188,3 +189,15 @@ def fetch_location_statuses(
for status_entry in workspace_request_context.get_code_location_statuses()
]
)


def fetch_location_entry(
request_context: WorkspaceRequestContext, name: str
) -> Optional["GrapheneWorkspaceLocationEntry"]:
from ..schema.external import GrapheneWorkspaceLocationEntry

location_entry = request_context.get_location_entry(name)
if location_entry is None:
return None

return GrapheneWorkspaceLocationEntry(location_entry)
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def default_on_exception(
) -> "GraphenePythonError":
from dagster_graphql.schema.errors import GraphenePythonError

# Transform exception in to PythonErron to present to user
# Transform exception in to PythonError to present to user
return GraphenePythonError(serializable_error_info_from_exc_info(exc_info))

# global behavior for how to handle unexpected exceptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,12 @@ class Meta:
name = "RepositoryOrError"


class GrapheneWorkspaceLocationEntryOrError(graphene.Union):
class Meta:
types = (GrapheneWorkspaceLocationEntry, GraphenePythonError)
name = "WorkspaceLocationEntryOrError"


types = [
GrapheneLocationStateChangeEvent,
GrapheneLocationStateChangeEventType,
Expand All @@ -506,4 +512,5 @@ class Meta:
GrapheneRepositoryConnection,
GrapheneRepositoryLocation,
GrapheneRepositoryOrError,
GrapheneWorkspaceLocationEntryOrError,
]
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
from dagster_graphql.schema.env_vars import GrapheneEnvVarWithConsumersListOrError

from ...implementation.external import (
fetch_location_entry,
fetch_location_statuses,
fetch_repositories,
fetch_repository,
Expand Down Expand Up @@ -119,6 +120,7 @@
GrapheneRepositoriesOrError,
GrapheneRepositoryConnection,
GrapheneRepositoryOrError,
GrapheneWorkspaceLocationEntryOrError,
GrapheneWorkspaceLocationStatusEntriesOrError,
GrapheneWorkspaceOrError,
)
Expand Down Expand Up @@ -207,7 +209,13 @@ class Meta:

locationStatusesOrError = graphene.Field(
graphene.NonNull(GrapheneWorkspaceLocationStatusEntriesOrError),
description="Retrieve location status for workspace locations",
description="Retrieve location status for workspace locations.",
)

workspaceLocationEntryOrError = graphene.Field(
GrapheneWorkspaceLocationEntryOrError,
name=graphene.Argument(graphene.NonNull(graphene.String)),
description="Retrieve a workspace entry by name.",
)

pipelineOrError = graphene.Field(
Expand Down Expand Up @@ -591,6 +599,10 @@ def resolve_repositoryOrError(
def resolve_workspaceOrError(self, graphene_info: ResolveInfo):
return fetch_workspace(graphene_info.context)

@capture_error
def resolve_workspaceLocationEntryOrError(self, graphene_info: ResolveInfo, name: str):
return fetch_location_entry(graphene_info.context, name)

@capture_error
def resolve_locationStatusesOrError(self, graphene_info: ResolveInfo):
return fetch_location_statuses(graphene_info.context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,65 +18,74 @@

from .graphql_context_test_suite import GraphQLContextVariant, make_graphql_context_test_suite

WORKSPACE_QUERY = """
query {
workspaceOrError {
__typename
... on Workspace {
locationEntries {
__typename
id
name
locationOrLoadError {
__typename
... on RepositoryLocation {
id
name
repositories {
name
}
isReloadSupported
dagsterLibraryVersions {
name
version
}
}
... on PythonError {
message
stack
errorChain {
error {
message
stack
}
}
}
}
loadStatus
displayMetadata {
key
value
}
updatedTimestamp
featureFlags {
name
enabled
}
LOCATION_ENTRY_FRAGMENT = """
fragment locationEntryFragment on WorkspaceLocationEntry {
__typename
id
name
locationOrLoadError {
__typename
... on RepositoryLocation {
id
name
repositories {
name
}
isReloadSupported
dagsterLibraryVersions {
name
version
}
}
... on PythonError {
message
stack
errorChain {
error {
message
stack
}
}
... on PythonError {
}
}
loadStatus
displayMetadata {
key
value
}
updatedTimestamp
featureFlags {
name
enabled
}
}
"""

WORKSPACE_QUERY = (
"""
query {
workspaceOrError {
__typename
... on Workspace {
locationEntries {
...locationEntryFragment
}
}
... on PythonError {
message
stack
errorChain {
error {
message
stack
errorChain {
error {
message
stack
}
}
}
}
}
}
}
"""
+ LOCATION_ENTRY_FRAGMENT
)

LOCATION_STATUS_QUERY = """
query {
Expand All @@ -98,6 +107,22 @@
}
"""

LOCATION_ENTRY_QUERY = (
"""
query ($name: String!) {
workspaceLocationEntryOrError(name: $name) {
__typename
...locationEntryFragment
... on PythonError {
message
stack
}
}
}
"""
+ LOCATION_ENTRY_FRAGMENT
)


@pytest.fixture(scope="function")
def enable_masking_user_code_errors() -> Any:
Expand Down Expand Up @@ -301,3 +326,34 @@ def test_load_workspace_masked(self, graphql_context, enable_masking_user_code_e
"Search in logs for this error ID for more details"
in failure_node["locationOrLoadError"]["message"]
)

def test_workspace_entry_by_name(self, graphql_context) -> None:
result = execute_dagster_graphql(graphql_context, LOCATION_ENTRY_QUERY, {"name": "test"})
assert result
assert result.data["workspaceLocationEntryOrError"]
assert (
result.data["workspaceLocationEntryOrError"]["__typename"] == "WorkspaceLocationEntry"
)
assert (
result.data["workspaceLocationEntryOrError"]["locationOrLoadError"]["__typename"]
== "RepositoryLocation"
)

result = execute_dagster_graphql(
graphql_context, LOCATION_ENTRY_QUERY, {"name": "does_not_exist"}
)
assert result
assert result.data["workspaceLocationEntryOrError"] is None

with mock.patch(
"dagster_graphql.schema.roots.query.fetch_location_entry",
) as mock_fetch:
mock_fetch.side_effect = Exception("boom")

result = execute_dagster_graphql(
graphql_context, LOCATION_ENTRY_QUERY, {"name": "test"}
)
assert result
assert result.data["workspaceLocationEntryOrError"]
assert result.data["workspaceLocationEntryOrError"]["__typename"] == "PythonError"
assert "boom" in result.data["workspaceLocationEntryOrError"]["message"]

1 comment on commit b8ed5ba

@github-actions
Copy link

Choose a reason for hiding this comment

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

Deploy preview for dagit-core-storybook ready!

✅ Preview
https://dagit-core-storybook-dxduazzfa-elementl.vercel.app

Built with commit b8ed5ba.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.