intuned-runtime 1.3.1__py3-none-any.whl → 1.3.3__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.
- intuned_cli/__init__.py +15 -24
- intuned_cli/commands/__init__.py +5 -0
- intuned_cli/commands/attempt_api_command.py +8 -2
- intuned_cli/commands/attempt_authsession_check_command.py +8 -2
- intuned_cli/commands/attempt_authsession_command.py +4 -7
- intuned_cli/commands/attempt_authsession_create_command.py +9 -3
- intuned_cli/commands/attempt_command.py +4 -7
- intuned_cli/commands/authsession_command.py +9 -0
- intuned_cli/commands/authsession_record_command.py +52 -0
- intuned_cli/commands/command.py +6 -7
- intuned_cli/commands/deploy_command.py +2 -3
- intuned_cli/commands/init_command.py +2 -3
- intuned_cli/commands/run_api_command.py +9 -3
- intuned_cli/commands/run_authsession_command.py +4 -7
- intuned_cli/commands/run_authsession_create_command.py +32 -5
- intuned_cli/commands/run_authsession_update_command.py +31 -5
- intuned_cli/commands/run_authsession_validate_command.py +30 -4
- intuned_cli/commands/run_command.py +4 -7
- intuned_cli/commands/save_command.py +2 -3
- intuned_cli/controller/__test__/test_api.py +159 -18
- intuned_cli/controller/__test__/test_authsession.py +497 -6
- intuned_cli/controller/api.py +40 -39
- intuned_cli/controller/authsession.py +213 -110
- intuned_cli/controller/deploy.py +3 -5
- intuned_cli/controller/save.py +47 -66
- intuned_cli/types.py +14 -0
- intuned_cli/utils/__test__/test_browser.py +132 -0
- intuned_cli/utils/__test__/test_traces.py +27 -0
- intuned_cli/utils/api_helpers.py +54 -5
- intuned_cli/utils/auth_session_helpers.py +42 -7
- intuned_cli/utils/backend.py +4 -1
- intuned_cli/utils/browser.py +63 -0
- intuned_cli/utils/error.py +14 -0
- intuned_cli/utils/exclusions.py +1 -0
- intuned_cli/utils/help.py +9 -0
- intuned_cli/utils/traces.py +31 -0
- intuned_cli/utils/wrapper.py +68 -0
- intuned_internal_cli/__init__.py +7 -0
- intuned_internal_cli/commands/__init__.py +8 -16
- intuned_internal_cli/commands/browser/__init__.py +1 -1
- intuned_internal_cli/commands/browser/save_state.py +2 -3
- intuned_internal_cli/commands/project/__init__.py +7 -9
- intuned_internal_cli/commands/project/auth_session/__init__.py +3 -3
- intuned_internal_cli/commands/project/auth_session/check.py +2 -2
- intuned_internal_cli/commands/project/auth_session/create.py +2 -3
- intuned_internal_cli/commands/project/auth_session/load.py +2 -3
- intuned_internal_cli/commands/project/project.py +2 -2
- intuned_internal_cli/commands/project/run.py +2 -2
- intuned_internal_cli/commands/project/run_interface.py +75 -8
- intuned_internal_cli/commands/project/type_check.py +5 -5
- intuned_internal_cli/commands/root.py +2 -1
- intuned_internal_cli/utils/wrapper.py +15 -0
- {intuned_runtime-1.3.1.dist-info → intuned_runtime-1.3.3.dist-info}/METADATA +4 -2
- intuned_runtime-1.3.3.dist-info/RECORD +115 -0
- runtime/browser/launch_browser.py +15 -0
- runtime/browser/launch_chromium.py +14 -1
- runtime/run/types.py +0 -5
- runtime/types/settings_types.py +13 -4
- runtime/utils/anyio.py +26 -0
- intuned_internal_cli/commands/ai_source/__init__.py +0 -4
- intuned_internal_cli/commands/ai_source/ai_source.py +0 -10
- intuned_internal_cli/commands/ai_source/deploy.py +0 -64
- intuned_internal_cli/commands/init.py +0 -127
- intuned_internal_cli/commands/project/upgrade.py +0 -92
- intuned_internal_cli/commands/publish_packages.py +0 -264
- intuned_runtime-1.3.1.dist-info/RECORD +0 -111
- {intuned_runtime-1.3.1.dist-info → intuned_runtime-1.3.3.dist-info}/WHEEL +0 -0
- {intuned_runtime-1.3.1.dist-info → intuned_runtime-1.3.3.dist-info}/entry_points.txt +0 -0
- {intuned_runtime-1.3.1.dist-info → intuned_runtime-1.3.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from contextlib import contextmanager
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from intuned_cli.utils.console import console
|
|
6
|
+
from runtime.types.run_types import TracingDisabled
|
|
7
|
+
from runtime.types.run_types import TracingEnabled
|
|
8
|
+
|
|
9
|
+
_trace_dir_name = datetime.now().isoformat()
|
|
10
|
+
|
|
11
|
+
_count = 0
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_trace_path(id: str):
|
|
15
|
+
global _count
|
|
16
|
+
_count += 1
|
|
17
|
+
return Path() / "traces" / _trace_dir_name / f"{_count}-{id}.zip"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@contextmanager
|
|
21
|
+
def cli_trace(id: str | None):
|
|
22
|
+
if not id:
|
|
23
|
+
yield TracingDisabled()
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
trace_path = get_trace_path(id)
|
|
27
|
+
try:
|
|
28
|
+
yield TracingEnabled(file_path=str(trace_path))
|
|
29
|
+
finally:
|
|
30
|
+
if trace_path.exists():
|
|
31
|
+
console.print(f"[bold]Trace saved to [/bold][underline]{str(trace_path)}[/underline]")
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from collections.abc import Awaitable
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from functools import wraps
|
|
5
|
+
from typing import Any
|
|
6
|
+
from typing import cast
|
|
7
|
+
from typing import ParamSpec
|
|
8
|
+
from typing import TypeVar
|
|
9
|
+
|
|
10
|
+
import arguably
|
|
11
|
+
|
|
12
|
+
from intuned_cli.utils.browser import close_cli_browser
|
|
13
|
+
from intuned_cli.utils.browser import is_cli_browser_launched
|
|
14
|
+
from intuned_cli.utils.console import console
|
|
15
|
+
from intuned_cli.utils.error import CLIError
|
|
16
|
+
from intuned_cli.utils.error import CLIExit
|
|
17
|
+
from intuned_cli.utils.error import log_automation_error
|
|
18
|
+
from runtime.errors.run_api_errors import RunApiError
|
|
19
|
+
from runtime.utils.anyio import run_sync
|
|
20
|
+
|
|
21
|
+
P = ParamSpec("P")
|
|
22
|
+
R = TypeVar("R")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def cli_command(fn: Callable[P, Awaitable[R]]) -> Callable[P, R]:
|
|
26
|
+
@arguably.command # type: ignore
|
|
27
|
+
@wraps(fn)
|
|
28
|
+
@run_sync
|
|
29
|
+
async def wrapper(*args: Any, **kwargs: Any) -> R:
|
|
30
|
+
keep_open = kwargs.get("keep_browser_open", False)
|
|
31
|
+
if keep_open:
|
|
32
|
+
console.print(
|
|
33
|
+
"[bold]--keep-browser-open is set, the CLI will not close the last browser after the command completes.[/bold]"
|
|
34
|
+
)
|
|
35
|
+
try:
|
|
36
|
+
result = await fn(*args, **kwargs)
|
|
37
|
+
return result
|
|
38
|
+
except CLIError as e:
|
|
39
|
+
if e.auto_color:
|
|
40
|
+
console.print(f"[bold red]{e.message}[/bold red]")
|
|
41
|
+
else:
|
|
42
|
+
console.print(e.message)
|
|
43
|
+
raise CLIExit(1) from e
|
|
44
|
+
except RunApiError as e:
|
|
45
|
+
log_automation_error(e)
|
|
46
|
+
raise CLIExit(1) from e
|
|
47
|
+
except KeyboardInterrupt:
|
|
48
|
+
console.print("[bold red]Aborted[/bold red]")
|
|
49
|
+
raise CLIExit(1) from None
|
|
50
|
+
except Exception as e:
|
|
51
|
+
console.print(
|
|
52
|
+
f"[red][bold]An error occurred: [/bold]{e}\n[bold]Please report this issue to the Intuned team.[/bold]"
|
|
53
|
+
)
|
|
54
|
+
raise CLIExit(1) from e
|
|
55
|
+
finally:
|
|
56
|
+
if keep_open:
|
|
57
|
+
await _wait_for_user_input()
|
|
58
|
+
await close_cli_browser()
|
|
59
|
+
|
|
60
|
+
return cast(Callable[P, R], wrapper)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
async def _wait_for_user_input():
|
|
64
|
+
if not is_cli_browser_launched():
|
|
65
|
+
return
|
|
66
|
+
if not console.is_terminal:
|
|
67
|
+
return
|
|
68
|
+
await asyncio.to_thread(console.input, "Press Enter to continue...")
|
intuned_internal_cli/__init__.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import sys
|
|
2
3
|
import traceback
|
|
3
4
|
|
|
@@ -12,6 +13,12 @@ from runtime.context.context import IntunedContext
|
|
|
12
13
|
|
|
13
14
|
from . import commands
|
|
14
15
|
|
|
16
|
+
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
|
17
|
+
|
|
18
|
+
logging.getLogger("runtime").setLevel(logging.INFO)
|
|
19
|
+
logging.getLogger("intuned_runtime").setLevel(logging.INFO)
|
|
20
|
+
logging.getLogger("intuned_browser").setLevel(logging.INFO)
|
|
21
|
+
|
|
15
22
|
|
|
16
23
|
def run():
|
|
17
24
|
dotenv = find_dotenv(usecwd=True)
|
|
@@ -1,23 +1,15 @@
|
|
|
1
|
-
from .
|
|
2
|
-
from .
|
|
3
|
-
from .
|
|
4
|
-
from .
|
|
5
|
-
from .project import
|
|
6
|
-
from .project import
|
|
7
|
-
from .project import
|
|
8
|
-
from .
|
|
9
|
-
from .project.auth_session import project__auth_session__create # type: ignore
|
|
10
|
-
from .project.auth_session import project__auth_session__load # type: ignore
|
|
11
|
-
from .publish_packages import publish_packages # type: ignore
|
|
12
|
-
from .root import __root__ # type: ignore
|
|
1
|
+
from .browser import browser__save_state
|
|
2
|
+
from .project import project
|
|
3
|
+
from .project import project__run
|
|
4
|
+
from .project import project__type_check
|
|
5
|
+
from .project.auth_session import project__auth_session__check
|
|
6
|
+
from .project.auth_session import project__auth_session__create
|
|
7
|
+
from .project.auth_session import project__auth_session__load
|
|
8
|
+
from .root import __root__
|
|
13
9
|
|
|
14
10
|
__all__ = [
|
|
15
11
|
"project__run",
|
|
16
|
-
"publish_packages",
|
|
17
|
-
"init",
|
|
18
12
|
"project",
|
|
19
|
-
"ai_source__deploy",
|
|
20
|
-
"ai_source",
|
|
21
13
|
"project__auth_session__load",
|
|
22
14
|
"project__auth_session__create",
|
|
23
15
|
"project__auth_session__check",
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
3
|
|
|
4
|
-
import
|
|
5
|
-
|
|
4
|
+
from intuned_internal_cli.utils.wrapper import internal_cli_command
|
|
6
5
|
from runtime.browser import launch_browser
|
|
7
6
|
from runtime.browser.storage_state import get_storage_state
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
@
|
|
9
|
+
@internal_cli_command
|
|
11
10
|
async def browser__save_state(
|
|
12
11
|
*,
|
|
13
12
|
cdp_address: str,
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
from .auth_session import project__auth_session__check
|
|
2
|
-
from .auth_session import project__auth_session__create
|
|
3
|
-
from .auth_session import project__auth_session__load
|
|
4
|
-
from .project import project
|
|
5
|
-
from .run import project__run
|
|
6
|
-
from .run_interface import project__run_interface
|
|
7
|
-
from .type_check import project__type_check
|
|
8
|
-
from .upgrade import project__upgrade # type: ignore
|
|
1
|
+
from .auth_session import project__auth_session__check
|
|
2
|
+
from .auth_session import project__auth_session__create
|
|
3
|
+
from .auth_session import project__auth_session__load
|
|
4
|
+
from .project import project
|
|
5
|
+
from .run import project__run
|
|
6
|
+
from .run_interface import project__run_interface
|
|
7
|
+
from .type_check import project__type_check
|
|
9
8
|
|
|
10
9
|
__all__ = [
|
|
11
10
|
"run",
|
|
@@ -15,6 +14,5 @@ __all__ = [
|
|
|
15
14
|
"project__auth_session__load",
|
|
16
15
|
"project__auth_session__create",
|
|
17
16
|
"project__auth_session__check",
|
|
18
|
-
"project__upgrade",
|
|
19
17
|
"project__run_interface",
|
|
20
18
|
]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from .check import project__auth_session__check
|
|
2
|
-
from .create import project__auth_session__create
|
|
3
|
-
from .load import project__auth_session__load
|
|
1
|
+
from .check import project__auth_session__check
|
|
2
|
+
from .create import project__auth_session__create
|
|
3
|
+
from .load import project__auth_session__load
|
|
4
4
|
|
|
5
5
|
__all__ = ["project__auth_session__check", "project__auth_session__create", "project__auth_session__load"]
|
|
@@ -2,7 +2,6 @@ import json
|
|
|
2
2
|
import os
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
|
-
import arguably
|
|
6
5
|
import pydantic # type: ignore
|
|
7
6
|
from more_termcolor import bold # type: ignore
|
|
8
7
|
from more_termcolor import green # type: ignore
|
|
@@ -12,6 +11,7 @@ from tenacity import retry_if_not_result
|
|
|
12
11
|
from tenacity import RetryError
|
|
13
12
|
from tenacity import stop_after_attempt
|
|
14
13
|
|
|
14
|
+
from intuned_internal_cli.utils.wrapper import internal_cli_command
|
|
15
15
|
from runtime.context.context import IntunedContext
|
|
16
16
|
from runtime.errors.run_api_errors import RunApiError
|
|
17
17
|
from runtime.run.intuned_settings import load_intuned_settings
|
|
@@ -27,7 +27,7 @@ from runtime.types.run_types import StorageState
|
|
|
27
27
|
from runtime.types.run_types import TracingDisabled
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
@
|
|
30
|
+
@internal_cli_command
|
|
31
31
|
async def project__auth_session__check(
|
|
32
32
|
*,
|
|
33
33
|
no_headless: bool = False,
|
|
@@ -2,8 +2,7 @@ import json
|
|
|
2
2
|
import os
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
|
|
5
|
+
from intuned_internal_cli.utils.wrapper import internal_cli_command
|
|
7
6
|
from runtime.context.context import IntunedContext
|
|
8
7
|
from runtime.errors.run_api_errors import RunApiError
|
|
9
8
|
from runtime.run.intuned_settings import load_intuned_settings
|
|
@@ -16,7 +15,7 @@ from runtime.types.run_types import StandaloneRunOptions
|
|
|
16
15
|
from runtime.types.run_types import TracingDisabled
|
|
17
16
|
|
|
18
17
|
|
|
19
|
-
@
|
|
18
|
+
@internal_cli_command
|
|
20
19
|
async def project__auth_session__create(
|
|
21
20
|
*,
|
|
22
21
|
no_headless: bool = False,
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
3
|
|
|
4
|
-
import
|
|
5
|
-
|
|
4
|
+
from intuned_internal_cli.utils.wrapper import internal_cli_command
|
|
6
5
|
from runtime.browser import launch_browser
|
|
7
6
|
from runtime.browser.storage_state import set_storage_state
|
|
8
7
|
from runtime.run.intuned_settings import load_intuned_settings
|
|
9
8
|
from runtime.types.run_types import StorageState
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
@
|
|
11
|
+
@internal_cli_command
|
|
13
12
|
async def project__auth_session__load(
|
|
14
13
|
*,
|
|
15
14
|
cdp_address: str,
|
|
@@ -10,7 +10,6 @@ from importlib import import_module
|
|
|
10
10
|
from typing import Any
|
|
11
11
|
from typing import cast
|
|
12
12
|
|
|
13
|
-
import arguably
|
|
14
13
|
from dotenv import find_dotenv
|
|
15
14
|
from dotenv import load_dotenv
|
|
16
15
|
from more_termcolor import bold # type: ignore
|
|
@@ -21,6 +20,7 @@ from more_termcolor import on_blue # type: ignore
|
|
|
21
20
|
from more_termcolor import underline # type: ignore
|
|
22
21
|
from more_termcolor import yellow # type: ignore
|
|
23
22
|
|
|
23
|
+
from intuned_internal_cli.utils.wrapper import internal_cli_command
|
|
24
24
|
from runtime.run.intuned_settings import load_intuned_settings
|
|
25
25
|
from runtime.types import Payload
|
|
26
26
|
from runtime.types.run_types import Auth
|
|
@@ -38,7 +38,7 @@ class Mode(StrEnum):
|
|
|
38
38
|
ide = "ide"
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
@
|
|
41
|
+
@internal_cli_command
|
|
42
42
|
async def project__run(
|
|
43
43
|
*,
|
|
44
44
|
api_name: str = "default",
|
|
@@ -2,18 +2,21 @@ import asyncio
|
|
|
2
2
|
import os
|
|
3
3
|
import signal
|
|
4
4
|
import socket
|
|
5
|
+
import sys
|
|
5
6
|
import time
|
|
6
7
|
from collections.abc import AsyncGenerator
|
|
8
|
+
from pathlib import Path
|
|
7
9
|
from typing import Any
|
|
8
10
|
from typing import cast
|
|
9
11
|
from typing import Literal
|
|
10
12
|
|
|
11
|
-
import arguably
|
|
12
13
|
from pydantic import Field
|
|
13
14
|
from pydantic import ValidationError
|
|
14
15
|
|
|
16
|
+
from intuned_internal_cli.utils.wrapper import internal_cli_command
|
|
15
17
|
from runtime.backend_functions import get_auth_session_parameters
|
|
16
18
|
from runtime.context import IntunedContext
|
|
19
|
+
from runtime.errors.run_api_errors import ApiNotFoundError
|
|
17
20
|
from runtime.errors.run_api_errors import InternalInvalidInputError
|
|
18
21
|
from runtime.errors.run_api_errors import RunApiError
|
|
19
22
|
from runtime.run.run_api import import_function_from_api_dir
|
|
@@ -69,15 +72,18 @@ class MessageWrapper(CamelBaseModel):
|
|
|
69
72
|
)
|
|
70
73
|
|
|
71
74
|
|
|
72
|
-
@
|
|
75
|
+
@internal_cli_command
|
|
73
76
|
async def project__run_interface(
|
|
74
77
|
socket_path: str,
|
|
78
|
+
*,
|
|
79
|
+
jsonl: bool = False,
|
|
75
80
|
):
|
|
76
81
|
"""
|
|
77
82
|
Runs the current project. Project must contain an "api" directory with API functions.
|
|
78
83
|
|
|
79
84
|
Args:
|
|
80
85
|
socket_path (str): Path to the socket file.
|
|
86
|
+
jsonl (bool, optional): Use a JSONL client instead of socket. Defaults to False.
|
|
81
87
|
|
|
82
88
|
"""
|
|
83
89
|
|
|
@@ -86,7 +92,7 @@ async def project__run_interface(
|
|
|
86
92
|
raise Exception("socket_path is required")
|
|
87
93
|
|
|
88
94
|
timeout_timestamp = time.time()
|
|
89
|
-
client =
|
|
95
|
+
client = SocketClient(socket_path) if not jsonl else JSONLFileClient(socket_path)
|
|
90
96
|
connected = await client.connect()
|
|
91
97
|
if not connected:
|
|
92
98
|
raise Exception("Failed to connect to UDAS")
|
|
@@ -97,7 +103,9 @@ async def project__run_interface(
|
|
|
97
103
|
|
|
98
104
|
def done(exitCode: int = 0):
|
|
99
105
|
client.close()
|
|
100
|
-
|
|
106
|
+
loop.remove_signal_handler(signal.SIGTERM)
|
|
107
|
+
loop.remove_signal_handler(signal.SIGINT)
|
|
108
|
+
sys.exit(exitCode)
|
|
101
109
|
|
|
102
110
|
def interrupt_signal_handler():
|
|
103
111
|
async def _impl():
|
|
@@ -133,6 +141,11 @@ async def project__run_interface(
|
|
|
133
141
|
asyncio.Task[RunAutomationSuccessResult] | None, None
|
|
134
142
|
)
|
|
135
143
|
|
|
144
|
+
def import_function(file_path: str, automation_name: str | None = None):
|
|
145
|
+
return import_function_from_api_dir(
|
|
146
|
+
automation_function_name=automation_name, file_path=file_path, base_dir=os.getcwd()
|
|
147
|
+
)
|
|
148
|
+
|
|
136
149
|
async def handle_message(message: Message):
|
|
137
150
|
nonlocal run_api_task
|
|
138
151
|
if message.type == "start":
|
|
@@ -151,9 +164,7 @@ async def project__run_interface(
|
|
|
151
164
|
run_api_task = asyncio.create_task(
|
|
152
165
|
run_api(
|
|
153
166
|
message.parameters,
|
|
154
|
-
import_function=
|
|
155
|
-
automation_function_name=automation_name, file_path=file_path, base_dir=os.getcwd()
|
|
156
|
-
),
|
|
167
|
+
import_function=import_function,
|
|
157
168
|
),
|
|
158
169
|
)
|
|
159
170
|
return
|
|
@@ -191,6 +202,14 @@ async def project__run_interface(
|
|
|
191
202
|
await client.send_message({"type": "done", "success": False, "result": message.json})
|
|
192
203
|
break
|
|
193
204
|
if message.type == "ping":
|
|
205
|
+
api_files = await get_python_files_from_dir(Path() / "api")
|
|
206
|
+
apis = [f'api/{str(p.with_suffix("").as_posix())}' for p in api_files]
|
|
207
|
+
|
|
208
|
+
for api in [*apis, "auth-sessions/create", "auth-sessions/check"]:
|
|
209
|
+
try:
|
|
210
|
+
import_function(api)
|
|
211
|
+
except ApiNotFoundError:
|
|
212
|
+
pass
|
|
194
213
|
await client.send_message({"type": "pong"})
|
|
195
214
|
break
|
|
196
215
|
await handle_message(message)
|
|
@@ -231,7 +250,7 @@ async def project__run_interface(
|
|
|
231
250
|
done()
|
|
232
251
|
|
|
233
252
|
|
|
234
|
-
class
|
|
253
|
+
class SocketClient:
|
|
235
254
|
def __init__(self, socket_path: str):
|
|
236
255
|
self.socket_path = socket_path
|
|
237
256
|
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
@@ -263,3 +282,51 @@ class UDASClient:
|
|
|
263
282
|
return
|
|
264
283
|
self.sock.shutdown(socket.SHUT_RDWR)
|
|
265
284
|
self.sock.close()
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
class JSONLFileClient(SocketClient):
|
|
288
|
+
def __init__(self, socket_path: str):
|
|
289
|
+
self.socket_path = socket_path
|
|
290
|
+
self.fp = None
|
|
291
|
+
|
|
292
|
+
async def connect(self):
|
|
293
|
+
if not os.path.exists(self.socket_path):
|
|
294
|
+
return False
|
|
295
|
+
self.fp = open(self.socket_path, "r+b", buffering=0)
|
|
296
|
+
return True
|
|
297
|
+
|
|
298
|
+
def receive_messages(self) -> AsyncGenerator[dict[str, Any], None]:
|
|
299
|
+
import json
|
|
300
|
+
|
|
301
|
+
async def generator():
|
|
302
|
+
if self.fp is None:
|
|
303
|
+
raise Exception("Socket not connected")
|
|
304
|
+
while True:
|
|
305
|
+
line = self.fp.readline()
|
|
306
|
+
if not line:
|
|
307
|
+
break
|
|
308
|
+
yield json.loads(line.decode("utf-8"))
|
|
309
|
+
|
|
310
|
+
return generator()
|
|
311
|
+
|
|
312
|
+
async def send_message(self, message: dict[str, Any]):
|
|
313
|
+
print("Sending message", message)
|
|
314
|
+
|
|
315
|
+
def close(self):
|
|
316
|
+
if not self.fp:
|
|
317
|
+
return
|
|
318
|
+
self.fp.close()
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
async def get_python_files_from_dir(dir: Path) -> list[Path]:
|
|
322
|
+
"""Get all Python files under a directory, returning relative paths."""
|
|
323
|
+
python_files: list[Path] = []
|
|
324
|
+
|
|
325
|
+
file_tree = await asyncio.to_thread(os.walk, dir)
|
|
326
|
+
for root, _, files in file_tree:
|
|
327
|
+
for file in files:
|
|
328
|
+
if file.endswith(".py"):
|
|
329
|
+
full_path = Path(root) / file
|
|
330
|
+
relative_path = full_path.relative_to(dir)
|
|
331
|
+
python_files.append(relative_path)
|
|
332
|
+
return python_files
|
|
@@ -2,15 +2,15 @@ import json
|
|
|
2
2
|
import os
|
|
3
3
|
import subprocess
|
|
4
4
|
import sys
|
|
5
|
+
from typing import Any
|
|
5
6
|
|
|
6
|
-
import
|
|
7
|
+
from intuned_internal_cli.utils.wrapper import internal_cli_command
|
|
7
8
|
|
|
8
9
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
9
|
-
PYRIGHT_CONFIG_PATH = os.path.join(current_dir, "..", "..", "pyright_type_check.json")
|
|
10
|
-
PYRIGHT_CONFIG_PATH = os.path.abspath(PYRIGHT_CONFIG_PATH)
|
|
10
|
+
PYRIGHT_CONFIG_PATH = os.path.abspath(os.path.join(current_dir, "..", "..", "pyright_type_check.json"))
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
@
|
|
13
|
+
@internal_cli_command
|
|
14
14
|
async def project__type_check():
|
|
15
15
|
"""
|
|
16
16
|
Run type checking on the API directory using pyright.
|
|
@@ -39,7 +39,7 @@ async def project__type_check():
|
|
|
39
39
|
print("📦 Checking Types...")
|
|
40
40
|
|
|
41
41
|
try:
|
|
42
|
-
pyright_issues = []
|
|
42
|
+
pyright_issues: list[dict[str, Any]] = []
|
|
43
43
|
pyright_result = subprocess.run(
|
|
44
44
|
["pyright", "--outputjson", project_dir, "--project", PYRIGHT_CONFIG_PATH],
|
|
45
45
|
capture_output=True,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from collections.abc import Awaitable
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from typing import ParamSpec
|
|
4
|
+
from typing import TypeVar
|
|
5
|
+
|
|
6
|
+
import arguably
|
|
7
|
+
|
|
8
|
+
from runtime.utils.anyio import run_sync
|
|
9
|
+
|
|
10
|
+
P = ParamSpec("P")
|
|
11
|
+
R = TypeVar("R")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def internal_cli_command(fn: Callable[P, R | Awaitable[R]]) -> Callable[P, R]:
|
|
15
|
+
return arguably.command(run_sync(fn)) # type: ignore
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: intuned-runtime
|
|
3
|
-
Version: 1.3.
|
|
4
|
-
Summary: Runtime
|
|
3
|
+
Version: 1.3.3
|
|
4
|
+
Summary: Runtime SDK that powers browser automation projects running on Intuned
|
|
5
5
|
License: Elastic-2.0
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: runtime,intuned
|
|
@@ -23,12 +23,14 @@ Requires-Dist: browserforge[all]
|
|
|
23
23
|
Requires-Dist: camoufox[geoip] (>=0.4.11,<0.5.0)
|
|
24
24
|
Requires-Dist: gitpython (>=3.1.43,<4.0.0)
|
|
25
25
|
Requires-Dist: httpx (>=0.23.0,<1)
|
|
26
|
+
Requires-Dist: jsonc-parser (>=1.1.5,<2.0.0)
|
|
26
27
|
Requires-Dist: more-termcolor (>=1.1.3,<2.0.0)
|
|
27
28
|
Requires-Dist: pathspec (>=0.12.1,<0.13.0)
|
|
28
29
|
Requires-Dist: pydantic (>=2.10.6,<3.0.0)
|
|
29
30
|
Requires-Dist: pyright (>=1.1.387,<2.0.0)
|
|
30
31
|
Requires-Dist: python-dotenv (==1.0.1)
|
|
31
32
|
Requires-Dist: pytimeparse (>=1.1.8,<2.0.0)
|
|
33
|
+
Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
|
|
32
34
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
|
33
35
|
Requires-Dist: rich (>=14.1.0,<15.0.0)
|
|
34
36
|
Requires-Dist: ruff (>=0.7.2,<0.8.0)
|