geonode-scraper-langchain 0.1.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.
@@ -0,0 +1,2 @@
1
+ include README.md
2
+ recursive-include geonode_scraper_langchain py.typed
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.4
2
+ Name: geonode-scraper-langchain
3
+ Version: 0.1.0
4
+ Summary: LangChain tools for the Geonode Scraper API
5
+ Author: Geonode Team
6
+ License-Expression: MIT
7
+ Classifier: Programming Language :: Python :: 3.10
8
+ Classifier: Programming Language :: Python :: 3.11
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Typing :: Typed
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: geonode-scraper-tools-core>=0.1.0
14
+ Requires-Dist: langchain-core>=1.0
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=8.0; extra == "dev"
17
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
18
+ Requires-Dist: ruff>=0.12.11; extra == "dev"
19
+
20
+ # Geonode Scraper LangChain Tools
21
+
22
+ LangChain tools for the Geonode Scraper API.
23
+
24
+ This package depends on `geonode-scraper-tools-core` for the shared service,
25
+ schemas, and operation registry.
26
+
27
+ ## Installation
28
+
29
+ ```sh
30
+ pip install geonode-scraper-langchain
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```python
36
+ from geonode_scraper_langchain import build_langchain_tools
37
+ from geonode_scraper_tools_core import ScraperToolSettings
38
+
39
+ settings = ScraperToolSettings(
40
+ host="https://api.example.com",
41
+ api_key="your-api-key",
42
+ )
43
+
44
+ tools = build_langchain_tools(settings=settings)
45
+ ```
46
+
47
+ ## Exposed Tools
48
+
49
+ - `scraper_extract_content`
50
+ - `scraper_get_job_result`
51
+ - `scraper_wait_for_job`
52
+ - `scraper_list_jobs`
53
+ - `scraper_get_statistics`
54
+ - `scraper_check_health`
@@ -0,0 +1,35 @@
1
+ # Geonode Scraper LangChain Tools
2
+
3
+ LangChain tools for the Geonode Scraper API.
4
+
5
+ This package depends on `geonode-scraper-tools-core` for the shared service,
6
+ schemas, and operation registry.
7
+
8
+ ## Installation
9
+
10
+ ```sh
11
+ pip install geonode-scraper-langchain
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ```python
17
+ from geonode_scraper_langchain import build_langchain_tools
18
+ from geonode_scraper_tools_core import ScraperToolSettings
19
+
20
+ settings = ScraperToolSettings(
21
+ host="https://api.example.com",
22
+ api_key="your-api-key",
23
+ )
24
+
25
+ tools = build_langchain_tools(settings=settings)
26
+ ```
27
+
28
+ ## Exposed Tools
29
+
30
+ - `scraper_extract_content`
31
+ - `scraper_get_job_result`
32
+ - `scraper_wait_for_job`
33
+ - `scraper_list_jobs`
34
+ - `scraper_get_statistics`
35
+ - `scraper_check_health`
@@ -0,0 +1,5 @@
1
+ from .toolkit import ScraperLangChainToolkit, build_langchain_tools
2
+
3
+ __all__ = ["ScraperLangChainToolkit", "build_langchain_tools"]
4
+
5
+ __version__ = "0.1.0"
@@ -0,0 +1,64 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ from typing import Any, Sequence
5
+
6
+ from geonode_scraper_tools_core import ScraperToolService, ScraperToolSettings, get_operations
7
+ from geonode_scraper_tools_core.registry import OperationSpec
8
+
9
+
10
+ class ScraperLangChainToolkit:
11
+ def __init__(self, service: ScraperToolService) -> None:
12
+ self.service = service
13
+
14
+ @classmethod
15
+ def from_settings(cls, settings: ScraperToolSettings) -> ScraperLangChainToolkit:
16
+ return cls(ScraperToolService(settings))
17
+
18
+ def get_tools(self, operations: Sequence[str] | None = None) -> list[Any]:
19
+ from langchain_core.tools import StructuredTool
20
+
21
+ return [
22
+ self._build_tool(StructuredTool=StructuredTool, operation=operation)
23
+ for operation in get_operations(operations)
24
+ ]
25
+
26
+ def _build_tool(self, *, StructuredTool: type[Any], operation: OperationSpec) -> Any:
27
+ def _invoke(**kwargs: Any) -> dict[str, Any]:
28
+ return operation.invoke(self.service, **kwargs)
29
+
30
+ async def _ainvoke(**kwargs: Any) -> dict[str, Any]:
31
+ return await asyncio.to_thread(operation.invoke, self.service, **kwargs)
32
+
33
+ _invoke.__name__ = operation.tool_name
34
+ _invoke.__doc__ = operation.description
35
+
36
+ return StructuredTool.from_function(
37
+ func=_invoke,
38
+ coroutine=_ainvoke,
39
+ name=operation.tool_name,
40
+ description=operation.description,
41
+ args_schema=operation.args_schema,
42
+ )
43
+
44
+
45
+ def build_langchain_tools(
46
+ *,
47
+ settings: ScraperToolSettings | None = None,
48
+ service: ScraperToolService | None = None,
49
+ operations: Sequence[str] | None = None,
50
+ ) -> list[Any]:
51
+ resolved_service = _resolve_service(settings=settings, service=service)
52
+ return ScraperLangChainToolkit(resolved_service).get_tools(operations=operations)
53
+
54
+
55
+ def _resolve_service(
56
+ *,
57
+ settings: ScraperToolSettings | None,
58
+ service: ScraperToolService | None,
59
+ ) -> ScraperToolService:
60
+ if service is not None:
61
+ return service
62
+ if settings is None:
63
+ raise ValueError("Provide either settings or service to build LangChain tools.")
64
+ return ScraperToolService(settings)
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.4
2
+ Name: geonode-scraper-langchain
3
+ Version: 0.1.0
4
+ Summary: LangChain tools for the Geonode Scraper API
5
+ Author: Geonode Team
6
+ License-Expression: MIT
7
+ Classifier: Programming Language :: Python :: 3.10
8
+ Classifier: Programming Language :: Python :: 3.11
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Typing :: Typed
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: geonode-scraper-tools-core>=0.1.0
14
+ Requires-Dist: langchain-core>=1.0
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=8.0; extra == "dev"
17
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
18
+ Requires-Dist: ruff>=0.12.11; extra == "dev"
19
+
20
+ # Geonode Scraper LangChain Tools
21
+
22
+ LangChain tools for the Geonode Scraper API.
23
+
24
+ This package depends on `geonode-scraper-tools-core` for the shared service,
25
+ schemas, and operation registry.
26
+
27
+ ## Installation
28
+
29
+ ```sh
30
+ pip install geonode-scraper-langchain
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```python
36
+ from geonode_scraper_langchain import build_langchain_tools
37
+ from geonode_scraper_tools_core import ScraperToolSettings
38
+
39
+ settings = ScraperToolSettings(
40
+ host="https://api.example.com",
41
+ api_key="your-api-key",
42
+ )
43
+
44
+ tools = build_langchain_tools(settings=settings)
45
+ ```
46
+
47
+ ## Exposed Tools
48
+
49
+ - `scraper_extract_content`
50
+ - `scraper_get_job_result`
51
+ - `scraper_wait_for_job`
52
+ - `scraper_list_jobs`
53
+ - `scraper_get_statistics`
54
+ - `scraper_check_health`
@@ -0,0 +1,12 @@
1
+ MANIFEST.in
2
+ README.md
3
+ pyproject.toml
4
+ geonode_scraper_langchain/__init__.py
5
+ geonode_scraper_langchain/py.typed
6
+ geonode_scraper_langchain/toolkit.py
7
+ geonode_scraper_langchain.egg-info/PKG-INFO
8
+ geonode_scraper_langchain.egg-info/SOURCES.txt
9
+ geonode_scraper_langchain.egg-info/dependency_links.txt
10
+ geonode_scraper_langchain.egg-info/requires.txt
11
+ geonode_scraper_langchain.egg-info/top_level.txt
12
+ tests/test_langchain_tools.py
@@ -0,0 +1,7 @@
1
+ geonode-scraper-tools-core>=0.1.0
2
+ langchain-core>=1.0
3
+
4
+ [dev]
5
+ pytest>=8.0
6
+ pytest-cov>=5.0
7
+ ruff>=0.12.11
@@ -0,0 +1 @@
1
+ geonode_scraper_langchain
@@ -0,0 +1,47 @@
1
+ [project]
2
+ name = "geonode-scraper-langchain"
3
+ version = "0.1.0"
4
+ description = "LangChain tools for the Geonode Scraper API"
5
+ authors = [
6
+ {name = "Geonode Team"},
7
+ ]
8
+ readme = "README.md"
9
+ license = "MIT"
10
+ requires-python = ">=3.10"
11
+ classifiers = [
12
+ "Programming Language :: Python :: 3.10",
13
+ "Programming Language :: Python :: 3.11",
14
+ "Programming Language :: Python :: 3.12",
15
+ "Typing :: Typed",
16
+ ]
17
+ dependencies = [
18
+ "geonode-scraper-tools-core>=0.1.0",
19
+ "langchain-core>=1.0",
20
+ ]
21
+
22
+ [project.optional-dependencies]
23
+ dev = [
24
+ "pytest>=8.0",
25
+ "pytest-cov>=5.0",
26
+ "ruff>=0.12.11",
27
+ ]
28
+
29
+ [build-system]
30
+ requires = ["setuptools"]
31
+ build-backend = "setuptools.build_meta"
32
+
33
+ [tool.setuptools.packages.find]
34
+ include = ["geonode_scraper_langchain*"]
35
+
36
+ [tool.setuptools.package-data]
37
+ geonode_scraper_langchain = ["py.typed"]
38
+
39
+ [tool.pytest.ini_options]
40
+ testpaths = ["tests"]
41
+
42
+ [tool.ruff]
43
+ target-version = "py310"
44
+ line-length = 120
45
+
46
+ [tool.ruff.lint]
47
+ select = ["E", "W", "F", "I", "B"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,63 @@
1
+ from __future__ import annotations
2
+
3
+ from geonode_scraper_langchain import build_langchain_tools
4
+
5
+
6
+ class StubService:
7
+ def extract(self, **kwargs):
8
+ return {"ok": True, "operation": "extract", "result": kwargs}
9
+
10
+ def get_job_result(self, **kwargs):
11
+ return {"ok": True, "operation": "get_job_result", "result": kwargs}
12
+
13
+ def wait_for_job(self, **kwargs):
14
+ return {"ok": True, "operation": "wait_for_job", "result": kwargs}
15
+
16
+ def list_jobs(self, **kwargs):
17
+ return {"ok": True, "operation": "list_jobs", "result": kwargs}
18
+
19
+ def get_statistics(self, **kwargs):
20
+ return {"ok": True, "operation": "get_statistics", "result": kwargs}
21
+
22
+ def health_check(self, **kwargs):
23
+ return {"ok": True, "operation": "health_check", "result": kwargs}
24
+
25
+
26
+ def test_build_langchain_tools_exposes_expected_names():
27
+ pytest = __import__("pytest")
28
+ pytest.importorskip("langchain_core.tools")
29
+
30
+ tools = build_langchain_tools(service=StubService())
31
+
32
+ assert [tool.name for tool in tools] == [
33
+ "scraper_extract_content",
34
+ "scraper_get_job_result",
35
+ "scraper_wait_for_job",
36
+ "scraper_list_jobs",
37
+ "scraper_get_statistics",
38
+ "scraper_check_health",
39
+ ]
40
+
41
+
42
+ def test_langchain_tool_invocation_returns_structured_output():
43
+ pytest = __import__("pytest")
44
+ pytest.importorskip("langchain_core.tools")
45
+
46
+ tools = build_langchain_tools(service=StubService(), operations=["extract"])
47
+ result = tools[0].invoke({"url": "https://example.com"})
48
+
49
+ assert result["ok"] is True
50
+ assert result["operation"] == "extract"
51
+ assert result["result"]["url"] == "https://example.com"
52
+
53
+
54
+ def test_langchain_wait_for_job_tool_is_selectable():
55
+ pytest = __import__("pytest")
56
+ pytest.importorskip("langchain_core.tools")
57
+
58
+ tools = build_langchain_tools(service=StubService(), operations=["wait_for_job"])
59
+ result = tools[0].invoke({"job_id": "test-job-uuid"})
60
+
61
+ assert result["ok"] is True
62
+ assert result["operation"] == "wait_for_job"
63
+ assert result["result"]["job_id"] == "test-job-uuid"