ds-caselaw-marklogic-api-client 17.3.0__tar.gz → 18.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.
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/PKG-INFO +2 -2
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/pyproject.toml +2 -2
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/Client.py +0 -14
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/__init__.py +0 -20
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/client_helpers/search_helpers.py +10 -4
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/models/documents.py +60 -28
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/models/judgments.py +1 -1
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/models/press_summaries.py +1 -1
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/models/utilities/__init__.py +0 -9
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/responses/search_response.py +4 -16
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/responses/search_result.py +10 -22
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/LICENSE.md +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/README.md +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/client_helpers/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/content_hash.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/errors.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/models/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/models/neutral_citation_mixin.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/models/utilities/aws.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/models/utilities/move.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/py.typed +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/responses/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/responses/xsl/search_match.xsl +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/search_parameters.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xml_helpers.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xml_tools.py +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/break_judgment_checkout.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/checkin_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/checkout_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/copy_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/delete_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/document_collections.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/document_exists.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/get_combined_stats_table.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/get_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/get_judgment_checkout_status.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/get_judgment_version.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/get_last_modified.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/get_properties_for_search_results.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/get_property.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/get_version_annotation.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/get_version_created.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/insert_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/list_judgment_versions.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/set_boolean_property.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/set_metadata_citation.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/set_metadata_court.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/set_metadata_name.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/set_metadata_this_uri.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/set_metadata_work_expression_date.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/set_property.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/update_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/update_locked_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/user_has_privilege.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/user_has_role.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/validate_all_documents.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/xslt.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery/xslt_transform.xqy +0 -0
- {ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/src/caselawclient/xquery_type_dicts.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ds-caselaw-marklogic-api-client
|
|
3
|
-
Version:
|
|
3
|
+
Version: 18.0.0
|
|
4
4
|
Summary: An API client for interacting with the underlying data in Find Caselaw.
|
|
5
5
|
Home-page: https://github.com/nationalarchives/ds-caselaw-custom-api-client
|
|
6
6
|
Keywords: national archives,caselaw
|
|
@@ -14,7 +14,7 @@ Requires-Dist: boto3 (>=1.26.112,<2.0.0)
|
|
|
14
14
|
Requires-Dist: certifi (>=2022.12.7,<2024.0.0)
|
|
15
15
|
Requires-Dist: charset-normalizer (>=3.0.0,<4.0.0)
|
|
16
16
|
Requires-Dist: django-environ (>=0.11.0,<0.12.0)
|
|
17
|
-
Requires-Dist: ds-caselaw-utils (>=1.3.
|
|
17
|
+
Requires-Dist: ds-caselaw-utils (>=1.3.3,<2.0.0)
|
|
18
18
|
Requires-Dist: idna (>=3.4,<4.0)
|
|
19
19
|
Requires-Dist: lxml (>=4.9.2,<5.0.0)
|
|
20
20
|
Requires-Dist: memoization (>=0.4.0,<0.5.0)
|
{ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.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 = "18.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"
|
|
@@ -21,7 +21,7 @@ requests-toolbelt = ">=0.10.1,<1.1.0"
|
|
|
21
21
|
urllib3 = "^1.26.15"
|
|
22
22
|
memoization = "^0.4.0"
|
|
23
23
|
lxml = "^4.9.2"
|
|
24
|
-
ds-caselaw-utils = "^1.3.
|
|
24
|
+
ds-caselaw-utils = "^1.3.3"
|
|
25
25
|
boto3 = "^1.26.112"
|
|
26
26
|
typing-extensions = "^4.7.1"
|
|
27
27
|
mypy-boto3-s3 = "^1.26.104"
|
|
@@ -951,17 +951,3 @@ class MarklogicApiClient:
|
|
|
951
951
|
)
|
|
952
952
|
|
|
953
953
|
return results
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
api_client = MarklogicApiClient(
|
|
957
|
-
host=env("MARKLOGIC_HOST", default=None),
|
|
958
|
-
username=env("MARKLOGIC_USER", default=None),
|
|
959
|
-
password=env("MARKLOGIC_PASSWORD", default=None),
|
|
960
|
-
use_https=env("MARKLOGIC_USE_HTTPS", default=False),
|
|
961
|
-
)
|
|
962
|
-
"""
|
|
963
|
-
An instance of the API client which is automatically initialised on importing the library.
|
|
964
|
-
|
|
965
|
-
.. deprecated:: 13.0.1
|
|
966
|
-
You should instead initialise your own instance of `MarklogicApiClient`
|
|
967
|
-
"""
|
|
@@ -37,24 +37,4 @@ client = MarklogicApiClient(
|
|
|
37
37
|
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
## (Deprecated) Use in-library client instance
|
|
41
|
-
|
|
42
|
-
This library will automatically initialise an instance of the client. This functionality is deprecated, and will be
|
|
43
|
-
removed.
|
|
44
|
-
|
|
45
|
-
The client expects the following environment variables to be set or defined in a `.env` file:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
MARKLOGIC_HOST
|
|
49
|
-
MARKLOGIC_USER
|
|
50
|
-
MARKLOGIC_PASSWORD
|
|
51
|
-
MARKLOGIC_USE_HTTPS # Optional, defaults to False
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Then import `api_client` from `caselawclient.Client`:
|
|
55
|
-
|
|
56
|
-
```python
|
|
57
|
-
from caselawclient.Client import api_client
|
|
58
|
-
```
|
|
59
|
-
|
|
60
40
|
"""
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from lxml import etree
|
|
2
|
+
|
|
1
3
|
from caselawclient.Client import MarklogicApiClient
|
|
2
4
|
from caselawclient.responses.search_response import SearchResponse
|
|
3
5
|
from caselawclient.search_parameters import SearchParameters
|
|
@@ -14,8 +16,11 @@ def search_judgments_and_parse_response(
|
|
|
14
16
|
|
|
15
17
|
:return: The parsed search response as a SearchResponse object
|
|
16
18
|
"""
|
|
17
|
-
return SearchResponse
|
|
18
|
-
|
|
19
|
+
return SearchResponse(
|
|
20
|
+
etree.fromstring(
|
|
21
|
+
api_client.search_judgments_and_decode_response(search_parameters)
|
|
22
|
+
),
|
|
23
|
+
api_client,
|
|
19
24
|
)
|
|
20
25
|
|
|
21
26
|
|
|
@@ -30,6 +35,7 @@ def search_and_parse_response(
|
|
|
30
35
|
|
|
31
36
|
:return: The parsed search response as a SearchResponse object
|
|
32
37
|
"""
|
|
33
|
-
return SearchResponse
|
|
34
|
-
api_client.search_and_decode_response(search_parameters)
|
|
38
|
+
return SearchResponse(
|
|
39
|
+
etree.fromstring(api_client.search_and_decode_response(search_parameters)),
|
|
40
|
+
api_client,
|
|
35
41
|
)
|
|
@@ -18,7 +18,7 @@ from ..errors import (
|
|
|
18
18
|
OnlySupportedOnVersion,
|
|
19
19
|
)
|
|
20
20
|
from ..xml_helpers import get_xpath_match_string, get_xpath_match_strings
|
|
21
|
-
from .utilities import VersionsDict,
|
|
21
|
+
from .utilities import VersionsDict, render_versions
|
|
22
22
|
from .utilities.aws import (
|
|
23
23
|
ParserInstructionsDict,
|
|
24
24
|
announce_document_event,
|
|
@@ -76,6 +76,12 @@ class DocumentNotSafeForDeletion(Exception):
|
|
|
76
76
|
pass
|
|
77
77
|
|
|
78
78
|
|
|
79
|
+
class NonXMLDocumentError(Exception):
|
|
80
|
+
"""A document cannot be parsed as XML."""
|
|
81
|
+
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
|
|
79
85
|
class Document:
|
|
80
86
|
"""
|
|
81
87
|
A base class from which all other document types are extensions. This class includes the essential methods for
|
|
@@ -142,6 +148,12 @@ class Document:
|
|
|
142
148
|
if not self.document_exists():
|
|
143
149
|
raise DocumentNotFoundError(f"Document {self.uri} does not exist")
|
|
144
150
|
|
|
151
|
+
self.xml = self.XML(
|
|
152
|
+
xml_bytestring=self.api_client.get_judgment_xml_bytestring(
|
|
153
|
+
self.uri, show_unpublished=True
|
|
154
|
+
)
|
|
155
|
+
)
|
|
156
|
+
|
|
145
157
|
def document_exists(self) -> bool:
|
|
146
158
|
"""Helper method to verify the existence of a document within MarkLogic.
|
|
147
159
|
|
|
@@ -167,14 +179,14 @@ class Document:
|
|
|
167
179
|
|
|
168
180
|
@cached_property
|
|
169
181
|
def name(self) -> str:
|
|
170
|
-
return self.
|
|
182
|
+
return self.xml.get_xpath_match_string(
|
|
171
183
|
"/akn:akomaNtoso/akn:*/akn:meta/akn:identification/akn:FRBRWork/akn:FRBRname/@value",
|
|
172
184
|
{"akn": "http://docs.oasis-open.org/legaldocml/ns/akn/3.0"},
|
|
173
185
|
)
|
|
174
186
|
|
|
175
187
|
@cached_property
|
|
176
188
|
def court(self) -> str:
|
|
177
|
-
return self.
|
|
189
|
+
return self.xml.get_xpath_match_string(
|
|
178
190
|
"/akn:akomaNtoso/akn:*/akn:meta/akn:proprietary/uk:court/text()",
|
|
179
191
|
{
|
|
180
192
|
"uk": "https://caselaw.nationalarchives.gov.uk/akn",
|
|
@@ -184,7 +196,7 @@ class Document:
|
|
|
184
196
|
|
|
185
197
|
@cached_property
|
|
186
198
|
def document_date_as_string(self) -> str:
|
|
187
|
-
return self.
|
|
199
|
+
return self.xml.get_xpath_match_string(
|
|
188
200
|
"/akn:akomaNtoso/akn:*/akn:meta/akn:identification/akn:FRBRWork/akn:FRBRdate/@date",
|
|
189
201
|
{"akn": "http://docs.oasis-open.org/legaldocml/ns/akn/3.0"},
|
|
190
202
|
)
|
|
@@ -208,7 +220,7 @@ class Document:
|
|
|
208
220
|
self, name: Optional[str] = None
|
|
209
221
|
) -> list[datetime.datetime]:
|
|
210
222
|
name_filter = f"[@name='{name}']" if name else ""
|
|
211
|
-
iso_datetimes = self.
|
|
223
|
+
iso_datetimes = self.xml.get_xpath_match_strings(
|
|
212
224
|
"/akn:akomaNtoso/akn:*/akn:meta/akn:identification/akn:FRBRManifestation"
|
|
213
225
|
f"/akn:FRBRdate{name_filter}/@date",
|
|
214
226
|
{"akn": "http://docs.oasis-open.org/legaldocml/ns/akn/3.0"},
|
|
@@ -250,6 +262,14 @@ class Document:
|
|
|
250
262
|
def is_held(self) -> bool:
|
|
251
263
|
return self.api_client.get_property(self.uri, "editor-hold") == "true"
|
|
252
264
|
|
|
265
|
+
@cached_property
|
|
266
|
+
def is_locked(self) -> bool:
|
|
267
|
+
return self.checkout_message is not None
|
|
268
|
+
|
|
269
|
+
@cached_property
|
|
270
|
+
def checkout_message(self) -> Optional[str]:
|
|
271
|
+
return self.api_client.get_judgment_checkout_status_message(self.uri)
|
|
272
|
+
|
|
253
273
|
@cached_property
|
|
254
274
|
def source_name(self) -> str:
|
|
255
275
|
return self.api_client.get_property(self.uri, "source-name")
|
|
@@ -324,17 +344,7 @@ class Document:
|
|
|
324
344
|
|
|
325
345
|
@cached_property
|
|
326
346
|
def content_as_xml(self) -> str:
|
|
327
|
-
return self.
|
|
328
|
-
|
|
329
|
-
@cached_property
|
|
330
|
-
def content_as_xml_bytestring(self) -> bytes:
|
|
331
|
-
return self.api_client.get_judgment_xml_bytestring(
|
|
332
|
-
self.uri, show_unpublished=True
|
|
333
|
-
)
|
|
334
|
-
|
|
335
|
-
@cached_property
|
|
336
|
-
def content_as_xml_tree(self) -> Any:
|
|
337
|
-
return etree.fromstring(self.content_as_xml_bytestring)
|
|
347
|
+
return self.xml.xml_as_string
|
|
338
348
|
|
|
339
349
|
def content_as_html(
|
|
340
350
|
self,
|
|
@@ -393,13 +403,10 @@ class Document:
|
|
|
393
403
|
|
|
394
404
|
:return: `True` if there was a complete parser failure, otherwise `False`
|
|
395
405
|
"""
|
|
396
|
-
if "error" in self.
|
|
406
|
+
if "error" in self.xml.root_element:
|
|
397
407
|
return True
|
|
398
408
|
return False
|
|
399
409
|
|
|
400
|
-
def _get_root(self) -> str:
|
|
401
|
-
return get_judgment_root(self.content_as_xml_bytestring)
|
|
402
|
-
|
|
403
410
|
@cached_property
|
|
404
411
|
def has_name(self) -> bool:
|
|
405
412
|
if not self.name:
|
|
@@ -511,14 +518,6 @@ class Document:
|
|
|
511
518
|
else:
|
|
512
519
|
raise DocumentNotSafeForDeletion()
|
|
513
520
|
|
|
514
|
-
def _get_xpath_match_string(self, xpath: str, namespaces: Dict[str, str]) -> str:
|
|
515
|
-
return get_xpath_match_string(self.content_as_xml_tree, xpath, namespaces)
|
|
516
|
-
|
|
517
|
-
def _get_xpath_match_strings(
|
|
518
|
-
self, xpath: str, namespaces: Dict[str, str]
|
|
519
|
-
) -> list[str]:
|
|
520
|
-
return get_xpath_match_strings(self.content_as_xml_tree, xpath, namespaces)
|
|
521
|
-
|
|
522
521
|
def overwrite(self, new_citation: str) -> None:
|
|
523
522
|
self.api_client.overwrite_document(self.uri, new_citation)
|
|
524
523
|
|
|
@@ -556,3 +555,36 @@ class Document:
|
|
|
556
555
|
reference=self.consignment_reference,
|
|
557
556
|
parser_instructions=parser_instructions,
|
|
558
557
|
)
|
|
558
|
+
|
|
559
|
+
class XML:
|
|
560
|
+
"""
|
|
561
|
+
Represents the XML of a document, and should contain all methods for interacting with it.
|
|
562
|
+
"""
|
|
563
|
+
|
|
564
|
+
def __init__(self, xml_bytestring: bytes):
|
|
565
|
+
"""
|
|
566
|
+
:raises NonXMLDocumentError: This document is not valid XML
|
|
567
|
+
"""
|
|
568
|
+
try:
|
|
569
|
+
self.xml_as_tree: etree.Element = etree.fromstring(xml_bytestring)
|
|
570
|
+
except etree.XMLSyntaxError:
|
|
571
|
+
raise NonXMLDocumentError
|
|
572
|
+
|
|
573
|
+
@property
|
|
574
|
+
def xml_as_string(self) -> str:
|
|
575
|
+
"""
|
|
576
|
+
:return: A string representation of this document's XML tree.
|
|
577
|
+
"""
|
|
578
|
+
return str(etree.tostring(self.xml_as_tree).decode(encoding="utf-8"))
|
|
579
|
+
|
|
580
|
+
@property
|
|
581
|
+
def root_element(self) -> str:
|
|
582
|
+
return str(self.xml_as_tree.tag)
|
|
583
|
+
|
|
584
|
+
def get_xpath_match_string(self, xpath: str, namespaces: Dict[str, str]) -> str:
|
|
585
|
+
return get_xpath_match_string(self.xml_as_tree, xpath, namespaces)
|
|
586
|
+
|
|
587
|
+
def get_xpath_match_strings(
|
|
588
|
+
self, xpath: str, namespaces: Dict[str, str]
|
|
589
|
+
) -> list[str]:
|
|
590
|
+
return get_xpath_match_strings(self.xml_as_tree, xpath, namespaces)
|
|
@@ -21,7 +21,7 @@ class Judgment(NeutralCitationMixin, Document):
|
|
|
21
21
|
@cached_property
|
|
22
22
|
def neutral_citation(self) -> str:
|
|
23
23
|
return get_xpath_match_string(
|
|
24
|
-
self.
|
|
24
|
+
self.xml.xml_as_tree,
|
|
25
25
|
"/akn:akomaNtoso/akn:*/akn:meta/akn:proprietary/uk:cite/text()",
|
|
26
26
|
{
|
|
27
27
|
"uk": "https://caselaw.nationalarchives.gov.uk/akn",
|
|
@@ -21,7 +21,7 @@ class PressSummary(NeutralCitationMixin, Document):
|
|
|
21
21
|
@cached_property
|
|
22
22
|
def neutral_citation(self) -> str:
|
|
23
23
|
return get_xpath_match_string(
|
|
24
|
-
self.
|
|
24
|
+
self.xml.xml_as_tree,
|
|
25
25
|
"/akn:akomaNtoso/akn:doc/akn:preface/akn:p/akn:neutralCitation/text()",
|
|
26
26
|
{
|
|
27
27
|
"akn": "http://docs.oasis-open.org/legaldocml/ns/akn/3.0",
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import re
|
|
2
|
-
import xml.etree.ElementTree as ET
|
|
3
2
|
from typing import TypedDict
|
|
4
3
|
|
|
5
4
|
from requests_toolbelt.multipart.decoder import BodyPart
|
|
@@ -12,14 +11,6 @@ akn_namespace = {"akn": "http://docs.oasis-open.org/legaldocml/ns/akn/3.0"}
|
|
|
12
11
|
uk_namespace = {"uk": "https://caselaw.nationalarchives.gov.uk/akn"}
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
def get_judgment_root(judgment_xml: bytes) -> str:
|
|
16
|
-
try:
|
|
17
|
-
parsed_xml = ET.XML(judgment_xml)
|
|
18
|
-
return parsed_xml.tag
|
|
19
|
-
except ET.ParseError:
|
|
20
|
-
return "error"
|
|
21
|
-
|
|
22
|
-
|
|
23
14
|
class VersionsDict(TypedDict):
|
|
24
15
|
uri: str
|
|
25
16
|
version: int
|
|
@@ -2,6 +2,7 @@ from typing import List
|
|
|
2
2
|
|
|
3
3
|
from lxml import etree
|
|
4
4
|
|
|
5
|
+
from caselawclient.Client import MarklogicApiClient
|
|
5
6
|
from caselawclient.responses.search_result import SearchResult
|
|
6
7
|
|
|
7
8
|
|
|
@@ -13,22 +14,14 @@ class SearchResponse:
|
|
|
13
14
|
NAMESPACES = {"search": "http://marklogic.com/appservices/search"}
|
|
14
15
|
""" Namespaces used in XPath expressions."""
|
|
15
16
|
|
|
16
|
-
def __init__(self, node: etree._Element) -> None:
|
|
17
|
+
def __init__(self, node: etree._Element, client: MarklogicApiClient) -> None:
|
|
17
18
|
"""
|
|
18
19
|
Initializes a SearchResponse instance from an xml node.
|
|
19
20
|
|
|
20
21
|
:param node: The XML data as an etree element
|
|
21
22
|
"""
|
|
22
23
|
self.node = node
|
|
23
|
-
|
|
24
|
-
@staticmethod
|
|
25
|
-
def from_response_string(xml: str) -> "SearchResponse":
|
|
26
|
-
"""
|
|
27
|
-
Constructs a SearchResponse instance from an xml response string.
|
|
28
|
-
|
|
29
|
-
:param xml: The XML data as a string
|
|
30
|
-
"""
|
|
31
|
-
return SearchResponse(etree.fromstring(xml))
|
|
24
|
+
self.client = client
|
|
32
25
|
|
|
33
26
|
@property
|
|
34
27
|
def total(self) -> str:
|
|
@@ -51,9 +44,4 @@ class SearchResponse:
|
|
|
51
44
|
results = self.node.xpath(
|
|
52
45
|
"//search:response/search:result", namespaces=self.NAMESPACES
|
|
53
46
|
)
|
|
54
|
-
return [
|
|
55
|
-
SearchResult(
|
|
56
|
-
result,
|
|
57
|
-
)
|
|
58
|
-
for result in results
|
|
59
|
-
]
|
|
47
|
+
return [SearchResult(result, self.client) for result in results]
|
|
@@ -2,6 +2,7 @@ import logging
|
|
|
2
2
|
import os
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from enum import Enum
|
|
5
|
+
from functools import cached_property
|
|
5
6
|
from typing import Dict, Optional
|
|
6
7
|
|
|
7
8
|
from dateutil import parser as dateparser
|
|
@@ -9,7 +10,7 @@ from dateutil.parser import ParserError
|
|
|
9
10
|
from ds_caselaw_utils.courts import Court, CourtNotFoundException, courts
|
|
10
11
|
from lxml import etree
|
|
11
12
|
|
|
12
|
-
from caselawclient.Client import
|
|
13
|
+
from caselawclient.Client import MarklogicApiClient
|
|
13
14
|
from caselawclient.models.documents import DocumentURIString
|
|
14
15
|
from caselawclient.xml_helpers import get_xpath_match_string
|
|
15
16
|
|
|
@@ -44,20 +45,6 @@ class SearchResultMetadata:
|
|
|
44
45
|
self.node = node
|
|
45
46
|
self.last_modified = last_modified
|
|
46
47
|
|
|
47
|
-
@staticmethod
|
|
48
|
-
def create_from_uri(uri: DocumentURIString) -> "SearchResultMetadata":
|
|
49
|
-
"""
|
|
50
|
-
Create a SearchResultMetadata instance from a search result URI.
|
|
51
|
-
|
|
52
|
-
:param uri: The URI of the search result
|
|
53
|
-
|
|
54
|
-
:return: The created SearchResultMetadata instance
|
|
55
|
-
"""
|
|
56
|
-
response_text = api_client.get_properties_for_search_results([uri])
|
|
57
|
-
last_modified = api_client.get_last_modified(uri)
|
|
58
|
-
root = etree.fromstring(response_text)
|
|
59
|
-
return SearchResultMetadata(root, last_modified)
|
|
60
|
-
|
|
61
48
|
@property
|
|
62
49
|
def author(self) -> str:
|
|
63
50
|
"""
|
|
@@ -162,12 +149,13 @@ class SearchResult:
|
|
|
162
149
|
}
|
|
163
150
|
""" Namespace mappings used in XPath expressions. """
|
|
164
151
|
|
|
165
|
-
def __init__(self, node: etree._Element):
|
|
152
|
+
def __init__(self, node: etree._Element, client: MarklogicApiClient):
|
|
166
153
|
"""
|
|
167
154
|
:param node: The XML element representing the search result
|
|
168
155
|
"""
|
|
169
156
|
|
|
170
157
|
self.node = node
|
|
158
|
+
self.client = client
|
|
171
159
|
|
|
172
160
|
@property
|
|
173
161
|
def uri(self) -> DocumentURIString:
|
|
@@ -259,15 +247,15 @@ class SearchResult:
|
|
|
259
247
|
xslt_transform = etree.XSLT(etree.parse(file_path))
|
|
260
248
|
return str(xslt_transform(self.node))
|
|
261
249
|
|
|
262
|
-
@
|
|
250
|
+
@cached_property
|
|
263
251
|
def metadata(self) -> SearchResultMetadata:
|
|
264
252
|
"""
|
|
265
|
-
:return:
|
|
253
|
+
:return: A `SearchResultMetadata` instance representing the metadata of this result
|
|
266
254
|
"""
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
)
|
|
255
|
+
response_text = self.client.get_properties_for_search_results([self.uri])
|
|
256
|
+
last_modified = self.client.get_last_modified(self.uri)
|
|
257
|
+
root = etree.fromstring(response_text)
|
|
258
|
+
return SearchResultMetadata(root, last_modified)
|
|
271
259
|
|
|
272
260
|
def _get_xpath_match_string(self, path: str) -> str:
|
|
273
261
|
return get_xpath_match_string(self.node, path, namespaces=self.NAMESPACES)
|
{ds_caselaw_marklogic_api_client-17.3.0 → ds_caselaw_marklogic_api_client-18.0.0}/LICENSE.md
RENAMED
|
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
|
|
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
|
|
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
|