snapquery 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.
Files changed (120) hide show
  1. {snapquery-0.1.0 → snapquery-0.2.1}/.github/workflows/build.yml +1 -1
  2. {snapquery-0.1.0 → snapquery-0.2.1}/PKG-INFO +17 -16
  3. {snapquery-0.1.0 → snapquery-0.2.1}/README.md +7 -7
  4. {snapquery-0.1.0 → snapquery-0.2.1}/pyproject.toml +12 -8
  5. snapquery-0.2.1/snapquery/__init__.py +1 -0
  6. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/authorization.py +5 -3
  7. snapquery-0.2.1/snapquery/github_access.py +119 -0
  8. snapquery-0.2.1/snapquery/prefix_merger.py +99 -0
  9. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/qimport.py +3 -4
  10. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/qimport_view.py +6 -5
  11. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/qlever.py +3 -4
  12. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/query_annotate.py +2 -4
  13. snapquery-0.2.1/snapquery/samples/endpoints.yaml +128 -0
  14. snapquery-0.2.1/snapquery/samples/endpoints_optional.yaml +74 -0
  15. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/scholia.py +6 -8
  16. snapquery-0.2.1/snapquery/sib_sparql_examples.py +167 -0
  17. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/snapquery_cmd.py +60 -17
  18. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/snapquery_core.py +20 -126
  19. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/snapquery_view.py +5 -5
  20. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/snapquery_webserver.py +57 -19
  21. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/sparql_analyzer.py +14 -9
  22. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/version.py +2 -2
  23. snapquery-0.2.1/snapquery/wd_page_query_extractor.py +280 -0
  24. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/wd_short_url.py +89 -47
  25. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_authorization.py +3 -6
  26. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_ceurws.py +3 -3
  27. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_cmdline.py +1 -1
  28. snapquery-0.2.1/tests/test_endpoints.py +61 -0
  29. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_error_filter.py +1 -1
  30. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_graph.py +2 -2
  31. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_import.py +3 -5
  32. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_namedqueries.py +7 -8
  33. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_oauth.py +1 -1
  34. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_orcid.py +10 -1
  35. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_pids.py +1 -1
  36. snapquery-0.1.0/tests/test_snapquery_core.py → snapquery-0.2.1/tests/test_prefix_merger.py +25 -14
  37. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_qlever.py +1 -1
  38. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_query_annotate.py +4 -8
  39. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_query_execution.py +1 -1
  40. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_query_name.py +1 -1
  41. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_restful_api.py +5 -3
  42. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_scholia.py +4 -4
  43. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_scholia_q.py +7 -7
  44. snapquery-0.2.1/tests/test_sib_examples.py +74 -0
  45. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_sparql_analyzer.py +18 -10
  46. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_sparql_components.py +12 -6
  47. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_wd_query_parsing.py +43 -17
  48. {snapquery-0.1.0 → snapquery-0.2.1}/tests/test_wd_short_url.py +1 -1
  49. snapquery-0.1.0/snapquery/__init__.py +0 -1
  50. snapquery-0.1.0/snapquery/endpoint.py +0 -90
  51. snapquery-0.1.0/snapquery/samples/endpoints.yaml +0 -606
  52. snapquery-0.1.0/snapquery/wd_page_query_extractor.py +0 -234
  53. snapquery-0.1.0/tests/test_endpoints.py +0 -29
  54. {snapquery-0.1.0 → snapquery-0.2.1}/.github/workflows/upload-to-pypi.yml +0 -0
  55. {snapquery-0.1.0 → snapquery-0.2.1}/.gitignore +0 -0
  56. {snapquery-0.1.0 → snapquery-0.2.1}/.project +0 -0
  57. {snapquery-0.1.0 → snapquery-0.2.1}/.pydevproject +0 -0
  58. {snapquery-0.1.0 → snapquery-0.2.1}/LICENSE +0 -0
  59. {snapquery-0.1.0 → snapquery-0.2.1}/docs/index.md +0 -0
  60. {snapquery-0.1.0 → snapquery-0.2.1}/mkdocs.yml +0 -0
  61. {snapquery-0.1.0 → snapquery-0.2.1}/scripts/blackisort +0 -0
  62. {snapquery-0.1.0 → snapquery-0.2.1}/scripts/doc +0 -0
  63. {snapquery-0.1.0 → snapquery-0.2.1}/scripts/fixdomain +0 -0
  64. {snapquery-0.1.0 → snapquery-0.2.1}/scripts/install +0 -0
  65. {snapquery-0.1.0 → snapquery-0.2.1}/scripts/qlv +0 -0
  66. {snapquery-0.1.0 → snapquery-0.2.1}/scripts/release +0 -0
  67. {snapquery-0.1.0 → snapquery-0.2.1}/scripts/restore_db +0 -0
  68. {snapquery-0.1.0 → snapquery-0.2.1}/scripts/test +0 -0
  69. {snapquery-0.1.0 → snapquery-0.2.1}/scripts/test_queries +0 -0
  70. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/basequeryview.py +0 -0
  71. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/ceurws.py +0 -0
  72. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/dblp.py +0 -0
  73. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/error_filter.py +0 -0
  74. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/execution.py +0 -0
  75. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/graph.py +0 -0
  76. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/models/__init__.py +0 -0
  77. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/models/person.py +0 -0
  78. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/models/sparql_components.py +0 -0
  79. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/mwlogin.py +0 -0
  80. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/namespace_stats_view.py +0 -0
  81. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/orcid.py +0 -0
  82. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/params_view.py +0 -0
  83. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/person_selector.py +0 -0
  84. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/pid.py +0 -0
  85. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/pid_lookup.py +0 -0
  86. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/query_selector.py +0 -0
  87. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/resources/sparql_language.json +0 -0
  88. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/WikiProject_LSEThesisProject.wiki +0 -0
  89. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/ceur-ws.json +0 -0
  90. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/dblp.json +0 -0
  91. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/federated-query-examples.json +0 -0
  92. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/graphs.yaml +0 -0
  93. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/meta_query.yaml +0 -0
  94. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/orkg.json +0 -0
  95. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/qlever.json +0 -0
  96. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/qlever_performance.json +0 -0
  97. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/query_stats.yaml +0 -0
  98. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/scholia.json +0 -0
  99. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/snapquery.json +0 -0
  100. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/wikidata-WikidataThesisToolkit.json +0 -0
  101. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/wikidata-WikidataThesisToolkitAlt.json +0 -0
  102. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/wikidata-examples.json +0 -0
  103. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/samples/wikidata-short-urls.json +0 -0
  104. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery/stats_view.py +0 -0
  105. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery.puml +0 -0
  106. {snapquery-0.1.0 → snapquery-0.2.1}/snapquery.yaml +0 -0
  107. {snapquery-0.1.0 → snapquery-0.2.1}/tests/__init__.py +0 -0
  108. {snapquery-0.1.0 → snapquery-0.2.1}/tests/query_extractors/__init__.py +0 -0
  109. {snapquery-0.1.0 → snapquery-0.2.1}/tests/query_extractors/sparql_standard_queries.py +0 -0
  110. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/qlever/ask_unsupported.txt +0 -0
  111. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/qlever/invalid_literal.txt +0 -0
  112. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/qlever/invalid_regex_func.txt +0 -0
  113. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/qlever/memory_limit.txt +0 -0
  114. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/qlever/timeout.txt +0 -0
  115. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/triplydb/parser_error.txt +0 -0
  116. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/wdqs/duplicate_prefix.txt +0 -0
  117. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/wdqs/invalid_iri_declaration.txt +0 -0
  118. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/wdqs/invalid_sparql_syntax.txt +0 -0
  119. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/wdqs/timeout.txt +0 -0
  120. {snapquery-0.1.0 → snapquery-0.2.1}/tests/resources/error_messages/wdqs/undefined_prefix.txt +0 -0
