dagster-shared 1.11.8__py3-none-any.whl → 1.11.9__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.
@@ -67,6 +67,64 @@ class DagsterPlusCliConfig:
67
67
  _, _, raw_plus_config, _ = result
68
68
  return cls(**raw_plus_config)
69
69
 
70
+ @classmethod
71
+ def create_for_deployment(
72
+ cls,
73
+ deployment: Optional[str],
74
+ organization: Optional[str] = None,
75
+ user_token: Optional[str] = None,
76
+ ) -> "DagsterPlusCliConfig":
77
+ """Create a DagsterPlusCliConfig instance for deployment-scoped operations.
78
+
79
+ Args:
80
+ deployment: The deployment name to target
81
+ organization: Organization name (if None, will try to load from existing config)
82
+ user_token: User token (if None, will try to load from existing config)
83
+ """
84
+ # Try to get base config if it exists, but don't require it
85
+ base_config = {}
86
+ if cls.exists():
87
+ try:
88
+ base_config = cls.get().__dict__
89
+ except Exception:
90
+ # If config exists but is invalid, start with empty base
91
+ pass
92
+
93
+ return cls(
94
+ url=base_config.get("url"),
95
+ organization=organization or base_config.get("organization"),
96
+ default_deployment=deployment, # Override with specific deployment
97
+ user_token=user_token or base_config.get("user_token"),
98
+ agent_timeout=base_config.get("agent_timeout"),
99
+ )
100
+
101
+ @classmethod
102
+ def create_for_organization(
103
+ cls, organization: Optional[str] = None, user_token: Optional[str] = None
104
+ ) -> "DagsterPlusCliConfig":
105
+ """Create a DagsterPlusCliConfig instance for organization-scoped operations.
106
+
107
+ Args:
108
+ organization: Organization name (if None, will try to load from existing config)
109
+ user_token: User token (if None, will try to load from existing config)
110
+ """
111
+ # Try to get base config if it exists, but don't require it
112
+ base_config = {}
113
+ if cls.exists():
114
+ try:
115
+ base_config = cls.get().__dict__
116
+ except Exception:
117
+ # If config exists but is invalid, start with empty base
118
+ pass
119
+
120
+ return cls(
121
+ url=base_config.get("url"),
122
+ organization=organization or base_config.get("organization"),
123
+ default_deployment=None, # No deployment for organization-scoped operations
124
+ user_token=user_token or base_config.get("user_token"),
125
+ agent_timeout=base_config.get("agent_timeout"),
126
+ )
127
+
70
128
  def write(self):
71
129
  existing_config = _get_dagster_plus_config_path_and_raw_config()
72
130
  if existing_config is None:
