Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CDF-23339] 🐙QuickStart demo #1228

Open
wants to merge 18 commits into
base: user-group
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion cognite_toolkit/_cdf_tk/commands/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
CDFToolConfig,
)

_HAS_PRINTED_COLLECT_MESSAGE = False


class ToolkitCommand:
def __init__(self, print_warning: bool = True, skip_tracking: bool = False, silent: bool = False):
Expand All @@ -39,15 +41,22 @@ def _track_command(self, result: str | Exception) -> None:
self.tracker.track_cli_command(self.warning_list, result, type(self).__name__.removesuffix("Command"))

def run(self, execute: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
global _HAS_PRINTED_COLLECT_MESSAGE
is_collect_command = len(sys.argv) >= 2 and "collect" == sys.argv[1]
if not self.tracker.opted_in and not self.tracker.opted_out and not is_collect_command:
if (
not self.tracker.opted_in
and not self.tracker.opted_out
and not is_collect_command
and not _HAS_PRINTED_COLLECT_MESSAGE
):
print(
"You acknowledge and agree that the CLI tool may collect usage information, user environment, "
"and crash reports for the purposes of providing services of functions that are relevant "
"to use of the CLI tool and product improvements. "
"To remove this message run 'cdf collect opt-in', "
"or to stop collecting usage information run 'cdf collect opt-out'."
)
_HAS_PRINTED_COLLECT_MESSAGE = True

try:
result = execute(*args, **kwargs)
Expand Down
85 changes: 52 additions & 33 deletions cognite_toolkit/_cdf_tk/commands/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
Package,
Packages,
)
from cognite_toolkit._cdf_tk.exceptions import ToolkitRequiredValueError
from cognite_toolkit._cdf_tk.exceptions import ToolkitRequiredValueError, ToolkitValueError
from cognite_toolkit._cdf_tk.hints import verify_module_directory
from cognite_toolkit._cdf_tk.tk_warnings import MediumSeverityWarning
from cognite_toolkit._cdf_tk.utils import humanize_collection, read_yaml_file
Expand Down Expand Up @@ -254,6 +254,9 @@ def init(
organization_dir: Optional[Path] = None,
select_all: bool = False,
clean: bool = False,
user_select: str | None = None,
user_environments: list[str] | None = None,
user_download_data: bool | None = None,
) -> None:
if not organization_dir:
new_line = "\n "
Expand All @@ -275,27 +278,34 @@ def init(
organization_dir=organization_dir, selected_packages=packages, environments=["dev", "prod"], mode=mode
)
return