@@ -19,7 +19,7 @@ jobs:
19
19
  strategy:
20
20
  matrix:
21
21
  #os: [ubuntu-latest, macos-latest, windows-latest]
22
- #python-version: [ '3.9', '3.10', '3.11', '3.12' ]
22
+ #python-version: [ '3.10', '3.11', '3.12', '3.13' ]
23
23
  # simplified build matrix to avoid rate limits
24
24
  os: [ubuntu-latest]
25
25
  python-version: ['3.11']
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snapquery
3
- Version: 0.1.0
4
- Summary: snapquery: Introduce Named Queries and Named Query Middleware to wikidata
3
+ Version: 0.2.1
4
+ Summary: Just Query wikidata and other SPARQL endpoints by query name - a frontend to Introduce Named Queries and Named Query Middleware to wikidata and other SPARQL endpoints
5
5
  Project-URL: Home, https://github.com/WolfgangFahl/snapquery
6
6
  Project-URL: Documentation, https://wiki.bitplan.com/index.php/snapquery
7
7
  Project-URL: Source, https://github.com/WolfgangFahl/snapquery
@@ -26,13 +26,14 @@ Classifier: Topic :: Software Development :: User Interfaces
26
26
  Requires-Python: >=3.10
27
27
  Requires-Dist: mwoauth>=0.4.0
28
28
  Requires-Dist: nameparser>=1.1.3
29
- Requires-Dist: ngwidgets>=0.28.0
30
- Requires-Dist: nicegui[plotly]
31
- Requires-Dist: py-3rdparty-mediawiki>=0.15.4
32
- Requires-Dist: py-ez-wikidata>=0.3.1
33
- Requires-Dist: pybasemkit>=0.0.3
34
- Requires-Dist: pylodstorage>=0.16.4
35
- Requires-Dist: pyopensourceprojects>=0.1.2
29
+ Requires-Dist: ngwidgets>=0.30.0
30
+ Requires-Dist: nicegui[plotly]==2.24.2
31
+ Requires-Dist: pandas>=2.3.3
32
+ Requires-Dist: py-3rdparty-mediawiki>=0.18.1
33
+ Requires-Dist: py-ez-wikidata>=0.3.2
34
+ Requires-Dist: pybasemkit>=0.1.3
35
+ Requires-Dist: pylodstorage>=0.18.5
36
+ Requires-Dist: pyopensourceprojects>=0.3.0
36
37
  Requires-Dist: python-slugify>=8.0.4
