intuned-runtime 1.1.0__py3-none-any.whl → 1.1.2__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.
- intuned_internal_cli/commands/browser/save_state.py +2 -2
- intuned_internal_cli/commands/project/auth_session/load.py +2 -2
- {intuned_runtime-1.1.0.dist-info → intuned_runtime-1.1.2.dist-info}/METADATA +3 -1
- {intuned_runtime-1.1.0.dist-info → intuned_runtime-1.1.2.dist-info}/RECORD +14 -11
- runtime/browser/__init__.py +3 -1
- runtime/browser/helpers.py +21 -0
- runtime/browser/launch_browser.py +31 -0
- runtime/browser/launch_camoufox.py +63 -0
- runtime/browser/launch_chromium.py +23 -28
- runtime/env.py +4 -0
- runtime/run/playwright_constructs.py +2 -3
- {intuned_runtime-1.1.0.dist-info → intuned_runtime-1.1.2.dist-info}/LICENSE +0 -0
- {intuned_runtime-1.1.0.dist-info → intuned_runtime-1.1.2.dist-info}/WHEEL +0 -0
- {intuned_runtime-1.1.0.dist-info → intuned_runtime-1.1.2.dist-info}/entry_points.txt +0 -0
@@ -3,7 +3,7 @@ import os
|
|
3
3
|
|
4
4
|
import arguably
|
5
5
|
|
6
|
-
from runtime.browser import
|
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
|
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
|
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
|
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)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: intuned-runtime
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.2
|
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)
|
@@ -40,13 +40,13 @@ intuned_internal_cli/commands/ai_source/__init__.py,sha256=lg7owgcK8owNn2a4VBUP9
|
|
40
40
|
intuned_internal_cli/commands/ai_source/ai_source.py,sha256=2woQtCmhxKvLfEz832eUoCT9gMsuSvEE6rMnHSYXC7w,138
|
41
41
|
intuned_internal_cli/commands/ai_source/deploy.py,sha256=NpomuP_2mo5SLKe7BZoY5H0Pp36aDtkYU_CyihqOvdI,2457
|
42
42
|
intuned_internal_cli/commands/browser/__init__.py,sha256=AuVbvh7aSBTFKYvewXZyPoIvfBTe2uHiPcnaAkzapas,95
|
43
|
-
intuned_internal_cli/commands/browser/save_state.py,sha256=
|
43
|
+
intuned_internal_cli/commands/browser/save_state.py,sha256=_gfspwLkk6j1zBzqY1Qr7KnEMjGP6x10Q2IvKdfjyuI,839
|
44
44
|
intuned_internal_cli/commands/init.py,sha256=8rWBenWZfwNtLxOBqhEMbOATyQNEnmDUmrFJ1xBGyxI,4384
|
45
45
|
intuned_internal_cli/commands/project/__init__.py,sha256=t97wvhSenerYRdbSeCKXqHASA6EWA3lc1hnRhF9baOE,734
|
46
46
|
intuned_internal_cli/commands/project/auth_session/__init__.py,sha256=gt7mlaW6xmqAc_4-pfF_FiecsR51C6fqCaq_NFbcbwA,300
|
47
47
|
intuned_internal_cli/commands/project/auth_session/check.py,sha256=AFILp7m34nAO_RD3IfRpuJm5Zh0wnCRtBXqIrerdbwo,4565
|
48
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=
|
49
|
+
intuned_internal_cli/commands/project/auth_session/load.py,sha256=Y0V6bFZQeHq_lTtR-rQvM9SSbExWhVVMFu-Uykl-9k4,1199
|
50
50
|
intuned_internal_cli/commands/project/project.py,sha256=_MSh6Xor2Cbh-ItifwgOPq_BP8UDuKB7S6w796FULKQ,137
|
51
51
|
intuned_internal_cli/commands/project/run.py,sha256=FDYYkU24aURYbljyYLFo8wLF-nvb86EVr9gMEjAfeE0,12274
|
52
52
|
intuned_internal_cli/commands/project/run_interface.py,sha256=4RyR8WZriIF7Va4z1wt-q6zZDQOI31n62Ho2dyimzUY,8717
|
@@ -63,12 +63,15 @@ runtime/__init__.py,sha256=87gDXuxUv_kGzQfuB1mh6DF-dDysJN8r684c7jGnHxc,144
|
|
63
63
|
runtime/backend_functions/__init__.py,sha256=j2EaK4FK8bmdFtqc5FxtFwx1KhIn_7qKPChrrAhJI3s,119
|
64
64
|
runtime/backend_functions/_call_backend_function.py,sha256=zuaf4mwYHSm5RTedhMdU66jAMAzdPYPMmXJE_V1xoyk,2869
|
65
65
|
runtime/backend_functions/get_auth_session_parameters.py,sha256=pOvB7XiWpphEuBpazdKALw9EWgBU1PeY3gkzBfVLpkc,869
|
66
|
-
runtime/browser/__init__.py,sha256=
|
67
|
-
runtime/browser/
|
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=TBOAwwipNGlbtMdFYnGkVM0ppLU44vWNkMGZA5uPZCE,1787
|
70
|
+
runtime/browser/launch_chromium.py,sha256=QY9Mxw8FImT_W23cT2zjTAeLvApzVHA_YSu0b77nfeA,7813
|
68
71
|
runtime/browser/storage_state.py,sha256=fwLg8sP-H-vgt_6AJKNl03CpgyMVCQWWcN2cqswTQMs,3603
|
69
72
|
runtime/context/__init__.py,sha256=hg8ejm4bJy4tNkwmZ9lKgYJx6bU7OgOdBS684Uv5XGg,73
|
70
73
|
runtime/context/context.py,sha256=pl_0x77_d5CiAznz1qGSk6o9cW-msNvlCt-2eFoMKlA,1739
|
71
|
-
runtime/env.py,sha256=
|
74
|
+
runtime/env.py,sha256=OXxzLpM56AJVlX0gmG7Ph82xAfqZboW3kv2232lzXb4,306
|
72
75
|
runtime/errors/__init__.py,sha256=oqiBSvT_yFLQ3hG0AbCUA3WYFaxkTDVkDMSy59xvBCo,688
|
73
76
|
runtime/errors/auth_session_errors.py,sha256=6b4XTI8UCDHDPX4jEA8_HyrNUp4VZ1TrEA8DRh6Z3rM,228
|
74
77
|
runtime/errors/run_api_errors.py,sha256=LdmOEHoUk7wjWSk0HQYqslfJNNmxVgga_0bankzvX-s,3341
|
@@ -80,7 +83,7 @@ runtime/helpers/get_auth_session_parameters.py,sha256=7bopGhJ7vjKAn_UxnHSAah-k2r
|
|
80
83
|
runtime/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
81
84
|
runtime/run/__init__.py,sha256=zxMYVb7hn147YTrhMLsrcX6-KTd71HLrYHstJOWeWXQ,52
|
82
85
|
runtime/run/intuned_settings.py,sha256=vy2-ktEzUfUp5Z90dp3l7jPKHNjgB-8GSMDgAY-rYaU,1074
|
83
|
-
runtime/run/playwright_constructs.py,sha256=
|
86
|
+
runtime/run/playwright_constructs.py,sha256=EIfnRlAi1k1wRiTT2OpPFVmrWwEeeiryuORibaLD1Xw,573
|
84
87
|
runtime/run/pydantic_encoder.py,sha256=wJCljwwINSICvCJ0i2izp2RLkQ15nYglUQCyyjM40Jk,332
|
85
88
|
runtime/run/run_api.py,sha256=iYekBi-mkBuBNvLIBXQ6RWvEDN7JhjSlX3i7a2td2P8,8952
|
86
89
|
runtime/run/traces.py,sha256=fKzh11LqV47ujgq_9I2tdp-dgld566wffWaHwU_4gis,1123
|
@@ -89,8 +92,8 @@ runtime/types/payload.py,sha256=sty8HgDEn3nJbZrwEOMCXyuG7_ICGDwlBIIWSON5ABY,124
|
|
89
92
|
runtime/types/run_types.py,sha256=-j-XKXfRkzlyoW-Doe0og2jbqMMQWjOTIUqRFEc8lHA,4582
|
90
93
|
runtime_helpers/__init__.py,sha256=XBrEiE9yNC8Lgn8NgIkqNXbI6e4ap237E83Zj_nlhCQ,249
|
91
94
|
runtime_helpers/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
92
|
-
intuned_runtime-1.1.
|
93
|
-
intuned_runtime-1.1.
|
94
|
-
intuned_runtime-1.1.
|
95
|
-
intuned_runtime-1.1.
|
96
|
-
intuned_runtime-1.1.
|
95
|
+
intuned_runtime-1.1.2.dist-info/LICENSE,sha256=9LIjQdgyU_ptzNIfItNCR7VmEHqYnrY1f1XwOreKFI0,3714
|
96
|
+
intuned_runtime-1.1.2.dist-info/METADATA,sha256=HP4J-g2b6h37GwRyjtMffGhuHNP1yQfJogzxfr_aiHc,5299
|
97
|
+
intuned_runtime-1.1.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
98
|
+
intuned_runtime-1.1.2.dist-info/entry_points.txt,sha256=ToMS2cqDeRmF1FGkflwoeD-Xz6jJV5p1zIbw9G7IxMg,85
|
99
|
+
intuned_runtime-1.1.2.dist-info/RECORD,,
|
runtime/browser/__init__.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
from .launch_browser import launch_browser
|
2
|
+
from .launch_camoufox import launch_camoufox
|
1
3
|
from .launch_chromium import dangerous_launch_chromium
|
2
4
|
from .launch_chromium import launch_chromium
|
3
5
|
|
4
|
-
__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,63 @@
|
|
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 playwright.async_api import Browser
|
10
|
+
from playwright.async_api import BrowserContext
|
11
|
+
from playwright.async_api import Page
|
12
|
+
|
13
|
+
from .helpers import get_proxy_env
|
14
|
+
|
15
|
+
logger = logging.getLogger(__name__)
|
16
|
+
|
17
|
+
|
18
|
+
async def create_user_dir():
|
19
|
+
# Create a temporary directory
|
20
|
+
playwright_temp_dir = anyio.Path(await anyio.mkdtemp(prefix="pw-"))
|
21
|
+
user_dir = playwright_temp_dir / "userdir"
|
22
|
+
|
23
|
+
return await user_dir.absolute()
|
24
|
+
|
25
|
+
|
26
|
+
@asynccontextmanager
|
27
|
+
async def launch_camoufox(
|
28
|
+
headless: bool = True,
|
29
|
+
timeout: int = 10,
|
30
|
+
**kwargs: Any,
|
31
|
+
) -> AsyncGenerator[Tuple[BrowserContext, Page], None]:
|
32
|
+
from camoufox.async_api import AsyncCamoufox
|
33
|
+
|
34
|
+
dir = await create_user_dir()
|
35
|
+
if kwargs.get("proxy") is None:
|
36
|
+
proxy_env = get_proxy_env()
|
37
|
+
else:
|
38
|
+
proxy_env = kwargs.get("proxy")
|
39
|
+
kwargs.pop("proxy", None)
|
40
|
+
async with AsyncCamoufox(
|
41
|
+
main_world_eval=True,
|
42
|
+
headless=headless,
|
43
|
+
config={"forceScopeAccess": True}, # required
|
44
|
+
disable_coop=True,
|
45
|
+
geoip=True,
|
46
|
+
proxy=proxy_env,
|
47
|
+
persistent_context=True,
|
48
|
+
user_data_dir=dir,
|
49
|
+
i_know_what_im_doing=True,
|
50
|
+
) as camoufox:
|
51
|
+
if isinstance(camoufox, Browser):
|
52
|
+
context = await camoufox.new_context()
|
53
|
+
else:
|
54
|
+
context = camoufox
|
55
|
+
context.set_default_timeout(timeout * 1000)
|
56
|
+
|
57
|
+
async def remove_dir_after_close(*_: Any, **__: Any) -> None:
|
58
|
+
if not dir:
|
59
|
+
return
|
60
|
+
os.system(f"rm -rf {os.path.realpath(dir)}")
|
61
|
+
|
62
|
+
context.once("close", remove_dir_after_close)
|
63
|
+
yield context, context.pages[0]
|
@@ -4,30 +4,14 @@ import logging
|
|
4
4
|
import os
|
5
5
|
from contextlib import asynccontextmanager
|
6
6
|
from typing import Any
|
7
|
-
from typing import Optional
|
8
|
-
from typing import TYPE_CHECKING
|
9
7
|
|
10
8
|
import anyio
|
11
9
|
|
12
|
-
|
13
|
-
from playwright.async_api import ProxySettings
|
10
|
+
from .helpers import get_proxy_env
|
14
11
|
|
15
12
|
logger = logging.getLogger(__name__)
|
16
13
|
|
17
14
|
|
18
|
-
def get_proxy_env() -> Optional["ProxySettings"]:
|
19
|
-
server = os.getenv("PROXY_SERVER")
|
20
|
-
username = os.getenv("PROXY_USERNAME")
|
21
|
-
password = os.getenv("PROXY_PASSWORD")
|
22
|
-
if server is None or username is None or password is None:
|
23
|
-
return None
|
24
|
-
return {
|
25
|
-
"server": server,
|
26
|
-
"username": username,
|
27
|
-
"password": password,
|
28
|
-
}
|
29
|
-
|
30
|
-
|
31
15
|
chromium_launch_args_to_ignore = [
|
32
16
|
"--disable-field-trial-config",
|
33
17
|
"--disable-background-networking",
|
@@ -85,16 +69,6 @@ async def create_user_dir_with_preferences():
|
|
85
69
|
return await user_dir.absolute(), await playwright_temp_dir.absolute()
|
86
70
|
|
87
71
|
|
88
|
-
extra_args = [
|
89
|
-
"--no-first-run",
|
90
|
-
"--disable-sync",
|
91
|
-
"--disable-translate",
|
92
|
-
"--disable-features=TranslateUI",
|
93
|
-
"--disable-features=NetworkService",
|
94
|
-
"--lang=en",
|
95
|
-
"--disable-blink-features=AutomationControlled",
|
96
|
-
]
|
97
|
-
|
98
72
|
default_user_agent = (
|
99
73
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
|
100
74
|
)
|
@@ -110,6 +84,15 @@ async def launch_chromium(
|
|
110
84
|
from playwright.async_api import async_playwright
|
111
85
|
from playwright.async_api import Browser
|
112
86
|
|
87
|
+
extra_args = [
|
88
|
+
"--no-first-run",
|
89
|
+
"--disable-sync",
|
90
|
+
"--disable-translate",
|
91
|
+
"--disable-features=TranslateUI",
|
92
|
+
"--disable-features=NetworkService",
|
93
|
+
"--lang=en",
|
94
|
+
"--disable-blink-features=AutomationControlled",
|
95
|
+
]
|
113
96
|
async with async_playwright() as playwright:
|
114
97
|
if cdp_address is not None:
|
115
98
|
browser: Browser = await playwright.chromium.connect_over_cdp(cdp_address)
|
@@ -117,7 +100,10 @@ async def launch_chromium(
|
|
117
100
|
user_preferences_dir = None
|
118
101
|
dir_to_clean = None
|
119
102
|
else:
|
120
|
-
|
103
|
+
(
|
104
|
+
user_preferences_dir,
|
105
|
+
dir_to_clean,
|
106
|
+
) = await create_user_dir_with_preferences()
|
121
107
|
if kwargs.get("proxy") is None:
|
122
108
|
proxy_env = get_proxy_env()
|
123
109
|
else:
|
@@ -172,6 +158,15 @@ async def dangerous_launch_chromium(
|
|
172
158
|
from playwright.async_api import async_playwright
|
173
159
|
from playwright.async_api import Browser
|
174
160
|
|
161
|
+
extra_args = [
|
162
|
+
"--no-first-run",
|
163
|
+
"--disable-sync",
|
164
|
+
"--disable-translate",
|
165
|
+
"--disable-features=TranslateUI",
|
166
|
+
"--disable-features=NetworkService",
|
167
|
+
"--lang=en",
|
168
|
+
"--disable-blink-features=AutomationControlled",
|
169
|
+
]
|
175
170
|
playwright = await async_playwright().start()
|
176
171
|
if cdp_url is not None:
|
177
172
|
logging.info(f"Connecting to cdp: {cdp_url}")
|
runtime/env.py
CHANGED
@@ -3,8 +3,7 @@ from typing import TYPE_CHECKING
|
|
3
3
|
|
4
4
|
if TYPE_CHECKING:
|
5
5
|
from playwright.async_api import ProxySettings
|
6
|
-
|
7
|
-
from ..browser import launch_chromium
|
6
|
+
from ..browser import launch_browser
|
8
7
|
|
9
8
|
|
10
9
|
@asynccontextmanager
|
@@ -14,7 +13,7 @@ async def get_production_playwright_constructs(
|
|
14
13
|
*,
|
15
14
|
cdp_address: str | None = None,
|
16
15
|
):
|
17
|
-
async with
|
16
|
+
async with launch_browser(headless=headless, cdp_address=cdp_address, proxy=proxy) as (context, page):
|
18
17
|
try:
|
19
18
|
yield context, page
|
20
19
|
finally:
|
File without changes
|
File without changes
|
File without changes
|