geonode-scraper-cli 0.1.0__tar.gz → 0.2.1__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.
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/PKG-INFO +9 -4
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/README.md +7 -2
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/__init__.py +1 -1
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/map.py +1 -1
- geonode_scraper_cli-0.2.1/geonode_scraper_cli/commands/search.py +74 -0
- geonode_scraper_cli-0.2.1/geonode_scraper_cli/commands/usage.py +21 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/config.py +7 -1
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/context.py +3 -1
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/main.py +4 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli.egg-info/PKG-INFO +9 -4
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli.egg-info/SOURCES.txt +4 -1
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli.egg-info/requires.txt +1 -1
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/pyproject.toml +2 -2
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/tests/test_cli.py +50 -1
- geonode_scraper_cli-0.2.1/tests/test_user_agent.py +28 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/__init__.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/_common.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/batch.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/config.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/crawl.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/extract.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/jobs.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/stats.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/system.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/errors.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/invoke.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/output.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/py.typed +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/renderers/__init__.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/renderers/tables.py +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli.egg-info/dependency_links.txt +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli.egg-info/entry_points.txt +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli.egg-info/top_level.txt +0 -0
- {geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: geonode-scraper-cli
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Command-line interface for the Geonode Scraper API
|
|
5
5
|
Author: Geonode Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
10
10
|
Classifier: Typing :: Typed
|
|
11
11
|
Requires-Python: >=3.10
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
|
-
Requires-Dist: geonode-scraper-tools-core>=0.
|
|
13
|
+
Requires-Dist: geonode-scraper-tools-core>=0.5.0
|
|
14
14
|
Requires-Dist: typer>=0.12
|
|
15
15
|
Requires-Dist: rich>=13.0
|
|
16
16
|
Requires-Dist: PyYAML>=6.0
|
|
@@ -129,11 +129,16 @@ gscraper crawl wait JOB_ID
|
|
|
129
129
|
gscraper crawl list [--url ...]
|
|
130
130
|
gscraper crawl cancel JOB_ID
|
|
131
131
|
|
|
132
|
-
gscraper map run URL [--search term] [--
|
|
133
|
-
gscraper map jobs list
|
|
132
|
+
gscraper map run URL [--search term] [--include-subdomains] # primary action
|
|
133
|
+
gscraper map jobs list # inspect past map jobs
|
|
134
134
|
gscraper map jobs get JOB_ID
|
|
135
135
|
|
|
136
|
+
gscraper search run QUERY [--locale en] [--page 1] [--safe off] [--time-range week]
|
|
137
|
+
gscraper search jobs list [--query ...] [--status completed]
|
|
138
|
+
gscraper search jobs get JOB_ID
|
|
139
|
+
|
|
136
140
|
gscraper stats [--start-date ISO] [--end-date ISO]
|
|
141
|
+
gscraper usage concurrency
|
|
137
142
|
gscraper health
|
|
138
143
|
```
|
|
139
144
|
|
|
@@ -107,11 +107,16 @@ gscraper crawl wait JOB_ID
|
|
|
107
107
|
gscraper crawl list [--url ...]
|
|
108
108
|
gscraper crawl cancel JOB_ID
|
|
109
109
|
|
|
110
|
-
gscraper map run URL [--search term] [--
|
|
111
|
-
gscraper map jobs list
|
|
110
|
+
gscraper map run URL [--search term] [--include-subdomains] # primary action
|
|
111
|
+
gscraper map jobs list # inspect past map jobs
|
|
112
112
|
gscraper map jobs get JOB_ID
|
|
113
113
|
|
|
114
|
+
gscraper search run QUERY [--locale en] [--page 1] [--safe off] [--time-range week]
|
|
115
|
+
gscraper search jobs list [--query ...] [--status completed]
|
|
116
|
+
gscraper search jobs get JOB_ID
|
|
117
|
+
|
|
114
118
|
gscraper stats [--start-date ISO] [--end-date ISO]
|
|
119
|
+
gscraper usage concurrency
|
|
115
120
|
gscraper health
|
|
116
121
|
```
|
|
117
122
|
|
|
@@ -20,7 +20,7 @@ def run(
|
|
|
20
20
|
ctx: typer.Context,
|
|
21
21
|
url: str = typer.Argument(..., help="Base URL to discover links from."),
|
|
22
22
|
search: Optional[str] = typer.Option(None, "--search", help="Filter discovered links by substring."),
|
|
23
|
-
include_subdomains: bool = typer.Option(
|
|
23
|
+
include_subdomains: bool = typer.Option(False, "--include-subdomains/--no-subdomains", help="Include subdomains."),
|
|
24
24
|
ignore_query_parameters: bool = typer.Option(
|
|
25
25
|
True, "--ignore-query/--keep-query", help="Ignore query parameters when de-duplicating links."
|
|
26
26
|
),
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""`gscraper search` — run a search query and inspect search jobs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
from geonode_scraper_tools_core.schemas import GetSearchJobInput, ListSearchJobsInput, SearchInput
|
|
9
|
+
|
|
10
|
+
from ..invoke import call, validated
|
|
11
|
+
from ._common import apply_output_override, optional
|
|
12
|
+
|
|
13
|
+
search_app = typer.Typer(help="Run search queries and inspect search jobs.", no_args_is_help=True)
|
|
14
|
+
search_jobs_app = typer.Typer(help="Inspect search jobs.", no_args_is_help=True)
|
|
15
|
+
search_app.add_typer(search_jobs_app, name="jobs")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@search_app.command("run")
|
|
19
|
+
def run(
|
|
20
|
+
ctx: typer.Context,
|
|
21
|
+
query: str = typer.Argument(..., help="Search query."),
|
|
22
|
+
locale: Optional[str] = typer.Option(None, "--locale", help="Locale tag, e.g. 'en' or 'en-US'."),
|
|
23
|
+
page: int = typer.Option(1, "--page", help="Result page to fetch (1-20)."),
|
|
24
|
+
safe: str = typer.Option("off", "--safe", help="Safe-search level: off|moderate|strict."),
|
|
25
|
+
time_range: Optional[str] = typer.Option(None, "--time-range", help="day|week|month|year."),
|
|
26
|
+
as_json: bool = typer.Option(False, "--json", help="Output raw JSON envelope."),
|
|
27
|
+
as_yaml: bool = typer.Option(False, "--yaml", help="Output raw YAML envelope."),
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Run a search query (returns synchronously)."""
|
|
30
|
+
apply_output_override(ctx, as_json, as_yaml)
|
|
31
|
+
payload = validated(
|
|
32
|
+
SearchInput,
|
|
33
|
+
query=query,
|
|
34
|
+
page=page,
|
|
35
|
+
safe=safe,
|
|
36
|
+
**optional(locale=locale, time_range=time_range),
|
|
37
|
+
)
|
|
38
|
+
call(ctx, "search", payload)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@search_jobs_app.command("list")
|
|
42
|
+
def list_jobs(
|
|
43
|
+
ctx: typer.Context,
|
|
44
|
+
query: Optional[str] = typer.Option(None, "--query", help="Filter by search query."),
|
|
45
|
+
status: Optional[str] = typer.Option(None, "--status", help="queued|processing|completed|failed|cancelled."),
|
|
46
|
+
start_date: Optional[str] = typer.Option(None, "--start-date", help="ISO 8601 lower bound."),
|
|
47
|
+
end_date: Optional[str] = typer.Option(None, "--end-date", help="ISO 8601 upper bound."),
|
|
48
|
+
page: int = typer.Option(1, "--page", help="Page number."),
|
|
49
|
+
page_size: int = typer.Option(100, "--page-size", help="Results per page (max 100)."),
|
|
50
|
+
as_json: bool = typer.Option(False, "--json", help="Output raw JSON envelope."),
|
|
51
|
+
as_yaml: bool = typer.Option(False, "--yaml", help="Output raw YAML envelope."),
|
|
52
|
+
) -> None:
|
|
53
|
+
"""List and filter search jobs."""
|
|
54
|
+
apply_output_override(ctx, as_json, as_yaml)
|
|
55
|
+
payload = validated(
|
|
56
|
+
ListSearchJobsInput,
|
|
57
|
+
page=page,
|
|
58
|
+
page_size=page_size,
|
|
59
|
+
**optional(query=query, status=status, start_date=start_date, end_date=end_date),
|
|
60
|
+
)
|
|
61
|
+
call(ctx, "list_search_jobs", payload)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@search_jobs_app.command("get")
|
|
65
|
+
def get(
|
|
66
|
+
ctx: typer.Context,
|
|
67
|
+
job_id: str = typer.Argument(..., help="Search job ID."),
|
|
68
|
+
as_json: bool = typer.Option(False, "--json", help="Output raw JSON envelope."),
|
|
69
|
+
as_yaml: bool = typer.Option(False, "--yaml", help="Output raw YAML envelope."),
|
|
70
|
+
) -> None:
|
|
71
|
+
"""Fetch a single search job by ID."""
|
|
72
|
+
apply_output_override(ctx, as_json, as_yaml)
|
|
73
|
+
payload = validated(GetSearchJobInput, job_id=job_id)
|
|
74
|
+
call(ctx, "get_search_job", payload)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""`gscraper usage` — plan usage and limits."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from ..invoke import call
|
|
8
|
+
from ._common import apply_output_override
|
|
9
|
+
|
|
10
|
+
usage_app = typer.Typer(help="Usage and limits.", no_args_is_help=True)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@usage_app.command("concurrency")
|
|
14
|
+
def concurrency(
|
|
15
|
+
ctx: typer.Context,
|
|
16
|
+
as_json: bool = typer.Option(False, "--json", help="Output raw JSON envelope."),
|
|
17
|
+
as_yaml: bool = typer.Option(False, "--yaml", help="Output raw YAML envelope."),
|
|
18
|
+
) -> None:
|
|
19
|
+
"""Check the caller's live work-concurrency slot usage against their plan limit."""
|
|
20
|
+
apply_output_override(ctx, as_json, as_yaml)
|
|
21
|
+
call(ctx, "get_concurrency_usage", {})
|
|
@@ -15,7 +15,13 @@ from geonode_scraper_tools_core import ScraperToolSettings
|
|
|
15
15
|
|
|
16
16
|
ENV_PREFIX = "GEONODE_SCRAPER_"
|
|
17
17
|
DEFAULT_PROFILE = "default"
|
|
18
|
-
|
|
18
|
+
# The production API. It used to be `http://localhost`, which is the OpenAPI
|
|
19
|
+
# generator's fallback for a spec with no `servers` block - harmless in a generated
|
|
20
|
+
# client that documents it, and wrong in a CLI a person installs and runs, where it
|
|
21
|
+
# means every command fails to connect until a host is configured. A flag, the
|
|
22
|
+
# environment or the config file still override it; this is only what happens when
|
|
23
|
+
# nobody said anything.
|
|
24
|
+
DEFAULT_HOST = "https://scraper.geonode.io"
|
|
19
25
|
|
|
20
26
|
|
|
21
27
|
class ConfigError(Exception):
|
|
@@ -7,6 +7,7 @@ from dataclasses import dataclass
|
|
|
7
7
|
import typer
|
|
8
8
|
from geonode_scraper_tools_core import ScraperToolService, ScraperToolSettings
|
|
9
9
|
|
|
10
|
+
from . import __version__
|
|
10
11
|
from .config import ConfigError, resolve_settings
|
|
11
12
|
from .errors import ExitCode
|
|
12
13
|
from .output import OutputFormat
|
|
@@ -49,7 +50,8 @@ class CLIContext:
|
|
|
49
50
|
|
|
50
51
|
def service(self) -> ScraperToolService:
|
|
51
52
|
if self._service is None:
|
|
52
|
-
|
|
53
|
+
# The API labels requests from this package `cli` (scraper-api#674).
|
|
54
|
+
self._service = ScraperToolService(self.settings(), client=f"geonode-cli/{__version__}")
|
|
53
55
|
return self._service
|
|
54
56
|
|
|
55
57
|
|
|
@@ -13,8 +13,10 @@ from .commands.crawl import crawl_app
|
|
|
13
13
|
from .commands.extract import extract
|
|
14
14
|
from .commands.jobs import jobs_app
|
|
15
15
|
from .commands.map import map_app
|
|
16
|
+
from .commands.search import search_app
|
|
16
17
|
from .commands.stats import stats
|
|
17
18
|
from .commands.system import health
|
|
19
|
+
from .commands.usage import usage_app
|
|
18
20
|
from .context import CLIContext
|
|
19
21
|
from .output import OutputFormat
|
|
20
22
|
|
|
@@ -76,6 +78,8 @@ app.add_typer(jobs_app, name="jobs")
|
|
|
76
78
|
app.add_typer(batch_app, name="batch")
|
|
77
79
|
app.add_typer(crawl_app, name="crawl")
|
|
78
80
|
app.add_typer(map_app, name="map")
|
|
81
|
+
app.add_typer(search_app, name="search")
|
|
82
|
+
app.add_typer(usage_app, name="usage")
|
|
79
83
|
app.add_typer(config_app, name="config")
|
|
80
84
|
|
|
81
85
|
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: geonode-scraper-cli
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Command-line interface for the Geonode Scraper API
|
|
5
5
|
Author: Geonode Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
10
10
|
Classifier: Typing :: Typed
|
|
11
11
|
Requires-Python: >=3.10
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
|
-
Requires-Dist: geonode-scraper-tools-core>=0.
|
|
13
|
+
Requires-Dist: geonode-scraper-tools-core>=0.5.0
|
|
14
14
|
Requires-Dist: typer>=0.12
|
|
15
15
|
Requires-Dist: rich>=13.0
|
|
16
16
|
Requires-Dist: PyYAML>=6.0
|
|
@@ -129,11 +129,16 @@ gscraper crawl wait JOB_ID
|
|
|
129
129
|
gscraper crawl list [--url ...]
|
|
130
130
|
gscraper crawl cancel JOB_ID
|
|
131
131
|
|
|
132
|
-
gscraper map run URL [--search term] [--
|
|
133
|
-
gscraper map jobs list
|
|
132
|
+
gscraper map run URL [--search term] [--include-subdomains] # primary action
|
|
133
|
+
gscraper map jobs list # inspect past map jobs
|
|
134
134
|
gscraper map jobs get JOB_ID
|
|
135
135
|
|
|
136
|
+
gscraper search run QUERY [--locale en] [--page 1] [--safe off] [--time-range week]
|
|
137
|
+
gscraper search jobs list [--query ...] [--status completed]
|
|
138
|
+
gscraper search jobs get JOB_ID
|
|
139
|
+
|
|
136
140
|
gscraper stats [--start-date ISO] [--end-date ISO]
|
|
141
|
+
gscraper usage concurrency
|
|
137
142
|
gscraper health
|
|
138
143
|
```
|
|
139
144
|
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli.egg-info/SOURCES.txt
RENAMED
|
@@ -22,8 +22,11 @@ geonode_scraper_cli/commands/crawl.py
|
|
|
22
22
|
geonode_scraper_cli/commands/extract.py
|
|
23
23
|
geonode_scraper_cli/commands/jobs.py
|
|
24
24
|
geonode_scraper_cli/commands/map.py
|
|
25
|
+
geonode_scraper_cli/commands/search.py
|
|
25
26
|
geonode_scraper_cli/commands/stats.py
|
|
26
27
|
geonode_scraper_cli/commands/system.py
|
|
28
|
+
geonode_scraper_cli/commands/usage.py
|
|
27
29
|
geonode_scraper_cli/renderers/__init__.py
|
|
28
30
|
geonode_scraper_cli/renderers/tables.py
|
|
29
|
-
tests/test_cli.py
|
|
31
|
+
tests/test_cli.py
|
|
32
|
+
tests/test_user_agent.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "geonode-scraper-cli"
|
|
3
|
-
version = "0.1
|
|
3
|
+
version = "0.2.1"
|
|
4
4
|
description = "Command-line interface for the Geonode Scraper API"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Geonode Team"},
|
|
@@ -15,7 +15,7 @@ classifiers = [
|
|
|
15
15
|
"Typing :: Typed",
|
|
16
16
|
]
|
|
17
17
|
dependencies = [
|
|
18
|
-
"geonode-scraper-tools-core>=0.
|
|
18
|
+
"geonode-scraper-tools-core>=0.5.0",
|
|
19
19
|
"typer>=0.12",
|
|
20
20
|
"rich>=13.0",
|
|
21
21
|
"PyYAML>=6.0",
|
|
@@ -97,7 +97,7 @@ def test_missing_api_key_is_usage_error(invoke, fake_service):
|
|
|
97
97
|
def test_flag_overrides_env_host(invoke, fake_service, monkeypatch):
|
|
98
98
|
captured: dict[str, object] = {}
|
|
99
99
|
|
|
100
|
-
def _capture(settings):
|
|
100
|
+
def _capture(settings, **_):
|
|
101
101
|
captured["host"] = settings.host
|
|
102
102
|
return fake_service
|
|
103
103
|
|
|
@@ -131,6 +131,55 @@ def test_map_run_renders_links(invoke, fake_service):
|
|
|
131
131
|
assert "https://a.com" in result.stdout
|
|
132
132
|
|
|
133
133
|
|
|
134
|
+
def test_map_run_defaults_include_subdomains_false(invoke, fake_service):
|
|
135
|
+
invoke(["map", "run", "https://example.com"])
|
|
136
|
+
_, kwargs = fake_service.calls[-1]
|
|
137
|
+
assert kwargs["include_subdomains"] is False
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def test_search_run_passes_validated_payload(invoke, fake_service):
|
|
141
|
+
fake_service.responses["search"] = {
|
|
142
|
+
"ok": True,
|
|
143
|
+
"operation": "search",
|
|
144
|
+
"result": {"job_id": "00000000-0000-0000-0000-000000000007", "results": []},
|
|
145
|
+
}
|
|
146
|
+
result = invoke(["search", "run", "geonode scraper api", "--page", "2", "--safe", "moderate"])
|
|
147
|
+
assert result.exit_code == 0
|
|
148
|
+
name, kwargs = fake_service.calls[-1]
|
|
149
|
+
assert name == "search"
|
|
150
|
+
assert kwargs["query"] == "geonode scraper api"
|
|
151
|
+
assert kwargs["page"] == 2
|
|
152
|
+
assert kwargs["safe"] == "moderate"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_search_jobs_list_calls_service(invoke, fake_service):
|
|
156
|
+
invoke(["search", "jobs", "list", "--query", "geonode", "--status", "completed"])
|
|
157
|
+
name, kwargs = fake_service.calls[-1]
|
|
158
|
+
assert name == "list_search_jobs"
|
|
159
|
+
assert kwargs["query"] == "geonode"
|
|
160
|
+
assert kwargs["status"] == "completed"
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def test_search_jobs_get_calls_service(invoke, fake_service):
|
|
164
|
+
invoke(["search", "jobs", "get", "00000000-0000-0000-0000-000000000008"])
|
|
165
|
+
name, kwargs = fake_service.calls[-1]
|
|
166
|
+
assert name == "get_search_job"
|
|
167
|
+
assert kwargs == {"job_id": "00000000-0000-0000-0000-000000000008"}
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def test_usage_concurrency_calls_service(invoke, fake_service):
|
|
171
|
+
fake_service.responses["get_concurrency_usage"] = {
|
|
172
|
+
"ok": True,
|
|
173
|
+
"operation": "get_concurrency_usage",
|
|
174
|
+
"result": {"work_concurrency_in_use": 2, "work_concurrency_limit": 10},
|
|
175
|
+
}
|
|
176
|
+
result = invoke(["usage", "concurrency"])
|
|
177
|
+
assert result.exit_code == 0
|
|
178
|
+
name, kwargs = fake_service.calls[-1]
|
|
179
|
+
assert name == "get_concurrency_usage"
|
|
180
|
+
assert kwargs == {}
|
|
181
|
+
|
|
182
|
+
|
|
134
183
|
def test_config_path(invoke):
|
|
135
184
|
result = invoke(["config", "path"], with_key=False)
|
|
136
185
|
assert result.exit_code == 0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from unittest.mock import MagicMock, patch
|
|
5
|
+
|
|
6
|
+
import urllib3
|
|
7
|
+
|
|
8
|
+
HEALTH = {"version": "0.1.0", "service": "scraper-api", "timestamp": "2026-01-01T00:00:00Z", "status": "ok"}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_requests_name_the_cli_first(runner, tmp_path):
|
|
12
|
+
# The API labels a request by the first User-Agent token (scraper-api#674).
|
|
13
|
+
from geonode_scraper_cli import __version__
|
|
14
|
+
from geonode_scraper_cli.main import app
|
|
15
|
+
|
|
16
|
+
response = MagicMock(status=200, reason="OK", data=json.dumps(HEALTH).encode())
|
|
17
|
+
response.headers = {"content-type": "application/json"}
|
|
18
|
+
env = {
|
|
19
|
+
"GEONODE_SCRAPER_CONFIG": str(tmp_path / "config.toml"),
|
|
20
|
+
"GEONODE_SCRAPER_API_KEY": "test-key",
|
|
21
|
+
"GEONODE_SCRAPER_HOST": "http://api.mock.local",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
with patch.object(urllib3.PoolManager, "request", return_value=response) as request:
|
|
25
|
+
result = runner.invoke(app, ["--json", "health"], env=env)
|
|
26
|
+
|
|
27
|
+
assert result.exit_code == 0, result.output
|
|
28
|
+
assert request.call_args.kwargs["headers"]["User-Agent"].split()[0] == f"geonode-cli/{__version__}"
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/__init__.py
RENAMED
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/_common.py
RENAMED
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/batch.py
RENAMED
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/config.py
RENAMED
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/crawl.py
RENAMED
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/extract.py
RENAMED
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/jobs.py
RENAMED
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/stats.py
RENAMED
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/commands/system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/renderers/__init__.py
RENAMED
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli/renderers/tables.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{geonode_scraper_cli-0.1.0 → geonode_scraper_cli-0.2.1}/geonode_scraper_cli.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|