narada 0.1.26__py3-none-any.whl → 0.1.28__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.
- narada/__init__.py +3 -10
- narada/client.py +40 -0
- narada/utils.py +41 -0
- narada/version.py +7 -0
- {narada-0.1.26.dist-info → narada-0.1.28.dist-info}/METADATA +3 -2
- narada-0.1.28.dist-info/RECORD +10 -0
- {narada-0.1.26.dist-info → narada-0.1.28.dist-info}/WHEEL +1 -1
- narada/render_html.py +0 -21
- narada-0.1.26.dist-info/RECORD +0 -10
narada/__init__.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import importlib.metadata
|
|
2
|
-
|
|
3
1
|
from narada_core.errors import (
|
|
4
2
|
NaradaError,
|
|
5
3
|
NaradaExtensionMissingError,
|
|
@@ -12,20 +10,15 @@ from narada_core.models import Agent, File, Response, ResponseContent
|
|
|
12
10
|
|
|
13
11
|
from narada.client import Narada
|
|
14
12
|
from narada.config import BrowserConfig
|
|
15
|
-
from narada.
|
|
13
|
+
from narada.utils import download_file, render_html
|
|
14
|
+
from narada.version import __version__
|
|
16
15
|
from narada.window import LocalBrowserWindow, RemoteBrowserWindow
|
|
17
16
|
|
|
18
|
-
# Get version from package metadata
|
|
19
|
-
try:
|
|
20
|
-
__version__ = importlib.metadata.version("narada")
|
|
21
|
-
except Exception:
|
|
22
|
-
# Fallback version if package metadata is not available
|
|
23
|
-
__version__ = "unknown"
|
|
24
|
-
|
|
25
17
|
__all__ = [
|
|
26
18
|
"__version__",
|
|
27
19
|
"Agent",
|
|
28
20
|
"BrowserConfig",
|
|
21
|
+
"download_file",
|
|
29
22
|
"File",
|
|
30
23
|
"LocalBrowserWindow",
|
|
31
24
|
"Narada",
|
narada/client.py
CHANGED
|
@@ -9,6 +9,8 @@ from dataclasses import dataclass
|
|
|
9
9
|
from typing import Any
|
|
10
10
|
from uuid import uuid4
|
|
11
11
|
|
|
12
|
+
import aiohttp
|
|
13
|
+
import semver
|
|
12
14
|
from narada_core.errors import (
|
|
13
15
|
NaradaExtensionMissingError,
|
|
14
16
|
NaradaExtensionUnauthenticatedError,
|
|
@@ -16,6 +18,7 @@ from narada_core.errors import (
|
|
|
16
18
|
NaradaTimeoutError,
|
|
17
19
|
NaradaUnsupportedBrowserError,
|
|
18
20
|
)
|
|
21
|
+
from narada_core.models import _SdkConfig
|
|
19
22
|
from playwright._impl._errors import Error as PlaywrightError
|
|
20
23
|
from playwright.async_api import (
|
|
21
24
|
ElementHandle,
|
|
@@ -31,6 +34,7 @@ from rich.console import Console
|
|
|
31
34
|
|
|
32
35
|
from narada.config import BrowserConfig
|
|
33
36
|
from narada.utils import assert_never
|
|
37
|
+
from narada.version import __version__
|
|
34
38
|
from narada.window import LocalBrowserWindow, create_side_panel_url
|
|
35
39
|
|
|
36
40
|
|
|
@@ -58,6 +62,8 @@ class Narada:
|
|
|
58
62
|
self._console = Console()
|
|
59
63
|
|
|
60
64
|
async def __aenter__(self) -> Narada:
|
|
65
|
+
await self._validate_sdk_config()
|
|
66
|
+
|
|
61
67
|
self._playwright_context_manager = async_playwright()
|
|
62
68
|
self._playwright = await self._playwright_context_manager.__aenter__()
|
|
63
69
|
return self
|
|
@@ -70,6 +76,40 @@ class Narada:
|
|
|
70
76
|
self._playwright_context_manager = None
|
|
71
77
|
self._playwright = None
|
|
72
78
|
|
|
79
|
+
async def _fetch_sdk_config(self) -> _SdkConfig | None:
|
|
80
|
+
base_url = os.getenv("NARADA_API_BASE_URL", "https://api.narada.ai/fast/v2")
|
|
81
|
+
url = f"{base_url}/sdk/config"
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
async with aiohttp.ClientSession() as session:
|
|
85
|
+
async with session.get(
|
|
86
|
+
url, headers={"x-api-key": self._api_key}
|
|
87
|
+
) as resp:
|
|
88
|
+
if not resp.ok:
|
|
89
|
+
logging.warning(
|
|
90
|
+
"Failed to fetch SDK config: %s %s",
|
|
91
|
+
resp.status,
|
|
92
|
+
await resp.text(),
|
|
93
|
+
)
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
return _SdkConfig.model_validate(await resp.json())
|
|
97
|
+
except Exception as e:
|
|
98
|
+
logging.warning("Failed to fetch SDK config: %s", e)
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
async def _validate_sdk_config(self) -> None:
|
|
102
|
+
config = await self._fetch_sdk_config()
|
|
103
|
+
if config is None:
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
package_config = config.packages["narada"]
|
|
107
|
+
if semver.compare(__version__, package_config.min_required_version) < 0:
|
|
108
|
+
raise RuntimeError(
|
|
109
|
+
f"narada<={__version__} is not supported. Please upgrade to version "
|
|
110
|
+
f"{package_config.min_required_version} or higher."
|
|
111
|
+
)
|
|
112
|
+
|
|
73
113
|
async def open_and_initialize_browser_window(
|
|
74
114
|
self, config: BrowserConfig | None = None
|
|
75
115
|
) -> LocalBrowserWindow:
|
narada/utils.py
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
|
+
import webbrowser
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from tempfile import NamedTemporaryFile
|
|
1
4
|
from typing import Never
|
|
2
5
|
|
|
3
6
|
|
|
4
7
|
def assert_never() -> Never:
|
|
5
8
|
raise AssertionError("Expected code to be unreachable")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def download_file(filename: str, content: str | bytes) -> None:
|
|
12
|
+
"""
|
|
13
|
+
Downloads a file to the user's Downloads directory.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
filename: The name of the file to save. Can include subdirectories
|
|
17
|
+
(e.g., "reports/2025/data.csv") relative to the Downloads
|
|
18
|
+
directory.
|
|
19
|
+
content: The content to write. If str, writes in text mode (UTF-8).
|
|
20
|
+
If bytes, writes in binary mode.
|
|
21
|
+
"""
|
|
22
|
+
path = Path.home() / "Downloads" / filename
|
|
23
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
if isinstance(content, str):
|
|
25
|
+
path.write_text(content, encoding="utf-8")
|
|
26
|
+
else:
|
|
27
|
+
path.write_bytes(content)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def render_html(html: str) -> None:
|
|
31
|
+
"""
|
|
32
|
+
Renders HTML content by opening it in the default browser.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
html: The HTML content to render.
|
|
36
|
+
"""
|
|
37
|
+
with NamedTemporaryFile(
|
|
38
|
+
mode="w+t",
|
|
39
|
+
encoding="utf-8",
|
|
40
|
+
suffix=".html",
|
|
41
|
+
delete=False,
|
|
42
|
+
) as temp:
|
|
43
|
+
temp.write(html)
|
|
44
|
+
path = temp.name
|
|
45
|
+
|
|
46
|
+
webbrowser.open_new_tab(f"file://{path}")
|
narada/version.py
ADDED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: narada
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.28
|
|
4
4
|
Summary: Python client SDK for Narada
|
|
5
5
|
Project-URL: Homepage, https://github.com/NaradaAI/narada-python-sdk/narada
|
|
6
6
|
Project-URL: Repository, https://github.com/NaradaAI/narada-python-sdk
|
|
@@ -9,9 +9,10 @@ Author-email: Narada <support@narada.ai>
|
|
|
9
9
|
License-Expression: Apache-2.0
|
|
10
10
|
Requires-Python: >=3.12
|
|
11
11
|
Requires-Dist: aiohttp>=3.12.13
|
|
12
|
-
Requires-Dist: narada-core==0.0.
|
|
12
|
+
Requires-Dist: narada-core==0.0.6
|
|
13
13
|
Requires-Dist: playwright>=1.53.0
|
|
14
14
|
Requires-Dist: rich>=14.0.0
|
|
15
|
+
Requires-Dist: semver>=3.0.4
|
|
15
16
|
Description-Content-Type: text/markdown
|
|
16
17
|
|
|
17
18
|
<p align="center">
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
narada/__init__.py,sha256=Jk941BV4iy70Ei2MmHkNXEOkZUHBa6Lij_jZZRfiyhg,936
|
|
2
|
+
narada/client.py,sha256=r_aBtqVYEBsr5N9E79qzl8q498F6cnSyejqZWSbB4qU,16768
|
|
3
|
+
narada/config.py,sha256=tvj16P_qAHOFB2O_VlrcizA8SrbmS_Nmkm2r7ltG-VM,1345
|
|
4
|
+
narada/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
narada/utils.py,sha256=gdLwNMXPpRohDcIIe0cB3KhvZ8X1QfAlKVh1sXWeJmk,1284
|
|
6
|
+
narada/version.py,sha256=kwW6yy0_4Pf3kt888eeCG0VwBb2L2rCkrkpdZEC_3rA,193
|
|
7
|
+
narada/window.py,sha256=OGuEs778xjxHivzWlJIIHKZPqGd4Sn9_YVArt_8TYoU,17762
|
|
8
|
+
narada-0.1.28.dist-info/METADATA,sha256=jVmIONyot5rg8HLvqMIpSIjj2h25ycOoTbQcnb_8TnQ,5146
|
|
9
|
+
narada-0.1.28.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
10
|
+
narada-0.1.28.dist-info/RECORD,,
|
narada/render_html.py
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import webbrowser
|
|
2
|
-
from tempfile import NamedTemporaryFile
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def render_html(html: str) -> None:
|
|
6
|
-
"""
|
|
7
|
-
Renders HTML content by opening it in the default browser.
|
|
8
|
-
|
|
9
|
-
Args:
|
|
10
|
-
html: The HTML content to render.
|
|
11
|
-
"""
|
|
12
|
-
with NamedTemporaryFile(
|
|
13
|
-
mode="w+t",
|
|
14
|
-
encoding="utf-8",
|
|
15
|
-
suffix=".html",
|
|
16
|
-
delete=False,
|
|
17
|
-
) as temp:
|
|
18
|
-
temp.write(html)
|
|
19
|
-
path = temp.name
|
|
20
|
-
|
|
21
|
-
webbrowser.open_new_tab(f"file://{path}")
|
narada-0.1.26.dist-info/RECORD
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
narada/__init__.py,sha256=kGBirP2C3ENrBHpSQ2wEKZe0kTFCRBJSnImiSqVYeRk,1097
|
|
2
|
-
narada/client.py,sha256=jksBBWdSJP88fP1DpLYoyJNNdgkUMrEKlcuYenARzaI,15265
|
|
3
|
-
narada/config.py,sha256=tvj16P_qAHOFB2O_VlrcizA8SrbmS_Nmkm2r7ltG-VM,1345
|
|
4
|
-
narada/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
narada/render_html.py,sha256=uJgh6AApSl6KJHEpj8KGbZrukOn7Z8sU1EWkRVVwI2Y,461
|
|
6
|
-
narada/utils.py,sha256=6NxADP1BxWLYLv40tAFlaGVxoyA_7k3dPUA-sFBQIZw,116
|
|
7
|
-
narada/window.py,sha256=OGuEs778xjxHivzWlJIIHKZPqGd4Sn9_YVArt_8TYoU,17762
|
|
8
|
-
narada-0.1.26.dist-info/METADATA,sha256=btpib6q-h8LelhpEj-hPp_IXyVKEUtoHpf7hZvuYmPw,5117
|
|
9
|
-
narada-0.1.26.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
10
|
-
narada-0.1.26.dist-info/RECORD,,
|