Skip to content

Commit 60c0f07

Browse files
committed
added the example external plugin
1 parent 00ffdd1 commit 60c0f07

File tree

8 files changed

+127
-1
lines changed

8 files changed

+127
-1
lines changed

docs/node-scraper-external

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# node-scraper external plugins (example)
2+
3+
This directory lives at **`/docs/node-scraper-external`** in the `node-scraper` repo and contains
4+
an example external plugin package you can install in editable mode.
5+
6+
## Installation
7+
8+
Use the same Python environment as `node-scraper`.
9+
10+
**Option A — from the repo root:**
11+
```bash
12+
cd ~/node-scraper
13+
pip install -e ./docs/node-scraper-external
14+
```
15+
You should see `ext-nodescraper-plugins` installed in editable mode.
16+
17+
18+
## Verify the external package is importable
19+
20+
```bash
21+
python - <<'PY'
22+
import ext_nodescraper_plugins
23+
print("ext_nodescraper_plugins loaded from:", ext_nodescraper_plugins.__file__)
24+
PY
25+
```
26+
27+
## Run external plugins
28+
29+
Confirm the CLI sees your external plugin(s):
30+
31+
```bash
32+
node-scraper run-plugins -h
33+
node-scraper run-plugins SamplePlugin
34+
```
35+
36+
## Add your own plugins
37+
38+
Add new modules under the **`ext_nodescraper_plugins/`** package. Example layout:
39+
40+
```
41+
/docs/node-scraper-external
42+
├─ pyproject.toml
43+
└─ ext_nodescraper_plugins/
44+
├─ __init__.py
45+
└─ sample/
46+
├─ __init__.py
47+
└─ sample_plugin.py
48+
```
49+
50+
```
51+
52+
Re-install (editable mode picks up code changes automatically, but if you add new files you may
53+
need to re-run):
54+
```bash
55+
pip install -e .
56+
```

docs/node-scraper-external/ext_nodescraper_plugins/sample/__init__.py

Whitespace-only changes.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus
2+
from nodescraper.interfaces import DataAnalyzer
3+
from nodescraper.models import TaskResult
4+
5+
from .sample_data import SampleDataModel
6+
7+
8+
class SampleAnalyzer(DataAnalyzer[SampleDataModel, None]):
9+
10+
DATA_MODEL = SampleDataModel
11+
12+
def analyze_data(self, data: SampleDataModel, args=None) -> TaskResult:
13+
if data.some_str != "expected_str":
14+
self.result.message = "String does not match expected"
15+
self.result.status = ExecutionStatus.ERROR
16+
return self.result
17+
18+
self._log_event(
19+
category=EventCategory.OS,
20+
description=f"{self.result.message}",
21+
data={"expected": "expected_str", "actual": data.some_str},
22+
priority=EventPriority.CRITICAL,
23+
console_log=True,
24+
)
25+
return self.result
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from nodescraper.base import InBandDataCollector
2+
from nodescraper.enums import ExecutionStatus
3+
from nodescraper.models import TaskResult
4+
5+
from .sample_data import SampleDataModel
6+
7+
8+
class SampleCollector(InBandDataCollector[SampleDataModel, None]):
9+
10+
DATA_MODEL = SampleDataModel
11+
12+
def collect_data(self, args=None) -> tuple[TaskResult, SampleDataModel | None]:
13+
sample_data = SampleDataModel(some_str="example123")
14+
self.result.message = "Collector ran successfully"
15+
self.result.status = ExecutionStatus.OK
16+
17+
return self.result, sample_data
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from nodescraper.models import DataModel
2+
3+
4+
class SampleDataModel(DataModel):
5+
some_str: str
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from nodescraper.base import InBandDataPlugin
2+
3+
from .sample_analyzer import SampleAnalyzer
4+
from .sample_collector import SampleCollector
5+
from .sample_data import SampleDataModel
6+
7+
8+
class SamplePlugin(InBandDataPlugin[SampleDataModel, None, None]):
9+
"""Example external plugin."""
10+
11+
DATA_MODEL = SampleDataModel
12+
13+
COLLECTOR = SampleCollector
14+
15+
ANALYZER = SampleAnalyzer
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[project]
2+
name = "ext-nodescraper-plugins"
3+
version = "0.1.0"
4+
requires-python = ">=3.10"
5+
dependencies = ["node-scraper"]
6+
7+
[build-system]
8+
requires = ["setuptools", "wheel"]
9+
build-backend = "setuptools.build_meta"

0 commit comments

Comments
 (0)