dagster-omni 0.27.9__tar.gz → 0.27.11__tar.gz

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.

Potentially problematic release.


This version of dagster-omni might be problematic. Click here for more details.

Files changed (21) hide show
  1. {dagster_omni-0.27.9/dagster_omni.egg-info → dagster_omni-0.27.11}/PKG-INFO +2 -2
  2. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/dagster_omni/component.py +37 -60
  3. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/dagster_omni/objects.py +50 -0
  4. dagster_omni-0.27.11/dagster_omni/translation.py +143 -0
  5. dagster_omni-0.27.11/dagster_omni/version.py +1 -0
  6. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/dagster_omni/workspace.py +35 -8
  7. {dagster_omni-0.27.9 → dagster_omni-0.27.11/dagster_omni.egg-info}/PKG-INFO +2 -2
  8. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/dagster_omni.egg-info/SOURCES.txt +1 -0
  9. dagster_omni-0.27.11/dagster_omni.egg-info/requires.txt +2 -0
  10. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/setup.py +1 -1
  11. dagster_omni-0.27.9/dagster_omni/version.py +0 -1
  12. dagster_omni-0.27.9/dagster_omni.egg-info/requires.txt +0 -2
  13. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/LICENSE +0 -0
  14. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/MANIFEST.in +0 -0
  15. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/README.md +0 -0
  16. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/dagster_omni/__init__.py +0 -0
  17. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/dagster_omni/py.typed +0 -0
  18. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/dagster_omni.egg-info/dependency_links.txt +0 -0
  19. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/dagster_omni.egg-info/not-zip-safe +0 -0
  20. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/dagster_omni.egg-info/top_level.txt +0 -0
  21. {dagster_omni-0.27.9 → dagster_omni-0.27.11}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dagster_omni
3
- Version: 0.27.9
3
+ Version: 0.27.11
4
4
  Summary: Package for integrating Omni with Dagster.
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-omni
6
6
  Author: Dagster Labs
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.13
14
14
  Classifier: License :: OSI Approved :: Apache Software License
15
15
  Classifier: Operating System :: OS Independent
16
16
  License-File: LICENSE
17
- Requires-Dist: dagster==1.11.9
17
+ Requires-Dist: dagster==1.11.11
18
18
  Requires-Dist: aiohttp
19
19
  Dynamic: author
20
20
  Dynamic: author-email
@@ -1,64 +1,30 @@
1
1
  import itertools
2
2
  from collections import defaultdict
3
3
  from pathlib import Path
4
- from typing import Optional, Union
4
+ from typing import Optional
5
5
 
6
6
  import dagster as dg
7
7
  from dagster._annotations import preview
8
- from dagster._core.definitions.metadata.metadata_set import NamespacedMetadataSet
9
- from dagster._core.definitions.metadata.metadata_value import UrlMetadataValue
10
8
  from dagster._core.errors import DagsterInvalidDefinitionError
11
9
  from dagster.components.component.state_backed_component import StateBackedComponent
12
- from dagster.components.utils.translation import ResolvedTranslationFn
13
- from dagster_shared.record import record
14
10
  from pydantic import Field
15
- from typing_extensions import Self
16
11
 
17
12
  from dagster_omni.objects import OmniDocument, OmniQuery, OmniWorkspaceData
13
+ from dagster_omni.translation import (
14
+ TRANSLATOR_DATA_METADATA_KEY,
15
+ OmniDocumentMetadataSet,
16
+ OmniTranslatorData,
17
+ ResolvedOmniTranslationFn,
18
+ )
18
19
  from dagster_omni.workspace import OmniWorkspace
19
20
 
20
- _TRANSLATOR_DATA_METADATA_KEY = ".dagster-omni/translator_data"
21
-
22
-
23
- class OmniDocumentMetadataSet(NamespacedMetadataSet):
24
- url: Optional[UrlMetadataValue] = None
25
- document_name: str
26
- document_type: str
27
-
28
- @classmethod
29
- def from_document(cls, workspace: OmniWorkspace, document: OmniDocument) -> Self:
30
- url_str = f"{workspace.base_url.rstrip('/')}/dashboards/{document.identifier}"
31
- return cls(
32
- url=UrlMetadataValue(url_str) if document.has_dashboard else None,
33
- document_name=document.name,
34
- document_type=document.type,
35
- )
36
-
37
- @classmethod
38
- def namespace(cls) -> str:
39
- return "dagster-omni"
40
-
41
-
42
- @record
43
- class OmniTranslatorData:
44
- """Container class for data required to translate an object in an
45
- Omni workspace into a Dagster definition.
46
-
47
- Properties:
48
- obj (Union[OmniDocument, OmniQuery]): The object to translate.
49
- workspace_data (OmniWorkspaceData): Global workspace data.
50
- """
51
-
52
- obj: Union[OmniDocument, OmniQuery]
53
- workspace_data: OmniWorkspaceData
54
-
55
21
 
