ds-caselaw-marklogic-api-client 27.0.0__tar.gz → 43.0.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.
Potentially problematic release.
This version of ds-caselaw-marklogic-api-client might be problematic. Click here for more details.
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/PKG-INFO +17 -12
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/README.md +3 -1
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/pyproject.toml +25 -16
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/Client.py +222 -33
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/__init__.py +63 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/client_helpers/__init__.py +35 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/errors.py +1 -3
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/factories.py +200 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/identifier_resolution.py +52 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/managers/merge/__init__.py +51 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/managers/merge/checks.py +79 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/models/documents/__init__.py +235 -75
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/documents/body.py +228 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/documents/comparison.py +42 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/models/documents/exceptions.py +4 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/documents/transforms/html.xsl +1070 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/documents/xml.py +72 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/identifiers/__init__.py +216 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/identifiers/collection.py +172 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/identifiers/exceptions.py +6 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/identifiers/fclid.py +55 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/identifiers/neutral_citation.py +77 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/identifiers/press_summary_ncn.py +24 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/identifiers/unpacker.py +61 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/judgments.py +60 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/models/neutral_citation_mixin.py +10 -9
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/parser_logs.py +14 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/press_summaries.py +59 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/models/utilities/__init__.py +6 -7
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/models/utilities/aws.py +49 -30
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/models/utilities/move.py +1 -1
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/py.typed +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/responses/search_result.py +42 -7
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/search_parameters.py +6 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/types.py +108 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xml_helpers.py +41 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/check_content_hash_unique_by_uri.xqy +15 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_components_for_document.xqy +1 -1
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/get_judgment.xqy +69 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/get_missing_fclid.xqy +25 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/get_next_document_sequence_number.xqy +14 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_pending_enrichment_for_version.xqy +20 -9
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_pending_parse_for_version.xqy +7 -4
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/get_property_as_node.xqy +9 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/get_recently_enriched.xqy +18 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/get_recently_parsed.xqy +19 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/insert_document.xqy +2 -6
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/resolve_from_identifier_slug.xqy +16 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/resolve_from_identifier_value.xqy +17 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/set_datetime_property.xqy +11 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xquery/set_property_as_node.xqy +11 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/update_locked_judgment.xqy +1 -2
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/xslt_transform.xqy +1 -1
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery_type_dicts.py +48 -2
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xslt/modify_xml_live.xsl +70 -0
- ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/xslt/sample.xsl +26 -0
- ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/__init__.py +0 -40
- ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/factories.py +0 -165
- ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/models/documents/body.py +0 -139
- ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/models/documents/xml.py +0 -43
- ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/models/judgments.py +0 -53
- ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/models/press_summaries.py +0 -54
- ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/xml_helpers.py +0 -22
- ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/xquery/get_judgment.xqy +0 -21
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/LICENSE.md +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/client_helpers/search_helpers.py +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/content_hash.py +0 -0
- /ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/py.typed → /ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/managers/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/models/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/models/documents/statuses.py +0 -0
- /ds_caselaw_marklogic_api_client-27.0.0/src/caselawclient/client_helpers/__init__.py → /ds_caselaw_marklogic_api_client-43.0.0/src/caselawclient/models/documents/versions.py +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/models/utilities/dates.py +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/responses/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/responses/search_response.py +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/responses/xsl/search_match.xsl +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/break_judgment_checkout.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/checkin_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/checkout_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/copy_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/delete_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/document_collections.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/document_exists.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_combined_stats_table.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_highest_enrichment_version.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_highest_parser_version.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_judgment_checkout_status.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_judgment_version.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_last_modified.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_properties_for_search_results.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_property.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_version_annotation.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/get_version_created.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/list_judgment_versions.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/set_boolean_property.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/set_metadata_citation.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/set_metadata_court.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/set_metadata_jurisdiction.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/set_metadata_name.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/set_metadata_this_uri.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/set_metadata_work_expression_date.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/set_property.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/update_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/user_has_privilege.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/user_has_role.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/validate_all_documents.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/validate_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/src/caselawclient/xquery/xslt.xqy +0 -0
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: ds-caselaw-marklogic-api-client
|
|
3
|
-
Version:
|
|
3
|
+
Version: 43.0.0
|
|
4
4
|
Summary: An API client for interacting with the underlying data in Find Caselaw.
|
|
5
|
-
Home-page: https://github.com/nationalarchives/ds-caselaw-custom-api-client
|
|
6
5
|
Keywords: national archives,caselaw
|
|
7
6
|
Author: The National Archives
|
|
8
|
-
Requires-Python: >=3.
|
|
7
|
+
Requires-Python: >=3.12.0,<4.0.0
|
|
9
8
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
11
|
Requires-Dist: boto3 (>=1.26.112,<2.0.0)
|
|
14
|
-
Requires-Dist: certifi (>=
|
|
12
|
+
Requires-Dist: certifi (>=2025.10.5,<2025.11.0)
|
|
15
13
|
Requires-Dist: charset-normalizer (>=3.0.0,<4.0.0)
|
|
16
|
-
Requires-Dist:
|
|
14
|
+
Requires-Dist: defusedxml (>=0.7.1,<0.8.0)
|
|
15
|
+
Requires-Dist: django-environ (>=0.12.0)
|
|
17
16
|
Requires-Dist: ds-caselaw-utils (>=2.0.0,<3.0.0)
|
|
18
17
|
Requires-Dist: idna (>=3.4,<4.0)
|
|
19
|
-
Requires-Dist: lxml (>=
|
|
18
|
+
Requires-Dist: lxml (>=6.0.0,<7.0.0)
|
|
20
19
|
Requires-Dist: memoization (>=0.4.0,<0.5.0)
|
|
21
20
|
Requires-Dist: mypy-boto3-s3 (>=1.26.104,<2.0.0)
|
|
22
21
|
Requires-Dist: mypy-boto3-sns (>=1.26.69,<2.0.0)
|
|
22
|
+
Requires-Dist: pydantic (>=2.12.3,<3.0.0)
|
|
23
23
|
Requires-Dist: python-dateutil (>=2.9.0-post.0,<3.0.0)
|
|
24
|
-
Requires-Dist: pytz (
|
|
24
|
+
Requires-Dist: pytz (>2024)
|
|
25
25
|
Requires-Dist: requests (>=2.28.2,<3.0.0)
|
|
26
26
|
Requires-Dist: requests-toolbelt (>=0.10.1,<1.1.0)
|
|
27
|
+
Requires-Dist: saxonche (>=12.5.0,<13.0.0)
|
|
28
|
+
Requires-Dist: sqids (>=0.5.0,<0.6.0)
|
|
27
29
|
Requires-Dist: typing-extensions (>=4.7.1,<5.0.0)
|
|
30
|
+
Project-URL: Homepage, https://github.com/nationalarchives/ds-caselaw-custom-api-client
|
|
28
31
|
Description-Content-Type: text/markdown
|
|
29
32
|
|
|
30
33
|
# The National Archives: Find Case Law
|
|
@@ -33,7 +36,9 @@ This repository is part of the [Find Case Law](https://caselaw.nationalarchives.
|
|
|
33
36
|
|
|
34
37
|
# MarkLogic API Client
|
|
35
38
|
|
|
36
|
-
[](https://pypi.org/project/ds-caselaw-marklogic-api-client/)
|
|
39
|
+
[](https://pypi.org/project/ds-caselaw-marklogic-api-client/)
|
|
40
|
+

|
|
41
|
+

|
|
37
42
|
|
|
38
43
|
This is an API Client for connecting to Marklogic for The National Archive's Caselaw site.
|
|
39
44
|
|
|
@@ -4,7 +4,9 @@ This repository is part of the [Find Case Law](https://caselaw.nationalarchives.
|
|
|
4
4
|
|
|
5
5
|
# MarkLogic API Client
|
|
6
6
|
|
|
7
|
-
[](https://pypi.org/project/ds-caselaw-marklogic-api-client/)
|
|
7
|
+
[](https://pypi.org/project/ds-caselaw-marklogic-api-client/)
|
|
8
|
+

|
|
9
|
+

|
|
8
10
|
|
|
9
11
|
This is an API Client for connecting to Marklogic for The National Archive's Caselaw site.
|
|
10
12
|
|
{ds_caselaw_marklogic_api_client-27.0.0 → ds_caselaw_marklogic_api_client-43.0.0}/pyproject.toml
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "ds-caselaw-marklogic-api-client"
|
|
3
|
-
version = "
|
|
3
|
+
version = "43.0.0"
|
|
4
4
|
description = "An API client for interacting with the underlying data in Find Caselaw."
|
|
5
5
|
authors = ["The National Archives"]
|
|
6
6
|
homepage = "https://github.com/nationalarchives/ds-caselaw-custom-api-client"
|
|
@@ -11,36 +11,42 @@ packages = [
|
|
|
11
11
|
]
|
|
12
12
|
|
|
13
13
|
[tool.poetry.dependencies]
|
|
14
|
-
python = "^3.
|
|
15
|
-
certifi = ">=
|
|
14
|
+
python = "^3.12.0"
|
|
15
|
+
certifi = ">=2025.10.5,<2025.11.0"
|
|
16
16
|
charset-normalizer = "^3.0.0"
|
|
17
|
-
django-environ = "
|
|
17
|
+
django-environ = ">=0.12.0"
|
|
18
18
|
idna = "^3.4"
|
|
19
19
|
requests = "^2.28.2"
|
|
20
20
|
requests-toolbelt = ">=0.10.1,<1.1.0"
|
|
21
21
|
memoization = "^0.4.0"
|
|
22
|
-
lxml = "^
|
|
22
|
+
lxml = "^6.0.0"
|
|
23
23
|
ds-caselaw-utils = "^2.0.0"
|
|
24
24
|
boto3 = "^1.26.112"
|
|
25
25
|
typing-extensions = "^4.7.1"
|
|
26
26
|
mypy-boto3-s3 = "^1.26.104"
|
|
27
27
|
mypy-boto3-sns = "^1.26.69"
|
|
28
|
-
pytz = "
|
|
28
|
+
pytz = ">2024"
|
|
29
29
|
python-dateutil = "^2.9.0-post.0"
|
|
30
|
+
saxonche = "^12.5.0"
|
|
31
|
+
sqids = "^0.5.0"
|
|
32
|
+
defusedxml = "^0.7.1"
|
|
33
|
+
pydantic = "^2.12.3"
|
|
30
34
|
|
|
31
35
|
[tool.poetry.group.dev.dependencies]
|
|
32
|
-
coverage = "
|
|
33
|
-
pytest = "
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
coverage = "7.11.0"
|
|
37
|
+
pytest = "8.4.2"
|
|
38
|
+
pytest-cov = "7.0.0"
|
|
39
|
+
beautifulsoup4 = "4.14.2"
|
|
40
|
+
responses = "0.25.8"
|
|
41
|
+
python-dotenv = "1.2.1"
|
|
42
|
+
time-machine = "2.19.0"
|
|
43
|
+
moto = {version = "5.1.15", extras = ["all"]}
|
|
38
44
|
|
|
39
45
|
[tool.poetry.group.docs]
|
|
40
46
|
optional = true
|
|
41
47
|
|
|
42
48
|
[tool.poetry.group.docs.dependencies]
|
|
43
|
-
pdoc = "^
|
|
49
|
+
pdoc = "^15.0.0"
|
|
44
50
|
|
|
45
51
|
|
|
46
52
|
[tool.commitizen]
|
|
@@ -49,6 +55,8 @@ tag_format = "v$version"
|
|
|
49
55
|
version_scheme = "semver2"
|
|
50
56
|
version_provider = "poetry"
|
|
51
57
|
update_changelog_on_bump = true
|
|
58
|
+
changelog_incremental = true
|
|
59
|
+
|
|
52
60
|
[build-system]
|
|
53
61
|
requires = ["poetry-core"]
|
|
54
62
|
build-backend = "poetry.core.masonry.api"
|
|
@@ -64,14 +72,15 @@ line-length = 120
|
|
|
64
72
|
|
|
65
73
|
[tool.ruff.lint]
|
|
66
74
|
ignore = ["E501", "G004", "PLR2004", "RUF005", "RUF012", "UP040"] # longlines, fstrings in logs, magic values, consider not concat, mutable classbits, type instead of TypeAlias
|
|
67
|
-
extend-select = ["W", "I", "SLF", "SIM"]
|
|
68
|
-
# extend-select = [ "B", "Q", "
|
|
75
|
+
extend-select = ["W", "I", "SLF", "SIM", "C90", "S"]
|
|
76
|
+
# extend-select = [ "B", "Q", "I", "UP", "YTT", "ASYNC", "BLE", "A", "COM", "C4", "DTZ", "T10", "DJ", "EM", "EXE", "FA",
|
|
69
77
|
# "ISC", "ICN", "G", "INP", "PIE", "T20", "PYI", "PT", "Q", "RSE", "RET", "SLOT", "TID", "TCH", "INT", "PTH",
|
|
70
78
|
# "FIX", "PGH", "PL", "TRY", "FLY", "PERF", "RUF"]
|
|
71
79
|
unfixable = ["ERA"]
|
|
72
80
|
|
|
73
81
|
[tool.ruff.lint.extend-per-file-ignores]
|
|
74
|
-
"tests/*" = ["S101"]
|
|
82
|
+
"tests/*" = ["S101"] # `assert` is fine in tests
|
|
83
|
+
"smoketest/*" = ["S101"] # `assert` is fine in tests
|
|
75
84
|
"tests/client/test_client.py" = ["SLF001"] # TODO: This really shouldn't be the case, but it's not important to fix right now.
|
|
76
85
|
|
|
77
86
|
# things skipped:
|
|
@@ -7,29 +7,34 @@ import warnings
|
|
|
7
7
|
from datetime import datetime, time, timedelta
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
from typing import Any, Optional, Type, Union
|
|
10
|
-
from xml.etree import
|
|
11
|
-
from xml.etree.ElementTree import Element, ParseError, fromstring
|
|
10
|
+
from xml.etree.ElementTree import Element
|
|
12
11
|
|
|
13
12
|
import environ
|
|
14
13
|
import requests
|
|
14
|
+
from dateutil.parser import isoparse
|
|
15
|
+
from defusedxml import ElementTree
|
|
16
|
+
from defusedxml.ElementTree import ParseError, fromstring
|
|
15
17
|
from ds_caselaw_utils.types import NeutralCitationString
|
|
18
|
+
from lxml import etree
|
|
16
19
|
from requests.auth import HTTPBasicAuth
|
|
17
20
|
from requests.structures import CaseInsensitiveDict
|
|
18
21
|
from requests_toolbelt.multipart import decoder
|
|
19
22
|
|
|
20
23
|
from caselawclient import xquery_type_dicts as query_dicts
|
|
21
|
-
from caselawclient.
|
|
24
|
+
from caselawclient.identifier_resolution import IdentifierResolutions
|
|
22
25
|
from caselawclient.models.documents import (
|
|
23
26
|
DOCUMENT_COLLECTION_URI_JUDGMENT,
|
|
24
27
|
DOCUMENT_COLLECTION_URI_PRESS_SUMMARY,
|
|
25
28
|
Document,
|
|
26
|
-
DocumentURIString,
|
|
27
29
|
)
|
|
30
|
+
from caselawclient.models.documents.versions import VersionAnnotation
|
|
28
31
|
from caselawclient.models.judgments import Judgment
|
|
29
32
|
from caselawclient.models.press_summaries import PressSummary
|
|
30
33
|
from caselawclient.models.utilities import move
|
|
31
34
|
from caselawclient.search_parameters import SearchParameters
|
|
35
|
+
from caselawclient.types import DocumentIdentifierSlug, DocumentIdentifierValue, DocumentURIString
|
|
32
36
|
from caselawclient.xquery_type_dicts import (
|
|
37
|
+
CheckContentHashUniqueByUriDict,
|
|
33
38
|
MarkLogicDocumentURIString,
|
|
34
39
|
MarkLogicDocumentVersionURIString,
|
|
35
40
|
MarkLogicPrivilegeURIString,
|
|
@@ -53,6 +58,11 @@ from .errors import (
|
|
|
53
58
|
)
|
|
54
59
|
|
|
55
60
|
env = environ.Env()
|
|
61
|
+
|
|
62
|
+
# Requests timeouts: https://requests.readthedocs.io/en/latest/user/advanced/
|
|
63
|
+
CONNECT_TIMEOUT = float(os.environ.get("CONNECT_TIMEOUT", "3.05"))
|
|
64
|
+
READ_TIMEOUT = float(os.environ.get("READ_TIMEOUT", "10.0"))
|
|
65
|
+
|
|
56
66
|
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
|
|
57
67
|
DEFAULT_XSL_TRANSFORM = "accessible-html.xsl"
|
|
58
68
|
|
|
@@ -62,6 +72,8 @@ except importlib.metadata.PackageNotFoundError:
|
|
|
62
72
|
VERSION = "0"
|
|
63
73
|
DEFAULT_USER_AGENT = f"ds-caselaw-marklogic-api-client/{VERSION}"
|
|
64
74
|
|
|
75
|
+
DEBUG: bool = bool(os.getenv("DEBUG", default=False))
|
|
76
|
+
|
|
65
77
|
|
|
66
78
|
class NoResponse(Exception):
|
|
67
79
|
"""A requests HTTPError has no response. We expect this will never happen."""
|
|
@@ -73,12 +85,6 @@ class MultipartResponseLongerThanExpected(Exception):
|
|
|
73
85
|
"""
|
|
74
86
|
|
|
75
87
|
|
|
76
|
-
class DocumentHasNoTypeCollection(Exception):
|
|
77
|
-
"""
|
|
78
|
-
A MarkLogic document is not part of a collection which identifies its document type.
|
|
79
|
-
"""
|
|
80
|
-
|
|
81
|
-
|
|
82
88
|
def get_multipart_strings_from_marklogic_response(
|
|
83
89
|
response: requests.Response,
|
|
84
90
|
) -> list[str]:
|
|
@@ -171,6 +177,7 @@ class MarklogicApiClient:
|
|
|
171
177
|
error_code_classes: dict[str, Type[MarklogicAPIError]] = {
|
|
172
178
|
"XDMP-DOCNOTFOUND": MarklogicResourceNotFoundError,
|
|
173
179
|
"XDMP-LOCKCONFLICT": MarklogicResourceLockedError,
|
|
180
|
+
"XDMP-LOCKED": MarklogicResourceLockedError,
|
|
174
181
|
"DLS-UNMANAGED": MarklogicResourceUnmanagedError,
|
|
175
182
|
"DLS-NOTCHECKEDOUT": MarklogicResourceNotCheckedOutError,
|
|
176
183
|
"DLS-CHECKOUTCONFLICT": MarklogicCheckoutConflictError,
|
|
@@ -207,20 +214,22 @@ class MarklogicApiClient:
|
|
|
207
214
|
Returns a list of PressSummary objects associated with a given Document URI
|
|
208
215
|
"""
|
|
209
216
|
vars: query_dicts.GetComponentsForDocumentDict = {
|
|
210
|
-
"parent_uri":
|
|
217
|
+
"parent_uri": uri,
|
|
211
218
|
"component": "pressSummary",
|
|
212
219
|
}
|
|
213
220
|
response = self._send_to_eval(vars, "get_components_for_document.xqy")
|
|
214
221
|
uris = get_multipart_strings_from_marklogic_response(response)
|
|
215
|
-
return [
|
|
222
|
+
return [
|
|
223
|
+
PressSummary(DocumentURIString(uri.strip("/").strip(".xml")), self) for uri in uris
|
|
224
|
+
] # TODO: Migrate this strip behaviour into proper manipulation of a MarkLogicURIString
|
|
216
225
|
|
|
217
226
|
def get_document_by_uri(
|
|
218
227
|
self,
|
|
219
228
|
uri: DocumentURIString,
|
|
220
|
-
|
|
229
|
+
search_query: Optional[str] = None,
|
|
221
230
|
) -> Document:
|
|
222
231
|
document_type_class = self.get_document_type_from_uri(uri)
|
|
223
|
-
return document_type_class(uri, self)
|
|
232
|
+
return document_type_class(uri, self, search_query=search_query)
|
|
224
233
|
|
|
225
234
|
def get_document_type_from_uri(self, uri: DocumentURIString) -> Type[Document]:
|
|
226
235
|
vars: query_dicts.DocumentCollectionsDict = {
|
|
@@ -233,9 +242,7 @@ class MarklogicApiClient:
|
|
|
233
242
|
return Judgment
|
|
234
243
|
if DOCUMENT_COLLECTION_URI_PRESS_SUMMARY in collections:
|
|
235
244
|
return PressSummary
|
|
236
|
-
|
|
237
|
-
f"The document at URI {uri} is not part of a valid document type collection.",
|
|
238
|
-
)
|
|
245
|
+
return Document
|
|
239
246
|
|
|
240
247
|
def _get_error_code_class(self, error_code: str) -> Type[MarklogicAPIError]:
|
|
241
248
|
"""
|
|
@@ -260,10 +267,12 @@ class MarklogicApiClient:
|
|
|
260
267
|
return "Unknown error, Marklogic returned a null or empty response"
|
|
261
268
|
try:
|
|
262
269
|
xml = fromstring(content_as_xml)
|
|
263
|
-
return
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
270
|
+
return str(
|
|
271
|
+
xml.find(
|
|
272
|
+
"message-code",
|
|
273
|
+
namespaces={"": "http://marklogic.com/xdmp/error"},
|
|
274
|
+
).text
|
|
275
|
+
)
|
|
267
276
|
except (ParseError, TypeError, AttributeError):
|
|
268
277
|
return "Unknown error, Marklogic returned a null or empty response"
|
|
269
278
|
|
|
@@ -316,11 +325,13 @@ class MarklogicApiClient:
|
|
|
316
325
|
self,
|
|
317
326
|
vars: query_dicts.MarkLogicAPIDict,
|
|
318
327
|
xquery_file_name: str,
|
|
328
|
+
timeout: tuple[float, float] = (CONNECT_TIMEOUT, READ_TIMEOUT),
|
|
319
329
|
) -> requests.Response:
|
|
320
330
|
return self.eval(
|
|
321
331
|
self._xquery_path(xquery_file_name),
|
|
322
332
|
vars=json.dumps(vars),
|
|
323
333
|
accept_header="application/xml",
|
|
334
|
+
timeout=timeout,
|
|
324
335
|
)
|
|
325
336
|
|
|
326
337
|
def _eval_and_decode(
|
|
@@ -403,6 +414,7 @@ class MarklogicApiClient:
|
|
|
403
414
|
judgment_uri: DocumentURIString,
|
|
404
415
|
version_uri: Optional[DocumentURIString] = None,
|
|
405
416
|
show_unpublished: bool = False,
|
|
417
|
+
search_query: Optional[str] = None,
|
|
406
418
|
) -> bytes:
|
|
407
419
|
marklogic_document_uri = self._format_uri_for_marklogic(judgment_uri)
|
|
408
420
|
marklogic_document_version_uri = (
|
|
@@ -418,6 +430,7 @@ class MarklogicApiClient:
|
|
|
418
430
|
"uri": marklogic_document_uri,
|
|
419
431
|
"version_uri": marklogic_document_version_uri,
|
|
420
432
|
"show_unpublished": show_unpublished,
|
|
433
|
+
"search_query": search_query,
|
|
421
434
|
}
|
|
422
435
|
|
|
423
436
|
response = self._eval_as_bytes(vars, "get_judgment.xqy")
|
|
@@ -433,11 +446,13 @@ class MarklogicApiClient:
|
|
|
433
446
|
judgment_uri: DocumentURIString,
|
|
434
447
|
version_uri: Optional[DocumentURIString] = None,
|
|
435
448
|
show_unpublished: bool = False,
|
|
449
|
+
search_query: Optional[str] = None,
|
|
436
450
|
) -> str:
|
|
437
451
|
return self.get_judgment_xml_bytestring(
|
|
438
452
|
judgment_uri,
|
|
439
453
|
version_uri,
|
|
440
454
|
show_unpublished,
|
|
455
|
+
search_query=search_query,
|
|
441
456
|
).decode(encoding="utf-8")
|
|
442
457
|
|
|
443
458
|
def set_document_name(
|
|
@@ -562,6 +577,7 @@ class MarklogicApiClient:
|
|
|
562
577
|
self,
|
|
563
578
|
document_uri: DocumentURIString,
|
|
564
579
|
document_xml: Element,
|
|
580
|
+
document_type: type[Document],
|
|
565
581
|
annotation: VersionAnnotation,
|
|
566
582
|
) -> requests.Response:
|
|
567
583
|
"""
|
|
@@ -569,6 +585,7 @@ class MarklogicApiClient:
|
|
|
569
585
|
|
|
570
586
|
:param document_uri: The URI to insert the document at
|
|
571
587
|
:param document_xml: The XML of the document to insert
|
|
588
|
+
:param document_type: The type class of the document
|
|
572
589
|
:param annotation: Annotations to record alongside this version
|
|
573
590
|
|
|
574
591
|
:return: The response object from MarkLogic
|
|
@@ -582,6 +599,7 @@ class MarklogicApiClient:
|
|
|
582
599
|
|
|
583
600
|
vars: query_dicts.InsertDocumentDict = {
|
|
584
601
|
"uri": uri,
|
|
602
|
+
"type_collection": document_type.type_collection_name,
|
|
585
603
|
"document": xml.decode("utf-8"),
|
|
586
604
|
"annotation": annotation.as_json,
|
|
587
605
|
}
|
|
@@ -634,12 +652,14 @@ class MarklogicApiClient:
|
|
|
634
652
|
judgment_uri: DocumentURIString,
|
|
635
653
|
annotation: str = "",
|
|
636
654
|
expires_at_midnight: bool = False,
|
|
655
|
+
timeout_seconds: int = -1,
|
|
637
656
|
) -> requests.Response:
|
|
657
|
+
"""If timeout_seconds is -1, the lock never times out"""
|
|
638
658
|
uri = self._format_uri_for_marklogic(judgment_uri)
|
|
639
659
|
vars: query_dicts.CheckoutJudgmentDict = {
|
|
640
660
|
"uri": uri,
|
|
641
661
|
"annotation": annotation,
|
|
642
|
-
"timeout":
|
|
662
|
+
"timeout": timeout_seconds,
|
|
643
663
|
}
|
|
644
664
|
|
|
645
665
|
if expires_at_midnight:
|
|
@@ -675,10 +695,12 @@ class MarklogicApiClient:
|
|
|
675
695
|
if content == "":
|
|
676
696
|
return None
|
|
677
697
|
response_xml = ElementTree.fromstring(content)
|
|
678
|
-
return
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
698
|
+
return str(
|
|
699
|
+
response_xml.find(
|
|
700
|
+
"dls:annotation",
|
|
701
|
+
namespaces={"dls": "http://marklogic.com/xdmp/dls"},
|
|
702
|
+
).text
|
|
703
|
+
)
|
|
682
704
|
|
|
683
705
|
def get_judgment_version(
|
|
684
706
|
self,
|
|
@@ -707,11 +729,20 @@ class MarklogicApiClient:
|
|
|
707
729
|
== 0
|
|
708
730
|
)
|
|
709
731
|
|
|
732
|
+
def has_unique_content_hash(self, judgment_uri: DocumentURIString) -> bool:
|
|
733
|
+
"""
|
|
734
|
+
Returns True if the content hash for this document is unique (not shared with other documents).
|
|
735
|
+
"""
|
|
736
|
+
uri = self._format_uri_for_marklogic(judgment_uri)
|
|
737
|
+
vars: CheckContentHashUniqueByUriDict = {"uri": uri}
|
|
738
|
+
return self._eval_and_decode(vars, "check_content_hash_unique_by_uri.xqy") == "true"
|
|
739
|
+
|
|
710
740
|
def eval(
|
|
711
741
|
self,
|
|
712
742
|
xquery_path: str,
|
|
713
743
|
vars: str,
|
|
714
744
|
accept_header: str = "multipart/mixed",
|
|
745
|
+
timeout: tuple[float, float] = (CONNECT_TIMEOUT, READ_TIMEOUT),
|
|
715
746
|
) -> requests.Response:
|
|
716
747
|
headers = {
|
|
717
748
|
"Content-type": "application/x-www-form-urlencoded",
|
|
@@ -722,11 +753,16 @@ class MarklogicApiClient:
|
|
|
722
753
|
"vars": vars,
|
|
723
754
|
}
|
|
724
755
|
path = "LATEST/eval"
|
|
756
|
+
|
|
757
|
+
if DEBUG:
|
|
758
|
+
print(f"Sending {vars} to {xquery_path}")
|
|
759
|
+
|
|
725
760
|
response = self.session.request(
|
|
726
761
|
"POST",
|
|
727
762
|
url=self._path_to_request_url(path),
|
|
728
763
|
headers=headers,
|
|
729
764
|
data=data,
|
|
765
|
+
timeout=timeout,
|
|
730
766
|
)
|
|
731
767
|
# Raise relevant exception for an erroneous response
|
|
732
768
|
self._raise_for_status(response)
|
|
@@ -766,6 +802,8 @@ class MarklogicApiClient:
|
|
|
766
802
|
:param judge:
|
|
767
803
|
:param party:
|
|
768
804
|
:param neutral_citation:
|
|
805
|
+
:param document_name:
|
|
806
|
+
:param consignment_number:
|
|
769
807
|
:param specific_keyword:
|
|
770
808
|
:param order:
|
|
771
809
|
:param date_from:
|
|
@@ -850,6 +888,17 @@ class MarklogicApiClient:
|
|
|
850
888
|
}
|
|
851
889
|
return self._eval_and_decode(vars, "get_property.xqy")
|
|
852
890
|
|
|
891
|
+
def get_property_as_node(self, judgment_uri: DocumentURIString, name: str) -> Optional[etree._Element]:
|
|
892
|
+
uri = self._format_uri_for_marklogic(judgment_uri)
|
|
893
|
+
vars: query_dicts.GetPropertyAsNodeDict = {
|
|
894
|
+
"uri": uri,
|
|
895
|
+
"name": name,
|
|
896
|
+
}
|
|
897
|
+
value = self._eval_and_decode(vars, "get_property_as_node.xqy")
|
|
898
|
+
if not value:
|
|
899
|
+
return None
|
|
900
|
+
return etree.fromstring(value)
|
|
901
|
+
|
|
853
902
|
def get_version_annotation(self, judgment_uri: DocumentURIString) -> str:
|
|
854
903
|
uri = self._format_uri_for_marklogic(judgment_uri)
|
|
855
904
|
vars: query_dicts.GetVersionAnnotationDict = {
|
|
@@ -882,6 +931,22 @@ class MarklogicApiClient:
|
|
|
882
931
|
|
|
883
932
|
return self._send_to_eval(vars, "set_property.xqy")
|
|
884
933
|
|
|
934
|
+
def set_property_as_node(
|
|
935
|
+
self,
|
|
936
|
+
judgment_uri: DocumentURIString,
|
|
937
|
+
name: str,
|
|
938
|
+
value: etree._Element,
|
|
939
|
+
) -> requests.Response:
|
|
940
|
+
"""Given a root node, set the value of the MarkLogic property for a document to the _contents_ of that root node. The root node itself is discarded."""
|
|
941
|
+
uri = self._format_uri_for_marklogic(judgment_uri)
|
|
942
|
+
vars: query_dicts.SetPropertyAsNodeDict = {
|
|
943
|
+
"uri": uri,
|
|
944
|
+
"value": etree.tostring(value).decode(),
|
|
945
|
+
"name": name,
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
return self._send_to_eval(vars, "set_property_as_node.xqy")
|
|
949
|
+
|
|
885
950
|
def set_boolean_property(
|
|
886
951
|
self,
|
|
887
952
|
judgment_uri: DocumentURIString,
|
|
@@ -895,12 +960,50 @@ class MarklogicApiClient:
|
|
|
895
960
|
"value": string_value,
|
|
896
961
|
"name": name,
|
|
897
962
|
}
|
|
963
|
+
"""
|
|
964
|
+
Set a property within MarkLogic which is specifically a boolean.
|
|
965
|
+
|
|
966
|
+
Since XML has no concept of boolean, the actual value in the database is set to `"true"` or `"false"`.
|
|
967
|
+
"""
|
|
898
968
|
return self._send_to_eval(vars, "set_boolean_property.xqy")
|
|
899
969
|
|
|
900
970
|
def get_boolean_property(self, judgment_uri: DocumentURIString, name: str) -> bool:
|
|
971
|
+
"""
|
|
972
|
+
Get a property from MarkLogic which is specifically a boolean.
|
|
973
|
+
|
|
974
|
+
:return: `True` if the property exists and has a value of `"true"`, otherwise `False`
|
|
975
|
+
"""
|
|
901
976
|
content = self.get_property(judgment_uri, name)
|
|
902
977
|
return content == "true"
|
|
903
978
|
|
|
979
|
+
def set_datetime_property(
|
|
980
|
+
self,
|
|
981
|
+
judgment_uri: DocumentURIString,
|
|
982
|
+
name: str,
|
|
983
|
+
value: datetime,
|
|
984
|
+
) -> requests.Response:
|
|
985
|
+
"""Set a property within MarkLogic which is specifically a datetime."""
|
|
986
|
+
uri = self._format_uri_for_marklogic(judgment_uri)
|
|
987
|
+
vars: query_dicts.SetDatetimePropertyDict = {
|
|
988
|
+
"uri": uri,
|
|
989
|
+
"value": value.isoformat(),
|
|
990
|
+
"name": name,
|
|
991
|
+
}
|
|
992
|
+
return self._send_to_eval(vars, "set_datetime_property.xqy")
|
|
993
|
+
|
|
994
|
+
def get_datetime_property(self, judgment_uri: DocumentURIString, name: str) -> Optional[datetime]:
|
|
995
|
+
"""
|
|
996
|
+
Get a property from MarkLogic which is specifically a datetime.
|
|
997
|
+
|
|
998
|
+
:return: A datetime with the value of the property, or `None` if it does not exist
|
|
999
|
+
"""
|
|
1000
|
+
content = self.get_property(judgment_uri, name)
|
|
1001
|
+
|
|
1002
|
+
if content:
|
|
1003
|
+
return isoparse(content)
|
|
1004
|
+
|
|
1005
|
+
return None
|
|
1006
|
+
|
|
904
1007
|
def set_published(
|
|
905
1008
|
self,
|
|
906
1009
|
judgment_uri: DocumentURIString,
|
|
@@ -1009,10 +1112,6 @@ class MarklogicApiClient:
|
|
|
1009
1112
|
if show_unpublished and not self.user_can_view_unpublished_judgments(
|
|
1010
1113
|
self.username,
|
|
1011
1114
|
):
|
|
1012
|
-
# The user cannot view unpublished judgments but is requesting to see them
|
|
1013
|
-
logging.warning(
|
|
1014
|
-
f"User {self.username} is attempting to view unpublished judgments but does not have that privilege.",
|
|
1015
|
-
)
|
|
1016
1115
|
return False
|
|
1017
1116
|
return show_unpublished
|
|
1018
1117
|
|
|
@@ -1025,14 +1124,14 @@ class MarklogicApiClient:
|
|
|
1025
1124
|
response = self._send_to_eval(vars, "get_properties_for_search_results.xqy")
|
|
1026
1125
|
return get_single_string_from_marklogic_response(response)
|
|
1027
1126
|
|
|
1028
|
-
def search_and_decode_response(self, search_parameters: SearchParameters) ->
|
|
1127
|
+
def search_and_decode_response(self, search_parameters: SearchParameters) -> bytes:
|
|
1029
1128
|
response = self.advanced_search(search_parameters)
|
|
1030
|
-
return
|
|
1129
|
+
return get_single_bytestring_from_marklogic_response(response)
|
|
1031
1130
|
|
|
1032
1131
|
def search_judgments_and_decode_response(
|
|
1033
1132
|
self,
|
|
1034
1133
|
search_parameters: SearchParameters,
|
|
1035
|
-
) ->
|
|
1134
|
+
) -> bytes:
|
|
1036
1135
|
search_parameters.collections = [DOCUMENT_COLLECTION_URI_JUDGMENT]
|
|
1037
1136
|
return self.search_and_decode_response(search_parameters)
|
|
1038
1137
|
|
|
@@ -1074,6 +1173,7 @@ class MarklogicApiClient:
|
|
|
1074
1173
|
self,
|
|
1075
1174
|
target_enrichment_version: tuple[int, int],
|
|
1076
1175
|
target_parser_version: tuple[int, int],
|
|
1176
|
+
maximum_records: int = 1000,
|
|
1077
1177
|
) -> list[list[Any]]:
|
|
1078
1178
|
"""Retrieve documents which are not yet enriched with a given version."""
|
|
1079
1179
|
vars: query_dicts.GetPendingEnrichmentForVersionDict = {
|
|
@@ -1081,6 +1181,7 @@ class MarklogicApiClient:
|
|
|
1081
1181
|
"target_enrichment_minor_version": target_enrichment_version[1],
|
|
1082
1182
|
"target_parser_major_version": target_parser_version[0],
|
|
1083
1183
|
"target_parser_minor_version": target_parser_version[1],
|
|
1184
|
+
"maximum_records": maximum_records,
|
|
1084
1185
|
}
|
|
1085
1186
|
results: list[list[Any]] = json.loads(
|
|
1086
1187
|
get_single_string_from_marklogic_response(
|
|
@@ -1093,6 +1194,21 @@ class MarklogicApiClient:
|
|
|
1093
1194
|
|
|
1094
1195
|
return results
|
|
1095
1196
|
|
|
1197
|
+
def get_recently_enriched(
|
|
1198
|
+
self,
|
|
1199
|
+
) -> list[list[Any]]:
|
|
1200
|
+
"""Retrieve documents which are not yet enriched with a given version."""
|
|
1201
|
+
results: list[list[Any]] = json.loads(
|
|
1202
|
+
get_single_string_from_marklogic_response(
|
|
1203
|
+
self._send_to_eval(
|
|
1204
|
+
{},
|
|
1205
|
+
"get_recently_enriched.xqy",
|
|
1206
|
+
),
|
|
1207
|
+
),
|
|
1208
|
+
)
|
|
1209
|
+
|
|
1210
|
+
return results
|
|
1211
|
+
|
|
1096
1212
|
def get_highest_parser_version(self) -> tuple[int, int]:
|
|
1097
1213
|
"""This gets the highest parser version in the database, so if nothing has been parsed with the most recent version of the parser, this won't reflect that change."""
|
|
1098
1214
|
table = json.loads(
|
|
@@ -1109,11 +1225,13 @@ class MarklogicApiClient:
|
|
|
1109
1225
|
def get_pending_parse_for_version(
|
|
1110
1226
|
self,
|
|
1111
1227
|
target_version: tuple[int, int],
|
|
1228
|
+
maximum_records: int = 1000,
|
|
1112
1229
|
) -> list[list[Any]]:
|
|
1113
1230
|
"""Retrieve documents which are not yet parsed with a given version."""
|
|
1114
1231
|
vars: query_dicts.GetPendingParseForVersionDict = {
|
|
1115
1232
|
"target_major_version": target_version[0],
|
|
1116
1233
|
"target_minor_version": target_version[1],
|
|
1234
|
+
"maximum_records": maximum_records,
|
|
1117
1235
|
}
|
|
1118
1236
|
results: list[list[Any]] = json.loads(
|
|
1119
1237
|
get_single_string_from_marklogic_response(
|
|
@@ -1125,3 +1243,74 @@ class MarklogicApiClient:
|
|
|
1125
1243
|
)
|
|
1126
1244
|
|
|
1127
1245
|
return results
|
|
1246
|
+
|
|
1247
|
+
def get_recently_parsed(
|
|
1248
|
+
self,
|
|
1249
|
+
) -> list[list[Any]]:
|
|
1250
|
+
"""Retrieve documents which are not yet enriched with a given version."""
|
|
1251
|
+
results: list[list[Any]] = json.loads(
|
|
1252
|
+
get_single_string_from_marklogic_response(
|
|
1253
|
+
self._send_to_eval(
|
|
1254
|
+
{},
|
|
1255
|
+
"get_recently_parsed.xqy",
|
|
1256
|
+
),
|
|
1257
|
+
),
|
|
1258
|
+
)
|
|
1259
|
+
|
|
1260
|
+
return results
|
|
1261
|
+
|
|
1262
|
+
def get_missing_fclid(
|
|
1263
|
+
self,
|
|
1264
|
+
maximum_records: int = 50,
|
|
1265
|
+
) -> list[str]:
|
|
1266
|
+
"""Retrieve the URIs of published documents which do not have an identifier in the `fclid` schema."""
|
|
1267
|
+
vars: query_dicts.GetMissingFclidDict = {
|
|
1268
|
+
"maximum_records": maximum_records,
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
results: list[str] = get_multipart_strings_from_marklogic_response(
|
|
1272
|
+
self._send_to_eval(
|
|
1273
|
+
vars,
|
|
1274
|
+
"get_missing_fclid.xqy",
|
|
1275
|
+
)
|
|
1276
|
+
)
|
|
1277
|
+
|
|
1278
|
+
return results
|
|
1279
|
+
|
|
1280
|
+
def resolve_from_identifier_slug(
|
|
1281
|
+
self, identifier_slug: DocumentIdentifierSlug, published_only: bool = True
|
|
1282
|
+
) -> IdentifierResolutions:
|
|
1283
|
+
"""Given a PUI/EUI url, look up the precomputed slug and return the
|
|
1284
|
+
MarkLogic document URIs which match that slug. Multiple returns should be anticipated"""
|
|
1285
|
+
vars: query_dicts.ResolveFromIdentifierSlugDict = {
|
|
1286
|
+
"identifier_slug": identifier_slug,
|
|
1287
|
+
"published_only": int(published_only),
|
|
1288
|
+
}
|
|
1289
|
+
raw_results: list[str] = get_multipart_strings_from_marklogic_response(
|
|
1290
|
+
self._send_to_eval(
|
|
1291
|
+
vars,
|
|
1292
|
+
"resolve_from_identifier_slug.xqy",
|
|
1293
|
+
),
|
|
1294
|
+
)
|
|
1295
|
+
return IdentifierResolutions.from_marklogic_output(raw_results)
|
|
1296
|
+
|
|
1297
|
+
def resolve_from_identifier_value(
|
|
1298
|
+
self, identifier_value: DocumentIdentifierValue, published_only: bool = True
|
|
1299
|
+
) -> IdentifierResolutions:
|
|
1300
|
+
"""Given a PUI/EUI url, look up the precomputed slug and return the
|
|
1301
|
+
MarkLogic document URIs which match that slug. Multiple returns should be anticipated"""
|
|
1302
|
+
vars: query_dicts.ResolveFromIdentifierValueDict = {
|
|
1303
|
+
"identifier_value": identifier_value,
|
|
1304
|
+
"published_only": int(published_only),
|
|
1305
|
+
}
|
|
1306
|
+
raw_results: list[str] = get_multipart_strings_from_marklogic_response(
|
|
1307
|
+
self._send_to_eval(
|
|
1308
|
+
vars,
|
|
1309
|
+
"resolve_from_identifier_value.xqy",
|
|
1310
|
+
),
|
|
1311
|
+
)
|
|
1312
|
+
return IdentifierResolutions.from_marklogic_output(raw_results)
|
|
1313
|
+
|
|
1314
|
+
def get_next_document_sequence_number(self) -> int:
|
|
1315
|
+
"""Increment the MarkLogic sequence number by one and return the value."""
|
|
1316
|
+
return int(self._eval_and_decode({}, "get_next_document_sequence_number.xqy"))
|