dagster-cloud-cli 1.12.16__py2.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.
- dagster_cloud_cli/__init__.py +5 -0
- dagster_cloud_cli/commands/__init__.py +0 -0
- dagster_cloud_cli/commands/branch_deployment/__init__.py +154 -0
- dagster_cloud_cli/commands/ci/__init__.py +1207 -0
- dagster_cloud_cli/commands/ci/checks.py +135 -0
- dagster_cloud_cli/commands/ci/report.py +49 -0
- dagster_cloud_cli/commands/ci/state.py +129 -0
- dagster_cloud_cli/commands/ci/utils.py +22 -0
- dagster_cloud_cli/commands/config.py +250 -0
- dagster_cloud_cli/commands/deployment/__init__.py +108 -0
- dagster_cloud_cli/commands/deployment/alert_policies/__init__.py +0 -0
- dagster_cloud_cli/commands/deployment/alert_policies/commands.py +52 -0
- dagster_cloud_cli/commands/integration/__init__.py +6 -0
- dagster_cloud_cli/commands/integration/atlan/__init__.py +94 -0
- dagster_cloud_cli/commands/job/__init__.py +117 -0
- dagster_cloud_cli/commands/metrics.py +114 -0
- dagster_cloud_cli/commands/organization/__init__.py +134 -0
- dagster_cloud_cli/commands/organization/saml/__init__.py +0 -0
- dagster_cloud_cli/commands/organization/saml/commands.py +85 -0
- dagster_cloud_cli/commands/run/__init__.py +27 -0
- dagster_cloud_cli/commands/serverless/Dockerfile +38 -0
- dagster_cloud_cli/commands/serverless/Dockerfile.dagster-cloud-cli +20 -0
- dagster_cloud_cli/commands/serverless/__init__.py +560 -0
- dagster_cloud_cli/commands/workspace/__init__.py +358 -0
- dagster_cloud_cli/config/__init__.py +6 -0
- dagster_cloud_cli/config/jinja_template_loader.py +45 -0
- dagster_cloud_cli/config/list_merge_strategies.py +77 -0
- dagster_cloud_cli/config/loader.py +23 -0
- dagster_cloud_cli/config/merger.py +92 -0
- dagster_cloud_cli/config/models.py +76 -0
- dagster_cloud_cli/config_utils.py +506 -0
- dagster_cloud_cli/core/__init__.py +0 -0
- dagster_cloud_cli/core/agent_queue.py +3 -0
- dagster_cloud_cli/core/alert_types.py +26 -0
- dagster_cloud_cli/core/artifacts.py +192 -0
- dagster_cloud_cli/core/docker_runner.py +57 -0
- dagster_cloud_cli/core/errors.py +32 -0
- dagster_cloud_cli/core/graphql_client.py +420 -0
- dagster_cloud_cli/core/headers/__init__.py +0 -0
- dagster_cloud_cli/core/headers/auth.py +16 -0
- dagster_cloud_cli/core/headers/impl.py +31 -0
- dagster_cloud_cli/core/headers/versioning/__init__.py +0 -0
- dagster_cloud_cli/core/headers/versioning/constants.py +2 -0
- dagster_cloud_cli/core/pex_builder/__init__.py +8 -0
- dagster_cloud_cli/core/pex_builder/code_location.py +126 -0
- dagster_cloud_cli/core/pex_builder/deploy.py +255 -0
- dagster_cloud_cli/core/pex_builder/deps.py +495 -0
- dagster_cloud_cli/core/pex_builder/git_context.py +29 -0
- dagster_cloud_cli/core/pex_builder/github_context.py +178 -0
- dagster_cloud_cli/core/pex_builder/gitlab_context.py +30 -0
- dagster_cloud_cli/core/pex_builder/parse_workspace.py +39 -0
- dagster_cloud_cli/core/pex_builder/pex_registry.py +148 -0
- dagster_cloud_cli/core/pex_builder/platforms.py +6105 -0
- dagster_cloud_cli/core/pex_builder/selftest.py +14 -0
- dagster_cloud_cli/core/pex_builder/source.py +166 -0
- dagster_cloud_cli/core/pex_builder/util.py +165 -0
- dagster_cloud_cli/core/workspace.py +145 -0
- dagster_cloud_cli/docker_utils.py +98 -0
- dagster_cloud_cli/entrypoint.py +209 -0
- dagster_cloud_cli/gql.py +1025 -0
- dagster_cloud_cli/pex_utils.py +180 -0
- dagster_cloud_cli/py.typed +0 -0
- dagster_cloud_cli/types.py +78 -0
- dagster_cloud_cli/ui.py +101 -0
- dagster_cloud_cli/utils.py +107 -0
- dagster_cloud_cli/version.py +1 -0
- dagster_cloud_cli-1.12.16.dist-info/METADATA +31 -0
- dagster_cloud_cli-1.12.16.dist-info/RECORD +71 -0
- dagster_cloud_cli-1.12.16.dist-info/WHEEL +5 -0
- dagster_cloud_cli-1.12.16.dist-info/entry_points.txt +3 -0
- dagster_cloud_cli-1.12.16.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Handles python executable (pex) specific flags and wraps pex_builder
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import tempfile
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from typer import Option
|
|
8
|
+
|
|
9
|
+
from dagster_cloud_cli import ui
|
|
10
|
+
from dagster_cloud_cli.core import pex_builder
|
|
11
|
+
from dagster_cloud_cli.core.pex_builder.deps import BuildMethod
|
|
12
|
+
from dagster_cloud_cli.utils import DEFAULT_PYTHON_VERSION, get_file_size
|
|
13
|
+
|
|
14
|
+
DEPLOY_PEX_OPTIONS = {
|
|
15
|
+
"python_version": (
|
|
16
|
+
str,
|
|
17
|
+
Option(
|
|
18
|
+
DEFAULT_PYTHON_VERSION,
|
|
19
|
+
"--python-version",
|
|
20
|
+
help="Target Python version specified as 'major.minor'.",
|
|
21
|
+
),
|
|
22
|
+
),
|
|
23
|
+
"deps_cache_from": (
|
|
24
|
+
str,
|
|
25
|
+
Option(
|
|
26
|
+
None,
|
|
27
|
+
"--deps-cache-from",
|
|
28
|
+
help=(
|
|
29
|
+
"Reuse cached dependencies for this tag, "
|
|
30
|
+
"if the dependency names match the cached names."
|
|
31
|
+
),
|
|
32
|
+
),
|
|
33
|
+
),
|
|
34
|
+
"deps_cache_to": (
|
|
35
|
+
str,
|
|
36
|
+
Option(
|
|
37
|
+
None,
|
|
38
|
+
"--deps-cache-to",
|
|
39
|
+
help=(
|
|
40
|
+
"Cache dependencies and annotate with this tag. "
|
|
41
|
+
"Use this tag in --deps-cache-from to reuse dependencies."
|
|
42
|
+
),
|
|
43
|
+
hidden=True,
|
|
44
|
+
),
|
|
45
|
+
),
|
|
46
|
+
"base_image_tag": (
|
|
47
|
+
str,
|
|
48
|
+
Option(
|
|
49
|
+
None,
|
|
50
|
+
"--base-image-tag",
|
|
51
|
+
help="Tag that selects a base image uploaded using upload-base-image",
|
|
52
|
+
),
|
|
53
|
+
),
|
|
54
|
+
"build_method": (
|
|
55
|
+
BuildMethod,
|
|
56
|
+
Option("docker-fallback", help="Environment used to build the dependencies."),
|
|
57
|
+
),
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def build_upload_pex(
|
|
62
|
+
url: str,
|
|
63
|
+
api_token: str,
|
|
64
|
+
location: pex_builder.parse_workspace.Location,
|
|
65
|
+
build_method: BuildMethod,
|
|
66
|
+
kwargs: dict[str, Any],
|
|
67
|
+
) -> dict[str, Any]:
|
|
68
|
+
# build and upload the python executable, return the modified kwargs with pex_tag and image
|
|
69
|
+
kwargs = kwargs.copy()
|
|
70
|
+
|
|
71
|
+
if kwargs.get("base_image_tag"):
|
|
72
|
+
if kwargs.get("image"):
|
|
73
|
+
raise ui.error("Only one of --base-image-tag or --image can be specified.")
|
|
74
|
+
os.environ["SERVERLESS_BASE_IMAGE_TAG"] = kwargs.pop("base_image_tag")
|
|
75
|
+
|
|
76
|
+
python_version = pex_builder.util.parse_python_version(
|
|
77
|
+
kwargs.setdefault("python_version", DEFAULT_PYTHON_VERSION)
|
|
78
|
+
)
|
|
79
|
+
ui.print(
|
|
80
|
+
ui.blue(
|
|
81
|
+
f"Building Python executable for {location.name} from directory {location.directory} "
|
|
82
|
+
f"and Python {python_version}."
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
deps_cache_tags = pex_builder.deploy.DepsCacheTags(
|
|
86
|
+
kwargs.pop("deps_cache_from", None), kwargs.pop("deps_cache_to", None)
|
|
87
|
+
)
|
|
88
|
+
with tempfile.TemporaryDirectory() as temp_folder:
|
|
89
|
+
builds = pex_builder.deploy.build_locations(
|
|
90
|
+
url,
|
|
91
|
+
api_token,
|
|
92
|
+
[location],
|
|
93
|
+
temp_folder,
|
|
94
|
+
upload_pex=True,
|
|
95
|
+
deps_cache_tags=deps_cache_tags,
|
|
96
|
+
python_version=python_version,
|
|
97
|
+
build_method=build_method,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
build = builds[0]
|
|
101
|
+
kwargs["pex_tag"] = build.pex_tag
|
|
102
|
+
image = kwargs.get("image")
|
|
103
|
+
if not image:
|
|
104
|
+
image = pex_builder.deploy.get_user_specified_base_image_for(url, api_token, build)
|
|
105
|
+
if image:
|
|
106
|
+
kwargs["image"] = image
|
|
107
|
+
if image:
|
|
108
|
+
ui.print(f"Will deploy {build.location.name} on image: {image}")
|
|
109
|
+
del kwargs["python_version"]
|
|
110
|
+
else:
|
|
111
|
+
ui.print(
|
|
112
|
+
f"Will deploy {build.location.name} on a standard base image for Python"
|
|
113
|
+
f" {python_version}"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
paths = [
|
|
117
|
+
filepath
|
|
118
|
+
for filepath in [
|
|
119
|
+
build.source_pex_path,
|
|
120
|
+
build.deps_pex_path,
|
|
121
|
+
]
|
|
122
|
+
if filepath is not None
|
|
123
|
+
]
|
|
124
|
+
if not paths:
|
|
125
|
+
raise ui.error("No built files for {build.location.name}.")
|
|
126
|
+
print_built_pex_details(build)
|
|
127
|
+
ui.print(f"Uploading Python executable for {build.location.name}.")
|
|
128
|
+
pex_builder.pex_registry.upload_files(url, api_token, paths)
|
|
129
|
+
|
|
130
|
+
# if a --deps-cache-to cache_tag is specified, set or update the cached deps details
|
|
131
|
+
if deps_cache_tags.deps_cache_to_tag:
|
|
132
|
+
# could be either a newly built pex or an published pex name copied from another tag
|
|
133
|
+
deps_pex_name = (
|
|
134
|
+
os.path.basename(build.deps_pex_path)
|
|
135
|
+
if build.deps_pex_path
|
|
136
|
+
else build.published_deps_pex
|
|
137
|
+
)
|
|
138
|
+
if not deps_pex_name:
|
|
139
|
+
raise ui.error(
|
|
140
|
+
"Failed to build or find the Python executable dependencies (deps.pex)."
|
|
141
|
+
)
|
|
142
|
+
if not build.dagster_version:
|
|
143
|
+
raise ui.error("Dagster not found in project's dependencies.")
|
|
144
|
+
|
|
145
|
+
pex_builder.pex_registry.set_cached_deps_details(
|
|
146
|
+
url,
|
|
147
|
+
api_token,
|
|
148
|
+
build.deps_requirements.hash,
|
|
149
|
+
deps_cache_tags.deps_cache_to_tag,
|
|
150
|
+
deps_pex_name,
|
|
151
|
+
dagster_version=build.dagster_version,
|
|
152
|
+
)
|
|
153
|
+
ui.print(
|
|
154
|
+
f"Updated cached deps.pex for requirements_hash {build.deps_requirements.hash}, cache_tag {deps_cache_tags.deps_cache_from_tag}.",
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
return kwargs
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def print_built_pex_details(location_build: pex_builder.deploy.LocationBuild):
|
|
161
|
+
ui.print(
|
|
162
|
+
f"Built {location_build.source_pex_path} ({get_file_size(location_build.source_pex_path)})"
|
|
163
|
+
" from:"
|
|
164
|
+
)
|
|
165
|
+
ui.print(f" - {location_build.location.directory}")
|
|
166
|
+
for local_path in location_build.local_packages.local_package_paths:
|
|
167
|
+
ui.print(f" - {local_path}")
|
|
168
|
+
|
|
169
|
+
if location_build.deps_pex_path:
|
|
170
|
+
ui.print(
|
|
171
|
+
f"Built {location_build.deps_pex_path} ({get_file_size(location_build.deps_pex_path)})"
|
|
172
|
+
f" with Dagster {location_build.dagster_version}"
|
|
173
|
+
)
|
|
174
|
+
ui.print("Included dependencies:")
|
|
175
|
+
for line in sorted(
|
|
176
|
+
location_build.deps_requirements.requirements_txt.splitlines(keepends=False)
|
|
177
|
+
):
|
|
178
|
+
print(f" - {line}") # noqa: T201
|
|
179
|
+
elif location_build.published_deps_pex:
|
|
180
|
+
ui.print(f"Reusing cached dependencies: {location_build.published_deps_pex}")
|
|
File without changes
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
2
|
+
from enum import Enum, EnumMeta
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class CliEventType(Enum):
|
|
6
|
+
DEPLOY = "deploy"
|
|
7
|
+
UPLOAD = "upload"
|
|
8
|
+
BUILD = "build"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
AgentStrategyTags = Enum(
|
|
12
|
+
"agent-strategy", {"hybrid": "agent-strategy:hybrid", "serverless": "agent-strategy:serverless"}
|
|
13
|
+
)
|
|
14
|
+
ServerStrategyTags = Enum(
|
|
15
|
+
"server-strategy", {"docker": "server-strategy:docker", "pex": "server-strategy:pex"}
|
|
16
|
+
)
|
|
17
|
+
SourceTags = Enum(
|
|
18
|
+
"source",
|
|
19
|
+
{
|
|
20
|
+
"bitbucket": "source:bitbucket",
|
|
21
|
+
"buildkite": "source:buildkite",
|
|
22
|
+
"circle_ci": "source:circle-ci",
|
|
23
|
+
"cli": "source:cli",
|
|
24
|
+
"codebuild": "source:codebuild",
|
|
25
|
+
"github": "source:github",
|
|
26
|
+
"gitlab": "source:gitlab",
|
|
27
|
+
"jenkins": "source:jenkins",
|
|
28
|
+
"travis": "source:travis",
|
|
29
|
+
"unknown": "source:unknown",
|
|
30
|
+
},
|
|
31
|
+
)
|
|
32
|
+
SubcommandTags = Enum(
|
|
33
|
+
"subcommand",
|
|
34
|
+
{
|
|
35
|
+
"dagster_cloud_ci": "subcommand:dagster-cloud-ci",
|
|
36
|
+
"dagster_cloud_serverless": "subcommand:dagster-cloud-serverless",
|
|
37
|
+
},
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class CliEventTags:
|
|
42
|
+
@classmethod
|
|
43
|
+
def enums(cls):
|
|
44
|
+
attrs = []
|
|
45
|
+
for attr in cls.__dict__.values():
|
|
46
|
+
if isinstance(attr, EnumMeta):
|
|
47
|
+
attrs.append(attr)
|
|
48
|
+
return attrs
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def contains(cls, value) -> bool:
|
|
52
|
+
for enum in cls.enums():
|
|
53
|
+
with suppress(ValueError):
|
|
54
|
+
if enum(value):
|
|
55
|
+
return True
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def split(cls, value: str) -> tuple[str, str]:
|
|
60
|
+
if cls.contains(value):
|
|
61
|
+
parts = value.split(":", 1)
|
|
62
|
+
return (parts[0], parts[1])
|
|
63
|
+
raise ValueError("Invalid tag value", value)
|
|
64
|
+
|
|
65
|
+
agent_strategy = AgentStrategyTags
|
|
66
|
+
server_strategy = ServerStrategyTags
|
|
67
|
+
source = SourceTags
|
|
68
|
+
subcommand = SubcommandTags
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class SnapshotBaseDeploymentCondition(Enum):
|
|
72
|
+
"""When to snapshot the base deployment during branch deployment create and update flows.
|
|
73
|
+
|
|
74
|
+
Enum values hyphenated for use in CLI.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
ON_CREATE = "on-create"
|
|
78
|
+
ON_UPDATE = "on-update"
|
dagster_cloud_cli/ui.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import questionary
|
|
6
|
+
import typer
|
|
7
|
+
import yaml
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ExitWithMessage(typer.Exit):
|
|
11
|
+
def __init__(self, message=None, *args, **kwargs):
|
|
12
|
+
self.message = message
|
|
13
|
+
super().__init__(*args, **kwargs)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def as_code(text: str) -> str:
|
|
17
|
+
"""Returns the given text colored and in backticks."""
|
|
18
|
+
return typer.style(f"`{text}`", fg=typer.colors.CYAN)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def red(text: str) -> str:
|
|
22
|
+
return typer.style(text, fg=typer.colors.RED)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def blue(text: str) -> str:
|
|
26
|
+
return typer.style(text, fg=typer.colors.BLUE)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def yellow(text: str) -> str:
|
|
30
|
+
return typer.style(text, fg=typer.colors.YELLOW)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def green(text: str) -> str:
|
|
34
|
+
return typer.style(text, fg=typer.colors.GREEN)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def warn(message: str) -> None:
|
|
38
|
+
"""Prints a warning message."""
|
|
39
|
+
print(f"{yellow('Warning:')} {message}")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def error(message: str, code: int = 1) -> Exception:
|
|
43
|
+
"""Prints an error message and returns an exception."""
|
|
44
|
+
print(f"{red('Error:')} {message}")
|
|
45
|
+
return ExitWithMessage(message=message, code=code)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def censor_token(token: str) -> str:
|
|
49
|
+
return ("*" * (len(token) - 6)) + token[-6:]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def list_input(
|
|
53
|
+
prompt: str,
|
|
54
|
+
choices: list[Any],
|
|
55
|
+
default: str | questionary.Choice | dict[str, Any] | None = None,
|
|
56
|
+
) -> str:
|
|
57
|
+
"""Presents the user with a list of choices that can be navigated with
|
|
58
|
+
the up and down arrows.
|
|
59
|
+
"""
|
|
60
|
+
return questionary.select(prompt, choices=choices, default=default).unsafe_ask()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def choice(value: Any, name: str) -> Any:
|
|
64
|
+
return questionary.Choice(title=name, value=value)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def input(prompt: str, default: str = "", validate: Callable | None = None) -> str: # noqa: A001
|
|
68
|
+
"""Prompts the user for text input."""
|
|
69
|
+
return questionary.text(prompt, default=default, validate=validate).unsafe_ask()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def password_input(prompt: str, default: str = "") -> str:
|
|
73
|
+
"""Prompts the user for text input, hidden by dots."""
|
|
74
|
+
return questionary.password(prompt, default=default).unsafe_ask()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def print(*args, **kwargs): # noqa: A001
|
|
78
|
+
"""Echos text to the console."""
|
|
79
|
+
return typer.echo(*args, **kwargs)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def print_json(data: Any):
|
|
83
|
+
return typer.echo(json.dumps(data, indent=2))
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def print_yaml(data: Any):
|
|
87
|
+
return typer.echo(yaml.dump(data))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def erase_previous_line(number_of_lines: int = 1) -> None:
|
|
91
|
+
"""Erases the previous line of output, which can then be printed over."""
|
|
92
|
+
return typer.echo("\033[F\033[K" * number_of_lines + "\033[F")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def confirm(prompt: str, default: bool = True) -> bool:
|
|
96
|
+
"""Asks the user to respond yes or no to the prompt."""
|
|
97
|
+
return questionary.confirm(prompt, default=default).unsafe_ask()
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def bool_input(prompt: str, default: bool = False) -> bool:
|
|
101
|
+
return confirm(prompt, default=default)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
import functools
|
|
3
|
+
import inspect
|
|
4
|
+
import math
|
|
5
|
+
import os
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from typer import Typer
|
|
10
|
+
from typer.models import OptionInfo
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
DEFAULT_PYTHON_VERSION = "3.11"
|
|
14
|
+
|
|
15
|
+
SUPPORTED_PYTHON_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def create_stub_app(package_name: str) -> "Typer":
|
|
19
|
+
import typer
|
|
20
|
+
|
|
21
|
+
return typer.Typer(
|
|
22
|
+
help=f"This command is not available unless you install the {package_name} package.",
|
|
23
|
+
hidden=True,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def create_stub_command(package_name: str):
|
|
28
|
+
from dagster_cloud_cli import ui
|
|
29
|
+
|
|
30
|
+
def fn():
|
|
31
|
+
ui.print(f"This command is not available unless you install the {package_name} package.")
|
|
32
|
+
|
|
33
|
+
return fn
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def with_added_params(
|
|
37
|
+
signature: inspect.Signature, to_add: dict[str, inspect.Parameter]
|
|
38
|
+
) -> inspect.Signature:
|
|
39
|
+
"""Returns a new signature based on the provided one, with the provided parameters added."""
|
|
40
|
+
params = collections.OrderedDict(signature.parameters)
|
|
41
|
+
for k, v in to_add.items():
|
|
42
|
+
params[k] = v
|
|
43
|
+
return signature.replace(parameters=list(params.values()))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def without_params(signature: inspect.Signature, to_remove: list[str]) -> inspect.Signature:
|
|
47
|
+
"""Returns a new signature based on the provided one with the given parameters removed by name.
|
|
48
|
+
Does nothing if the parameter is not found.
|
|
49
|
+
"""
|
|
50
|
+
params = collections.OrderedDict(signature.parameters)
|
|
51
|
+
for r in to_remove:
|
|
52
|
+
if r in params:
|
|
53
|
+
del params[r]
|
|
54
|
+
return signature.replace(parameters=list(params.values()))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def add_options(options: dict[str, tuple[Any, "OptionInfo"]]):
|
|
58
|
+
"""Decorator to add Options to a particular command."""
|
|
59
|
+
|
|
60
|
+
def decorator(to_wrap):
|
|
61
|
+
# Ensure that the function signature has the correct typer.Option defaults,
|
|
62
|
+
# so that every command need not specify them
|
|
63
|
+
|
|
64
|
+
# Remove kwargs, since Typer doesn't know how to handle it
|
|
65
|
+
to_wrap_sig = inspect.signature(to_wrap)
|
|
66
|
+
has_kwargs = "kwargs" in to_wrap_sig.parameters
|
|
67
|
+
sig = without_params(to_wrap_sig, ["kwargs"])
|
|
68
|
+
sig = with_added_params(
|
|
69
|
+
sig,
|
|
70
|
+
{
|
|
71
|
+
name: inspect.Parameter(
|
|
72
|
+
name,
|
|
73
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
74
|
+
annotation=_type,
|
|
75
|
+
default=default,
|
|
76
|
+
)
|
|
77
|
+
for name, (_type, default) in options.items()
|
|
78
|
+
},
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
@functools.wraps(to_wrap)
|
|
82
|
+
def wrap_function(*args, **kwargs):
|
|
83
|
+
modified_kwargs = kwargs
|
|
84
|
+
if not has_kwargs and not hasattr(to_wrap, "modified_options"):
|
|
85
|
+
modified_kwargs: dict[Any, Any] = {
|
|
86
|
+
k: v for k, v in kwargs.items() if k in to_wrap_sig.parameters
|
|
87
|
+
}
|
|
88
|
+
return to_wrap(*args, **modified_kwargs)
|
|
89
|
+
|
|
90
|
+
wrap_function.__signature__ = sig # pyright: ignore[reportAttributeAccessIssue]
|
|
91
|
+
wrap_function.modified_options = True # pyright: ignore[reportAttributeAccessIssue]
|
|
92
|
+
return wrap_function
|
|
93
|
+
|
|
94
|
+
return decorator
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def get_file_size(path) -> str:
|
|
98
|
+
size = os.path.getsize(path)
|
|
99
|
+
if size == 0:
|
|
100
|
+
return "0 bytes"
|
|
101
|
+
units = ["bytes", "KB", "MB", "GB"]
|
|
102
|
+
magnitude = math.floor(math.log(size, 1024))
|
|
103
|
+
magnitude = min([len(units) - 1, magnitude])
|
|
104
|
+
|
|
105
|
+
unit = units[magnitude]
|
|
106
|
+
value = size // (1024**magnitude)
|
|
107
|
+
return f"{value} {unit}"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.12.16"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dagster-cloud-cli
|
|
3
|
+
Version: 1.12.16
|
|
4
|
+
Project-URL: Homepage, https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-cloud-cli
|
|
5
|
+
Author-email: Dagster Labs <hello@dagsterlabs.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Requires-Dist: click
|
|
15
|
+
Requires-Dist: dagster-shared==1.12.16
|
|
16
|
+
Requires-Dist: github3-py
|
|
17
|
+
Requires-Dist: jinja2
|
|
18
|
+
Requires-Dist: packaging>=20.9
|
|
19
|
+
Requires-Dist: pyyaml>=5.1
|
|
20
|
+
Requires-Dist: questionary
|
|
21
|
+
Requires-Dist: requests
|
|
22
|
+
Requires-Dist: setuptools
|
|
23
|
+
Requires-Dist: tomli>=1.1.0; python_version < '3.11'
|
|
24
|
+
Requires-Dist: typer>=0.15.0
|
|
25
|
+
Requires-Dist: validators
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: flaky; extra == 'test'
|
|
28
|
+
Requires-Dist: freezegun; extra == 'test'
|
|
29
|
+
Requires-Dist: pex<2.60.0,>=2.1.132; extra == 'test'
|
|
30
|
+
Requires-Dist: pytest-mock==3.14.0; extra == 'test'
|
|
31
|
+
Requires-Dist: pytest>=8; extra == 'test'
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
dagster_cloud_cli/__init__.py,sha256=EJXilJR-i5RN_f2x8Av_6frGiJMdzO9B0EH_vVeJLng,178
|
|
2
|
+
dagster_cloud_cli/config_utils.py,sha256=04C5OnOCwQyMn38nqTNPSON81n13ZJANzL4kzEKO09Y,18315
|
|
3
|
+
dagster_cloud_cli/docker_utils.py,sha256=kJqcXQzrUOIrnddFe1womFdVu-j2efut7ep2t5xaRX4,3164
|
|
4
|
+
dagster_cloud_cli/entrypoint.py,sha256=fzC1EIDfQcTgJrUeD5PpGKvp-QyFDu7pEskq0DkueyI,7069
|
|
5
|
+
dagster_cloud_cli/gql.py,sha256=KQbgv7_paqi1DkbQj071l2ozoLhKRA2ZHCSDFRzNygc,29299
|
|
6
|
+
dagster_cloud_cli/pex_utils.py,sha256=BVTK_322R0sTIKYhXloyRG8aK0fPlR4owJ2z_hXRT-g,6190
|
|
7
|
+
dagster_cloud_cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
dagster_cloud_cli/types.py,sha256=JM1YMIIkR_fgGOSduoRKlnu4jK3h-ubALSAO8YEo6xY,2070
|
|
9
|
+
dagster_cloud_cli/ui.py,sha256=VFkv1C1mtY03cXwI86vXEqgjHGg67Au7U89BJzhj_Xk,2791
|
|
10
|
+
dagster_cloud_cli/utils.py,sha256=mRvkz8meUGlIYiBVpW6ptxmDjn6Ge4SO2w77s7TxsiI,3443
|
|
11
|
+
dagster_cloud_cli/version.py,sha256=fFgL2l_aO8HuiIYIT4ROy3I4MuBkR-FzMsPtNDtQisU,24
|
|
12
|
+
dagster_cloud_cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
dagster_cloud_cli/commands/config.py,sha256=4Fy3Ku7roV9hDuHFE3djJ5fde4w8rEjku-cTRdzqaXo,8308
|
|
14
|
+
dagster_cloud_cli/commands/metrics.py,sha256=zqdCvyin_CUtPJrSPaTMfo7LlrlhmGo_QVlqZmV3f7w,4375
|
|
15
|
+
dagster_cloud_cli/commands/branch_deployment/__init__.py,sha256=ly2buH2L-2-PMCb5VZ6v0uRd7YLGNjFjO1JRTSKBvAc,5938
|
|
16
|
+
dagster_cloud_cli/commands/ci/__init__.py,sha256=iFzgWCbAFvJRJOsX3SK-xeP_P7jPKcr6gjTHR2mXFI0,44578
|
|
17
|
+
dagster_cloud_cli/commands/ci/checks.py,sha256=EHItKj9U27DZ-13lNi1EvhXq3A5zx0s4BgQV3O8r-RA,4079
|
|
18
|
+
dagster_cloud_cli/commands/ci/report.py,sha256=L7GYWMlMpECW4r3tT5hZ6d-Y45bEuigvpugNu32dDo0,1875
|
|
19
|
+
dagster_cloud_cli/commands/ci/state.py,sha256=nzct66Gd85SGVYVMZUSwV835QseexpVnUiisxW2VRD8,4273
|
|
20
|
+
dagster_cloud_cli/commands/ci/utils.py,sha256=FL0-fUYw4PpbimE29BXR_NC1vpswa6xFM9DcyIz15kA,608
|
|
21
|
+
dagster_cloud_cli/commands/deployment/__init__.py,sha256=yj4lQwk-4Z9-nSvk3ya3a16Ja1R6WuYmx77-2PIoHYs,3176
|
|
22
|
+
dagster_cloud_cli/commands/deployment/alert_policies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
dagster_cloud_cli/commands/deployment/alert_policies/commands.py,sha256=Qoa4bjYZ-P4DvNhMIUCfqLcOC0O7G6JTiV9_5IfC9WQ,1619
|
|
24
|
+
dagster_cloud_cli/commands/integration/__init__.py,sha256=1h6xQ6wUmHAVl1zuM1TDuED-4RaXU4ds9x0yuUfUHcg,227
|
|
25
|
+
dagster_cloud_cli/commands/integration/atlan/__init__.py,sha256=LyAhxtfk-hR-NK-WUlvQVJnzcNv1s-FvELXMcPjNHeA,3199
|
|
26
|
+
dagster_cloud_cli/commands/job/__init__.py,sha256=L5Zi7Sw8-C0GzND14tTZR9UUGeiZ_RjrlBUgqDIjuO4,3569
|
|
27
|
+
dagster_cloud_cli/commands/organization/__init__.py,sha256=Lv-tGr6oXK28AQ0rgtmnHDZ39H-ORRPFZYhV4tVe2rM,4083
|
|
28
|
+
dagster_cloud_cli/commands/organization/saml/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
dagster_cloud_cli/commands/organization/saml/commands.py,sha256=_rewsy04tdn_HDU4uQj6U9TnQpncJVCzy6kQvRVrn7M,2760
|
|
30
|
+
dagster_cloud_cli/commands/run/__init__.py,sha256=CVjs26DRPbIcVk4De4-9vEZwQckkgwybW2YOwr01Wc8,871
|
|
31
|
+
dagster_cloud_cli/commands/serverless/Dockerfile,sha256=UciDiFRDhRT6TfV-xkwK4W5DPFy-wT1RAmgidq8L7XU,1633
|
|
32
|
+
dagster_cloud_cli/commands/serverless/Dockerfile.dagster-cloud-cli,sha256=zPYmTNOJsngRQy_W-4KQDGO1A-WTQhxeZ9Yx_rd9nOs,628
|
|
33
|
+
dagster_cloud_cli/commands/serverless/__init__.py,sha256=KvsiUT6GIJd2MRBwPqRIvrKDVo1xa3o-2-HGKNILAX0,18947
|
|
34
|
+
dagster_cloud_cli/commands/workspace/__init__.py,sha256=wI7NGwjcBFLGStA72nphZ91BmibNoazoHYk4dVI8yeA,12221
|
|
35
|
+
dagster_cloud_cli/config/__init__.py,sha256=wzfzYYuXm8Un_xl5pwTcQydwg8iib2j49XWtCvYKXe8,233
|
|
36
|
+
dagster_cloud_cli/config/jinja_template_loader.py,sha256=-bl9GoIZrYc_qzDL_6LpgIYzhKvfY1JxwoEAfx34mUw,1441
|
|
37
|
+
dagster_cloud_cli/config/list_merge_strategies.py,sha256=q7XDO4uXMCCed8nzTFIAAfFerm7zfv6KSkTs-LNiM24,2532
|
|
38
|
+
dagster_cloud_cli/config/loader.py,sha256=tLX_mddEEztbKudQN-I94vetTf7SaYkai7kkqHhBqGc,925
|
|
39
|
+
dagster_cloud_cli/config/merger.py,sha256=P_rnIQ6DmezkEPl08Bx_1D4-BfnX9CTcgzd5Sn8cBTE,4583
|
|
40
|
+
dagster_cloud_cli/config/models.py,sha256=I4Cxo--Lrb_p5FpxbXpFovuNDNygq0hxdG-GiM0UBOI,2567
|
|
41
|
+
dagster_cloud_cli/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
|
+
dagster_cloud_cli/core/agent_queue.py,sha256=7rfBHM_Fp3Cyo6FztBsCX2XbVKSaikGGMrgF709bX48,65
|
|
43
|
+
dagster_cloud_cli/core/alert_types.py,sha256=xgoixkdzG_Iz2ANYZ8wo_Rlvrut90rgDKRkvkEAvuvw,907
|
|
44
|
+
dagster_cloud_cli/core/artifacts.py,sha256=fuw4VClMWfxfey_558jcfViOW4JocZvS1woSaZlSxfM,4800
|
|
45
|
+
dagster_cloud_cli/core/docker_runner.py,sha256=cahSc-63-toFaxulvFqoGTkp-loZ1hdrJRZj6u8FEgs,1686
|
|
46
|
+
dagster_cloud_cli/core/errors.py,sha256=k5SJHOOo4jitnxhRd-0lYghc1nhvaaBggmAmAmUjKpo,1044
|
|
47
|
+
dagster_cloud_cli/core/graphql_client.py,sha256=uMlz0rqFiIGbD6fPUPwEwZ_sQu1Zs8qc_iYt8dBj7po,13883
|
|
48
|
+
dagster_cloud_cli/core/workspace.py,sha256=y-fSPWtH6ZzydL5VLpj77H4VtISnI_NihE2D79lKrkg,5046
|
|
49
|
+
dagster_cloud_cli/core/headers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
|
+
dagster_cloud_cli/core/headers/auth.py,sha256=byw8T_23WOsESjnLIqc9NwvMNlJTyEl2wLt2S0U-1NI,376
|
|
51
|
+
dagster_cloud_cli/core/headers/impl.py,sha256=Lv4n8QRtc39feDkc81Y92R5wC6jgjLtA1QzfsrDBYQI,972
|
|
52
|
+
dagster_cloud_cli/core/headers/versioning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
|
+
dagster_cloud_cli/core/headers/versioning/constants.py,sha256=wfW1FJjd5tSx7uHeFrAI8wPuQQr8Z6wtoh0iXjEVoCw,96
|
|
54
|
+
dagster_cloud_cli/core/pex_builder/__init__.py,sha256=D-NtbxoQWhlgbXCzRsh8RKU5YoW1kHz5ur5o3LS8ChA,205
|
|
55
|
+
dagster_cloud_cli/core/pex_builder/code_location.py,sha256=T2oaHPCFaox7AgnVz3Kt39tKmzMlBrZEumRPSA_CIWs,4601
|
|
56
|
+
dagster_cloud_cli/core/pex_builder/deploy.py,sha256=gtBig0q6ifSPRxaLBR4TniTuxFEyUPDNjoogxzN2OVY,8445
|
|
57
|
+
dagster_cloud_cli/core/pex_builder/deps.py,sha256=NSYkjaSezj4dsMlFi712kad0pFPm2lit_SGZX1SrayI,18250
|
|
58
|
+
dagster_cloud_cli/core/pex_builder/git_context.py,sha256=hRtH1D----3N409EOrGQJSVt31d6_LQRXxpAgxWf-eE,946
|
|
59
|
+
dagster_cloud_cli/core/pex_builder/github_context.py,sha256=uTGIi-pINFaKDV8lZpnh0ATkM_zElh6m0GYS8cqtASQ,6779
|
|
60
|
+
dagster_cloud_cli/core/pex_builder/gitlab_context.py,sha256=fRzxcA2kpZdbNT61Re19BLQVBkrLvLtrPP8xkP40hdo,1065
|
|
61
|
+
dagster_cloud_cli/core/pex_builder/parse_workspace.py,sha256=KDC38iPGaG4DM2dof4knR2YMRGvW-HlThyVqhQCYZMA,1220
|
|
62
|
+
dagster_cloud_cli/core/pex_builder/pex_registry.py,sha256=M6DLZ7VXwVNB4Mlx3W5W9YvR9tppWO4jH9WuXQzrWr4,4799
|
|
63
|
+
dagster_cloud_cli/core/pex_builder/platforms.py,sha256=RrxBK5UeBZqF9_YlygEuKJCmrIXTnnCRJUSzFIGxwJk,282469
|
|
64
|
+
dagster_cloud_cli/core/pex_builder/selftest.py,sha256=rdaaJbdSLxPhtZPAMwFyjSurBVn8UnLlmeUu5nVmSWg,383
|
|
65
|
+
dagster_cloud_cli/core/pex_builder/source.py,sha256=6BiJG9MuIsZiKPB6JkL_MnKZRbVosmtRKYfuTibxFl4,5899
|
|
66
|
+
dagster_cloud_cli/core/pex_builder/util.py,sha256=NoI2wPa9HrBbBvkvspHIH2QBDntrUXX1SqO-R892NeM,6377
|
|
67
|
+
dagster_cloud_cli-1.12.16.dist-info/METADATA,sha256=h2RnQloD73pHwk2xyF9FkVRN8igAQV7ayMmrQ7z1aEo,1184
|
|
68
|
+
dagster_cloud_cli-1.12.16.dist-info/WHEEL,sha256=e22IIVjxDyt0lABi4WpktFIGsmO_ebSDXLnPUbPK0E0,105
|
|
69
|
+
dagster_cloud_cli-1.12.16.dist-info/entry_points.txt,sha256=AN8s1nvYFGRZFgMJKP3WDyr9dtRMy5VhD_m6HyYs-U0,115
|
|
70
|
+
dagster_cloud_cli-1.12.16.dist-info/licenses/LICENSE,sha256=hgU51ohULAFKZE2la8sartPYoUaAA14jxFAfFC4Tow0,11347
|
|
71
|
+
dagster_cloud_cli-1.12.16.dist-info/RECORD,,
|