print("\n")
print(
Panel(
"\n".join(
[
"Wizard for selecting initial modules"
"The modules are thematically bundled in packages you can choose between. You can add more by repeating the process.",
"You can use the arrow keys ⬆ ⬇ on your keyboard to select modules, and press enter ⮐ to continue with your selection.",
]
),
title="Select initial modules",
style="green",
padding=(1, 2),
is_interactive = user_select is not None
if not is_interactive:
print("\n")
print(
Panel(
"\n".join(
[
"Wizard for selecting initial modules"
"The modules are thematically bundled in packages you can choose between. You can add more by repeating the process.",
"You can use the arrow keys ⬆ ⬇ on your keyboard to select modules, and press enter ⮐ to continue with your selection.",
]
),
title="Select initial modules",
style="green",
padding=(1, 2),
)
)
)
mode = self._verify_clean(modules_root_dir, clean)

print(f" [{'yellow' if mode == 'clean' else 'green'}]Using directory [bold]{organization_dir}[/]")

selected = self._select_packages(packages)
if user_select is None:
selected = self._select_packages(packages)
else:
selected = Packages([v for k, v in packages.items() if k == user_select])
if not selected:
raise ToolkitValueError(f"Package {user_select} not found.")

if "bootcamp" in selected:
bootcamp_org = Path.cwd() / "ice-cream-dataops"
if bootcamp_org != organization_dir:
Expand All @@ -306,24 +316,33 @@ def init(
self._create(bootcamp_org, selected, ["test"], mode)
raise typer.Exit()

if not questionary.confirm("Would you like to continue with creation?", default=True).ask():
if (
not is_interactive
and not questionary.confirm("Would you like to continue with creation?", default=True).ask()
):
print("Exiting...")
raise typer.Exit()

environments = questionary.checkbox(
"Which environments would you like to include?",
instruction="Use arrow up/down, press space to select item(s) and enter to save",
choices=[
questionary.Choice(title="dev", checked=True),
questionary.Choice(title="prod", checked=True),
questionary.Choice(title="staging", checked=False),
],
qmark=INDENT,
pointer=POINTER,
style=custom_style_fancy,
).ask()
if user_environments is None:
environments = questionary.checkbox(
"Which environments would you like to include?",
instruction="Use arrow up/down, press space to select item(s) and enter to save",
choices=[
questionary.Choice(title="dev", checked=True),
questionary.Choice(title="prod", checked=True),
questionary.Choice(title="staging", checked=False),
],
qmark=INDENT,
pointer=POINTER,
style=custom_style_fancy,
).ask()
else:
environments = user_environments

download_data = self._get_download_data(selected)
if user_download_data is None:
download_data = self._get_download_data(selected)
else:
download_data = user_download_data
self._create(organization_dir, selected, environments, mode, download_data)

print(
Expand All @@ -339,8 +358,8 @@ def init(
"Please check out https://docs.cognite.com/cdf/deploy/cdf_toolkit/guides/modules/custom for guidance on writing custom modules",
)
)

raise typer.Exit()
if not is_interactive:
raise typer.Exit()

@staticmethod
def _get_download_data(selected: Packages) -> bool:
Expand Down
2 changes: 1 addition & 1 deletion cognite_toolkit/_cdf_tk/hints.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def verify_module_directory(organization_dir: Path, build_env_name: str | None)
cdf_toml = CDFToml.load()
if not cdf_toml.cdf.has_user_set_default_org:
print(
f"{Hint._lead_text} You can specify a 'default_organization_dir = ...' in the '\[cdf]' section of your "
f"{Hint._lead_text} You can specify a 'default_organization_dir = ...' in the 'cdf' section of your "
f"'{CDFToml.file_name}' file to avoid using the -o/--organization-dir argument"
)

Expand Down
16 changes: 11 additions & 5 deletions cognite_toolkit/_cdf_tk/tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from mixpanel import Consumer, Mixpanel

from cognite_toolkit._cdf_tk.cdf_toml import CDFToml
from cognite_toolkit._cdf_tk.constants import IN_BROWSER
from cognite_toolkit._cdf_tk.data_classes._built_modules import BuiltModule
from cognite_toolkit._cdf_tk.tk_warnings import ToolkitWarning, WarningList
from cognite_toolkit._cdf_tk.utils import get_cicd_environment
Expand Down Expand Up @@ -97,11 +98,16 @@ def track() -> None:
event_information,
)

thread = threading.Thread(
target=track,
daemon=False,
)
thread.start()
if IN_BROWSER:
# Pyodide does not support threading
track()
else:
thread = threading.Thread(
target=track,
daemon=False,
)
thread.start()

return True

def get_distinct_id(self) -> str:
Expand Down
7 changes: 6 additions & 1 deletion cognite_toolkit/_cdf_tk/utils/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from rich import print
from rich.progress import track

from cognite_toolkit._cdf_tk.constants import IN_BROWSER
from cognite_toolkit._cdf_tk.tk_warnings import HTTPWarning


Expand All @@ -22,7 +23,11 @@ def __init__(self, repo: str, errors: Literal["continue", "raise"] = "continue")
def copy(self, source: str, destination: Path) -> None:
source_path = Path(source)
to_download = list(self._find_files(source_path))
for path, url in track(to_download, description=f"Downloading from {source_path.as_posix()!r}"):
if IN_BROWSER:
iterable = to_download
else:
iterable = track(to_download, description=f"Downloading from {source_path.as_posix()!r}") # type: ignore [assignment]
for path, url in iterable:
self._download_file(url, path, destination)

def _find_files(self, source: Path) -> Iterable[tuple[Path, str]]:
Expand Down
3 changes: 3 additions & 0 deletions cognite_toolkit/demo/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from ._base import CogniteToolkitDemo

__all__ = ["CogniteToolkitDemo"]
97 changes: 97 additions & 0 deletions cognite_toolkit/demo/_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import tempfile
import textwrap
from pathlib import Path

from rich import print
from rich.panel import Panel

from cognite_toolkit._cdf_tk.commands import BuildCommand, DeployCommand, ModulesCommand
from cognite_toolkit._cdf_tk.loaders import LOADER_BY_FOLDER_NAME
from cognite_toolkit._cdf_tk.utils.auth import CDFToolConfig


class CogniteToolkitDemo:
def __init__(self) -> None:
self._cdf_tool_config = CDFToolConfig()
print(
Panel(
textwrap.dedent("""
This is a demo version of the Cognite Toolkit.

It is intended to demonstrate the content and capabilities of the Toolkit.
It is not intended to be used in production or development environments.

To learn more about the Cognite Toolkit, visit https://docs.cognite.com/cdf/deploy/cdf_toolkit/.
""")
)
)

@property
def _tmp_path(self) -> Path:
return Path(tempfile.gettempdir()).resolve()

@property
def _build_dir(self) -> Path:
build_path = self._tmp_path / "cognite-toolkit-build"
build_path.mkdir(exist_ok=True)
return build_path

@property
def _organization_dir(self) -> Path:
organization_path = self._tmp_path / "cognite-toolkit-organization"
organization_path.mkdir(exist_ok=True)
return organization_path

def quickstart(self) -> None:
print(Panel("Running Toolkit QuickStart..."))
# Lookup user ID to add user ID to the group to run the workflow
user = self._cdf_tool_config.toolkit_client.iam.user_profiles.me()

modules_cmd = ModulesCommand()
modules_cmd.run(
lambda: modules_cmd.init(
organization_dir=self._organization_dir,
user_select="quickstart",
clean=True,
user_download_data=True,
user_environments=["dev"],
)
)
config_yaml = self._organization_dir / "config.dev.yaml"
config_raw = config_yaml.read_text()
# Ensure the user can execute the workflow
config_raw = config_raw.replace("<your user id>", user.user_identifier)
# To avoid warnings about not set values
config_raw = config_raw.replace("<not set>", "123456-to-be-replaced")
config_raw = config_raw.replace("<my-project-dev>", self._cdf_tool_config.project)
config_yaml.write_text(config_raw)

build = BuildCommand()
build.run(
lambda: build.execute(
build_dir=self._build_dir,
organization_dir=self._organization_dir,
selected=None,
build_env_name="dev",
verbose=False,
ToolGlobals=self._cdf_tool_config,
on_error="raise",
no_clean=False,
)
)

deploy = DeployCommand()

deploy.run(
lambda: deploy.execute(
ToolGlobals=self._cdf_tool_config,
build_dir=self._build_dir,
build_env_name="dev",
dry_run=False,
drop_data=False,
drop=False,
force_update=False,
include=list(LOADER_BY_FOLDER_NAME.keys()),
verbose=False,
)
)
Binary file added dist/cognite_toolkit-0.3.12-py3-none-any.whl
Binary file not shown.
Loading