@@ -0,0 +1,186 @@
1
+ import functools
2
+ import os
3
+ from typing import Optional
4
+
5
+ import click
6
+
7
+ from dagster_shared.plus.config import DagsterPlusCliConfig
8
+
9
+ # Constants for CLI arguments and environment variables
10
+ DEPLOYMENT_CLI_ARGUMENT = "deployment"
11
+ DEPLOYMENT_ENV_VAR_NAME = "DAGSTER_CLOUD_DEPLOYMENT"
12
+
13
+ ORGANIZATION_CLI_ARGUMENT = "organization"
14
+ ORGANIZATION_ENV_VAR_NAME = "DAGSTER_CLOUD_ORGANIZATION"
15
+
16
+ TOKEN_CLI_ARGUMENT = "api_token"
17
+ TOKEN_ENV_VAR_NAME = "DAGSTER_CLOUD_API_TOKEN"
18
+
19
+
20
+ def get_deployment(ctx: Optional[click.Context] = None) -> Optional[str]:
21
+ """Gets the configured deployment to target.
22
+ Highest precedence is a deployment argument, then `DAGSTER_CLOUD_DEPLOYMENT` env var, then config file default.
23
+ """
24
+ if ctx and ctx.params.get(DEPLOYMENT_CLI_ARGUMENT):
25
+ return ctx.params[DEPLOYMENT_CLI_ARGUMENT]
26
+
27
+ env_value = os.getenv(DEPLOYMENT_ENV_VAR_NAME)
28
+ if env_value:
29
+ return env_value
30
+
31
+ # Fall back to config file
32
+ if DagsterPlusCliConfig.exists():
33
+ try:
34
+ config = DagsterPlusCliConfig.get()
35
+ return config.default_deployment
36
+ except Exception:
37
+ pass
38
+
39
+ return None
40
+
41
+
42
+ def get_organization(ctx: Optional[click.Context] = None) -> Optional[str]:
43
+ """Gets the configured organization to target.
44
+ Highest precedence is an organization argument, then `DAGSTER_CLOUD_ORGANIZATION` env var, then config file.
45
+ """
46
+ if ctx and ctx.params.get(ORGANIZATION_CLI_ARGUMENT):
47
+ return ctx.params[ORGANIZATION_CLI_ARGUMENT]
48
+
49
+ env_value = os.getenv(ORGANIZATION_ENV_VAR_NAME)
50
+ if env_value:
51
+ return env_value
52
+
53
+ # Fall back to config file
54
+ if DagsterPlusCliConfig.exists():
55
+ try:
56
+ config = DagsterPlusCliConfig.get()
57
+ return config.organization
58
+ except Exception:
59
+ pass
60
+
61
+ return None
62
+
63
+
64
+ def get_user_token(ctx: Optional[click.Context] = None) -> Optional[str]:
65
+ """Gets the configured user token to use.
66
+ Highest precedence is an api-token argument, then `DAGSTER_CLOUD_API_TOKEN` env var, then config file.
67
+ """
68
+ if ctx and ctx.params.get(TOKEN_CLI_ARGUMENT):
69
+ return ctx.params[TOKEN_CLI_ARGUMENT]
70
+
71
+ env_value = os.getenv(TOKEN_ENV_VAR_NAME)
72
+ if env_value:
73
+ return env_value
74
+
75
+ # Fall back to config file
76
+ if DagsterPlusCliConfig.exists():
77
+ try:
78
+ config = DagsterPlusCliConfig.get()
79
+ return config.user_token
80
+ except Exception:
81
+ pass
82
+
83
+ return None
84
+
85
+
86
+ # Click option definitions for reuse across commands
87
+ DEPLOYMENT_OPTION = click.option(
88
+ "--deployment",
89
+ "-d",
90
+ help="Deployment to target.",
91
+ envvar=DEPLOYMENT_ENV_VAR_NAME,
92
+ )
93
+
94
+ ORGANIZATION_OPTION = click.option(
95
+ "--organization",
96
+ "-o",
97
+ help="Organization to target.",
98
+ envvar=ORGANIZATION_ENV_VAR_NAME,
99
+ )
100
+
101
+ TOKEN_OPTION = click.option(
102
+ "--api-token",
103
+ help="Dagster Cloud API token.",
104
+ envvar=TOKEN_ENV_VAR_NAME,
105
+ )
106
+
107
+ VIEW_GRAPHQL_OPTION = click.option(
108
+ "--view-graphql",
109
+ is_flag=True,
110
+ help="Print GraphQL queries and responses to stderr for debugging.",
111
+ )
112
+
113
+
114
+ def dg_api_options(
115
+ deployment_scoped: bool = False,
116
+ organization_scoped: bool = False,
117
+ ):
118
+ """Apply this decorator to Click commands to add organization, deployment, and token options.
119
+
120
+ Args:
121
+ deployment_scoped: If True, requires deployment to be specified and validates it
122
+ organization_scoped: If True, only requires organization (deployment is optional)
123
+ """
124
+ if deployment_scoped and organization_scoped:
125
+ raise ValueError("Cannot specify both deployment_scoped and organization_scoped")
126
+
127
+ if not deployment_scoped and not organization_scoped:
128
+ raise ValueError("Must specify either deployment_scoped or organization_scoped")
129
+
130
+ def decorator(func):
131
+ # Add options in reverse order (Click applies them in reverse)
132
+ func = VIEW_GRAPHQL_OPTION(func)
133
+ func = TOKEN_OPTION(func)
134
+ func = ORGANIZATION_OPTION(func)
135
+
136
+ if deployment_scoped:
137
+ func = DEPLOYMENT_OPTION(func)
138
+
139
+ @functools.wraps(func)
140
+ def wrapper(*args, **kwargs):
141
+ ctx = click.get_current_context()
142
+
143
+ # Check if we're in test mode with DgApiTestContext
144
+ # Import here to avoid circular imports
145
+ from dagster_dg_cli.cli.api.client import DgApiTestContext
146
+
147
+ if ctx.obj and isinstance(ctx.obj, DgApiTestContext):
148
+ organization = ctx.obj.organization
149
+ deployment = ctx.obj.deployment if deployment_scoped else None
150
+ api_token = None
151
+ view_graphql = False # Default to False in test mode
152
+ else:
153
+ # Get resolved values using precedence chain
154
+ organization = get_organization(ctx)
155
+ deployment = get_deployment(ctx) if deployment_scoped else None
156
+ api_token = get_user_token(ctx)
157
+ view_graphql = kwargs.get("view_graphql", False)
158
+
159
+ if not organization:
160
+ raise click.UsageError(
161
+ "A Dagster Cloud organization must be specified.\n\n"
162
+ "You may specify an organization by:\n"
163
+ f"- Providing the --organization parameter\n"
164
+ f"- Setting the {ORGANIZATION_ENV_VAR_NAME} environment variable"
165
+ )
166
+
167
+ if deployment_scoped and not deployment:
168
+ raise click.UsageError(
169
+ "A Dagster Cloud deployment must be specified for this command.\n\n"
170
+ "You may specify a deployment by:\n"
171
+ f"- Providing the --deployment parameter\n"
172
+ f"- Setting the {DEPLOYMENT_ENV_VAR_NAME} environment variable"
173
+ )
174
+
175
+ # Update kwargs with resolved values
176
+ kwargs["organization"] = organization
177
+ kwargs["api_token"] = api_token
178
+ kwargs["view_graphql"] = view_graphql
179
+ if deployment_scoped:
180
+ kwargs["deployment"] = deployment
181
+
182
+ return func(*args, **kwargs)
183
+
184
+ return wrapper
185
+
186
+ return decorator
dagster_shared/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.11.8"
1
+ __version__ = "1.11.9"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dagster_shared
3
- Version: 1.11.8
3
+ Version: 1.11.9
4
4
  Summary: Shared code between dagster and dagster-dg-core.
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-shared
6
6
  Author: Dagster Labs
