intuned-runtime 1.0.0__py3-none-any.whl → 1.1.1__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.
Files changed (82) hide show
  1. intuned_cli/__init__.py +40 -0
  2. intuned_cli/commands/__init__.py +18 -0
  3. intuned_cli/commands/attempt_api_command.py +51 -0
  4. intuned_cli/commands/attempt_authsession_check_command.py +38 -0
  5. intuned_cli/commands/attempt_authsession_command.py +12 -0
  6. intuned_cli/commands/attempt_authsession_create_command.py +44 -0
  7. intuned_cli/commands/attempt_command.py +12 -0
  8. intuned_cli/commands/command.py +26 -0
  9. intuned_cli/commands/deploy_command.py +47 -0
  10. intuned_cli/commands/init_command.py +21 -0
  11. intuned_cli/commands/run_api_command.py +69 -0
  12. intuned_cli/commands/run_authsession_command.py +12 -0
  13. intuned_cli/commands/run_authsession_create_command.py +50 -0
  14. intuned_cli/commands/run_authsession_update_command.py +52 -0
  15. intuned_cli/commands/run_authsession_validate_command.py +49 -0
  16. intuned_cli/commands/run_command.py +12 -0
  17. intuned_cli/constants/__init__.py +1 -0
  18. intuned_cli/constants/readme.py +134 -0
  19. intuned_cli/controller/__test__/__init__.py +0 -0
  20. intuned_cli/controller/__test__/test_api.py +529 -0
  21. intuned_cli/controller/__test__/test_authsession.py +907 -0
  22. intuned_cli/controller/api.py +212 -0
  23. intuned_cli/controller/authsession.py +458 -0
  24. intuned_cli/controller/deploy.py +352 -0
  25. intuned_cli/controller/init.py +97 -0
  26. intuned_cli/types.py +33 -0
  27. intuned_cli/utils/api_helpers.py +32 -0
  28. intuned_cli/utils/auth_session_helpers.py +57 -0
  29. intuned_cli/utils/backend.py +5 -0
  30. intuned_cli/utils/confirmation.py +0 -0
  31. intuned_cli/utils/console.py +6 -0
  32. intuned_cli/utils/error.py +27 -0
  33. intuned_cli/utils/exclusions.py +40 -0
  34. intuned_cli/utils/get_auth_parameters.py +18 -0
  35. intuned_cli/utils/import_function.py +15 -0
  36. intuned_cli/utils/timeout.py +25 -0
  37. {cli → intuned_internal_cli}/__init__.py +1 -1
  38. {cli → intuned_internal_cli}/commands/__init__.py +2 -0
  39. {cli → intuned_internal_cli}/commands/ai_source/deploy.py +1 -1
  40. {cli → intuned_internal_cli}/commands/browser/save_state.py +2 -2
  41. {cli → intuned_internal_cli}/commands/project/auth_session/load.py +2 -2
  42. {cli → intuned_internal_cli}/commands/project/type_check.py +39 -32
  43. intuned_internal_cli/commands/root.py +15 -0
  44. {intuned_runtime-1.0.0.dist-info → intuned_runtime-1.1.1.dist-info}/METADATA +5 -1
  45. intuned_runtime-1.1.1.dist-info/RECORD +99 -0
  46. intuned_runtime-1.1.1.dist-info/entry_points.txt +4 -0
  47. runtime/__init__.py +2 -1
  48. runtime/backend_functions/_call_backend_function.py +0 -5
  49. runtime/browser/__init__.py +5 -2
  50. runtime/browser/helpers.py +21 -0
  51. runtime/browser/launch_browser.py +31 -0
  52. runtime/browser/launch_camoufox.py +61 -0
  53. runtime/browser/launch_chromium.py +64 -61
  54. runtime/browser/storage_state.py +11 -12
  55. runtime/env.py +4 -0
  56. runtime/errors/run_api_errors.py +14 -10
  57. runtime/run/playwright_constructs.py +6 -5
  58. runtime/run/pydantic_encoder.py +15 -0
  59. runtime/run/run_api.py +5 -4
  60. runtime/types/run_types.py +16 -0
  61. intuned_runtime-1.0.0.dist-info/RECORD +0 -58
  62. intuned_runtime-1.0.0.dist-info/entry_points.txt +0 -3
  63. {cli → intuned_internal_cli}/commands/ai_source/__init__.py +0 -0
  64. {cli → intuned_internal_cli}/commands/ai_source/ai_source.py +0 -0
  65. {cli → intuned_internal_cli}/commands/browser/__init__.py +0 -0
  66. {cli → intuned_internal_cli}/commands/init.py +0 -0
  67. {cli → intuned_internal_cli}/commands/project/__init__.py +0 -0
  68. {cli → intuned_internal_cli}/commands/project/auth_session/__init__.py +0 -0
  69. {cli → intuned_internal_cli}/commands/project/auth_session/check.py +0 -0
  70. {cli → intuned_internal_cli}/commands/project/auth_session/create.py +0 -0
  71. {cli → intuned_internal_cli}/commands/project/project.py +0 -0
  72. {cli → intuned_internal_cli}/commands/project/run.py +0 -0
  73. {cli → intuned_internal_cli}/commands/project/run_interface.py +0 -0
  74. {cli → intuned_internal_cli}/commands/project/upgrade.py +0 -0
  75. {cli → intuned_internal_cli}/commands/publish_packages.py +0 -0
  76. {cli → intuned_internal_cli}/logger.py +0 -0
  77. {cli → intuned_internal_cli}/utils/ai_source_project.py +0 -0
  78. {cli → intuned_internal_cli}/utils/code_tree.py +0 -0
  79. {cli → intuned_internal_cli}/utils/run_apis.py +0 -0
  80. {cli → intuned_internal_cli}/utils/unix_socket.py +0 -0
  81. {intuned_runtime-1.0.0.dist-info → intuned_runtime-1.1.1.dist-info}/LICENSE +0 -0
  82. {intuned_runtime-1.0.0.dist-info → intuned_runtime-1.1.1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,15 @@
1
+ from anyio import Path
2
+
3
+ from runtime.run.run_api import import_function_from_api_dir
4
+ from runtime.run.run_api import ImportFunction
5
+
6
+
7
+ async def get_cli_import_function() -> ImportFunction:
8
+ """
9
+ Import a function from the API directory for CLI usage.
10
+ """
11
+ cwd = await Path().resolve()
12
+
13
+ return lambda file_path, name=None: import_function_from_api_dir(
14
+ file_path=file_path, automation_function_name=name, base_dir=str(cwd)
15
+ )
@@ -0,0 +1,25 @@
1
+ import asyncio
2
+ from contextlib import asynccontextmanager
3
+
4
+ from runtime.context.context import IntunedContext
5
+ from runtime.errors.run_api_errors import AutomationError
6
+
7
+
8
+ @asynccontextmanager
9
+ async def extendable_timeout(timeout: float):
10
+ try:
11
+ async with asyncio.timeout(timeout) as tm:
12
+ existing_extend_timeout = IntunedContext.current().extend_timeout
13
+
14
+ async def extend_timeout():
15
+ tm.reschedule(asyncio.timeout(timeout).when())
16
+ if existing_extend_timeout:
17
+ await existing_extend_timeout()
18
+
19
+ IntunedContext.current().extend_timeout = extend_timeout
20
+ try:
21
+ yield
22
+ finally:
23
+ IntunedContext.current().extend_timeout = existing_extend_timeout
24
+ except asyncio.TimeoutError as e:
25
+ raise AutomationError(Exception("Timed out")) from e
@@ -18,7 +18,7 @@ def run():
18
18
  load_dotenv(dotenv, override=True)
19
19
  try:
20
20
  with IntunedContext():
21
- arguably.run()
21
+ arguably.run(name="intuned-internal")
22
22
  except ValueError as e:
23
23
  print(bold(red(str(e))))
24
24
  sys.exit(1)
@@ -9,6 +9,7 @@ from .project.auth_session import project__auth_session__check # type: ignore
9
9
  from .project.auth_session import project__auth_session__create # type: ignore
10
10
  from .project.auth_session import project__auth_session__load # type: ignore
11
11
  from .publish_packages import publish_packages # type: ignore
12
+ from .root import __root__ # type: ignore
12
13
 
13
14
  __all__ = [
14
15
  "project__run",
@@ -22,4 +23,5 @@ __all__ = [
22
23
  "project__auth_session__check",
23
24
  "project__type_check",
24
25
  "browser__save_state",
26
+ "__root__",
25
27
  ]
@@ -6,7 +6,7 @@ from more_termcolor import cyan # type: ignore
6
6
  from more_termcolor import green # type: ignore
7
7
  from more_termcolor import red # type: ignore
8
8
 
9
- from cli.utils.code_tree import convert_project_to_code_tree
9
+ from intuned_internal_cli.utils.code_tree import convert_project_to_code_tree
10
10
 
11
11
  from ...utils.ai_source_project import AiSourceInfo
12
12
  from ...utils.ai_source_project import deploy_ai_source
@@ -3,7 +3,7 @@ import os
3
3
 
4
4
  import arguably
5
5
 
6
- from runtime.browser import launch_chromium
6
+ from runtime.browser import launch_browser
7
7
  from runtime.browser.storage_state import get_storage_state
8
8
 
9
9
 
@@ -21,7 +21,7 @@ async def browser__save_state(
21
21
  output_path (str): Path to save browser state to.
22
22
  """
23
23
 
24
- async with launch_chromium(
24
+ async with launch_browser(
25
25
  cdp_address=cdp_address,
26
26
  ) as (context, _):
27
27
  storage_state = await get_storage_state(context)
@@ -3,7 +3,7 @@ import os
3
3
 
4
4
  import arguably
5
5
 
6
- from runtime.browser import launch_chromium
6
+ from runtime.browser import launch_browser
7
7
  from runtime.browser.storage_state import set_storage_state
8
8
  from runtime.run.intuned_settings import load_intuned_settings
9
9
  from runtime.types.run_types import StorageState
@@ -26,7 +26,7 @@ async def project__auth_session__load(
26
26
  if not intuned_settings.auth_sessions.enabled:
27
27
  raise Exception("Auth sessions are not enabled")
28
28
 
29
- async with launch_chromium(
29
+ async with launch_browser(
30
30
  cdp_address=cdp_address,
31
31
  ) as (context, _):
32
32
  auth_session_path = os.path.join(os.getcwd(), auth_session_path)
@@ -9,6 +9,7 @@ current_dir = os.path.dirname(os.path.abspath(__file__))
9
9
  PYRIGHT_CONFIG_PATH = os.path.join(current_dir, "..", "..", "pyright_type_check.json")
10
10
  PYRIGHT_CONFIG_PATH = os.path.abspath(PYRIGHT_CONFIG_PATH)
11
11
 
12
+
12
13
  @arguably.command # type: ignore
13
14
  async def project__type_check():
14
15
  """
@@ -37,44 +38,50 @@ async def project__type_check():
37
38
  project_dir = os.getcwd()
38
39
  print("📦 Checking Types...")
39
40
 
40
- try:
41
- pyright_issues = []
42
- pyright_result = subprocess.run(
43
- ["pyright", "--outputjson", project_dir, "--project", PYRIGHT_CONFIG_PATH],
44
- capture_output=True,
45
- text=True,
46
- check=False
47
- )
41
+ try:
42
+ pyright_issues = []
43
+ pyright_result = subprocess.run(
44
+ ["pyright", "--outputjson", project_dir, "--project", PYRIGHT_CONFIG_PATH],
45
+ capture_output=True,
46
+ text=True,
47
+ check=False,
48
+ )
49
+
50
+ if pyright_result.stdout:
51
+ pyright_data = json.loads(pyright_result.stdout)
52
+ for diagnostic in pyright_data.get("generalDiagnostics", []):
53
+ severity = diagnostic.get("severity", "").lower()
54
+ severity_emoji = "ℹ️" if severity == "information" else "⚠️" if severity == "warning" else "🔴"
55
+
56
+ pyright_issues.append(
57
+ {
58
+ "path": diagnostic.get("file", ""),
59
+ "line": diagnostic.get("range", {}).get("start", {}).get("line", 0) + 1,
60
+ "severity": diagnostic.get("severity", ""),
61
+ "message": diagnostic.get("message", ""),
62
+ "rule": "type-check",
63
+ }
64
+ )
48
65
 
49
- if pyright_result.stdout:
50
- pyright_data = json.loads(pyright_result.stdout)
51
- for diagnostic in pyright_data.get("generalDiagnostics", []):
52
- severity = diagnostic.get("severity", "").lower()
53
- severity_emoji = "ℹ️" if severity == "information" else "⚠️" if severity == "warning" else "🔴"
54
-
55
- pyright_issues.append(
56
- {"path": diagnostic.get("file", ""), "line": diagnostic.get("range", {}).get("start", {}).get("line", 0) + 1, "severity": diagnostic.get("severity", ""), "message": diagnostic.get("message", ""), "rule": "type-check"}
57
- )
58
-
59
- file_path = diagnostic.get("file", "")
60
- if "api/" in file_path:
61
- file_path = file_path[file_path.index("api/"):]
62
- line_num = diagnostic.get("range", {}).get("start", {}).get("line", 0) + 1
63
- message = diagnostic.get("message", "")
64
- print(f"{severity_emoji} {file_path}:{line_num} - {message}")
65
-
66
- if severity.lower() == "error":
67
- print("\n🔴 Type check failed")
68
- sys.exit(1)
66
+ file_path = diagnostic.get("file", "")
67
+ if "api/" in file_path:
68
+ file_path = file_path[file_path.index("api/") :]
69
+ line_num = diagnostic.get("range", {}).get("start", {}).get("line", 0) + 1
70
+ message = diagnostic.get("message", "")
71
+ print(f"{severity_emoji} {file_path}:{line_num} - {message}")
69
72
 
70
- if pyright_issues:
73
+ if severity.lower() == "error":
74
+ print("\n🔴 Type check failed")
75
+ sys.exit(1)
76
+
77
+ if pyright_issues:
71
78
  has_warnings = any(issue["severity"].lower() == "warning" for issue in pyright_issues)
72
79
  if has_warnings:
73
80
  print("\n⚠️ Type check passed with warnings")
74
81
  sys.exit(0)
75
-
76
- print("✨ Python type checking passed without errors.")
77
- sys.exit(0)
82
+
83
+ print("✨ Python type checking passed without errors.")
84
+ sys.exit(0)
78
85
  except json.JSONDecodeError:
79
86
  print("🔴 Failed to parse pyright output as JSON")
80
87
  sys.exit(1)
@@ -0,0 +1,15 @@
1
+ import arguably
2
+
3
+
4
+ @arguably.command # type: ignore
5
+ async def __root__():
6
+ """Internal Intuned CLI.
7
+
8
+ This command is intended for internal use by Intuned and is not intended for general users.
9
+ Breaking changes and experimental features may be present.
10
+
11
+ If you are not an Intuned developer, please use the main Intuned CLI instead.
12
+ """
13
+ if arguably.is_target():
14
+ print("-h/--help")
15
+ exit(1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: intuned-runtime
3
- Version: 1.0.0
3
+ Version: 1.1.1
4
4
  Summary: Runtime commands for Intuned platform Python scrapers
5
5
  License: Elastic-2.0
6
6
  Keywords: runtime,intuned
@@ -17,6 +17,8 @@ Classifier: Programming Language :: Python :: 3.12
17
17
  Classifier: Programming Language :: Python :: 3.13
18
18
  Requires-Dist: aiofiles (>=24.1.0,<25.0.0)
19
19
  Requires-Dist: arguably (>=1.3.0,<2.0.0)
20
+ Requires-Dist: browserforge[all]
21
+ Requires-Dist: camoufox[geoip] (>=0.4.11,<0.5.0)
20
22
  Requires-Dist: gitpython (>=3.1.43,<4.0.0)
21
23
  Requires-Dist: httpx (>=0.23.0,<1)
22
24
  Requires-Dist: more-termcolor (>=1.1.3,<2.0.0)
@@ -24,7 +26,9 @@ Requires-Dist: pathspec (>=0.12.1,<0.13.0)
24
26
  Requires-Dist: pydantic (>=2.10.6,<3.0.0)
25
27
  Requires-Dist: pyright (>=1.1.387,<2.0.0)
26
28
  Requires-Dist: python-dotenv (==1.0.1)
29
+ Requires-Dist: pytimeparse (>=1.1.8,<2.0.0)
27
30
  Requires-Dist: requests (>=2.32.3,<3.0.0)
31
+ Requires-Dist: rich (>=14.1.0,<15.0.0)
28
32
  Requires-Dist: ruff (>=0.7.2,<0.8.0)
29
33
  Requires-Dist: semver (>=3.0.4,<4.0.0)
30
34
  Requires-Dist: tenacity (>=8.5.0,<9.0.0)
@@ -0,0 +1,99 @@
1
+ intuned_cli/__init__.py,sha256=SNcUoVkqPTmIxjEsp05GZBKaAzgCt-rBkvkzndjpfPo,1124
2
+ intuned_cli/commands/__init__.py,sha256=qndefhU1fGHYYu7f7wxcv03F27NPMIwsxUd3K-fmOD8,1236
3
+ intuned_cli/commands/attempt_api_command.py,sha256=f4Oi8vjNzGLMgk_1XXO5KzOIAw9sq9N8A62d3QIZxso,1954
4
+ intuned_cli/commands/attempt_authsession_check_command.py,sha256=RdKRltXIp51wnXamRB1Xr45TUBUs1AQCmAzW8tMQnxo,1334
5
+ intuned_cli/commands/attempt_authsession_command.py,sha256=hir9y1XyW9VYioOWT6C1-dH43f3JcHhIlfEEijMg2Lc,277
6
+ intuned_cli/commands/attempt_authsession_create_command.py,sha256=ynAKlNoHuaVPgx4gv2AJquIt7ZVIe8Nh1IIHwNiDeNA,1708
7
+ intuned_cli/commands/attempt_command.py,sha256=7NZC2dXA8GViCH3ZS2PMziR43hv2RmS6-jgW7l9bu40,253
8
+ intuned_cli/commands/command.py,sha256=b0OlQIFhoCjCo5QIerfysccBKcU9iIsvqiU7oxshA2M,727
9
+ intuned_cli/commands/deploy_command.py,sha256=0XG8lo5fGeorZMxMtEx12EaqLFMvmFYJ7Zu9sgJCmQ8,1540
10
+ intuned_cli/commands/init_command.py,sha256=MV5WR5o4KH1J_Zai6K5S84NG41KZbsJ-I8NPGXurt2o,671
11
+ intuned_cli/commands/run_api_command.py,sha256=Y6FkSFI9wybuoW204YqOAiQ794__hIw12Eaf9px_ovE,3013
12
+ intuned_cli/commands/run_authsession_command.py,sha256=kM_TANy8M3yx8iBUsgSDO42byzccikLOd9KJfytfLmQ,269
13
+ intuned_cli/commands/run_authsession_create_command.py,sha256=SiuIZ7LTMqT3gnd8DUt-VmP3cyuA0I_i27daI3IJ2tw,2089
14
+ intuned_cli/commands/run_authsession_update_command.py,sha256=Op7epDgvEhjp17qs2dIXerTckHz7wlOsZsBDp8UJLjI,2145
15
+ intuned_cli/commands/run_authsession_validate_command.py,sha256=5eET02paijq1f1rzsheINvAqVYj1JGUA_iGD5Py3LVM,2008
16
+ intuned_cli/commands/run_command.py,sha256=JN1yCewcyb4zFquMcv0wEZ_aRmhJZIBMheY8L9yBeDE,245
17
+ intuned_cli/constants/__init__.py,sha256=AIfIQYQ55zSdGKL2p15wv4H9ANeRjYEkeUiObu6JFt8,37
18
+ intuned_cli/constants/readme.py,sha256=3OUkZNmz9kss7hA3V2j5h49dv7ADy4LON5-iJkrJUA4,5240
19
+ intuned_cli/controller/__test__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ intuned_cli/controller/__test__/test_api.py,sha256=8Hk3V52qKhWIqjirKFwN68Tv5er70gTxemjI35HyZiU,19295
21
+ intuned_cli/controller/__test__/test_authsession.py,sha256=y7O3dkDPHZTf2W7WRLEhysYYRati0hg93-J8BvGjRUM,35110
22
+ intuned_cli/controller/api.py,sha256=1wHgatavA5zr6kYMf1BJ3lC5JR1IvlVBiab_ahOSVnY,7172
23
+ intuned_cli/controller/authsession.py,sha256=z8C97T-beEORNemLFx2x_JsHr2gXRakwKGV3Rgivnu8,14309
24
+ intuned_cli/controller/deploy.py,sha256=5cQgtpT2nDQ5XSUnIoeBR9xdyVoLWcY-2btuUxUD7Es,12343
25
+ intuned_cli/controller/init.py,sha256=TfkPkq9rbYam2-fchwrpMIt9GJIkY-TQnWpwvPomRZE,3774
26
+ intuned_cli/types.py,sha256=Lsykui4mbq5T1_1L7Gg5OZpJvCOmaz9EiQcZVfUEoLc,766
27
+ intuned_cli/utils/api_helpers.py,sha256=57gvXVYM_9hMGIkMqSEN_jzs3mYWlXzinPjYXzzqgg8,1122
28
+ intuned_cli/utils/auth_session_helpers.py,sha256=acKAPUjOfdybstLur4Lk3huaLFP2Ipl4AjPSqQPQLzY,1899
29
+ intuned_cli/utils/backend.py,sha256=NFMAqHFslxad9KYirUz3b0BsRz1aQqOGhZRUJdEiO8k,106
30
+ intuned_cli/utils/confirmation.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ intuned_cli/utils/console.py,sha256=jgin2xB-0kpANPMoiDBOnWhrc8Ey5zT4IHRxQa8f5CQ,93
32
+ intuned_cli/utils/error.py,sha256=DmNlXBb7zfpHDRya00ouEcRgUEZuGaTqIy1SIjDWVfo,842
33
+ intuned_cli/utils/exclusions.py,sha256=Qe7NkWA3lsX73dOC9WprdD0KyYc_vuiwkrUCwD105gk,796
34
+ intuned_cli/utils/get_auth_parameters.py,sha256=HmMSjBE8bPulkUdX319Ipr383Ko2Gtz3y8_WT9CK3Kw,798
35
+ intuned_cli/utils/import_function.py,sha256=UmE2yw5std1ENMFdBU-TUBuQ01qsv7Qr5ElnAhqE6Yc,453
36
+ intuned_cli/utils/timeout.py,sha256=DkoeoU9XvKKKSQ06CpwqcNvxWqLPAOVuAMw6kSr4Tuo,886
37
+ intuned_internal_cli/__init__.py,sha256=iz-mTdcPhNCknHZzdO5-9PHFSapbXiLCwg_cTaYfww4,1337
38
+ intuned_internal_cli/commands/__init__.py,sha256=gZ-r8UIXvRakeCfvmOZCNWr8CJHBcYzRzbMjyKYPXV0,1003
39
+ intuned_internal_cli/commands/ai_source/__init__.py,sha256=lg7owgcK8owNn2a4VBUP9RKxzFsLruhtnnQV0F_z6pc,149
40
+ intuned_internal_cli/commands/ai_source/ai_source.py,sha256=2woQtCmhxKvLfEz832eUoCT9gMsuSvEE6rMnHSYXC7w,138
41
+ intuned_internal_cli/commands/ai_source/deploy.py,sha256=NpomuP_2mo5SLKe7BZoY5H0Pp36aDtkYU_CyihqOvdI,2457
42
+ intuned_internal_cli/commands/browser/__init__.py,sha256=AuVbvh7aSBTFKYvewXZyPoIvfBTe2uHiPcnaAkzapas,95
43
+ intuned_internal_cli/commands/browser/save_state.py,sha256=_gfspwLkk6j1zBzqY1Qr7KnEMjGP6x10Q2IvKdfjyuI,839
44
+ intuned_internal_cli/commands/init.py,sha256=8rWBenWZfwNtLxOBqhEMbOATyQNEnmDUmrFJ1xBGyxI,4384
45
+ intuned_internal_cli/commands/project/__init__.py,sha256=t97wvhSenerYRdbSeCKXqHASA6EWA3lc1hnRhF9baOE,734
46
+ intuned_internal_cli/commands/project/auth_session/__init__.py,sha256=gt7mlaW6xmqAc_4-pfF_FiecsR51C6fqCaq_NFbcbwA,300
47
+ intuned_internal_cli/commands/project/auth_session/check.py,sha256=AFILp7m34nAO_RD3IfRpuJm5Zh0wnCRtBXqIrerdbwo,4565
48
+ intuned_internal_cli/commands/project/auth_session/create.py,sha256=r-eYu3uLUo2mzF836CbVgu4oBzcIIDekzzFwwekxmg0,3374
49
+ intuned_internal_cli/commands/project/auth_session/load.py,sha256=Y0V6bFZQeHq_lTtR-rQvM9SSbExWhVVMFu-Uykl-9k4,1199
50
+ intuned_internal_cli/commands/project/project.py,sha256=_MSh6Xor2Cbh-ItifwgOPq_BP8UDuKB7S6w796FULKQ,137
51
+ intuned_internal_cli/commands/project/run.py,sha256=FDYYkU24aURYbljyYLFo8wLF-nvb86EVr9gMEjAfeE0,12274
52
+ intuned_internal_cli/commands/project/run_interface.py,sha256=4RyR8WZriIF7Va4z1wt-q6zZDQOI31n62Ho2dyimzUY,8717
53
+ intuned_internal_cli/commands/project/type_check.py,sha256=QFnXL93Y-z250EQRln5sRqwkVqjGJ-eP_p1jGrXB7NA,3522
54
+ intuned_internal_cli/commands/project/upgrade.py,sha256=XmkZLflM4O-mwvhwcswlZpazRotwi3xesLgE0Zz8fTI,3061
55
+ intuned_internal_cli/commands/publish_packages.py,sha256=sijkaG7_s0I1EWgLekGy1qm8Aqi_gYY8poXbMX0B6Yw,10505
56
+ intuned_internal_cli/commands/root.py,sha256=o75rSb5WYa5JMD8HLN3eiNu4fM0mar3y15A63-Qm4s4,426
57
+ intuned_internal_cli/logger.py,sha256=bZK3q-KUdGxk_qzDb6pn-n0LOhKJvi6a9p8oSwZtq3s,594
58
+ intuned_internal_cli/utils/ai_source_project.py,sha256=xUCM6p3i1XN4bJbuQz8LCzeI4BwqAdSvCl_vwDAEi0k,831
59
+ intuned_internal_cli/utils/code_tree.py,sha256=1wfxZoQ5kRCfqs2SEPAicbAIPTiD6P1LxSuwYu_eeaI,2790
60
+ intuned_internal_cli/utils/run_apis.py,sha256=Zee4zkgt9R8XY1XCGzj2Nc4zJ3jlRz1xnO493wotuWw,4690
61
+ intuned_internal_cli/utils/unix_socket.py,sha256=UISmkJMHrir5iBLUm6vxC3uzTGIFyOk_wa0C9LUw4Cc,1889
62
+ runtime/__init__.py,sha256=87gDXuxUv_kGzQfuB1mh6DF-dDysJN8r684c7jGnHxc,144
63
+ runtime/backend_functions/__init__.py,sha256=j2EaK4FK8bmdFtqc5FxtFwx1KhIn_7qKPChrrAhJI3s,119
64
+ runtime/backend_functions/_call_backend_function.py,sha256=zuaf4mwYHSm5RTedhMdU66jAMAzdPYPMmXJE_V1xoyk,2869
65
+ runtime/backend_functions/get_auth_session_parameters.py,sha256=pOvB7XiWpphEuBpazdKALw9EWgBU1PeY3gkzBfVLpkc,869
66
+ runtime/browser/__init__.py,sha256=EPWfa4ZmdR8GJqh2qcsx1ZvHmCYiUYrQ-zeHYVapH9s,285
67
+ runtime/browser/helpers.py,sha256=b1Xp005adbl7ZeJrSEYgH2OPzrZEHxTPgGTsnS3OqS0,554
68
+ runtime/browser/launch_browser.py,sha256=f71hLUDbIBEv5hhQVOQFTXleUm_X1kmEpp0kTx0SqZo,966
69
+ runtime/browser/launch_camoufox.py,sha256=8dg14UfN9nBA7T075UQFhpyhvJD_aVqLdDJTNiwU0FY,1752
70
+ runtime/browser/launch_chromium.py,sha256=0i0IWQO5rByPw56F_OsUp8Z55Qn2-ETQ6q5B2aXvNv4,7456
71
+ runtime/browser/storage_state.py,sha256=fwLg8sP-H-vgt_6AJKNl03CpgyMVCQWWcN2cqswTQMs,3603
72
+ runtime/context/__init__.py,sha256=hg8ejm4bJy4tNkwmZ9lKgYJx6bU7OgOdBS684Uv5XGg,73
73
+ runtime/context/context.py,sha256=pl_0x77_d5CiAznz1qGSk6o9cW-msNvlCt-2eFoMKlA,1739
74
+ runtime/env.py,sha256=OXxzLpM56AJVlX0gmG7Ph82xAfqZboW3kv2232lzXb4,306
75
+ runtime/errors/__init__.py,sha256=oqiBSvT_yFLQ3hG0AbCUA3WYFaxkTDVkDMSy59xvBCo,688
76
+ runtime/errors/auth_session_errors.py,sha256=6b4XTI8UCDHDPX4jEA8_HyrNUp4VZ1TrEA8DRh6Z3rM,228
77
+ runtime/errors/run_api_errors.py,sha256=LdmOEHoUk7wjWSk0HQYqslfJNNmxVgga_0bankzvX-s,3341
78
+ runtime/errors/trace_errors.py,sha256=Lzfo0sH3zGaWz1kn5DHcAXQMn3aR2y2bnauj6xP1LYE,110
79
+ runtime/helpers/__init__.py,sha256=jozYPKHgZJ7Na5U1Wjt83egzjPATMZ_OMInEI6swSbY,234
80
+ runtime/helpers/extend_payload.py,sha256=towZF08WTpTTDBL4AV1bUU3XpKAQHEB66kGUfTICDe0,246
81
+ runtime/helpers/extend_timeout.py,sha256=KjfSLEUrqoz7v00rhnPAKq2OmUzEzcv-eQ3M8c2U46s,348
82
+ runtime/helpers/get_auth_session_parameters.py,sha256=7bopGhJ7vjKAn_UxnHSAah-k2rVOPbq0zi9FQOOCFds,472
83
+ runtime/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
+ runtime/run/__init__.py,sha256=zxMYVb7hn147YTrhMLsrcX6-KTd71HLrYHstJOWeWXQ,52
85
+ runtime/run/intuned_settings.py,sha256=vy2-ktEzUfUp5Z90dp3l7jPKHNjgB-8GSMDgAY-rYaU,1074
86
+ runtime/run/playwright_constructs.py,sha256=EIfnRlAi1k1wRiTT2OpPFVmrWwEeeiryuORibaLD1Xw,573
87
+ runtime/run/pydantic_encoder.py,sha256=wJCljwwINSICvCJ0i2izp2RLkQ15nYglUQCyyjM40Jk,332
88
+ runtime/run/run_api.py,sha256=iYekBi-mkBuBNvLIBXQ6RWvEDN7JhjSlX3i7a2td2P8,8952
89
+ runtime/run/traces.py,sha256=fKzh11LqV47ujgq_9I2tdp-dgld566wffWaHwU_4gis,1123
90
+ runtime/types/__init__.py,sha256=IJkDfqsau8F8R_j8TO6j-JwW4ElQr6aU6LNaWRehg5U,401
91
+ runtime/types/payload.py,sha256=sty8HgDEn3nJbZrwEOMCXyuG7_ICGDwlBIIWSON5ABY,124
92
+ runtime/types/run_types.py,sha256=-j-XKXfRkzlyoW-Doe0og2jbqMMQWjOTIUqRFEc8lHA,4582
93
+ runtime_helpers/__init__.py,sha256=XBrEiE9yNC8Lgn8NgIkqNXbI6e4ap237E83Zj_nlhCQ,249
94
+ runtime_helpers/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
+ intuned_runtime-1.1.1.dist-info/LICENSE,sha256=9LIjQdgyU_ptzNIfItNCR7VmEHqYnrY1f1XwOreKFI0,3714
96
+ intuned_runtime-1.1.1.dist-info/METADATA,sha256=X7RhKRebpDcNZzUCoO4YvgAvToqPrh6UL8ad8ysB0l0,5299
97
+ intuned_runtime-1.1.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
98
+ intuned_runtime-1.1.1.dist-info/entry_points.txt,sha256=ToMS2cqDeRmF1FGkflwoeD-Xz6jJV5p1zIbw9G7IxMg,85
99
+ intuned_runtime-1.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ intuned=intuned_cli:run
3
+ intuned-internal=intuned_internal_cli:run
4
+
runtime/__init__.py CHANGED
@@ -1,3 +1,4 @@
1
- from .browser import launch_chromium, dangerous_launch_chromium
1
+ from .browser import dangerous_launch_chromium
2
+ from .browser import launch_chromium
2
3
 
3
4
  __all__ = ["launch_chromium", "dangerous_launch_chromium"]
@@ -32,11 +32,6 @@ async def call_backend_function[T: BaseModel](
32
32
  # todo
33
33
  raise Exception("No run context found.")
34
34
 
35
- auth_session_id = context.run_context.auth_session_id
36
- if auth_session_id is None:
37
- # todo
38
- raise Exception("No auth session ID found.")
39
-
40
35
  async with AsyncClient() as client:
41
36
  if context.functions_token:
42
37
  client.headers["Authorization"] = f"Bearer {context.functions_token}"
@@ -1,3 +1,6 @@
1
- from .launch_chromium import launch_chromium, dangerous_launch_chromium
1
+ from .launch_browser import launch_browser
2
+ from .launch_camoufox import launch_camoufox
3
+ from .launch_chromium import dangerous_launch_chromium
4
+ from .launch_chromium import launch_chromium
2
5
 
3
- __all__ = ["launch_chromium", "dangerous_launch_chromium"]
6
+ __all__ = ["launch_chromium", "dangerous_launch_chromium", "launch_camoufox", "launch_browser"]
@@ -0,0 +1,21 @@
1
+ import os
2
+ from typing import Optional
3
+ from typing import TYPE_CHECKING
4
+
5
+ from playwright.async_api import ProxySettings
6
+
7
+ if TYPE_CHECKING:
8
+ from playwright.async_api import ProxySettings
9
+
10
+
11
+ def get_proxy_env() -> Optional["ProxySettings"]:
12
+ server = os.getenv("PROXY_SERVER")
13
+ username = os.getenv("PROXY_USERNAME")
14
+ password = os.getenv("PROXY_PASSWORD")
15
+ if server is None or username is None or password is None:
16
+ return None
17
+ return {
18
+ "server": server,
19
+ "username": username,
20
+ "password": password,
21
+ }
@@ -0,0 +1,31 @@
1
+ from contextlib import asynccontextmanager
2
+
3
+ from playwright.async_api import ProxySettings
4
+
5
+ from runtime.env import get_browser_type
6
+
7
+ from .launch_camoufox import launch_camoufox
8
+ from .launch_chromium import launch_chromium
9
+
10
+
11
+ @asynccontextmanager
12
+ async def launch_browser(
13
+ proxy: ProxySettings | None = None,
14
+ headless: bool = False,
15
+ *,
16
+ cdp_address: str | None = None,
17
+ ):
18
+ browser_type = get_browser_type()
19
+ match browser_type:
20
+ case "camoufox":
21
+ async with launch_camoufox(headless=headless, proxy=proxy) as (context, page):
22
+ try:
23
+ yield context, page
24
+ finally:
25
+ await context.close()
26
+ case "chromium" | _:
27
+ async with launch_chromium(headless=headless, cdp_address=cdp_address, proxy=proxy) as (context, page):
28
+ try:
29
+ yield context, page
30
+ finally:
31
+ await context.close()
@@ -0,0 +1,61 @@
1
+ import logging
2
+ import os
3
+ from contextlib import asynccontextmanager
4
+ from typing import Any
5
+ from typing import AsyncGenerator
6
+ from typing import Tuple
7
+
8
+ import anyio
9
+ from camoufox.async_api import AsyncCamoufox
10
+ from playwright.async_api import Browser
11
+ from playwright.async_api import BrowserContext
12
+ from playwright.async_api import Page
13
+
14
+ from .helpers import get_proxy_env
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ async def create_user_dir():
20
+ # Create a temporary directory
21
+ playwright_temp_dir = anyio.Path(await anyio.mkdtemp(prefix="pw-"))
22
+ user_dir = playwright_temp_dir / "userdir"
23
+
24
+ return await user_dir.absolute()
25
+
26
+
27
+ @asynccontextmanager
28
+ async def launch_camoufox(
29
+ headless: bool = True,
30
+ timeout: int = 10,
31
+ **kwargs: Any,
32
+ ) -> AsyncGenerator[Tuple[BrowserContext, Page], None]:
33
+ dir = await create_user_dir()
34
+ if kwargs.get("proxy") is None:
35
+ proxy_env = get_proxy_env()
36
+ else:
37
+ proxy_env = kwargs.get("proxy")
38
+ kwargs.pop("proxy", None)
39
+ async with AsyncCamoufox(
40
+ headless=headless,
41
+ config={"forceScopeAccess": True}, # required
42
+ disable_coop=True,
43
+ geoip=True,
44
+ proxy=proxy_env,
45
+ persistent_context=True,
46
+ user_data_dir=dir,
47
+ i_know_what_im_doing=True,
48
+ ) as camoufox:
49
+ if isinstance(camoufox, Browser):
50
+ context = await camoufox.new_context()
51
+ else:
52
+ context = camoufox
53
+ context.set_default_timeout(timeout * 1000)
54
+
55
+ async def remove_dir_after_close(*_: Any, **__: Any) -> None:
56
+ if not dir:
57
+ return
58
+ os.system(f"rm -rf {os.path.realpath(dir)}")
59
+
60
+ context.once("close", remove_dir_after_close)
61
+ yield context, context.pages[0]