lucarne 1.0.0__tar.gz
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.
- lucarne-1.0.0/.gitignore +1 -0
- lucarne-1.0.0/PKG-INFO +49 -0
- lucarne-1.0.0/README.md +32 -0
- lucarne-1.0.0/lucarne.py +52 -0
- lucarne-1.0.0/pyproject.toml +31 -0
lucarne-1.0.0/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dist/
|
lucarne-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lucarne
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python client for lucarne — self-hostable browser sessions you can drive, watch, and record.
|
|
5
|
+
Project-URL: Homepage, https://github.com/volter-ai/lucarne
|
|
6
|
+
Project-URL: Repository, https://github.com/volter-ai/lucarne
|
|
7
|
+
Project-URL: Changelog, https://github.com/volter-ai/lucarne/blob/main/CHANGELOG.md
|
|
8
|
+
Author: Aaron Volter
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: agent,automation,browser,cdp,lucarne,playwright,remote-browser
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
|
|
14
|
+
Classifier: Topic :: Software Development :: Testing
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# lucarne (Python client)
|
|
19
|
+
|
|
20
|
+
Python client for **[lucarne](https://github.com/volter-ai/lucarne)** — self-hostable
|
|
21
|
+
browser sessions you can drive (CDP/Playwright), watch + control (porthole), and record,
|
|
22
|
+
on your own machine and your own IP.
|
|
23
|
+
|
|
24
|
+
This package is the **client**. The engine is a Node daemon — install and run it
|
|
25
|
+
separately (`npm install -g lucarne && lucarne serve`); you talk to it over HTTP, and
|
|
26
|
+
drive the browser over CDP with Playwright.
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
pip install lucarne playwright
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from lucarne import LucarneClient
|
|
34
|
+
from playwright.sync_api import sync_playwright
|
|
35
|
+
|
|
36
|
+
luc = LucarneClient("http://127.0.0.1:7800") # token="..." if the daemon needs one
|
|
37
|
+
s = luc.create(profile="demo", backend="native")
|
|
38
|
+
print("watch:", s["viewUrl"])
|
|
39
|
+
|
|
40
|
+
with sync_playwright() as p:
|
|
41
|
+
page = p.chromium.connect_over_cdp(s["cdpUrl"]).contexts[0].pages[0]
|
|
42
|
+
page.goto("https://example.com", wait_until="domcontentloaded")
|
|
43
|
+
print(page.title())
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The client is stdlib-only (no dependencies) and covers
|
|
47
|
+
`health / create / list / get / destroy / act / content`. For the rest of the API, call
|
|
48
|
+
the HTTP endpoints directly — see the [OpenAPI spec](https://github.com/volter-ai/lucarne)
|
|
49
|
+
at `/openapi.json`. MIT © Aaron Volter.
|
lucarne-1.0.0/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# lucarne (Python client)
|
|
2
|
+
|
|
3
|
+
Python client for **[lucarne](https://github.com/volter-ai/lucarne)** — self-hostable
|
|
4
|
+
browser sessions you can drive (CDP/Playwright), watch + control (porthole), and record,
|
|
5
|
+
on your own machine and your own IP.
|
|
6
|
+
|
|
7
|
+
This package is the **client**. The engine is a Node daemon — install and run it
|
|
8
|
+
separately (`npm install -g lucarne && lucarne serve`); you talk to it over HTTP, and
|
|
9
|
+
drive the browser over CDP with Playwright.
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
pip install lucarne playwright
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from lucarne import LucarneClient
|
|
17
|
+
from playwright.sync_api import sync_playwright
|
|
18
|
+
|
|
19
|
+
luc = LucarneClient("http://127.0.0.1:7800") # token="..." if the daemon needs one
|
|
20
|
+
s = luc.create(profile="demo", backend="native")
|
|
21
|
+
print("watch:", s["viewUrl"])
|
|
22
|
+
|
|
23
|
+
with sync_playwright() as p:
|
|
24
|
+
page = p.chromium.connect_over_cdp(s["cdpUrl"]).contexts[0].pages[0]
|
|
25
|
+
page.goto("https://example.com", wait_until="domcontentloaded")
|
|
26
|
+
print(page.title())
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The client is stdlib-only (no dependencies) and covers
|
|
30
|
+
`health / create / list / get / destroy / act / content`. For the rest of the API, call
|
|
31
|
+
the HTTP endpoints directly — see the [OpenAPI spec](https://github.com/volter-ai/lucarne)
|
|
32
|
+
at `/openapi.json`. MIT © Aaron Volter.
|
lucarne-1.0.0/lucarne.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Minimal Python client for the lucarne control API (stdlib only).
|
|
2
|
+
|
|
3
|
+
The daemon is the source of truth; this is convenience sugar. The session's
|
|
4
|
+
``cdpUrl`` is still driven with your CDP client of choice (e.g. Playwright).
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import urllib.request
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
__version__ = "1.0.0"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LucarneClient:
|
|
16
|
+
def __init__(self, base_url: str = "http://127.0.0.1:7800", token: str | None = None) -> None:
|
|
17
|
+
self.base_url = base_url.rstrip("/")
|
|
18
|
+
self.token = token
|
|
19
|
+
|
|
20
|
+
def _req(self, method: str, path: str, body: Any | None = None) -> Any:
|
|
21
|
+
data = json.dumps(body).encode() if body is not None else None
|
|
22
|
+
req = urllib.request.Request(self.base_url + path, data=data, method=method)
|
|
23
|
+
if self.token:
|
|
24
|
+
req.add_header("Authorization", f"Bearer {self.token}")
|
|
25
|
+
if data is not None:
|
|
26
|
+
req.add_header("Content-Type", "application/json")
|
|
27
|
+
with urllib.request.urlopen(req) as resp:
|
|
28
|
+
raw = resp.read()
|
|
29
|
+
ctype = resp.headers.get("content-type", "")
|
|
30
|
+
return json.loads(raw) if "application/json" in ctype else raw.decode()
|
|
31
|
+
|
|
32
|
+
def health(self) -> dict:
|
|
33
|
+
return self._req("GET", "/health")
|
|
34
|
+
|
|
35
|
+
def create(self, **opts: Any) -> dict:
|
|
36
|
+
return self._req("POST", "/sessions", opts)
|
|
37
|
+
|
|
38
|
+
def list(self, **meta: str) -> list:
|
|
39
|
+
q = "?" + "&".join(f"meta.{k}={v}" for k, v in meta.items()) if meta else ""
|
|
40
|
+
return self._req("GET", "/sessions" + q)
|
|
41
|
+
|
|
42
|
+
def get(self, session_id: str) -> dict:
|
|
43
|
+
return self._req("GET", f"/sessions/{session_id}")
|
|
44
|
+
|
|
45
|
+
def destroy(self, session_id: str) -> dict:
|
|
46
|
+
return self._req("DELETE", f"/sessions/{session_id}")
|
|
47
|
+
|
|
48
|
+
def act(self, session_id: str, **action: Any) -> dict:
|
|
49
|
+
return self._req("POST", f"/sessions/{session_id}/act", action)
|
|
50
|
+
|
|
51
|
+
def content(self, session_id: str) -> str:
|
|
52
|
+
return self._req("GET", f"/sessions/{session_id}/content")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "lucarne"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Python client for lucarne — self-hostable browser sessions you can drive, watch, and record."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{ name = "Aaron Volter" }]
|
|
13
|
+
keywords = ["browser", "playwright", "cdp", "automation", "remote-browser", "agent", "lucarne"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Topic :: Software Development :: Testing",
|
|
18
|
+
"Topic :: Internet :: WWW/HTTP :: Browsers",
|
|
19
|
+
]
|
|
20
|
+
dependencies = []
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/volter-ai/lucarne"
|
|
24
|
+
Repository = "https://github.com/volter-ai/lucarne"
|
|
25
|
+
Changelog = "https://github.com/volter-ai/lucarne/blob/main/CHANGELOG.md"
|
|
26
|
+
|
|
27
|
+
[tool.hatch.build.targets.wheel]
|
|
28
|
+
only-include = ["lucarne.py"]
|
|
29
|
+
|
|
30
|
+
[tool.hatch.build.targets.sdist]
|
|
31
|
+
include = ["lucarne.py", "README.md", "pyproject.toml"]
|