diffbot 3.0.0__tar.gz → 3.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.
Files changed (33) hide show
  1. {diffbot-3.0.0 → diffbot-3.1.0}/PKG-INFO +15 -2
  2. {diffbot-3.0.0 → diffbot-3.1.0}/README.md +13 -0
  3. {diffbot-3.0.0 → diffbot-3.1.0}/pyproject.toml +1 -1
  4. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/__init__.py +1 -1
  5. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/cli/__init__.py +4 -3
  6. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/client.py +32 -6
  7. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/web_search.py +12 -0
  8. diffbot-3.1.0/tests/test_web_search.py +51 -0
  9. diffbot-3.0.0/tests/test_web_search.py +0 -12
  10. {diffbot-3.0.0 → diffbot-3.1.0}/.gitignore +0 -0
  11. {diffbot-3.0.0 → diffbot-3.1.0}/LICENSE +0 -0
  12. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/_auth.py +0 -0
  13. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/ask.py +0 -0
  14. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/cli/__main__.py +0 -0
  15. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/cli/_common.py +0 -0
  16. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/cli/dql.py +0 -0
  17. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/cli/entities.py +0 -0
  18. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/cli/ontology.py +0 -0
  19. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/crawl.py +0 -0
  20. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/errors.py +0 -0
  21. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/extract.py +0 -0
  22. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/kg.py +0 -0
  23. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/nlp.py +0 -0
  24. {diffbot-3.0.0 → diffbot-3.1.0}/src/diffbot/ontology.py +0 -0
  25. {diffbot-3.0.0 → diffbot-3.1.0}/tests/conftest.py +0 -0
  26. {diffbot-3.0.0 → diffbot-3.1.0}/tests/test_ask.py +0 -0
  27. {diffbot-3.0.0 → diffbot-3.1.0}/tests/test_async.py +0 -0
  28. {diffbot-3.0.0 → diffbot-3.1.0}/tests/test_crawl.py +0 -0
  29. {diffbot-3.0.0 → diffbot-3.1.0}/tests/test_dql.py +0 -0
  30. {diffbot-3.0.0 → diffbot-3.1.0}/tests/test_dql_cli.py +0 -0
  31. {diffbot-3.0.0 → diffbot-3.1.0}/tests/test_extract.py +0 -0
  32. {diffbot-3.0.0 → diffbot-3.1.0}/tests/test_ontology.py +0 -0
  33. {diffbot-3.0.0 → diffbot-3.1.0}/tests/test_readme_examples.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: diffbot
3
- Version: 3.0.0
3
+ Version: 3.1.0
4
4
  Summary: Python client library for Diffbot APIs
5
5
  Project-URL: Homepage, https://github.com/diffbot/diffbot-python
6
6
  Project-URL: Documentation, https://github.com/diffbot/diffbot-python#readme
@@ -224,6 +224,13 @@ results = db.web_search("diffbot knowledge graph")
224
224
  for r in results["search_results"]:
225
225
  print(r["score"], r["title"], r["pageUrl"])
226
226
  print(r["content"])
227
+
228
+ # snippet_length controls how much of each page comes back in "content":
229
+ # "short" (~1-1.5 KB per result), "medium", "long" (default), or "full"
230
+ results = db.web_search("diffbot knowledge graph", num_results=5, snippet_length="short")
231
+
232
+ # "full" with a url: query returns the whole stored page
233
+ page = db.web_search("url:https://en.wikipedia.org/wiki/Knowledge_graph", snippet_length="full")
227
234
  ```
228
235
 
229
236
  ### Entities (NLP)
@@ -385,6 +392,8 @@ db crawl-list-jobs
385
392
  db crawl-delete-job crawl-1234567890
386
393
  db web-search "diffbot knowledge graph"
387
394
  db web-search "diffbot knowledge graph" -n 5 -f json
395
+ db web-search "diffbot knowledge graph" -n 5 -s short
396
+ db web-search "url:https://en.wikipedia.org/wiki/Knowledge_graph" -s full -f json
388
397
  db entities "Apple CEO Tim Cook announced record quarterly earnings."
389
398
  db entities "Apple CEO Tim Cook announced record quarterly earnings." -f dql
390
399
  ```