37
38
  Requires-Dist: ratelimit>=2.2.1
38
39
  Requires-Dist: requests
@@ -56,14 +57,14 @@ comparison across various backends and over time.
56
57
  This tool is designed to assist users in curating and collaborating on queries, ensuring their continued functionality
57
58
  over time. Developers and data consumers can access data conveniently through APIs, streamlining their workflow.
58
59
 
60
+ | | |
61
+ | :--- | :--- |
62
+ | **PyPi** | [![PyPI Status](https://img.shields.io/pypi/v/snapquery.svg)](https://pypi.python.org/pypi/snapquery/) [![License](https://img.shields.io/github/license/WolfgangFahl/snapquery.svg)](https://www.apache.org/licenses/LICENSE-2.0) [![pypi](https://img.shields.io/pypi/pyversions/snapquery)](https://pypi.org/project/snapquery/) [![format](https://img.shields.io/pypi/format/snapquery)](https://pypi.org/project/snapquery/) [![downloads](https://img.shields.io/pypi/dd/snapquery)](https://pypi.org/project/snapquery/) |
63
+ | **GitHub** | [![Github Actions Build](https://github.com/WolfgangFahl/snapquery/actions/workflows/build.yml/badge.svg)](https://github.com/WolfgangFahl/snapquery/actions/workflows/build.yml) [![Release](https://img.shields.io/github/v/release/WolfgangFahl/snapquery)](https://github.com/WolfgangFahl/snapquery/releases) [![Contributors](https://img.shields.io/github/contributors/WolfgangFahl/snapquery)](https://github.com/WolfgangFahl/snapquery/graphs/contributors) [![Last Commit](https://img.shields.io/github/last-commit/WolfgangFahl/snapquery)](https://github.com/WolfgangFahl/snapquery/commits/) [![GitHub issues](https://img.shields.io/github/issues/WolfgangFahl/snapquery.svg)](https://github.com/WolfgangFahl/snapquery/issues) [![GitHub closed issues](https://img.shields.io/github/issues-closed/WolfgangFahl/snapquery.svg)](https://github.com/WolfgangFahl/snapquery/issues/?q=is%3Aissue+is%3Aclosed) |
64
+ | **Code** | [![style-black](https://img.shields.io/badge/%20style-black-000000.svg)](https://github.com/psf/black) [![imports-isort](https://img.shields.io/badge/%20imports-isort-%231674b1)](https://pycqa.github.io/isort/) |
65
+ | **Docs** | [![API Docs](https://img.shields.io/badge/API-Documentation-blue)](https://WolfgangFahl.github.io/snapquery/) [![formatter-docformatter](https://img.shields.io/badge/%20formatter-docformatter-fedcba.svg)](https://github.com/PyCQA/docformatter) [![style-google](https://img.shields.io/badge/%20style-google-3666d6.svg)](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings) |
66
+
59
67
  [![Join the discussion at https://github.com/WolfgangFahl/snapquery/discussions](https://img.shields.io/github/discussions/WolfgangFahl/snapquery)](https://github.com/WolfgangFahl/snapquery/discussions)
60
- [![pypi](https://img.shields.io/pypi/pyversions/snapquery)](https://pypi.org/project/snapquery/)
61
- [![Github Actions Build](https://github.com/WolfgangFahl/snapquery/actions/workflows/build.yml/badge.svg)](https://github.com/WolfgangFahl/snapquery/actions/workflows/build.yml)
62
- [![PyPI Status](https://img.shields.io/pypi/v/snapquery.svg)](https://pypi.python.org/pypi/snapquery/)
63
- [![GitHub issues](https://img.shields.io/github/issues/WolfgangFahl/snapquery.svg)](https://github.com/WolfgangFahl/snapquery/issues)
64
- [![GitHub closed issues](https://img.shields.io/github/issues-closed/WolfgangFahl/snapquery.svg)](https://github.com/WolfgangFahl/snapquery/issues/?q=is%3Aissue+is%3Aclosed)
65
- [![API Docs](https://img.shields.io/badge/API-Documentation-blue)](https://WolfgangFahl.github.io/snapquery/)
66
- [![License](https://img.shields.io/github/license/WolfgangFahl/snapquery.svg)](https://www.apache.org/licenses/LICENSE-2.0)
67
68
  ## Demos
68
69
 
69
70
  * [wikimedia toolhub](https://toolhub.wikimedia.org/tools/snapquery)
@@ -12,14 +12,14 @@ comparison across various backends and over time.
12
12
  This tool is designed to assist users in curating and collaborating on queries, ensuring their continued functionality
13
13
  over time. Developers and data consumers can access data conveniently through APIs, streamlining their workflow.
14
14
 
15
+ | | |
16
+ | :--- | :--- |
17
+ | **PyPi** | [![PyPI Status](https://img.shields.io/pypi/v/snapquery.svg)](https://pypi.python.org/pypi/snapquery/) [![License](https://img.shields.io/github/license/WolfgangFahl/snapquery.svg)](https://www.apache.org/licenses/LICENSE-2.0) [![pypi](https://img.shields.io/pypi/pyversions/snapquery)](https://pypi.org/project/snapquery/) [![format](https://img.shields.io/pypi/format/snapquery)](https://pypi.org/project/snapquery/) [![downloads](https://img.shields.io/pypi/dd/snapquery)](https://pypi.org/project/snapquery/) |
18
+ | **GitHub** | [![Github Actions Build](https://github.com/WolfgangFahl/snapquery/actions/workflows/build.yml/badge.svg)](https://github.com/WolfgangFahl/snapquery/actions/workflows/build.yml) [![Release](https://img.shields.io/github/v/release/WolfgangFahl/snapquery)](https://github.com/WolfgangFahl/snapquery/releases) [![Contributors](https://img.shields.io/github/contributors/WolfgangFahl/snapquery)](https://github.com/WolfgangFahl/snapquery/graphs/contributors) [![Last Commit](https://img.shields.io/github/last-commit/WolfgangFahl/snapquery)](https://github.com/WolfgangFahl/snapquery/commits/) [![GitHub issues](https://img.shields.io/github/issues/WolfgangFahl/snapquery.svg)](https://github.com/WolfgangFahl/snapquery/issues) [![GitHub closed issues](https://img.shields.io/github/issues-closed/WolfgangFahl/snapquery.svg)](https://github.com/WolfgangFahl/snapquery/issues/?q=is%3Aissue+is%3Aclosed) |
19
+ | **Code** | [![style-black](https://img.shields.io/badge/%20style-black-000000.svg)](https://github.com/psf/black) [![imports-isort](https://img.shields.io/badge/%20imports-isort-%231674b1)](https://pycqa.github.io/isort/) |
20
+ | **Docs** | [![API Docs](https://img.shields.io/badge/API-Documentation-blue)](https://WolfgangFahl.github.io/snapquery/) [![formatter-docformatter](https://img.shields.io/badge/%20formatter-docformatter-fedcba.svg)](https://github.com/PyCQA/docformatter) [![style-google](https://img.shields.io/badge/%20style-google-3666d6.svg)](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings) |
21
+
15
22
  [![Join the discussion at https://github.com/WolfgangFahl/snapquery/discussions](https://img.shields.io/github/discussions/WolfgangFahl/snapquery)](https://github.com/WolfgangFahl/snapquery/discussions)
16
- [![pypi](https://img.shields.io/pypi/pyversions/snapquery)](https://pypi.org/project/snapquery/)
17
- [![Github Actions Build](https://github.com/WolfgangFahl/snapquery/actions/workflows/build.yml/badge.svg)](https://github.com/WolfgangFahl/snapquery/actions/workflows/build.yml)
18
- [![PyPI Status](https://img.shields.io/pypi/v/snapquery.svg)](https://pypi.python.org/pypi/snapquery/)
19
- [![GitHub issues](https://img.shields.io/github/issues/WolfgangFahl/snapquery.svg)](https://github.com/WolfgangFahl/snapquery/issues)
20
- [![GitHub closed issues](https://img.shields.io/github/issues-closed/WolfgangFahl/snapquery.svg)](https://github.com/WolfgangFahl/snapquery/issues/?q=is%3Aissue+is%3Aclosed)
21
- [![API Docs](https://img.shields.io/badge/API-Documentation-blue)](https://WolfgangFahl.github.io/snapquery/)
22
- [![License](https://img.shields.io/github/license/WolfgangFahl/snapquery.svg)](https://www.apache.org/licenses/LICENSE-2.0)
23
23
  ## Demos
24
24
 
25
25
  * [wikimedia toolhub](https://toolhub.wikimedia.org/tools/snapquery)
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
 
6
6
  [project]
7
7
  name = "snapquery"
8
- description = "snapquery: Introduce Named Queries and Named Query Middleware to wikidata"
8
+ description = "Just Query wikidata and other SPARQL endpoints by query name - a frontend to Introduce Named Queries and Named Query Middleware to wikidata and other SPARQL endpoints "
9
9
  keywords = [ "nicegui", "wikidata","SPARQL","query","middleware","qlever","blazegraph"]
10
10
  home-page = "https://github.com/WolfgangFahl/snapquery"
11
11
  authors = [
@@ -22,13 +22,13 @@ dependencies = [
22
22
  # https://pypi.org/project/pybasemkit/
23
23
  # https://github.com/WolfgangFahl/pybasemkit
24
24
  # Python base module kit: YAML/JSON I/O, structured logging, CLI tooling, shell execution, and remote pydevd debug support.
25
- "pybasemkit>=0.0.3",
25
+ "pybasemkit>=0.1.3",
26
26
  # https://github.com/WolfgangFahl/nicegui_widgets
27
- "ngwidgets>=0.28.0",
27
+ "ngwidgets>=0.30.0",
28
28
  # https://pypi.org/project/pyLodStorage/
29
- "pyLodStorage>=0.16.4",
29
+ "pyLodStorage>=0.18.5",
30
30
  # https://pypi.org/project/py-3rdparty-mediawiki/
31
- "py-3rdparty-mediawiki>=0.15.4",
31
+ "py-3rdparty-mediawiki>=0.18.1",
32
32
  "wikitextparser",
33
33
  "requests",
34
34
  # https://pypi.org/project/python-slugify/
@@ -40,14 +40,18 @@ dependencies = [
40
40
  #"mwoauth@git+https://github.com/mediawiki-utilities/python-mwoauth"
41
41
  #https://pypi.org/project/tqdm/
42
42
  "tqdm>=4.66.4",
43
- "nicegui[plotly]",
43
+ #https://pypi.org/project/pandas/
44
+ "pandas>=2.3.3",
45
+ # https://pypi.org/project/nicegui/
46
+ # force pin of nicegui
47
+ "nicegui[plotly]==2.24.2",
44
48
  # py_ez_wikidata
45
49
  # https://github.com/WolfgangFahl/py_ez_wikidata
46
- "py_ez_wikidata>=0.3.1",
50
+ "py_ez_wikidata>=0.3.2",
47
51
  # https://pypi.org/project/nameparser/
48
52
  "nameparser>=1.1.3",
49
53
  # https://github.com/WolfgangFahl/pyOpenSourceProjects
50
- "pyOpenSourceProjects>=0.1.2"
54
+ "pyOpenSourceProjects>=0.3.0"
51
55
  ]
52
56
 
53
57
  requires-python = ">=3.10"
@@ -0,0 +1 @@
1
+ __version__ = "0.2.1"
@@ -16,6 +16,7 @@ class UserRights:
16
16
  """
17
17
  the rights of a single user
18
18
  """
19
+
19
20
  name: str
20
21
  rights: str
21
22
 
@@ -25,10 +26,11 @@ class Authorization:
25
26
  """
26
27
  Authorization check.
27
28
  """
28
- user_rights: dict[str,UserRights] = field(default_factory=dict)
29
+
30
+ user_rights: dict[str, UserRights] = field(default_factory=dict)
29
31
 
30
32
  @classmethod
31
- def load(cls,yaml_path:str=None) -> "Authorization":
33
+ def load(cls, yaml_path: str = None) -> "Authorization":
32
34
  """
33
35
  Load user rights from a YAML file, ensuring the file exists.
34
36
  """
@@ -49,4 +51,4 @@ class Authorization:
49
51
  if user_right is None:
50
52
  return False
51
53
  ok = rights in user_right.rights
52
- return ok
54
+ return ok
@@ -0,0 +1,119 @@
1
+ """
2
+ GitHub API client for accessing repository contents.
3
+
4
+ Created on 2025-12-02
5
+ @author: wf
6
+ """
7
+ import json
8
+ from pathlib import Path
9
+ from typing import List, Dict, Any, Optional, Union
10
+
11
+ import requests
12
+
13
+
14
+ class GitHub:
15
+ """
16
+ A simple GitHub API client for accessing repository contents.
17
+ """
18
+
19
+ def __init__(self, owner: str, repo: str, token: Optional[str] = None, session: Optional[requests.Session] = None):
20
+ """
21
+ Initialize GitHub client.
22
+
23
+ Args:
24
+ owner: Repository owner (username or organization)
25
+ repo: Repository name
26
+ token: Optional GitHub API token for authentication
27
+ session: Optional custom requests.Session
28
+ """
29
+ self.owner = owner
30
+ self.repo = repo
31
+ self.token = token
32
+ self.base_url = f"https://api.github.com/repos/{owner}/{repo}"
33
+ # Use provided token or read from file (compatible with GitHubApi)
34
+ self.token = token if token is not None else self._read_token()
35
+
36
+ # Use custom session or create new one
37
+ self.session = session or requests.Session()
38
+
39
+
40
+
41
+ def _headers(self) -> Dict[str, str]:
42
+ headers = {"Accept": "application/vnd.github.v3+json"}
43
+ if self.token:
44
+ headers["Authorization"] = f"token {self.token}"
45
+ return headers
46
+
47
+ def _read_token(self) -> Optional[str]:
48
+ """
49
+ Read GitHub token from ~/.github/access_token.json
50
+ (compatible with GitHubApi token storage format).
51
+
52
+ Returns:
53
+ GitHub token or None if not found
54
+ """
55
+ token_path = Path.home() / ".github" / "access_token.json"
56
+ if token_path.exists():
57
+ try:
58
+ with open(token_path, 'r') as f:
59
+ data = json.load(f)
60
+ return data.get("access_token")
61
+ except (json.JSONDecodeError, OSError):
62
+ pass
63
+ return None
64
+
65
+
66
+ def get_contents(self, path: str = "") -> Union[List[Dict[str, Any]], Dict[str, Any]]:
67
+ """
68
+ Get contents of a directory or file from the repository.
69
+
70
+ Args:
71
+ path: Path within the repository
72
+
73
+ Returns:
74
+ List of dictionaries for directories, or content for files
75
+ """
76
+ url = f"{self.base_url}/contents/{path}"
77
+ response = self.session.get(url, headers=self._headers(), timeout=30)
78
+ response.raise_for_status()
79
+ return response.json()
80
+
81
+ def list_files_recursive(self, path: str = "", suffix: Optional[str] = None) -> List[Dict[str, Any]]:
82
+ """
83
+ Recursively list files under a given path. Optionally filter by file suffix.
84
+
85
+ Args:
86
+ path: starting path within the repository
87
+ suffix: optional filename suffix filter, e.g., ".ttl"
88
+
89
+ Returns:
90
+ A flat list of GitHub content item dicts for files.
91
+ """
92
+ items = self.get_contents(path)
93
+ if isinstance(items, dict):
94
+ items = [items]
95
+
96
+ files: List[Dict[str, Any]] = []
97
+ for item in items:
98
+ item_type = item.get("type")
99
+ item_path = item.get("path", "")
100
+ if item_type == "file":
101
+ if suffix is None or item_path.endswith(suffix):
102
+ files.append(item)
103
+ elif item_type == "dir":
104
+ files.extend(self.list_files_recursive(item_path, suffix=suffix))
105
+ return files
106
+
107
+ def download(self, download_url: str) -> str:
108
+ """
109
+ Download raw file content via a download_url.
110
+
111
+ Args:
112
+ download_url: The GitHub-provided raw download URL
113
+
114
+ Returns:
115
+ The text content of the file
116
+ """
117
+ response = self.session.get(download_url, headers=self._headers(), timeout=30)
118
+ response.raise_for_status()
119
+ return response.text
@@ -0,0 +1,99 @@
1
+ """
2
+ Created 2024
3
+
4
+ @author: tholzheim
5
+
6
+ Move to separate module in 2025-12-01 by wf
7
+ """
8
+
9
+ import logging
10
+ from enum import Enum
11
+
12
+ from lodstorage.prefix_config import PrefixConfigs
13
+ from lodstorage.prefixes import Prefixes
14
+ from lodstorage.query import Endpoint, Query
15
+
16
+ from snapquery.sparql_analyzer import SparqlAnalyzer
17
+
18
+
19
+ class QueryPrefixMerger(Enum):
20
+ """
21
+ SPARQL Query prefix merger
22
+ """
23
+
24
+ RAW = "raw"
25
+ SIMPLE_MERGER = "simple merger"
26
+ ANALYSIS_MERGER = "analysis merger"
27
+
28
+ @classmethod
29
+ def _missing_(cls, key):
30
+ logging.warning(f"Invalid QueryPrefixMerger key: {key}, defaulting to SIMPLE_MERGER")
31
+ merger = cls.default_merger()
32
+ return merger
33
+
34
+ @classmethod
35
+ def default_merger(cls) -> "QueryPrefixMerger":
36
+ merger = cls.SIMPLE_MERGER
37
+ return merger
38
+
39
+ @classmethod
40
+ def get_by_name(cls, name: str) -> "QueryPrefixMerger":
41
+ merger_map = {merger.name: merger.value for merger in QueryPrefixMerger}
42
+ merger_value = merger_map.get(name, None)
43
+ merger = QueryPrefixMerger(merger_value)
44
+ return merger
45
+
46
+ @classmethod
47
+ def merge_prefixes(
48
+ cls,
49
+ query: Query,
50
+ endpoint: Endpoint,
51
+ merger: "QueryPrefixMerger",
52
+ ) -> str:
53
+ """
54
+ Merge prefixes with the given merger
55
+ Args:
56
+ query (Query):
57
+ endpoint (Endpoint):
58
+ merger (QueryPrefixMerger):
59
+
60
+ Returns:
61
+ merged query
62
+ """
63
+ sparql_query = query.query
64
+ if merger == QueryPrefixMerger.SIMPLE_MERGER:
65
+ sparql_query = cls.simple_prefix_merger(sparql_query, endpoint)
66
+ elif merger == QueryPrefixMerger.ANALYSIS_MERGER:
67
+ sparql_query = cls.analysis_prefix_merger(sparql_query)
68
+ return sparql_query
69
+
70
+ @classmethod
71
+ def simple_prefix_merger(cls, query_str: str, endpoint: Endpoint) -> str:
72
+ """
73
+ Simple prefix merger
74
+ Args:
75
+ query_str (str): the query string
76
+ endpoint (Endpoint): the endpoint
77
+
78
+ Returns:
79
+ merged query
80
+ """
81
+ prefixes_str = endpoint.get_prefixes(PrefixConfigs.get_instance())
82
+ if not prefixes_str.strip():
83
+ return
84
+
85
+ merged_query = Prefixes.merge_prefixes(query_str, prefixes_str)
86
+ return merged_query
87
+
88
+ @classmethod
89
+ def analysis_prefix_merger(cls, query_str: str) -> str:
90
+ """
91
+ Analysis prefix merger
92
+ Args:
93
+ query_str
94
+
95
+ Returns:
96
+ merged query
97
+ """
98
+ merged_query = SparqlAnalyzer.add_missing_prefixes(query_str)
99
+ return merged_query
@@ -5,12 +5,11 @@ Created on 2024-05-05
5
5
  """
6
6
 
7
7
  import glob
8
- import json
9
8
  import os
10
9
 
11
10
  from tqdm import tqdm
12
11
 
13
- from snapquery.snapquery_core import NamedQueryManager, NamedQuerySet, NamedQuery
12
+ from snapquery.snapquery_core import NamedQuery, NamedQueryManager, NamedQuerySet
14
13
  from snapquery.wd_short_url import ShortUrl
15
14
 
16
15
 
@@ -63,7 +62,7 @@ class QueryImport:
63
62
  Returns:
64
63
  NamedQuerySet: A NamedQuerySet object containing the imported NamedQuery objects.
65
64
  """
66
- nq_set = NamedQuerySet.load_from_json_file(json_file)
65
+ nq_set = NamedQuerySet.load_from_json_file(json_file) # @UndefinedVariable
67
66
  iterable = (
68
67
  tqdm(
69
68
  nq_set.queries,
@@ -90,7 +89,7 @@ class QueryImport:
90
89
  self,
91
90
  short_url: ShortUrl,
92
91
  domain: str,
93
- namespace:str,
92
+ namespace: str,
94
93
  ) -> NamedQuery | None:
95
94
  """
96
95
  Read and process a single short URL, optionally enriching it with LLM-generated metadata.
@@ -5,14 +5,15 @@ Created on 2024-05-05
5
5
  """
6
6
 
7
7
  from lodstorage.query import Query, QuerySyntaxHighlight
8
- from nicegui import ui, background_tasks
8
+ from nicegui import background_tasks, ui
9
9
 
10
10
  from snapquery.models.person import Person
11
+ from snapquery.person_selector import PersonSelector, PersonView
11
12
  from snapquery.qimport import QueryImport
12
13
  from snapquery.snapquery_core import NamedQuery
13
- from snapquery.person_selector import PersonSelector, PersonView
14
14
  from snapquery.wd_short_url import ShortUrl
15
15
 
16
+
16
17
  class QueryImportView:
17
18
  """
18
19
  display Query Import UI
@@ -24,7 +25,7 @@ class QueryImportView:
24
25
  ):
25
26
  self.person = None
26
27
  self.solution = solution
27
- self.domain="wikidata.org"
28
+ self.domain = "wikidata.org"
28
29
  self.namespace = "short_url"
29
30
  self.name = ""
30
31
  self.url = ""
@@ -32,12 +33,12 @@ class QueryImportView:
32
33
  self.description = ""
33
34
  self.comment = ""
34
35
  self.query = None
35
- self.allow_importing_from_url=self.solution.user_has_llm_right
36
+ self.allow_importing_from_url = self.solution.user_has_llm_right
36
37
  if self.solution:
37
38
  self.qimport = QueryImport()
38
39
  self.nqm = self.solution.nqm
39
40
 
40
- def on_select_person(self,person: Person=None):
41
+ def on_select_person(self, person: Person = None):
41
42
  """
42
43
  react on a person having been selected
43
44
 
@@ -30,12 +30,11 @@ class QLeverUrl(ShortUrl):
30
30
  Returns:
31
31
  str: The SPARQL query extracted from the short URL.
32
32
  """
33
- self.fetch_final_url()
33
+ self.fetch_final_url(self.short_url)
34
34
  if self.url:
35
35
  try:
36
- response = requests.get(self.url)
37
- response.raise_for_status()
38
- soup = BeautifulSoup(response.content, "html.parser")
36
+ text=self.get_wikitext(self.url)
37
+ soup = BeautifulSoup(text, "html.parser")
39
38
  query_element = soup.find("textarea", {"id": "query"})
40
39
  if query_element and query_element.text:
41
40
  self.sparql = query_element.text.strip()
@@ -9,9 +9,9 @@ import re
9
9
  from pathlib import Path
10
10
  from typing import Optional
11
11
 
12
+ from basemkit.yamlable import lod_storable
12
13
  from bs4 import BeautifulSoup, ResultSet
13
14
  from lodstorage.query import Query, QuerySyntaxHighlight
14
- from basemkit.yamlable import lod_storable
15
15
 
16
16
  from snapquery.models.sparql_components import SPARQLLanguage
17
17
 
@@ -248,6 +248,4 @@ class FunctionStat:
248
248
  count: int = 0
249
249
 
250
250
 
251
- QUERY_ITEM_STATS: Stats = Stats.load_from_yaml_file(
252
- Path(__file__).parent.joinpath("samples", "query_stats.yaml")
253
- )
251
+ QUERY_ITEM_STATS: Stats = Stats.load_from_yaml_file(Path(__file__).parent.joinpath("samples", "query_stats.yaml"))
@@ -0,0 +1,128 @@
1
+ # Default SPARQL endpoints for snapquery tool
2
+ # 2022-02-14 tholzheim
3
+ # 2025-12-01 new format with prefix-sets
4
+ endpoints:
5
+ wikidata:
6
+ description: |
7
+ Wikimedia Wikidata Query Service (legacy full).
8
+ Stable but high-load; prefer -main/-scholarly.
9
+ lang: sparql
10
+ endpoint: https://query.wikidata.org/sparql
11
+ website: https://query.wikidata.org
12
+ database: blazegraph
13
+ method: POST
14
+ calls_per_minute: 30
15
+ auto_update: true
16
+ data_seeded: 2012-10-29
17
+ uptime_days: 4500
18
+ mtriples: 22000
19
+ prefix_sets:
20
+ - rdf
21
+ - wikidata
22
+ - blazegraph
23
+ - commons
24
+
25
+ wikidata-main:
26
+ description: WDQS Graph Split — main (non-scholarly).
27
+ lang: sparql
28
+ endpoint: https://query-main.wikidata.org/sparql
29
+ website: https://query-main.wikidata.org/
30
+ database: blazegraph
31
+ method: POST
32
+ calls_per_minute: 30
33
+ auto_update: true
34
+ data_seeded: 2025-01-01
35
+ uptime_days: 200
36
+ mtriples: 8580
37
+ prefix_sets:
38
+ - rdf
39
+ - wikidata
40
+ - blazegraph
41
+ - commons
42
+
43
+ wikidata-scholarly:
44
+ description: WDQS Graph Split — scholarly.
45
+ lang: sparql
46
+ endpoint: https://query-scholarly.wikidata.org/sparql
47
+ website: https://query-scholarly.wikidata.org/
48
+ database: blazegraph
49
+ method: POST
50
+ calls_per_minute: 30
51
+ auto_update: true
52
+ data_seeded: 2025-01-01
53
+ uptime_days: 200
54
+ mtriples: 8730
55
+ prefix_sets:
56
+ - rdf
57
+ - wikidata
58
+ - blazegraph
59
+ - commons
60
+
61
+ wikidata-dbis:
62
+ description: RWTH Aachen full Wikidata mirror (stable).
63
+ lang: sparql
64
+ endpoint: https://wdqs.wikidata.dbis.rwth-aachen.de/sparql
65
+ website: https://wdqs.wikidata.dbis.rwth-aachen.de/
66
+ database: blazegraph
67
+ method: POST
68
+ calls_per_minute: 30
69
+ auto_update: false
70
+ data_seeded: 2025-06-01
71
+ uptime_days: 1
72
+ mtriples: 17029
73
+ prefix_sets:
74
+ - rdf
75
+ - wikidata
76
+ - blazegraph
77
+ - commons
78
+
79
+ wikidata-qlever:
80
+ description: QLever Freiburg Wikidata.
81
+ lang: sparql
82
+ method: POST
83
+ database: qlever
84
+ endpoint: https://qlever.dev/api/wikidata
85
+ website: https://qlever.dev/wikidata
86
+ calls_per_minute: 60
87
+ prefix_sets:
88
+ - rdf
89
+ - wikidata
90
+ - commons
91
+
92
+ wikidata-qlever-dbis:
93
+ description: QLever RWTH Wikidata.
94
+ lang: sparql
95
+ method: POST
96
+ database: qlever
97
+ endpoint: https://qlever-api.wikidata.dbis.rwth-aachen.de/
98
+ website: https://qlever.wikidata.dbis.rwth-aachen.de/wikidata
99
+ calls_per_minute: 60
100
+ prefix_sets:
101
+ - rdf
102
+ - wikidata
103
+
104
+ dblp:
105
+ description: DBLP official (qlever - reliable).
106
+ lang: sparql
107
+ method: POST
108
+ database: qlever
109
+ endpoint: https://sparql.dblp.org/sparql
110
+ website: https://sparql.dblp.org
111
+ calls_per_minute: 60
112
+ prefix_sets:
113
+ - rdf
114
+ - dblp
115
+ - datacite
116
+ - litre
117
+
118
+ gov:
119
+ description: GOV Genealogy (stable).
120
+ lang: sparql
121
+ endpoint: https://gov-sparql.genealogy.net/dataset/sparql
122
+ website: https://gov-sparql.genealogy.net/
123
+ database: gov-genealogy
124
+ method: POST
125
+ calls_per_minute: 30
126
+ prefix_sets:
127
+ - rdf
128
+ - gov