Skip to content

Commit 508cca6

Browse files
authored
[gql] Add boolean endpoint for whether a location has integrated docs (#29216)
## Summary Adds a boolean `hasLocationDocs` endpoint which returns whether a location has integrated docs. Nested under `GrapheneRepository`, along with moving the endpoint from #29167 ## How I Tested These Changes Update unit test.
1 parent 76408dc commit 508cca6

File tree

6 files changed

+117
-66
lines changed

6 files changed

+117
-66
lines changed

Diff for: js_modules/dagster-ui/packages/ui-core/src/graphql/possibleTypes.generated.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: js_modules/dagster-ui/packages/ui-core/src/graphql/schema.graphql

+10-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: js_modules/dagster-ui/packages/ui-core/src/graphql/types.ts

+10-11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: python_modules/dagster-graphql/dagster_graphql/schema/external.py

+43-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import asyncio
2-
from typing import TYPE_CHECKING, Optional
2+
from typing import TYPE_CHECKING, Optional, cast
33

44
import graphene
55
from dagster import _check as check
@@ -19,10 +19,16 @@
1919
from dagster._core.remote_representation.handle import RepositoryHandle
2020
from dagster._core.workspace.context import WorkspaceProcessContext
2121
from dagster._core.workspace.workspace import CodeLocationEntry, CodeLocationLoadStatus
22+
from dagster.components.core.load_defs import PLUGIN_COMPONENT_TYPES_JSON_METADATA_KEY
2223

2324
from dagster_graphql.implementation.fetch_solids import get_solid, get_solids
2425
from dagster_graphql.implementation.loader import RepositoryScopedBatchLoader, StaleStatusLoader
26+
from dagster_graphql.implementation.utils import capture_error
2527
from dagster_graphql.schema.asset_graph import GrapheneAssetGroup, GrapheneAssetNode
28+
from dagster_graphql.schema.env_vars import (
29+
GrapheneLocationDocsJson,
30+
GrapheneLocationDocsJsonOrError,
31+
)
2632
from dagster_graphql.schema.errors import GraphenePythonError, GrapheneRepositoryNotFoundError
2733
from dagster_graphql.schema.partition_sets import GraphenePartitionSet
2834
from dagster_graphql.schema.permissions import GraphenePermission
@@ -265,6 +271,15 @@ class GrapheneRepository(graphene.ObjectType):
265271
displayMetadata = non_null_list(GrapheneRepositoryMetadata)
266272
assetGroups = non_null_list(GrapheneAssetGroup)
267273
allTopLevelResourceDetails = non_null_list(GrapheneResourceDetails)
274+
hasLocationDocs = graphene.Field(
275+
graphene.NonNull(graphene.Boolean),
276+
description="Retrieves whether the code location has integrated docs.",
277+
)
278+
279+
locationDocsJsonOrError = graphene.Field(
280+
graphene.NonNull(GrapheneLocationDocsJsonOrError),
281+
description="Retrieves JSON blob to drive integrated code location docs.",
282+
)
268283

269284
class Meta:
270285
name = "Repository"
@@ -420,6 +435,33 @@ def resolve_allTopLevelResourceDetails(self, graphene_info) -> list[GrapheneReso
420435
if resource.is_top_level
421436
]
422437

438+
def resolve_hasLocationDocs(self, graphene_info: ResolveInfo):
439+
repository = self.get_repository(graphene_info)
440+
441+
return bool(
442+
repository.repository_snap.metadata
443+
and repository.repository_snap.metadata.get(PLUGIN_COMPONENT_TYPES_JSON_METADATA_KEY)
444+
)
445+
446+
@capture_error
447+
def resolve_locationDocsJsonOrError(
448+
self,
449+
graphene_info: ResolveInfo,
450+
) -> GrapheneLocationDocsJson:
451+
repository = self.get_repository(graphene_info)
452+
plugin_docs_json = (
453+
cast(
454+
list,
455+
repository.repository_snap.metadata.get(
456+
PLUGIN_COMPONENT_TYPES_JSON_METADATA_KEY, [[]]
457+
),
458+
)[0]
459+
if repository.repository_snap.metadata
460+
else []
461+
)
462+
463+
return GrapheneLocationDocsJson(json=plugin_docs_json)
464+
423465

424466
class GrapheneRepositoryConnection(graphene.ObjectType):
425467
nodes = non_null_list(GrapheneRepository)

Diff for: python_modules/dagster-graphql/dagster_graphql/schema/roots/query.py

+1-33
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from dagster._core.scheduler.instigation import InstigatorStatus, InstigatorType
2222
from dagster._core.storage.event_log.base import AssetRecord
2323
from dagster._core.workspace.permissions import Permissions
24-
from dagster.components.core.load_defs import PLUGIN_COMPONENT_TYPES_JSON_METADATA_KEY
2524

2625
from dagster_graphql.implementation.execution.backfill import get_asset_backfill_preview
2726
from dagster_graphql.implementation.external import (
@@ -119,11 +118,7 @@
119118
GraphenePartitionBackfillsOrError,
120119
)
121120
from dagster_graphql.schema.entity_key import GrapheneAssetKey
122-
from dagster_graphql.schema.env_vars import (
123-
GrapheneEnvVarWithConsumersListOrError,
124-
GrapheneLocationDocsJson,
125-
GrapheneLocationDocsJsonOrError,
126-
)
121+
from dagster_graphql.schema.env_vars import GrapheneEnvVarWithConsumersListOrError
127122
from dagster_graphql.schema.external import (
128123
GrapheneRepositoriesOrError,
129124
GrapheneRepositoryConnection,
@@ -317,12 +312,6 @@ class Meta:
317312
description="Retrieve all the utilized environment variables for the given repo.",
318313
)
319314

320-
locationDocsJsonOrError = graphene.Field(
321-
graphene.NonNull(GrapheneLocationDocsJsonOrError),
322-
repositorySelector=graphene.NonNull(GrapheneRepositorySelector),
323-
description="Retrieves JSON blob to drive integrated code location docs.",
324-
)
325-
326315
sensorOrError = graphene.Field(
327316
graphene.NonNull(GrapheneSensorOrError),
328317
sensorSelector=graphene.NonNull(GrapheneSensorSelector),
@@ -778,27 +767,6 @@ def resolve_utilizedEnvVarsOrError(self, graphene_info: ResolveInfo, **kwargs):
778767
RepositorySelector.from_graphql_input(kwargs.get("repositorySelector")),
779768
)
780769

781-
@capture_error
782-
def resolve_locationDocsJsonOrError(
783-
self, graphene_info: ResolveInfo, repositorySelector: GrapheneRepositorySelector
784-
) -> GrapheneLocationDocsJson:
785-
repo_selector = RepositorySelector.from_graphql_input(repositorySelector)
786-
787-
location = graphene_info.context.get_code_location(repo_selector.location_name)
788-
repository = location.get_repository(repo_selector.repository_name)
789-
plugin_docs_json = (
790-
cast(
791-
list,
792-
repository.repository_snap.metadata.get(
793-
PLUGIN_COMPONENT_TYPES_JSON_METADATA_KEY, [[]]
794-
),
795-
)[0]
796-
if repository.repository_snap.metadata
797-
else []
798-
)
799-
800-
return GrapheneLocationDocsJson(json=plugin_docs_json)
801-
802770
@capture_error
803771
def resolve_sensorOrError(
804772
self, graphene_info: ResolveInfo, sensorSelector: GrapheneRepositorySelector

Diff for: python_modules/dagster-graphql/dagster_graphql_tests/graphql/components/test_dg_docs_json.py

+52-11
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111

1212
ensure_dagster_tests_import()
1313

14-
GET_DOCS_JSON_QUERY = """
15-
query GetDocsJson {
16-
locationDocsJsonOrError(repositorySelector: {repositoryLocationName: "test_location", repositoryName: "__repository__"}) {
14+
GET_HAS_LOCATION_DOCS_QUERY = """
15+
query GetHasLocationDocs {
16+
repositoryOrError(repositorySelector: {repositoryLocationName: "test_location", repositoryName: "__repository__"}) {
1717
__typename
18-
... on LocationDocsJson {
19-
json
18+
... on Repository {
19+
hasLocationDocs
2020
}
2121
... on PythonError {
2222
message
@@ -25,6 +25,25 @@
2525
}
2626
"""
2727

28+
GET_DOCS_JSON_QUERY = """
29+
query GetDocsJson {
30+
repositoryOrError(repositorySelector: {repositoryLocationName: "test_location", repositoryName: "__repository__"}) {
31+
__typename
32+
... on Repository {
33+
locationDocsJsonOrError {
34+
__typename
35+
... on LocationDocsJson {
36+
json
37+
}
38+
... on PythonError {
39+
message
40+
}
41+
}
42+
}
43+
}
44+
}
45+
"""
46+
2847

2948
def get_empty_repo() -> RepositoryDefinition:
3049
return Definitions().get_repository_def()
@@ -35,13 +54,24 @@ def test_get_empty_docs_json():
3554
instance_for_test() as instance,
3655
define_out_of_process_context(__file__, "get_empty_repo", instance) as context,
3756
):
57+
has_location_docs_result = execute_dagster_graphql(context, GET_HAS_LOCATION_DOCS_QUERY)
58+
assert has_location_docs_result.data["repositoryOrError"]["__typename"] == "Repository"
59+
assert has_location_docs_result.data["repositoryOrError"]["hasLocationDocs"] is False
60+
3861
get_docs_json_result = execute_dagster_graphql(context, GET_DOCS_JSON_QUERY)
62+
assert get_docs_json_result.data["repositoryOrError"]["__typename"] == "Repository"
3963
assert (
40-
get_docs_json_result.data["locationDocsJsonOrError"]["__typename"] == "LocationDocsJson"
64+
get_docs_json_result.data["repositoryOrError"]["locationDocsJsonOrError"]["__typename"]
65+
== "LocationDocsJson"
66+
)
67+
assert (
68+
get_docs_json_result.data["repositoryOrError"]["locationDocsJsonOrError"]["json"]
69+
is not None
4170
)
42-
assert get_docs_json_result.data["locationDocsJsonOrError"]["json"] is not None
4371

44-
json_contents = json.loads(get_docs_json_result.data["locationDocsJsonOrError"]["json"])
72+
json_contents = json.loads(
73+
get_docs_json_result.data["repositoryOrError"]["locationDocsJsonOrError"]["json"]
74+
)
4575
assert len(json_contents) == 0
4676

4777

@@ -71,12 +101,23 @@ def test_get_docs_json():
71101
instance_for_test() as instance,
72102
define_out_of_process_context(__file__, "get_components_repo", instance) as context,
73103
):
104+
has_location_docs_result = execute_dagster_graphql(context, GET_HAS_LOCATION_DOCS_QUERY)
105+
assert has_location_docs_result.data["repositoryOrError"]["__typename"] == "Repository"
106+
assert has_location_docs_result.data["repositoryOrError"]["hasLocationDocs"] is True
107+
74108
get_docs_json_result = execute_dagster_graphql(context, GET_DOCS_JSON_QUERY)
109+
assert get_docs_json_result.data["repositoryOrError"]["__typename"] == "Repository"
110+
assert (
111+
get_docs_json_result.data["repositoryOrError"]["locationDocsJsonOrError"]["__typename"]
112+
== "LocationDocsJson"
113+
)
75114
assert (
76-
get_docs_json_result.data["locationDocsJsonOrError"]["__typename"] == "LocationDocsJson"
115+
get_docs_json_result.data["repositoryOrError"]["locationDocsJsonOrError"]["json"]
116+
is not None
77117
)
78-
assert get_docs_json_result.data["locationDocsJsonOrError"]["json"] is not None
79118

80-
json_contents = json.loads(get_docs_json_result.data["locationDocsJsonOrError"]["json"])
119+
json_contents = json.loads(
120+
get_docs_json_result.data["repositoryOrError"]["locationDocsJsonOrError"]["json"]
121+
)
81122
assert len(json_contents) == 1
82123
assert json_contents[0]["name"] == "dagster_test"

0 commit comments

Comments
 (0)