@@ -408,3 +417,7 @@ environment variable or `~/.diffbot/credentials`:
408
417
  ```bash
409
418
  DIFFBOT_API_TOKEN=your_token python -m pytest -m live
410
419
  ```
420
+
421
+ ## Acknowledgements
422
+
423
+ Thanks to [@attilaolah](https://github.com/attilaolah), who published the original `diffbot` package in 2012 and looked after the name for 14 years.
@@ -188,6 +188,13 @@ results = db.web_search("diffbot knowledge graph")
188
188
  for r in results["search_results"]:
189
189
  print(r["score"], r["title"], r["pageUrl"])
190
190
  print(r["content"])
191
+
192
+ # snippet_length controls how much of each page comes back in "content":
193
+ # "short" (~1-1.5 KB per result), "medium", "long" (default), or "full"
194
+ results = db.web_search("diffbot knowledge graph", num_results=5, snippet_length="short")
195
+
196
+ # "full" with a url: query returns the whole stored page
197
+ page = db.web_search("url:https://en.wikipedia.org/wiki/Knowledge_graph", snippet_length="full")
191
198
  ```
192
199
 
193
200
  ### Entities (NLP)
@@ -349,6 +356,8 @@ db crawl-list-jobs
349
356
  db crawl-delete-job crawl-1234567890
350
357
  db web-search "diffbot knowledge graph"
351
358
  db web-search "diffbot knowledge graph" -n 5 -f json
359
+ db web-search "diffbot knowledge graph" -n 5 -s short
360
+ db web-search "url:https://en.wikipedia.org/wiki/Knowledge_graph" -s full -f json
352
361
  db entities "Apple CEO Tim Cook announced record quarterly earnings."
353
362
  db entities "Apple CEO Tim Cook announced record quarterly earnings." -f dql
354
363
  ```
@@ -372,3 +381,7 @@ environment variable or `~/.diffbot/credentials`:
372
381
  ```bash
373
382
  DIFFBOT_API_TOKEN=your_token python -m pytest -m live
374
383
  ```
384
+
385
+ ## Acknowledgements
386
+
387
+ Thanks to [@attilaolah](https://github.com/attilaolah), who published the original `diffbot` package in 2012 and looked after the name for 14 years.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "diffbot"
7
- version = "3.0.0"
7
+ version = "3.1.0"
8
8
  description = "Python client library for Diffbot APIs"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -13,7 +13,7 @@ def _installed_version(dist: str):
13
13
 
14
14
 
15
15
  # The distribution was renamed from diffbot-python to diffbot. The final
16
- # diffbot-python release ships this same code (see legacy/diffbot-python), so
16
+ # diffbot-python release ships this same code (tag legacy-diffbot-python-v0.3.0), so
17
17
  # fall back to its version when that's what is installed.
18
18
  _legacy_version = _installed_version("diffbot-python")
19
19
  # "0.0.0" when not installed (e.g. running from a source tree).
@@ -359,16 +359,17 @@ def _strip_markdown(text: str) -> str:
359
359
  @click.option("-n", "--num-results", type=int, default=None, help="Number of results to return")
360
360
  @click.option("-m", "--max-tokens", type=int, default=None, help="Limit total response tokens (for agentic use cases)")
361
361
  @click.option("-f", "--format", "fmt", type=click.Choice(["list", "json", "text"]), default="list", help="Output format (text is plain/agent-friendly)")
362
- def web_search(query: str, num_results, max_tokens, fmt: str):
362
+ @click.option("-s", "--snippet-length", type=click.Choice(["short", "medium", "long", "full"], case_sensitive=False), default=None, help="How much of each page's matching content to return (default: long). short keeps a result to ~1-1.5 KB; full returns the whole stored page, for url: lookups")
363
+ def web_search(query: str, num_results, max_tokens, fmt: str, snippet_length):
363
364
  """Search the web using the Diffbot LLM web search API."""
364
365
  db = get_client()
365
366
  try:
366
367
  if is_interactive:
367
368
  with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=True) as progress:
368
369
  progress.add_task(description="Searching...", total=None)
369
- data = db.web_search(query, num_results=num_results, max_tokens=max_tokens)
370
+ data = db.web_search(query, num_results=num_results, max_tokens=max_tokens, snippet_length=snippet_length)
370
371
  else:
371
- data = db.web_search(query, num_results=num_results, max_tokens=max_tokens)
372
+ data = db.web_search(query, num_results=num_results, max_tokens=max_tokens, snippet_length=snippet_length)
372
373
 
373
374
  if fmt == "json":
374
375
  sys.stdout.write(json.dumps(data, indent=2))
@@ -197,9 +197,22 @@ class Diffbot:
197
197
  """Download the ontology and return it as a queryable Ontology (no caching)."""
198
198
  return _dql_fetch_ontology(self)
199
199
 
200
- def web_search(self, text: str, *, num_results: Optional[int] = None, max_tokens: Optional[int] = None) -> Dict[str, Any]:
201
- """Search the web via the Diffbot LLM web search API."""
202
- return _web_search(self, text, num_results=num_results, max_tokens=max_tokens)
200
+ def web_search(
201
+ self,
202
+ text: str,
203
+ *,
204
+ num_results: Optional[int] = None,
205
+ max_tokens: Optional[int] = None,
206
+ snippet_length: Optional[str] = None,
207
+ ) -> Dict[str, Any]:
208
+ """Search the web via the Diffbot LLM web search API.
209
+
210
+ snippet_length: "short", "medium", "long" or "full" — how much of each
211
+ page's matching content to return. Omit for the API default (long).
212
+ "full" returns the whole stored page (reranking is disabled for it);
213
+ use it with a url:<URL> query.
214
+ """
215
+ return _web_search(self, text, num_results=num_results, max_tokens=max_tokens, snippet_length=snippet_length)
203
216
 
204
217
  def entities(self, text: str, *, lang: str = "auto") -> Dict[str, Any]:
205
218
  """Identify and resolve entities and sentiment in text using the Diffbot NLP API.
@@ -349,9 +362,22 @@ class DiffbotAsync:
349
362
  """Download the ontology and return it as a queryable Ontology (no caching)."""
350
363
  return await _dql_fetch_ontology_async(self)
351
364
 
352
- async def web_search(self, text: str, *, num_results: Optional[int] = None, max_tokens: Optional[int] = None) -> Dict[str, Any]:
353
- """Search the web via the Diffbot LLM web search API."""
354
- return await _web_search_async(self, text, num_results=num_results, max_tokens=max_tokens)
365
+ async def web_search(
366
+ self,
367
+ text: str,
368
+ *,
369
+ num_results: Optional[int] = None,
370
+ max_tokens: Optional[int] = None,
371
+ snippet_length: Optional[str] = None,
372
+ ) -> Dict[str, Any]:
373
+ """Search the web via the Diffbot LLM web search API.
374
+
375
+ snippet_length: "short", "medium", "long" or "full" — how much of each
376
+ page's matching content to return. Omit for the API default (long).
377
+ "full" returns the whole stored page (reranking is disabled for it);
378
+ use it with a url:<URL> query.
379
+ """
380
+ return await _web_search_async(self, text, num_results=num_results, max_tokens=max_tokens, snippet_length=snippet_length)
355
381
 
356
382
  async def entities(self, text: str, *, lang: str = "auto") -> Dict[str, Any]:
357
383
  """Identify and resolve entities and sentiment in text using the Diffbot NLP API.
@@ -14,6 +14,7 @@ def web_search(
14
14
  *,
15
15
  num_results: Optional[int] = None,
16
16
  max_tokens: Optional[int] = None,
17
+ snippet_length: Optional[str] = None,
17
18
  ) -> Dict[str, Any]:
18
19
  headers = {"Authorization": f"Bearer {client.token}"}
19
20
  params: Dict[str, Any] = {"text": text}
@@ -21,6 +22,11 @@ def web_search(
21
22
  params["size"] = num_results
22
23
  if max_tokens is not None:
23
24
  params["maxTokens"] = max_tokens
25
+ if snippet_length is not None:
26
+ params["snippetLength"] = snippet_length.upper()
27
+ if params["snippetLength"] == "FULL":
28
+ # the reranker always chunks; only the unranked path returns the stored page
29
+ params["rerank"] = "none"
24
30
  response = client._http.get(client.web_search_url, headers=headers, params=params)
25
31
  client._raise_for_status(response)
26
32
  return response.json()
@@ -32,6 +38,7 @@ async def web_search_async(
32
38
  *,
33
39
  num_results: Optional[int] = None,
34
40
  max_tokens: Optional[int] = None,
41
+ snippet_length: Optional[str] = None,
35
42
  ) -> Dict[str, Any]:
36
43
  headers = {"Authorization": f"Bearer {client.token}"}
37
44
  params: Dict[str, Any] = {"text": text}
@@ -39,6 +46,11 @@ async def web_search_async(
39
46
  params["size"] = num_results
40
47
  if max_tokens is not None:
41
48
  params["maxTokens"] = max_tokens
49
+ if snippet_length is not None:
50
+ params["snippetLength"] = snippet_length.upper()
51
+ if params["snippetLength"] == "FULL":
52
+ # the reranker always chunks; only the unranked path returns the stored page
53
+ params["rerank"] = "none"
42
54
  response = await client._http.get(client.web_search_url, headers=headers, params=params)
43
55
  client._raise_for_status(response)
44
56
  return response.json()
@@ -0,0 +1,51 @@
1
+ import pytest
2
+
3
+
4
+ """
5
+ Live
6
+ """
7
+
8
+ @pytest.mark.live
9
+ def test_live_web_search(db):
10
+ result = db.web_search("diffbot knowledge graph", num_results=3)
11
+ assert "search_results" in result
12
+ assert len(result["search_results"]) > 0
13
+
14
+
15
+ @pytest.mark.live
16
+ def test_live_web_search_snippet_length(db):
17
+ long = db.web_search("diffbot knowledge graph", num_results=3)
18
+ short = db.web_search("diffbot knowledge graph", num_results=3, snippet_length="short")
19
+ assert len(short["search_results"]) > 0
20
+ total_long = sum(len(r.get("content", "")) for r in long["search_results"])
21
+ total_short = sum(len(r.get("content", "")) for r in short["search_results"])
22
+ assert total_short <= total_long
23
+
24
+
25
+ """
26
+ Mocked
27
+ """
28
+
29
+ def test_web_search_sends_snippet_length_param():
30
+ import httpx
31
+ from diffbot import Diffbot
32
+
33
+ seen = {}
34
+
35
+ def handler(request: httpx.Request) -> httpx.Response:
36
+ seen.update(request.url.params)
37
+ return httpx.Response(200, json={"search_results": []})
38
+
39
+ db = Diffbot(token="t", transport=httpx.MockTransport(handler))
40
+ db.web_search("q", num_results=3, snippet_length="short")
41
+ assert seen["size"] == "3"
42
+ assert seen["snippetLength"] == "SHORT"
43
+
44
+ seen.clear()
45
+ db.web_search("q")
46
+ assert "snippetLength" not in seen
47
+
48
+ seen.clear()
49
+ db.web_search("url:https://example.com", snippet_length="full")
50
+ assert seen["snippetLength"] == "FULL"
51
+ assert seen["rerank"] == "none"
@@ -1,12 +0,0 @@
1
- import pytest
2
-
3
-
4
- """
5
- Live
6
- """
7
-
8
- @pytest.mark.live
9
- def test_live_web_search(db):
10
- result = db.web_search("diffbot knowledge graph", num_results=3)
11
- assert "search_results" in result
12
- assert len(result["search_results"]) > 0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes