pyannotators-entityfishing 1.6.151__tar.gz → 1.6.156__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 (50) hide show
  1. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/PKG-INFO +1 -1
  2. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/src/pyannotators_entityfishing/__init__.py +1 -1
  3. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/src/pyannotators_entityfishing/candidates.py +1 -0
  4. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/src/pyannotators_entityfishing/ef_client.py +18 -4
  5. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/.claude/skills/ef-mapping/SKILL.md +0 -0
  6. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/.gitignore +0 -0
  7. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/.gitmodules +0 -0
  8. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/.python-version +0 -0
  9. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/LICENSE +0 -0
  10. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/README.md +0 -0
  11. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/Taskfile.yml +0 -0
  12. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/pyproject.toml +0 -0
  13. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/src/pyannotators_entityfishing/entityfishing.py +0 -0
  14. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/.claude-plugin/marketplace.json +0 -0
  15. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/.claude-plugin/plugin.json +0 -0
  16. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/HOWTO.md +0 -0
  17. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/README.md +0 -0
  18. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/resources/Stages.yml +0 -0
  19. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/resources/Taskfile.yml +0 -0
  20. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/resources/help/help_examples.py +0 -0
  21. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/resources/help/plugin-help.py +0 -0
  22. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/resources/help/template.en.md +0 -0
  23. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/resources/help/template.fr.md +0 -0
  24. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/skills/new-plugin/SKILL.md +0 -0
  25. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/skills/new-plugin/references/annotator.md +0 -0
  26. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/skills/new-plugin/references/converter.md +0 -0
  27. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/skills/new-plugin/references/formatter.md +0 -0
  28. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/skills/new-plugin/references/importer.md +0 -0
  29. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/skills/new-plugin/references/processor.md +0 -0
  30. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/skills/new-plugin/references/segmenter.md +0 -0
  31. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/skills/new-plugin/references/types.md +0 -0
  32. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/skills/plugin-help/SKILL.md +0 -0
  33. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/tools/check-marketplace.py +0 -0
  34. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/submodules/python-archetype/vars/pythonPipeline.groovy +0 -0
  35. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/build_poi.py +0 -0
  36. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/build_poi_lexicons.py +0 -0
  37. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/build_rerank_data.py +0 -0
  38. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/check_rerank_endpoint.py +0 -0
  39. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/el_jev.py +0 -0
  40. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/eval_linking.py +0 -0
  41. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/eval_mappings.py +0 -0
  42. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/eval_rerank.py +0 -0
  43. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/finetune_rerank.py +0 -0
  44. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/merge_rerank.py +0 -0
  45. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/poi_common_words.json +0 -0
  46. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/recalibrate_linking.py +0 -0
  47. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/review_linking.html +0 -0
  48. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/review_linking.py +0 -0
  49. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/sherpa_plan_project.py +0 -0
  50. {pyannotators_entityfishing-1.6.151 → pyannotators_entityfishing-1.6.156}/tools/wdfilter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyannotators-entityfishing
3
- Version: 1.6.151
3
+ Version: 1.6.156
4
4
  Summary: Annotator based on entity-fishing
5
5
  Project-URL: Homepage, https://github.com/oterrier/pyannotators_entityfishing/
6
6
  Author-email: Olivier Terrier <olivier.terrier@kairntech.com>
@@ -1,3 +1,3 @@
1
1
  """Annotator based on entity-fishing"""
2
2
 
3
- __version__ = "1.6.151"
3
+ __version__ = "1.6.156"
@@ -320,6 +320,7 @@ def report_failures(document: Document, lost: list[tuple[str, str, str]]) -> Non
320
320
  they concern may have lost candidates, and the document is worth processing again. A document
321
321
  processed again without failure drops the report of the earlier run."""
322
322
  metadata = {k: v for k, v in (document.metadata or {}).items() if k != ERROR_METADATA}
323
+ lost = list(dict.fromkeys(lost)) # a page fetched again by a later step fails again
323
324
  if lost:
324
325
  calls = ", ".join(f"{kind} {key}" for kind, _, key in lost)
325
326
  metadata[ERROR_METADATA] = f"{len(lost)} entity-fishing calls failed, candidates may be missing: {calls}"[:MAX_ERROR_CHARS]
@@ -1,6 +1,8 @@
1
1
  import hashlib
2
+ import json
2
3
  import logging
3
4
  import os
5
+ import re
4
6
  import time
5
7
  from collections.abc import Iterable
6
8
  from concurrent.futures import as_completed
@@ -25,6 +27,18 @@ VERIFY_SSL = os.getenv("APP_EF_VERIFY_SSL", "true").lower() not in ("0", "false"
25
27
  RETRY = Retry(total=4, backoff_factor=1, status_forcelist=(429, 500, 502, 503, 504), allowed_methods=None, raise_on_status=False)
26
28
  # (connect, read) seconds for a term lookup or a concept: without one, a stuck entity-fishing holds the document forever
27
29
  KB_TIMEOUT = (10, 60)
30
+ # EF does not escape the quotes of a property name ("Apple Maps "auid" identifier", P10046), which breaks the JSON of
31
+ # every concept holding that property: the White House, Georgia... Workaround until kermitt2/entity-fishing#177 is fixed
32
+ PROPERTY_NAME = re.compile(r'("propertyName" : ")(.*?)(", "valueType")')
33
+
34
+
35
+ def concept_json(resp: requests.Response) -> dict:
36
+ """The concept of a kb response, its unescaped property names escaped if it does not parse as is."""
37
+ try:
38
+ return resp.json()
39
+ except ValueError:
40
+ # ponytail: repairs propertyName only; drop concept_json once kermitt2/entity-fishing#177 is fixed
41
+ return json.loads(PROPERTY_NAME.sub(lambda m: m[1] + re.sub(r'(?<!\\)"', r"\"", m[2]) + m[3], resp.text))
28
42
 
29
43
 
30
44
  class EntityFishingClient:
@@ -228,7 +242,7 @@ class EntityFishingClient:
228
242
  try:
229
243
  resp = self.ksession.get(self.base_url + self.kb_url + qid)
230
244
  if resp.ok:
231
- return resp.json()
245
+ return concept_json(resp)
232
246
  else:
233
247
  resp.raise_for_status()
234
248
  except Exception:
@@ -244,7 +258,7 @@ class EntityFishingClient:
244
258
  try:
245
259
  resp = future.result()
246
260
  if resp.ok:
247
- concept = resp.json()
261
+ concept = concept_json(resp)
248
262
  if "wikidataId" in concept:
249
263
  concepts[concept["wikidataId"]] = concept
250
264
  else:
@@ -288,11 +302,11 @@ class EntityFishingClient:
288
302
  try:
289
303
  resp = future.result()
290
304
  if resp.ok:
291
- concepts[futures[future]] = resp.json()
305
+ concepts[futures[future]] = concept_json(resp)
292
306
  elif resp.status_code != 404: # 404: a page the KB does not hold, not a failure
293
307
  resp.raise_for_status()
294
308
  except Exception:
295
- logging.warning("An exception was thrown!", exc_info=True)
309
+ logging.warning("EF kb concept of page %s (%s) failed", futures[future], lang, exc_info=True)
296
310
  self.failures.append(("concept", lang, str(futures[future])))
297
311
  logger.debug("EF get kb %d concepts by page duration %0.3fs", len(pageids), time.time() - start)
298
312
  return concepts