@@ -5,7 +5,7 @@ dagster_shared/match.py,sha256=o2ZzDuNEsDpX6rF6CV3GSVrfdLIpnJvr8B75bSQ_T40,3433
5
5
  dagster_shared/merger.py,sha256=c9cJTwHtgMXgR9MtB-KwZEMtQSXn13rF08F2ID5aDTg,1758
6
6
  dagster_shared/modules.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  dagster_shared/py.typed,sha256=mDShSrm8qg9qjacQc2F-rI8ATllqP6EdgHuEYxuCXZ0,7
8
- dagster_shared/version.py,sha256=vZhy1cF0OZEZHiWDrJmoiOSfcjoeLvRH3BnE8L9ET5A,23
8
+ dagster_shared/version.py,sha256=V8SC1Po1URCKM7OaordHON5q2PcRVlKme4VoQcIn7fI,23
9
9
  dagster_shared/check/README.md,sha256=UlxRVMWJEoVAlaHWDvhobUpuNQGBG5-ddqZ6OIfLYnM,1352
10
10
  dagster_shared/check/__init__.py,sha256=CHSOqJpaeWr6skJT7jD8HnN5s4bdnoX4x94sGN55KqA,3482
11
11
  dagster_shared/check/builder.py,sha256=SVu2OSL206R1HVP4qiGSA1WHt4Oyb-bDzGh9OvPlhJ8,17427
