dagster-evidence 0.1.6__py3-none-any.whl → 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,185 @@
1
+ """Evidence.dev project component for Dagster.
2
+
3
+ This module provides the main component class for integrating Evidence.dev
4
+ projects with Dagster, automatically discovering sources and generating assets.
5
+ """
6
+
7
+ from dataclasses import dataclass, field
8
+ from functools import cached_property
9
+ from pathlib import Path
10
+ from typing import Annotated, Optional, Union
11
+
12
+ import dagster as dg
13
+ from dagster._annotations import beta, public
14
+ from dagster.components import Resolvable, Resolver, StateBackedComponent
15
+ from dagster.components.utils.defs_state import (
16
+ DefsStateConfig,
17
+ DefsStateConfigArgs,
18
+ ResolvedDefsStateConfig,
19
+ )
20
+
21
+ from .projects import (
22
+ BaseEvidenceProject,
23
+ EvidenceProjectData,
24
+ EvidenceStudioProjectArgs,
25
+ LocalEvidenceProjectArgs,
26
+ resolve_evidence_project,
27
+ )
28
+ from .sources import EvidenceProjectTranslatorData, EvidenceSourceTranslatorData
29
+ from .translator import DagsterEvidenceTranslator
30
+
31
+
32
+ @beta
33
+ @public
34
+ @dataclass
35
+ class EvidenceProjectComponentV2(StateBackedComponent, Resolvable):
36
+ """Evidence.dev project component with state-backed definitions.
37
+
38
+ This component manages Evidence.dev dashboard projects and their deployments,
39
+ automatically discovering sources and generating Dagster assets for each
40
+ source query and the main project.
41
+
42
+ Attributes:
43
+ evidence_project: Evidence project configuration (local or studio).
44
+ defs_state: Configuration for state management.
45
+
46
+ Example:
47
+
48
+ Basic local project with GitHub Pages deployment:
49
+
50
+ .. code-block:: yaml
51
+
52
+ # defs.yaml
53
+ type: dagster_evidence.EvidenceProjectComponentV2
54
+ attributes:
55
+ evidence_project:
56
+ project_type: local
57
+ project_path: ./my-evidence-project
58
+ project_deployment:
59
+ type: github_pages
60
+ github_repo: my-org/my-dashboard
61
+ branch: gh-pages
62
+
63
+ Local project with custom deployment command:
64
+
65
+ .. code-block:: yaml
66
+
67
+ # defs.yaml
68
+ type: dagster_evidence.EvidenceProjectComponentV2
69
+ attributes:
70
+ evidence_project:
71
+ project_type: local
72
+ project_path: ./my-evidence-project
73
+ project_deployment:
74
+ type: custom
75
+ deploy_command: "rsync -avz build/ user@server:/var/www/dashboard/"
76
+
77
+ Customizing asset specs by subclassing and overriding get_asset_spec:
78
+
79
+ .. code-block:: python
80
+
81
+ from dagster_evidence import (
82
+ EvidenceSourceTranslatorData,
83
+ EvidenceProjectComponentV2,
84
+ )
85
+
86
+ class CustomEvidenceComponent(EvidenceProjectComponentV2):
87
+ def get_asset_spec(self, data):
88
+ spec = super().get_asset_spec(data)
89
+ if isinstance(data, EvidenceSourceTranslatorData):
90
+ return spec.replace_attributes(
91
+ key=spec.key.with_prefix("evidence"),
92
+ )
93
+ return spec
94
+ """
95
+
96
+ evidence_project: Annotated[
97
+ BaseEvidenceProject,
98
+ Resolver(
99
+ resolve_evidence_project,
100
+ model_field_name="evidence_project",
101
+ model_field_type=Union[
102
+ LocalEvidenceProjectArgs.model(), EvidenceStudioProjectArgs.model()
103
+ ],
104
+ description="Evidence project configuration.",
105
+ examples=[],
106
+ ),
107
+ ]
108
+
109
+ defs_state: ResolvedDefsStateConfig = field(
110
+ default_factory=DefsStateConfigArgs.legacy_code_server_snapshots
111
+ )
112
+
113
+ @cached_property
114
+ def _base_translator(self) -> DagsterEvidenceTranslator:
115
+ """Return the translator instance for this component."""
116
+ return DagsterEvidenceTranslator()
117
+
118
+ @public
119
+ def get_asset_spec(
120
+ self, data: Union[EvidenceSourceTranslatorData, EvidenceProjectTranslatorData]
121
+ ) -> Union[dg.AssetSpec, dg.AssetsDefinition]:
122
+ """Get asset spec for an Evidence object using the configured translator.
123
+
124
+ Override this method in a subclass to customize how Evidence sources
125
+ and projects are translated to Dagster AssetSpecs.
126
+
127
+ Args:
128
+ data: Either EvidenceSourceTranslatorData for source queries
129
+ or EvidenceProjectTranslatorData for the main project asset.
130
+
131
+ Returns:
132
+ For source queries: AssetsDefinition with automation condition.
133
+ For project: AssetSpec for the Evidence project.
134
+
135
+ Example:
136
+
137
+ Override this method to add custom metadata:
138
+
139
+ .. code-block:: python
140
+
141
+ from dagster_evidence import EvidenceProjectComponentV2
142
+
143
+ class CustomEvidenceComponent(EvidenceProjectComponentV2):
144
+ def get_asset_spec(self, data):
145
+ spec = super().get_asset_spec(data)
146
+ return spec.replace_attributes(
147
+ metadata={"custom_key": "custom_value"},
148
+ )
149
+ """
150
+ return self._base_translator.get_asset_spec(data)
151
+
152
+ async def write_state_to_path(self, state_path: Path) -> None:
153
+ # Fetch the workspace data
154
+ evidence_project_data = self.evidence_project.parse_evidence_project()
155
+
156
+ # Serialize and write to path
157
+ state_path.write_text(dg.serialize_value(evidence_project_data))
158
+
159
+ @property
160
+ def defs_state_config(self) -> DefsStateConfig:
161
+ default_key = f"{self.__class__.__name__}[{self.evidence_project.get_evidence_project_name()}]"
162
+ return DefsStateConfig.from_args(self.defs_state, default_key=default_key)
163
+
164
+ def build_defs_from_state(
165
+ self, context: dg.ComponentLoadContext, state_path: Optional[Path]
166
+ ) -> dg.Definitions:
167
+ """Builds Dagster definitions from the cached Evidence project state."""
168
+ if state_path is None:
169
+ return dg.Definitions()
170
+
171
+ # Deserialize evidence project data
172
+ evidence_project_data = dg.deserialize_value(
173
+ state_path.read_text(), EvidenceProjectData
174
+ )
175
+
176
+ assets, sensors = self.evidence_project.load_evidence_project_assets(
177
+ evidence_project_data,
178
+ translator=self._base_translator,
179
+ )
180
+
181
+ return dg.Definitions(
182
+ assets=assets,
183
+ sensors=sensors,
184
+ resources={"pipes_subprocess_client": dg.PipesSubprocessClient()},
185
+ )