56
22
  @preview
57
23
  class OmniComponent(StateBackedComponent, dg.Model, dg.Resolvable):
58
24
  workspace: OmniWorkspace = Field(
59
25
  description="Defines configuration for interacting with an Omni instance.",
60
26
  )
61
- translation: Optional[ResolvedTranslationFn[OmniTranslatorData]] = Field(
27
+ translation: Optional[ResolvedOmniTranslationFn] = Field(
62
28
  default=None,
63
29
  description="Defines how to translate an Omni object into an AssetSpec object.",
64
30
  )
@@ -72,49 +38,58 @@ class OmniComponent(StateBackedComponent, dg.Model, dg.Resolvable):
72
38
  """Load state from path using Dagster's deserialization system."""
73
39
  return dg.deserialize_value(state_path.read_text(), OmniWorkspaceData)
74
40
 
75
- def _get_default_asset_spec(self, data: OmniTranslatorData) -> dg.AssetSpec:
41
+ def _get_default_omni_spec(
42
+ self, context: dg.ComponentLoadContext, data: OmniTranslatorData, workspace: OmniWorkspace
43
+ ) -> Optional[dg.AssetSpec]:
76
44
  """Core function for converting an Omni document into an AssetSpec object."""
77
45
  if isinstance(data.obj, OmniDocument):
78
46
  doc = data.obj
79
- deps = [
47
+ maybe_deps = [
80
48
  self.get_asset_spec(
81
- OmniTranslatorData(obj=query, workspace_data=data.workspace_data)
49
+ context, OmniTranslatorData(obj=query, workspace_data=data.workspace_data)
82
50
  )
83
- for query in doc.queries
51
+ for query in data.obj.queries
84
52
  ]
85
53
 
86
54
  prefix = doc.folder.path.split("/") if doc.folder else []
55
+ user = data.workspace_data.get_user(doc.owner.id)
56
+ owner_email = user.primary_email if user else None
57
+
87
58
  return dg.AssetSpec(
88
59
  key=dg.AssetKey([*prefix, doc.name]),
89
60
  group_name=prefix[0].replace("-", "_") if prefix else None,
90
61
  tags={label.name: "" for label in doc.labels},
91
- deps=deps,
62
+ deps=list(filter(None, maybe_deps)),
92
63
  metadata={
93
- **OmniDocumentMetadataSet.from_document(self.workspace, doc),
94
- _TRANSLATOR_DATA_METADATA_KEY: data,
64
+ **OmniDocumentMetadataSet.from_document(workspace, doc),
65
+ TRANSLATOR_DATA_METADATA_KEY: data,
95
66
  },
96
67
  kinds={"omni"},
68
+ owners=[owner_email] if owner_email else None,
97
69
  )
98
- elif isinstance(data.obj, OmniQuery):
70
+ if isinstance(data.obj, OmniQuery):
99
71
  return dg.AssetSpec(key=dg.AssetKey([data.obj.query_config.table]))
100
- else:
101
- raise ValueError(f"Unsupported object type: {type(data.obj)}")
72
+ return None
102
73
 
103
- def get_asset_spec(self, data: OmniTranslatorData) -> dg.AssetSpec:
74
+ def get_asset_spec(
75
+ self, context: dg.ComponentLoadContext, data: OmniTranslatorData
76
+ ) -> Optional[dg.AssetSpec]:
104
77
  """Core function for converting an Omni document into an AssetSpec object."""
105
- base_asset_spec = self._get_default_asset_spec(data)
106
- if self.translation:
78
+ base_asset_spec = self._get_default_omni_spec(context, data, self.workspace)
79
+ if self.translation and base_asset_spec:
107
80
  return self.translation(base_asset_spec, data)
108
81
  else:
109
82
  return base_asset_spec
110
83
 
111
- def _build_asset_specs(self, workspace_data: OmniWorkspaceData) -> list[dg.AssetSpec]:
84
+ def _build_asset_specs(
85
+ self, context: dg.ComponentLoadContext, workspace_data: OmniWorkspaceData
86
+ ) -> list[dg.AssetSpec]:
112
87
  """Invokes the `get_asset_spec` method on all objects in the provided `workspace_data`.
113
88
  Filters out any cases where the asset_spec is `None`, and provides a helpful error
114
89
  message in cases where keys overlap between different documents.
115
90
  """
116
91
  maybe_specs = [
117
- self.get_asset_spec(OmniTranslatorData(obj=doc, workspace_data=workspace_data))
92
+ self.get_asset_spec(context, OmniTranslatorData(obj=doc, workspace_data=workspace_data))
118
93
  for doc in workspace_data.documents
119
94
  ]
120
95
 
@@ -136,8 +111,10 @@ class OmniComponent(StateBackedComponent, dg.Model, dg.Resolvable):
136
111
 
137
112
  return list(itertools.chain.from_iterable(specs_by_key.values()))
138
113
 
139
- def build_defs_from_workspace_data(self, workspace_data: OmniWorkspaceData) -> dg.Definitions:
140
- return dg.Definitions(assets=self._build_asset_specs(workspace_data))
114
+ def build_defs_from_workspace_data(
115
+ self, context: dg.ComponentLoadContext, workspace_data: OmniWorkspaceData
116
+ ) -> dg.Definitions:
117
+ return dg.Definitions(assets=self._build_asset_specs(context, workspace_data))
141
118
 
142
119
  def build_defs_from_state(
143
120
  self, context: dg.ComponentLoadContext, state_path: Optional[Path]
@@ -146,4 +123,4 @@ class OmniComponent(StateBackedComponent, dg.Model, dg.Resolvable):
146
123
  return dg.Definitions()
147
124
 
148
125
  state = self.load_state_from_path(state_path)
149
- return self.build_defs_from_workspace_data(state)
126
+ return self.build_defs_from_workspace_data(context, state)
@@ -1,3 +1,4 @@
1
+ from functools import cached_property
1
2
  from typing import Any, Optional
2
3
 
3
4
  from dagster_shared.record import record
@@ -57,6 +58,8 @@ class OmniDocument:
57
58
  folder: Optional[OmniFolder]
58
59
  labels: list[OmniLabel]
59
60
  queries: list["OmniQuery"]
61
+ favorites: Optional[int] = None
62
+ views: Optional[int] = None
60
63
 
61
64
  @classmethod
62
65
  def from_json(cls, data: dict[str, Any], queries: list["OmniQuery"]) -> "OmniDocument":
@@ -81,6 +84,8 @@ class OmniDocument:
81
84
  folder=folder,
82
85
  labels=labels,
83
86
  queries=queries,
87
+ favorites=data.get("_count", {}).get("favorites", None),
88
+ views=data.get("_count", {}).get("views", None),
84
89
  )
85
90
 
86
91
 
@@ -118,6 +123,42 @@ class OmniQuery:
118
123
  )
119
124
 
120
125
 
126
+ @whitelist_for_serdes
127
+ @record
128
+ class OmniUser:
129
+ """Represents an Omni user with all user information in a single class."""
130
+
131
+ id: str
132
+ name: Optional[str]
133
+ display_name: str
134
+ user_name: str
135
+ active: bool
136
+ primary_email: Optional[str]
137
+ groups: list[str]
138
+ created: str
139
+ last_modified: str
140
+
141
+ @classmethod
142
+ def from_json(cls, data: dict[str, Any]) -> "OmniUser":
143
+ """Create OmniUser from JSON response data."""
144
+ primary_email = next(
145
+ (email["value"] for email in data.get("emails", []) if email["primary"]), None
146
+ )
147
+ groups = [group["display"] for group in data.get("groups", [])]
148
+
149
+ return cls(
150
+ id=data["id"],
151
+ name=data.get("displayName") or data.get("userName") or "",
152
+ display_name=data.get("displayName", ""),
153
+ user_name=data.get("userName", ""),
154
+ active=data.get("active", True),
155
+ primary_email=primary_email,
156
+ groups=groups,
157
+ created=data.get("meta", {}).get("created", ""),
158
+ last_modified=data.get("meta", {}).get("lastModified", ""),
159
+ )
160
+
161
+
121
162
  @whitelist_for_serdes
122
163
  @record
123
164
  class OmniWorkspaceData:
@@ -125,6 +166,15 @@ class OmniWorkspaceData:
125
166
 
126
167
  Properties:
127
168
  documents: list[OmniDocument]
169
+ users: list[OmniUser]
128
170
  """
129
171
 
130
172
  documents: list[OmniDocument]
173
+ users: list[OmniUser]
174
+
175
+ @cached_property
176
+ def _users_by_id(self) -> dict[str, OmniUser]:
177
+ return {user.id: user for user in self.users}
178
+
179
+ def get_user(self, user_id: str) -> Optional[OmniUser]:
180
+ return self._users_by_id.get(user_id)
@@ -0,0 +1,143 @@
1
+ from typing import Annotated, Optional, Union
2
+
3
+ import dateutil
4
+ from dagster._core.definitions.assets.definition.asset_spec import AssetSpec
5
+ from dagster._core.definitions.metadata.metadata_set import NamespacedMetadataSet
6
+ from dagster._core.definitions.metadata.metadata_value import (
7
+ TimestampMetadataValue,
8
+ UrlMetadataValue,
9
+ )
10
+ from dagster.components import Resolvable, Resolver
11
+ from dagster.components.resolved.base import resolve_fields
12
+ from dagster.components.resolved.context import ResolutionContext
13
+ from dagster.components.resolved.core_models import AssetSpecKeyUpdateKwargs, AssetSpecUpdateKwargs
14
+ from dagster.components.utils import TranslatorResolvingInfo
15
+ from dagster.components.utils.translation import TranslationFn, TranslationFnResolver
16
+ from dagster_shared.record import record
17
+ from typing_extensions import Self, TypeAlias
18
+
19
+ from dagster_omni.objects import OmniDocument, OmniQuery, OmniWorkspaceData
20
+ from dagster_omni.workspace import OmniWorkspace
21
+
22
+ TRANSLATOR_DATA_METADATA_KEY = ".dagster-omni/translator_data"
23
+
24
+
25
+ class OmniDocumentMetadataSet(NamespacedMetadataSet):
26
+ """Represents metadata that is captured from an Omni document."""
27
+
28
+ url: Optional[UrlMetadataValue] = None
29
+ owner_name: str
30
+ document_name: str
31
+ document_type: str
32
+ updated_at: TimestampMetadataValue
33
+ favorites: Optional[int] = None
34
+ views: Optional[int] = None
35
+
36
+ @classmethod
37
+ def from_document(cls, workspace: OmniWorkspace, document: OmniDocument) -> Self:
38
+ url_str = f"{workspace.base_url.rstrip('/')}/dashboards/{document.identifier}"
39
+
40
+ return cls(
41
+ url=UrlMetadataValue(url_str) if document.has_dashboard else None,
42
+ document_name=document.name,
43
+ document_type=document.type,
44
+ updated_at=TimestampMetadataValue(
45
+ dateutil.parser.parse(document.updated_at).timestamp()
46
+ ),
47
+ owner_name=document.owner.name,
48
+ favorites=document.favorites,
49
+ views=document.views,
50
+ )
51
+
52
+ @classmethod
53
+ def namespace(cls) -> str:
54
+ return "dagster-omni"
55
+
56
+
57
+ @record
58
+ class OmniTranslatorData:
59
+ """Container class for data required to translate an object in an
60
+ Omni workspace into a Dagster definition.
61
+
62
+ Properties:
63
+ obj (Union[OmniDocument, OmniQuery]): The object to translate.
64
+ workspace_data (OmniWorkspaceData): Global workspace data.
65
+ """
66
+
67
+ obj: Union[OmniDocument, OmniQuery]
68
+ workspace_data: OmniWorkspaceData
69
+
70
+
71
+ def _resolve_multilayer_translation(context: ResolutionContext, model):
72
+ """The Omni translation schema supports defining global transforms
73
+ as well as per-object-type transforms. This resolver composes the
74
+ per-object-type transforms with the global transforms.
75
+ """
76
+ info = TranslatorResolvingInfo(
77
+ asset_attributes=model,
78
+ resolution_context=context,
79
+ model_key="translation",
80
+ )
81
+
82
+ def _translation_fn(base_asset_spec: AssetSpec, data: OmniTranslatorData):
83
+ processed_spec = info.get_asset_spec(
84
+ base_asset_spec,
85
+ {
86
+ "data": data,
87
+ "spec": base_asset_spec,
88
+ },
89
+ )
90
+
91
+ nested_translation_fns = resolve_fields(
92
+ model=model,
93
+ resolved_cls=OmniTranslationArgs,
94
+ context=context.with_scope(
95
+ **{
96
+ "data": data,
97
+ "spec": processed_spec,
98
+ }
99
+ ),
100
+ )
101
+ for_document = nested_translation_fns.get("for_document")
102
+ for_query = nested_translation_fns.get("for_query")
103
+
104
+ if isinstance(data.obj, OmniDocument) and for_document:
105
+ return for_document(processed_spec, data)
106
+ if isinstance(data.obj, OmniQuery) and for_query:
107
+ return for_query(processed_spec, data)
108
+
109
+ return processed_spec
110
+
111
+ return _translation_fn
112
+
113
+
114
+ OmniTranslationFn: TypeAlias = TranslationFn[OmniTranslatorData]
115
+
116
+ ResolvedTargetedOmniTranslationFn = Annotated[
117
+ OmniTranslationFn,
118
+ TranslationFnResolver[OmniTranslatorData](lambda data: {"data": data}),
119
+ ]
120
+
121
+ ResolvedTargetedKeyOnlyOmniTranslationFn = Annotated[
122
+ OmniTranslationFn,
123
+ TranslationFnResolver[OmniTranslatorData](
124
+ lambda data: {"data": data}, model_field_type=AssetSpecKeyUpdateKwargs.model()
125
+ ),
126
+ ]
127
+
128
+
129
+ @record
130
+ class OmniTranslationArgs(AssetSpecUpdateKwargs, Resolvable):
131
+ """Model used to allow per-object-type translation of an Omni object."""
132
+
133
+ for_document: Optional[ResolvedTargetedOmniTranslationFn] = None
134
+ for_query: Optional[ResolvedTargetedKeyOnlyOmniTranslationFn] = None
135
+
136
+
137
+ ResolvedOmniTranslationFn = Annotated[
138
+ OmniTranslationFn,
139
+ Resolver(
140
+ _resolve_multilayer_translation,
141
+ model_field_type=Union[str, OmniTranslationArgs.model()],
142
+ ),
143
+ ]
@@ -0,0 +1 @@
1
+ __version__ = "0.27.11"
@@ -8,7 +8,7 @@ from aiohttp.client_exceptions import ClientResponseError
8
8
  from dagster._utils.backoff import async_backoff, exponential_delay_generator
9
9
  from pydantic import Field
10
10
 
11
- from dagster_omni.objects import OmniDocument, OmniQuery, OmniWorkspaceData
11
+ from dagster_omni.objects import OmniDocument, OmniQuery, OmniUser, OmniWorkspaceData
12
12
 
13
13
 
14
14
  class OmniWorkspace(dg.Resolvable, dg.Model):
@@ -50,7 +50,7 @@ class OmniWorkspace(dg.Resolvable, dg.Model):
50
50
  return isinstance(exc, aiohttp.ClientError)
51
51
 
52
52
  def _build_url(self, endpoint: str) -> str:
53
- return f"{self.base_url.rstrip('/')}/api/v1/{endpoint.lstrip('/')}"
53
+ return f"{self.base_url.rstrip('/')}/{endpoint.lstrip('/')}"
54
54
 
55
55
  async def make_request(
56
56
  self,
@@ -79,7 +79,7 @@ class OmniWorkspace(dg.Resolvable, dg.Model):
79
79
 
80
80
  async def _fetch_document_queries(self, document_identifier: str) -> list[OmniQuery]:
81
81
  """Fetch all queries for a specific document."""
82
- endpoint = f"documents/{document_identifier}/queries"
82
+ endpoint = f"api/v1/documents/{document_identifier}/queries"
83
83
  try:
84
84
  response = await self.make_request(endpoint)
85
85
  return [OmniQuery.from_json(query_data) for query_data in response.get("queries", [])]
@@ -96,7 +96,7 @@ class OmniWorkspace(dg.Resolvable, dg.Model):
96
96
 
97
97
  async def _fetch_documents(self) -> list[OmniDocument]:
98
98
  """Fetch all documents from the Omni API with their queries embedded."""
99
- base_params = {"pageSize": "100"}
99
+ base_params = {"pageSize": "100", "include": "_count"}
100
100
  documents = []
101
101
  next_cursor = None
102
102
 
@@ -105,7 +105,7 @@ class OmniWorkspace(dg.Resolvable, dg.Model):
105
105
  if next_cursor:
106
106
  params["cursor"] = next_cursor
107
107
 
108
- response = await self.make_request("documents", params)
108
+ response = await self.make_request("api/v1/documents", params)
109
109
 
110
110
  # Fan out the requests to fetch queries for each document in parallel
111
111
  coroutines = [
@@ -120,10 +120,37 @@ class OmniWorkspace(dg.Resolvable, dg.Model):
120
120
 
121
121
  return documents
122
122
 
123
+ async def _fetch_users(self) -> list[OmniUser]:
124
+ """Fetch all users from the Omni SCIM API."""
125
+ base_params = {"count": "100"}
126
+ users = []
127
+ start_index = 1
128
+
129
+ while True:
130
+ params = base_params.copy()
131
+ params["startIndex"] = str(start_index)
132
+
133
+ response = await self.make_request("api/scim/v2/users", params)
134
+
135
+ user_resources = response.get("Resources", [])
136
+ if not user_resources:
137
+ break
138
+
139
+ users.extend([OmniUser.from_json(user_data) for user_data in user_resources])
140
+
141
+ # Check if we've received fewer users than requested, indicating we're done
142
+ if len(user_resources) < int(base_params["count"]):
143
+ break
144
+
145
+ start_index += len(user_resources)
146
+
147
+ return users
148
+
123
149
  async def fetch_omni_state(self) -> OmniWorkspaceData:
124
- """Fetch all documents from the Omni API with queries embedded.
150
+ """Fetch all documents and users from the Omni API.
125
151
 
126
152
  This is the main public method for getting complete Omni state.
127
153
  """
128
- documents = await self._fetch_documents()
129
- return OmniWorkspaceData(documents=documents)
154
+ # Fetch documents and users concurrently
155
+ documents, users = await asyncio.gather(self._fetch_documents(), self._fetch_users())
156
+ return OmniWorkspaceData(documents=documents, users=users)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dagster_omni
3
- Version: 0.27.9
3
+ Version: 0.27.11
4
4
  Summary: Package for integrating Omni with Dagster.
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-omni
6
6
  Author: Dagster Labs
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.13
14
14
  Classifier: License :: OSI Approved :: Apache Software License
15
15
  Classifier: Operating System :: OS Independent
16
16
  License-File: LICENSE
17
- Requires-Dist: dagster==1.11.9
17
+ Requires-Dist: dagster==1.11.11
18
18
  Requires-Dist: aiohttp
19
19
  Dynamic: author
20
20
  Dynamic: author-email
@@ -7,6 +7,7 @@ dagster_omni/__init__.py
7
7
  dagster_omni/component.py
8
8
  dagster_omni/objects.py
9
9
  dagster_omni/py.typed
10
+ dagster_omni/translation.py
10
11
  dagster_omni/version.py
11
12
  dagster_omni/workspace.py
12
13
  dagster_omni.egg-info/PKG-INFO
@@ -0,0 +1,2 @@
1
+ dagster==1.11.11
2
+ aiohttp
@@ -34,7 +34,7 @@ setup(
34
34
  packages=find_packages(exclude=["dagster_omni_tests*"]),
35
35
  include_package_data=True,
36
36
  install_requires=[
37
- "dagster==1.11.9",
37
+ "dagster==1.11.11",
38
38
  "aiohttp",
39
39
  ],
40
40
  zip_safe=False,
@@ -1 +0,0 @@
1
- __version__ = "0.27.9"
@@ -1,2 +0,0 @@
1
- dagster==1.11.9
2
- aiohttp
File without changes
File without changes
File without changes