@@ -17,7 +17,8 @@ dagster_shared/dagster_model/__init__.py,sha256=MoUreIsyzBIjn1w2noiyR0CmBg2kiP2V
17
17
  dagster_shared/dagster_model/pydantic_compat_layer.py,sha256=9c2BmeucYvvfnmeSffOqadKX0Kitx1rBu-WW32A116Y,2892
18
18
  dagster_shared/libraries/__init__.py,sha256=Z4JaXvbhGRF06HgheiPwO4iKfn2Uka_BItr1VF9JLoU,4685
19
19
  dagster_shared/plus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- dagster_shared/plus/config.py,sha256=MWLAvp2ZqDRFBEj4fz1_U5xEGGO2EVsl7uoWSkOeIm0,3411
20
+ dagster_shared/plus/config.py,sha256=0kAWocZFYh9NmCoOT348YUg0vQe9SEpJ_Ze9R3uyR-w,5756
21
+ dagster_shared/plus/config_utils.py,sha256=eVvahsrGQdcYL1H3_63kXO2NKsVPtWXhlGFajvJPQ5w,6147
21
22
  dagster_shared/plus/login_server.py,sha256=zRc85NUHtxpgXGfzV1d4hq-n9ZdXTBiSmagUebwxqdE,3630
22
23
  dagster_shared/record/__init__.py,sha256=L1k0imyJZ2AQXyQJPBouFsRHq1WaZsM-NEy7Ud8nVGs,22346
23
24
  dagster_shared/scaffold/__init__.py,sha256=xb5-ZdbZ5wSYYJy8VA1KGDnPodM6bKTCSBPS85Wqi_w,3759
@@ -45,8 +46,8 @@ dagster_shared/utils/warnings.py,sha256=uaCngAy2aPwuuN8ktod1Z5GEIvwwBaJYMSo4inNN
45
46
  dagster_shared/yaml_utils/__init__.py,sha256=Ya7qT3aJGPC1TgD-pSkkhLX5U4QbrUkCsrUtZQeACXg,10529
46
47
  dagster_shared/yaml_utils/sample_yaml.py,sha256=YC-1h1P48F3QV-Uwo-MqzEkzlrMliXPfZM_X6ynZvTQ,5461
47
48
  dagster_shared/yaml_utils/source_position.py,sha256=yVSnHUkBYzWzLzqtyGbqRjH2b7oTeiE4K3b-uokYUIQ,9786
48
- dagster_shared-1.11.8.dist-info/licenses/LICENSE,sha256=hgU51ohULAFKZE2la8sartPYoUaAA14jxFAfFC4Tow0,11347
49
- dagster_shared-1.11.8.dist-info/METADATA,sha256=IBd0-u_OsIK9YBBp3wEqKujBkjGZ5puiKXCvTF28xns,1175
50
- dagster_shared-1.11.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
51
- dagster_shared-1.11.8.dist-info/top_level.txt,sha256=S8ADcO4aTW07ONhLHXDxiuSkDzucgYKOlocB2x3r_dY,15
52
- dagster_shared-1.11.8.dist-info/RECORD,,
49
+ dagster_shared-1.11.9.dist-info/licenses/LICENSE,sha256=hgU51ohULAFKZE2la8sartPYoUaAA14jxFAfFC4Tow0,11347
50
+ dagster_shared-1.11.9.dist-info/METADATA,sha256=zCP-3c0OMQL0da2c5w0CTo-0kp0Oj2Bw8FMR8Z_MvWA,1175
51
+ dagster_shared-1.11.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
52
+ dagster_shared-1.11.9.dist-info/top_level.txt,sha256=S8ADcO4aTW07ONhLHXDxiuSkDzucgYKOlocB2x3r_dY,15
53
+ dagster_shared-1.11.9.dist-info/RECORD,,