Skip to content

Commit 0335a2e

Browse files
authored
Merge pull request #2362 from unclecode/fix/cli-json-output-2334
Fail early when `-o json` has no extraction strategy
2 parents a6e3bb3 + 1e54fa7 commit 0335a2e

2 files changed

Lines changed: 25 additions & 3 deletions

File tree

‎crawl4ai/cli.py‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def show_examples():
175175
crwl https://example.com -o markdown
176176
177177
# Verbose JSON output with cache bypass
178-
crwl https://example.com -o json -v --bypass-cache
178+
crwl https://example.com -o all -v --bypass-cache
179179
180180
2️⃣ Using Config Files:
181181
# Using browser and crawler configs
@@ -516,7 +516,7 @@ async def crawl_with_profile_cli(profile_path, url):
516516
# Ask for output format
517517
output_format = Prompt.ask(
518518
"[cyan]Output format[/cyan]",
519-
choices=["all", "json", "markdown", "md", "title"],
519+
choices=["all", "markdown", "md", "title"],
520520
default="markdown"
521521
)
522522

@@ -1204,6 +1204,12 @@ def crawl_cmd(url: str, browser_config: str, crawler_config: str, filter_config:
12041204
else:
12051205
ensure_ascii = config.get("JSON_ENSURE_ASCII", USER_SETTINGS["JSON_ENSURE_ASCII"]["default"])
12061206

1207+
if output == "json" and not question and crawler_cfg.extraction_strategy is None:
1208+
raise click.UsageError(
1209+
"-o json needs an extraction strategy (-j or -e). "
1210+
"Use -o all for the full crawl result."
1211+
)
1212+
12071213
# Run crawler
12081214
result : CrawlResult = anyio.run(
12091215
run_crawler,
@@ -1242,7 +1248,6 @@ def crawl_cmd(url: str, browser_config: str, crawler_config: str, filter_config:
12421248
else:
12431249
click.echo(json.dumps(main_result.model_dump(), indent=2, ensure_ascii=ensure_ascii))
12441250
elif output == "json":
1245-
print(main_result.extracted_content)
12461251
extracted_items = json.loads(main_result.extracted_content)
12471252
click.echo(json.dumps(extracted_items, indent=2, ensure_ascii=ensure_ascii))
12481253

@@ -1292,6 +1297,8 @@ def crawl_cmd(url: str, browser_config: str, crawler_config: str, filter_config:
12921297
else:
12931298
f.write(main_result.markdown.fit_markdown)
12941299

1300+
except click.ClickException:
1301+
raise
12951302
except Exception as e:
12961303
raise click.ClickException(str(e))
12971304

‎tests/cli/test_cli.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,5 +253,20 @@ def test_single_crawl_markdown_output_unchanged(self, runner):
253253
assert 'Content here' in result.output
254254

255255

256+
def test_json_output_without_extractor_fails_early(runner):
257+
with patch("crawl4ai.cli.anyio.run") as run:
258+
result = runner.invoke(cli, ["crawl", "https://example.com", "-o", "json"])
259+
assert result.exit_code == 2
260+
assert "-o json needs an extraction strategy" in result.output
261+
run.assert_not_called() # browser never started
262+
263+
264+
def test_json_output_with_question_is_allowed(runner):
265+
with patch("crawl4ai.cli.anyio.run") as run, \
266+
patch("crawl4ai.cli.setup_llm_config", return_value=("openai/gpt-4o", "x")):
267+
runner.invoke(cli, ["crawl", "https://example.com", "-o", "json", "-q", "hi"])
268+
run.assert_called() # no early error
269+
270+
256271
if __name__ == '__main__':
257272
pytest.main(['-v', '-s', '--tb=native', __file__])

0 commit comments

Comments
 (0)