intuned-runtime 1.3.2__py3-none-any.whl → 1.3.4__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.

Potentially problematic release.


This version of intuned-runtime might be problematic. Click here for more details.

Files changed (51) hide show
  1. intuned_cli/commands/__init__.py +1 -1
  2. intuned_cli/commands/attempt_api_command.py +0 -2
  3. intuned_cli/commands/attempt_authsession_check_command.py +0 -2
  4. intuned_cli/commands/attempt_authsession_command.py +0 -3
  5. intuned_cli/commands/attempt_authsession_create_command.py +0 -2
  6. intuned_cli/commands/attempt_command.py +0 -3
  7. intuned_cli/commands/authsession_command.py +0 -3
  8. intuned_cli/commands/authsession_record_command.py +0 -2
  9. intuned_cli/commands/command.py +0 -3
  10. intuned_cli/commands/deploy_command.py +0 -3
  11. intuned_cli/commands/init_command.py +0 -3
  12. intuned_cli/commands/run_api_command.py +0 -2
  13. intuned_cli/commands/run_authsession_command.py +0 -3
  14. intuned_cli/commands/run_authsession_create_command.py +2 -5
  15. intuned_cli/commands/run_authsession_update_command.py +3 -6
  16. intuned_cli/commands/run_authsession_validate_command.py +2 -5
  17. intuned_cli/commands/run_command.py +0 -3
  18. intuned_cli/commands/save_command.py +0 -3
  19. intuned_cli/controller/deploy.py +0 -2
  20. intuned_cli/controller/save.py +0 -18
  21. intuned_cli/utils/wrapper.py +13 -3
  22. intuned_internal_cli/commands/__init__.py +8 -16
  23. intuned_internal_cli/commands/browser/__init__.py +1 -1
  24. intuned_internal_cli/commands/browser/save_state.py +2 -3
  25. intuned_internal_cli/commands/project/__init__.py +7 -9
  26. intuned_internal_cli/commands/project/auth_session/__init__.py +3 -3
  27. intuned_internal_cli/commands/project/auth_session/check.py +2 -2
  28. intuned_internal_cli/commands/project/auth_session/create.py +2 -3
  29. intuned_internal_cli/commands/project/auth_session/load.py +2 -3
  30. intuned_internal_cli/commands/project/project.py +2 -2
  31. intuned_internal_cli/commands/project/run.py +2 -2
  32. intuned_internal_cli/commands/project/run_interface.py +75 -8
  33. intuned_internal_cli/commands/project/type_check.py +5 -5
  34. intuned_internal_cli/commands/root.py +2 -1
  35. intuned_internal_cli/utils/wrapper.py +15 -0
  36. {intuned_runtime-1.3.2.dist-info → intuned_runtime-1.3.4.dist-info}/METADATA +1 -1
  37. {intuned_runtime-1.3.2.dist-info → intuned_runtime-1.3.4.dist-info}/RECORD +45 -49
  38. runtime/browser/launch_browser.py +15 -0
  39. runtime/browser/launch_chromium.py +10 -1
  40. runtime/run/types.py +0 -5
  41. runtime/types/settings_types.py +12 -4
  42. runtime/utils/anyio.py +26 -0
  43. intuned_internal_cli/commands/ai_source/__init__.py +0 -4
  44. intuned_internal_cli/commands/ai_source/ai_source.py +0 -10
  45. intuned_internal_cli/commands/ai_source/deploy.py +0 -64
  46. intuned_internal_cli/commands/init.py +0 -127
  47. intuned_internal_cli/commands/project/upgrade.py +0 -92
  48. intuned_internal_cli/commands/publish_packages.py +0 -264
  49. {intuned_runtime-1.3.2.dist-info → intuned_runtime-1.3.4.dist-info}/WHEEL +0 -0
  50. {intuned_runtime-1.3.2.dist-info → intuned_runtime-1.3.4.dist-info}/entry_points.txt +0 -0
  51. {intuned_runtime-1.3.2.dist-info → intuned_runtime-1.3.4.dist-info}/licenses/LICENSE +0 -0
@@ -1,127 +0,0 @@
1
- import json
2
- import os
3
- from typing import Any
4
-
5
- import arguably
6
- import toml
7
- from more_termcolor import bold # type: ignore
8
- from more_termcolor import green # type: ignore
9
-
10
- from ..utils.code_tree import get_project_name
11
-
12
-
13
- @arguably.command # type: ignore
14
- def init(
15
- *,
16
- yes_to_all: bool = False,
17
- no_to_all: bool = False,
18
- project_name: str | None,
19
- ):
20
- """
21
- Initializes current app, creating pyproject.toml and Intuned.json files. Will ask for confirmation before overwriting existing files.
22
-
23
- Args:
24
- yes_to_all (bool): [-y/--yes] Answer yes to all confirmation prompts
25
- no_to_all (bool): [-n/--no] Answer no to any confirmation prompts
26
- project_name (str | None): Name of the project. Will automatically resolve if not provided.
27
-
28
- Returns:
29
- None
30
- """
31
-
32
- if yes_to_all and no_to_all:
33
- raise ValueError("Cannot specify both --yes and --no")
34
-
35
- def should_write_file(file: str) -> bool:
36
- if not os.path.exists(file):
37
- return True
38
- if no_to_all:
39
- return False
40
- elif yes_to_all:
41
- print(bold(f"Overwriting {green(file)}"))
42
- return True
43
- return input(f"Overwrite {green(file)}? (y/N) ").lower().strip() == "y"
44
-
45
- project_name = project_name or get_project_name(".")
46
- print(bold("Initializing"), green(project_name))
47
-
48
- def print_created(file: str) -> None:
49
- print(bold("📦 Created"), green(file))
50
-
51
- pyproject_name = "pyproject.toml"
52
- if should_write_file(pyproject_name):
53
- with open(pyproject_name, "w") as f:
54
- toml.dump(_get_pyproject(project_name), f)
55
- print_created(pyproject_name)
56
-
57
- intuned_json_name = "Intuned.json"
58
- if should_write_file(intuned_json_name):
59
- with open(intuned_json_name, "w") as f:
60
- json.dump(_get_intuned_json(project_name), f, indent=2)
61
- print_created(intuned_json_name)
62
-
63
- readme_name = "README.md"
64
- if should_write_file(readme_name):
65
- with open(readme_name, "w") as f:
66
- f.write(_get_readme(project_name))
67
- print_created(readme_name)
68
-
69
- print(bold("✨ Done!"))
70
-
71
-
72
- def _get_pyproject(project_name: str) -> dict[str, Any]:
73
- return {
74
- "build-system": {"requires": ["poetry-core>=1.2.0"], "build-backend": "poetry.core.masonry.api"},
75
- "tool": {
76
- "poetry": {
77
- "package-mode": False,
78
- "name": project_name,
79
- "version": "0.0.1",
80
- "description": f"Project {project_name}",
81
- "authors": ["Intuned <service@intunedhq.com>"],
82
- "readme": "README.md",
83
- "dependencies": {
84
- "python": ">=3.12,<3.13",
85
- "intuned-runtime": {
86
- "git": "ssh://git@github.com/Intuned/python-packages.git",
87
- "tag": "runtime-latest",
88
- "subdirectory": "runtime",
89
- },
90
- "intuned-sdk": {
91
- "git": "ssh://git@github.com/Intuned/python-packages.git",
92
- "tag": "sdk-latest",
93
- "subdirectory": "sdk",
94
- },
95
- },
96
- }
97
- },
98
- }
99
-
100
-
101
- def _get_intuned_json(_project_name: str) -> dict[str, Any]:
102
- return {
103
- "authSessions": {"enabled": False},
104
- "scale": {"machineCount": 1, "softLimit": 1, "hardLimit": 5, "memory": 2048, "cpus": 6},
105
- "proxy": {"enabled": False},
106
- }
107
-
108
-
109
- def _get_readme(project_name: str) -> str:
110
- return (
111
- f"# `{project_name}` Intuned Automation Project\n"
112
- f"\n"
113
- f"\n"
114
- f"## Getting started\n"
115
- f"- Install dependencies: `poetry install`\n"
116
- f"- Activate virtual environment: `poetry shell`\n"
117
- f"- Project commands: `intuned project --help`\n"
118
- f" - Run the project:\n"
119
- f" - Sample mode: `intuned project run`\n"
120
- f" - Full mode: `intuned project run --mode full`\n"
121
- f" - Single mode: `intuned project run --mode single`\n"
122
- f" - Deploy the project: `intuned project deploy`\n"
123
- f" - Use `--help` for full details on each command.\n"
124
- f"\n"
125
- f"## SDK\n"
126
- f"- If you want to use a specific version of the SDK, make sure to change the tag from `sdk-latest` to `sdk-<version>` in **pyproject.toml**.\n"
127
- )
@@ -1,92 +0,0 @@
1
- import os
2
- import subprocess
3
- from typing import List
4
- from typing import Tuple
5
-
6
- import arguably
7
- import git
8
- import git.cmd
9
- import semver
10
-
11
-
12
- @arguably.command # type: ignore
13
- def project__upgrade():
14
- """
15
- Upgrade the project's Intuned runtime and Intuned SDK to the latest version.
16
- """
17
- runtime_version, sdk_version = resolve_packages_versions()
18
- print(f"Upgrading to runtime version {runtime_version} and SDK version {sdk_version}")
19
-
20
- # Upgrade runtime and SDK using poetry
21
- repo_url = "git+ssh://git@github.com/intuned/python-packages.git"
22
- cwd = os.getcwd()
23
-
24
- try:
25
- # Upgrade runtime
26
- subprocess.run(
27
- ["poetry", "add", f"{repo_url}@runtime-{runtime_version}#subdirectory=runtime"], check=True, cwd=cwd
28
- )
29
-
30
- # Upgrade SDK
31
- subprocess.run(["poetry", "add", f"{repo_url}@sdk-{sdk_version}#subdirectory=sdk"], check=True, cwd=cwd)
32
-
33
- except subprocess.CalledProcessError as e:
34
- raise RuntimeError(f"Failed to upgrade packages: {e.stderr}") from e
35
-
36
-
37
- def get_latest_version(versions: List[str], prefix: str) -> str:
38
- """
39
- Get the latest version from a list of versioned tags.
40
- Filters out dev versions and returns the highest semver version.
41
- """
42
- valid_versions: list[str] = []
43
- for version in versions:
44
- version_str = version.replace(f"{prefix}-", "")
45
- try:
46
- # Skip dev versions
47
- if "dev" not in version_str:
48
- semver.VersionInfo.parse(version_str)
49
- valid_versions.append(version_str)
50
- except ValueError:
51
- continue
52
-
53
- if not valid_versions:
54
- raise ValueError(f"No valid versions found for {prefix}")
55
-
56
- # Sort versions and get the latest
57
- latest = str(max(map(semver.VersionInfo.parse, valid_versions)))
58
- return latest
59
-
60
-
61
- def resolve_packages_versions() -> Tuple[str, str]:
62
- """
63
- Resolves the latest versions of runtime and SDK packages using git ls-remote.
64
- Returns a tuple of (runtime_version, sdk_version)
65
- """
66
- try:
67
- # Use GitPython to get remote tags
68
- repo = git.cmd.Git()
69
- refs = repo.ls_remote("--tags", "git@github.com:intuned/python-packages.git").split("\n")
70
-
71
- # Parse the output which looks like:
72
- # hash refs/tags/runtime-1.0.1
73
- # hash refs/tags/sdk-0.1.1
74
- tags: list[str] = []
75
- for line in refs:
76
- if not line.strip():
77
- continue
78
- _, ref = line.split(None, 1)
79
- tag = ref.replace("refs/tags/", "")
80
- tags.append(tag)
81
-
82
- # Split into runtime and sdk versions
83
- runtime_versions = [tag for tag in tags if tag.startswith("runtime-")]
84
- sdk_versions = [tag for tag in tags if tag.startswith("sdk-")]
85
-
86
- latest_runtime = get_latest_version(runtime_versions, "runtime")
87
- latest_sdk = get_latest_version(sdk_versions, "sdk")
88
-
89
- return latest_runtime, latest_sdk
90
-
91
- except git.GitCommandError as e:
92
- raise RuntimeError(f"Failed to fetch tags from git repository: {e.stderr}") from e
@@ -1,264 +0,0 @@
1
- import functools
2
- import subprocess
3
- from os import environ
4
- from os import path
5
-
6
- import arguably
7
- import toml
8
- from more_termcolor import bold # type: ignore
9
- from more_termcolor import cyan # type: ignore
10
- from more_termcolor import green # type: ignore
11
- from more_termcolor import italic # type: ignore
12
- from more_termcolor import underline # type: ignore
13
- from more_termcolor import yellow # type: ignore
14
-
15
-
16
- @arguably.command # type: ignore
17
- def publish_packages(
18
- *,
19
- sdk: bool = False,
20
- runtime: bool = False,
21
- show_diff: bool = False,
22
- update_template: bool = False,
23
- ):
24
- """
25
- Publishes the SDK and Runtime packages to `python-packages` repository. Uses the version defined in the pyproject.toml file.
26
- Args:
27
- sdk (bool): Publish the SDK package.
28
- runtime (bool): Publish the Runtime package.
29
- show_diff (bool): Show the diff of the files that will be copied to the package repo. Configure your git difftool to use your preferred diff tool (VSCode recommended).
30
- update_template (bool): [-u/--update-template] Update the template versions in the WebApp repo.
31
- """
32
-
33
- sdk_source_path = None
34
- sdk_runtime_path = None
35
-
36
- webapp_path = environ.get("WEBAPP_PATH")
37
- if not webapp_path:
38
- webapp_resolved_path = path.join(path.dirname(__file__), "..", "..", "..", "..")
39
- if path.exists(path.join(webapp_resolved_path, ".git")):
40
- webapp_path = webapp_resolved_path
41
- else:
42
- raise ValueError(
43
- "WebApp repo could not be found. Maybe you are not running the globally-installed CLI. Set WEBAPP_PATH environment variable."
44
- )
45
- print(bold("WebApp path"), underline(cyan(path.abspath(webapp_path))))
46
-
47
- sdk_source_path = path.join(webapp_path, "apps", "python-sdk")
48
- sdk_runtime_path = path.join(webapp_path, "apps", "python-runtime")
49
-
50
- if True not in [sdk, runtime]:
51
- raise ValueError("You should select at least one package to release")
52
-
53
- _release_package = functools.partial(release_package, webapp_path=webapp_path, show_diff=show_diff)
54
-
55
- if sdk:
56
- _release_package(
57
- package_human_name="SDK",
58
- package_name="intuned-sdk",
59
- packages_repo_dirname="sdk",
60
- package_source_path=sdk_source_path,
61
- )
62
-
63
- if runtime:
64
- _release_package(
65
- package_human_name="Runtime",
66
- package_name="intuned-runtime",
67
- packages_repo_dirname="runtime",
68
- package_source_path=sdk_runtime_path,
69
- )
70
-
71
- runtime_version = check_package_version(sdk_runtime_path, "intuned-runtime")
72
- sdk_version = check_package_version(sdk_source_path, "intuned-sdk")
73
-
74
- # Only run template generation in production environment
75
- if update_template:
76
- update_template_version(webapp_path, runtime_version, sdk_version)
77
- generate_authoring_template_files(webapp_path)
78
- else:
79
- print(bold(f"\n🔍 {yellow('Skipping authoring template generation - only runs in production environment')}"))
80
-
81
-
82
- def generate_authoring_template_files(webapp_path: str):
83
- """
84
- Generates the authoring template files by running the `yarn generate:build-authoring-template-files` command.
85
- """
86
- web_app_dir = path.join(webapp_path, "apps", "web")
87
- if not path.exists(web_app_dir):
88
- raise ValueError(f"Web app directory not found at {web_app_dir}")
89
-
90
- print(bold("\n📝 Generating authoring template files..."))
91
-
92
- # Run the command to generate the authoring template files
93
- subprocess.run(
94
- ["yarn", "generate:build-authoring-template-files"],
95
- cwd=web_app_dir,
96
- check=True,
97
- )
98
- print(bold(f"\n✨ {green('Authoring template files generated successfully!')}"))
99
-
100
-
101
- def update_template_version(webapp_path: str, runtime_version: str, sdk_version: str):
102
- template_path = path.join(
103
- webapp_path, "apps", "web", "packagerWorkerAssets", "packagerTemplates", "playwright_v1_python", "default"
104
- )
105
- pyproject_path = path.join(template_path, "pyproject.toml")
106
- if not path.exists(pyproject_path):
107
- raise ValueError(f"pyproject.toml not found at {pyproject_path}")
108
-
109
- with open(pyproject_path) as f:
110
- pyproject = toml.load(f)
111
-
112
- # Update the runtime and sdk versions
113
- pyproject["tool"]["poetry"]["dependencies"]["intuned-runtime"]["tag"] = f"runtime-{runtime_version}"
114
- pyproject["tool"]["poetry"]["dependencies"]["intuned-sdk"]["tag"] = f"sdk-{sdk_version}"
115
-
116
- with open(pyproject_path, "w") as f:
117
- toml.dump(pyproject, f)
118
-
119
- print(bold(f"\n✨ {green('Updated template versions successfully!')}"))
120
-
121
-
122
- def release_package(
123
- *,
124
- package_human_name: str,
125
- package_name: str,
126
- package_source_path: str | None,
127
- webapp_path: str,
128
- packages_repo_dirname: str,
129
- show_diff: bool = False,
130
- ):
131
- print(bold(f"🚀 Releasing {green(package_human_name)}"))
132
- if not package_source_path:
133
- package_source_path_input = input(bold(f" Enter {green(package_human_name)} path:"))
134
- package_source_path = package_source_path_input
135
- else:
136
- print(bold(f" {green(package_human_name)} Source Path"), underline(cyan(path.abspath(package_source_path))))
137
- package_version = check_package_version(package_source_path, package_name)
138
-
139
- print(bold(f" Using package version {green(package_version)} to release:"))
140
-
141
- package_repo_path = path.join(webapp_path, "..", "python-packages", packages_repo_dirname)
142
- if not path.exists(package_repo_path):
143
- raise ValueError(
144
- f"Package path does not exist. The {underline("python-packages")} repo is expected to be next to the {underline("WebApp")} (expected package at {underline(path.abspath(package_repo_path))})"
145
- )
146
-
147
- package_tag = f"{packages_repo_dirname}-{package_version}"
148
-
149
- # Check if a tag with the sdk_version exists
150
- result = subprocess.run(
151
- ["git", "tag", "--list", package_tag], capture_output=True, text=True, cwd=package_repo_path
152
- )
153
- should_delete_tag = False
154
- if package_tag in result.stdout.split():
155
- raise ValueError(f"Tag {package_version} already exists. Please update the version in the pyproject.toml file.")
156
-
157
- # fetch and pull main branch
158
- print(bold("\n📡 Fetching main branch..."))
159
- subprocess.run(["git", "fetch", "origin", "main"], cwd=package_repo_path, check=True)
160
- print(bold("🔃 Pulling main branch..."))
161
- subprocess.run(["git", "reset", "--hard", "origin/main"], cwd=package_repo_path, check=True)
162
-
163
- # switch to main branch
164
- print(bold("🔄 Switching to main branch..."))
165
- subprocess.run(["git", "checkout", "main"], cwd=package_repo_path, check=True)
166
-
167
- print(bold("📑 Writing source to repo path..."))
168
- print(
169
- yellow(
170
- f"This will delete all files in {underline(path.realpath(package_repo_path))} and copy the source from {underline(path.realpath(package_source_path))}"
171
- )
172
- )
173
- if input("Continue? (y, N) ").lower().strip() != "y":
174
- raise ValueError("Publish cancelled")
175
-
176
- # delete all files in the repo path except .git
177
- subprocess.run(
178
- [
179
- "find",
180
- package_repo_path,
181
- "-mindepth",
182
- "1",
183
- "-maxdepth",
184
- "1",
185
- "-not",
186
- "-name",
187
- ".git",
188
- "-exec",
189
- "rm",
190
- "-rf",
191
- "{}",
192
- "+",
193
- ]
194
- )
195
- yes_process = subprocess.Popen(["yes"], stdout=subprocess.PIPE)
196
- try:
197
- subprocess.run(
198
- ["cp", "-rf", f"{path.realpath(package_source_path)}/", path.realpath(package_repo_path)],
199
- stdin=yes_process.stdout,
200
- check=True,
201
- )
202
- finally:
203
- yes_process.kill()
204
-
205
- # Commit and push copied changes to main, force with lease
206
- print(bold("\n📄 Committing changes..."))
207
- subprocess.run(["git", "add", "."], cwd=package_repo_path, check=True)
208
- subprocess.run(
209
- ["git", "commit", "--allow-empty", "-m", f"Release {package_human_name} version {package_version}"],
210
- cwd=package_repo_path,
211
- check=True,
212
- )
213
-
214
- try:
215
- if show_diff:
216
- print(bold("\n🔍 Showing diff..."))
217
- print(italic("Close the diff tool to continue. You will be prompted to confirm the release."))
218
- subprocess.run(["git", "difftool", "HEAD^", "-t", "vscode", "-y"], cwd=package_repo_path, check=True)
219
-
220
- if input("Push? (y, N) ").lower().strip() != "y":
221
- raise ValueError("Publish cancelled")
222
-
223
- print(bold("\n📝 Pushing changes..."))
224
- subprocess.run(["git", "push", "origin", "main", "--force-with-lease"], cwd=package_repo_path, check=True)
225
-
226
- except (KeyboardInterrupt, ValueError):
227
- print(bold("Resetting commit..."))
228
- # drop the current commit and go back to the previous state
229
- subprocess.run(["git", "reset", "--hard", "HEAD^"], cwd=package_repo_path, check=True)
230
- raise
231
-
232
- # Create a tag with the version to the current HEAD and push it
233
- print(bold(f"\n📝 Creating tag {green(package_tag)}..."))
234
- if should_delete_tag:
235
- subprocess.run(["git", "tag", "-d", package_tag], cwd=package_repo_path, check=True)
236
- subprocess.run(["git", "tag", package_tag], cwd=package_repo_path, check=True)
237
- subprocess.run(
238
- ["git", "push", "origin", package_tag, *(["--force"] if should_delete_tag else [])],
239
- cwd=package_repo_path,
240
- check=True,
241
- )
242
-
243
- print(bold(f"\n✨ {green(package_human_name)} released successfully!\n\n"))
244
-
245
-
246
- def check_package_version(package_path: str, package_expected_name: str):
247
- if not path.exists(package_path):
248
- raise ValueError("Invalid package path")
249
- pyproject_path = path.join(package_path, "pyproject.toml")
250
- if not path.exists(pyproject_path):
251
- raise ValueError("pyproject.toml not found in package path")
252
- with open(pyproject_path) as f:
253
- pyproject = toml.load(f)
254
- if not pyproject:
255
- raise ValueError("Invalid pyproject.toml")
256
- if not pyproject.get("tool"):
257
- raise ValueError("Invalid pyproject.toml")
258
- if not pyproject["tool"].get("poetry"):
259
- raise ValueError("Invalid pyproject.toml")
260
- if pyproject["tool"]["poetry"].get("name") != package_expected_name:
261
- raise ValueError(f"Invalid package name - expected {package_expected_name}")
262
- if not pyproject["tool"]["poetry"].get("version"):
263
- raise ValueError("Invalid package version")
264
- return pyproject["tool"]["poetry"]["version"]