ds-caselaw-marklogic-api-client 22.0.2__tar.gz → 23.0.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.
Potentially problematic release.
This version of ds-caselaw-marklogic-api-client might be problematic. Click here for more details.
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/PKG-INFO +1 -1
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/pyproject.toml +3 -2
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/Client.py +16 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/models/documents.py +64 -4
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/models/judgments.py +21 -1
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/models/press_summaries.py +23 -1
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/models/utilities/aws.py +15 -1
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/responses/search_response.py +17 -0
- ds_caselaw_marklogic_api_client-23.0.1/src/caselawclient/xquery/validate_document.xqy +7 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery_type_dicts.py +5 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/LICENSE.md +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/README.md +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/client_helpers/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/client_helpers/search_helpers.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/content_hash.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/errors.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/models/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/models/neutral_citation_mixin.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/models/utilities/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/models/utilities/move.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/py.typed +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/responses/__init__.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/responses/search_result.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/responses/xsl/search_match.xsl +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/search_parameters.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xml_helpers.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xml_tools.py +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/break_judgment_checkout.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/checkin_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/checkout_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/copy_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/delete_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/document_collections.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/document_exists.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_combined_stats_table.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_components_for_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_highest_enrichment_version.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_highest_parser_version.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_judgment_checkout_status.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_judgment_version.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_last_modified.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_pending_enrichment_for_version.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_pending_parse_for_version.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_properties_for_search_results.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_property.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_version_annotation.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/get_version_created.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/insert_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/list_judgment_versions.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/set_boolean_property.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/set_metadata_citation.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/set_metadata_court.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/set_metadata_jurisdiction.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/set_metadata_name.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/set_metadata_this_uri.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/set_metadata_work_expression_date.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/set_property.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/update_document.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/update_locked_judgment.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/user_has_privilege.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/user_has_role.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/validate_all_documents.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/xslt.xqy +0 -0
- {ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/src/caselawclient/xquery/xslt_transform.xqy +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ds-caselaw-marklogic-api-client
|
|
3
|
-
Version:
|
|
3
|
+
Version: 23.0.1
|
|
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
|
{ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/pyproject.toml
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "ds-caselaw-marklogic-api-client"
|
|
3
|
-
version = "
|
|
3
|
+
version = "23.0.1"
|
|
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"
|
|
@@ -30,9 +30,10 @@ mypy-boto3-sns = "^1.26.69"
|
|
|
30
30
|
[tool.poetry.group.dev.dependencies]
|
|
31
31
|
coverage = "^7.2.3"
|
|
32
32
|
pytest = "^7.3.2"
|
|
33
|
-
responses = "^0.
|
|
33
|
+
responses = "^0.25.0"
|
|
34
34
|
python-dotenv = "^1.0.0"
|
|
35
35
|
time-machine = "^2.13.0"
|
|
36
|
+
moto = {version = "^5.0.1", extras = ["all"]}
|
|
36
37
|
|
|
37
38
|
[tool.poetry.group.docs]
|
|
38
39
|
optional = true
|
|
@@ -647,6 +647,22 @@ class MarklogicApiClient:
|
|
|
647
647
|
|
|
648
648
|
return self._send_to_eval(vars, "get_judgment_version.xqy")
|
|
649
649
|
|
|
650
|
+
def validate_document(self, document_uri: DocumentURIString) -> bool:
|
|
651
|
+
vars: query_dicts.ValidateDocumentDict = {
|
|
652
|
+
"uri": self._format_uri_for_marklogic(document_uri)
|
|
653
|
+
}
|
|
654
|
+
response = self._send_to_eval(vars, "validate_document.xqy")
|
|
655
|
+
content = decoder.MultipartDecoder.from_response(response).parts[0].text
|
|
656
|
+
xml = ElementTree.fromstring(content)
|
|
657
|
+
return (
|
|
658
|
+
len(
|
|
659
|
+
xml.findall(
|
|
660
|
+
".//error:error", {"error": "http://marklogic.com/xdmp/error"}
|
|
661
|
+
),
|
|
662
|
+
)
|
|
663
|
+
== 0
|
|
664
|
+
)
|
|
665
|
+
|
|
650
666
|
def eval(
|
|
651
667
|
self, xquery_path: str, vars: str, accept_header: str = "multipart/mixed"
|
|
652
668
|
) -> requests.Response:
|
|
@@ -22,6 +22,7 @@ from .utilities import VersionsDict, render_versions
|
|
|
22
22
|
from .utilities.aws import (
|
|
23
23
|
ParserInstructionsDict,
|
|
24
24
|
announce_document_event,
|
|
25
|
+
check_docx_exists,
|
|
25
26
|
delete_documents_from_private_bucket,
|
|
26
27
|
generate_docx_url,
|
|
27
28
|
generate_pdf_url,
|
|
@@ -31,6 +32,8 @@ from .utilities.aws import (
|
|
|
31
32
|
uri_for_s3,
|
|
32
33
|
)
|
|
33
34
|
|
|
35
|
+
MINIMUM_ENRICHMENT_TIME = datetime.timedelta(minutes=20)
|
|
36
|
+
|
|
34
37
|
|
|
35
38
|
class UnparsableDate(Warning):
|
|
36
39
|
pass
|
|
@@ -165,13 +168,17 @@ class Document:
|
|
|
165
168
|
:return: `True` if the document exists, `False` otherwise."""
|
|
166
169
|
return self.api_client.document_exists(self.uri)
|
|
167
170
|
|
|
171
|
+
def docx_exists(self) -> bool:
|
|
172
|
+
"""There is a docx in S3 private bucket for this Document"""
|
|
173
|
+
return check_docx_exists(self.uri)
|
|
174
|
+
|
|
168
175
|
@property
|
|
169
176
|
def best_human_identifier(self) -> Optional[str]:
|
|
170
177
|
"""
|
|
171
178
|
Some identifier that is understood by legal professionals to refer to this legal event
|
|
172
179
|
that is not the name of the document.
|
|
173
180
|
Typically, this will be the neutral citation number, should it exist.
|
|
174
|
-
Should typically overridden in subclasses.
|
|
181
|
+
Should typically be overridden in subclasses.
|
|
175
182
|
"""
|
|
176
183
|
return None
|
|
177
184
|
|
|
@@ -270,10 +277,12 @@ class Document:
|
|
|
270
277
|
|
|
271
278
|
@cached_property
|
|
272
279
|
def transformation_datetime(self) -> Optional[datetime.datetime]:
|
|
280
|
+
"""When was this document successfully parsed or reparsed (date from XML)"""
|
|
273
281
|
return self.get_latest_manifestation_datetime("transform")
|
|
274
282
|
|
|
275
283
|
@cached_property
|
|
276
284
|
def enrichment_datetime(self) -> Optional[datetime.datetime]:
|
|
285
|
+
"""When was this document successfully enriched (date from XML)"""
|
|
277
286
|
return self.get_latest_manifestation_datetime("tna-enriched")
|
|
278
287
|
|
|
279
288
|
@cached_property
|
|
@@ -480,9 +489,9 @@ class Document:
|
|
|
480
489
|
|
|
481
490
|
return DOCUMENT_STATUS_NEW
|
|
482
491
|
|
|
483
|
-
def
|
|
492
|
+
def force_enrich(self) -> None:
|
|
484
493
|
"""
|
|
485
|
-
Request enrichment of the document
|
|
494
|
+
Request enrichment of the document, but do no checks
|
|
486
495
|
"""
|
|
487
496
|
now = datetime.datetime.now(datetime.timezone.utc)
|
|
488
497
|
self.api_client.set_property(
|
|
@@ -495,6 +504,42 @@ class Document:
|
|
|
495
504
|
enrich=True,
|
|
496
505
|
)
|
|
497
506
|
|
|
507
|
+
def enrich(self) -> bool:
|
|
508
|
+
"""
|
|
509
|
+
Request enrichment of a document, if it's sensible to do so.
|
|
510
|
+
"""
|
|
511
|
+
if self.can_enrich:
|
|
512
|
+
self.force_enrich()
|
|
513
|
+
return True
|
|
514
|
+
return False
|
|
515
|
+
|
|
516
|
+
@cached_property
|
|
517
|
+
def can_enrich(self) -> bool:
|
|
518
|
+
"""
|
|
519
|
+
Is it sensible to enrich this document?
|
|
520
|
+
"""
|
|
521
|
+
if (self.enriched_recently is False) and self.validates_against_schema:
|
|
522
|
+
return True
|
|
523
|
+
return False
|
|
524
|
+
|
|
525
|
+
@cached_property
|
|
526
|
+
def enriched_recently(self) -> bool:
|
|
527
|
+
"""
|
|
528
|
+
Has this document been enriched recently?
|
|
529
|
+
"""
|
|
530
|
+
last_enrichment = self.enrichment_datetime
|
|
531
|
+
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
|
532
|
+
if last_enrichment and now - last_enrichment < MINIMUM_ENRICHMENT_TIME:
|
|
533
|
+
return True
|
|
534
|
+
return False
|
|
535
|
+
|
|
536
|
+
@cached_property
|
|
537
|
+
def validates_against_schema(self) -> bool:
|
|
538
|
+
"""
|
|
539
|
+
Does the document validate against the most recent schema?
|
|
540
|
+
"""
|
|
541
|
+
return self.api_client.validate_document(self.uri)
|
|
542
|
+
|
|
498
543
|
def publish(self) -> None:
|
|
499
544
|
"""
|
|
500
545
|
:raises CannotPublishUnpublishableDocument: This document has not passed the checks in `is_publishable`, and as
|
|
@@ -553,7 +598,7 @@ class Document:
|
|
|
553
598
|
def move(self, new_citation: str) -> None:
|
|
554
599
|
self.api_client.update_document_uri(self.uri, new_citation)
|
|
555
600
|
|
|
556
|
-
def
|
|
601
|
+
def force_reparse(self) -> None:
|
|
557
602
|
"Send an SNS notification that triggers reparsing, also sending all editor-modifiable metadata and URI"
|
|
558
603
|
|
|
559
604
|
now = datetime.datetime.now(datetime.timezone.utc)
|
|
@@ -589,6 +634,21 @@ class Document:
|
|
|
589
634
|
parser_instructions=parser_instructions,
|
|
590
635
|
)
|
|
591
636
|
|
|
637
|
+
def reparse(self) -> bool:
|
|
638
|
+
if self.can_reparse:
|
|
639
|
+
self.force_reparse()
|
|
640
|
+
return True
|
|
641
|
+
return False
|
|
642
|
+
|
|
643
|
+
@cached_property
|
|
644
|
+
def can_reparse(self) -> bool:
|
|
645
|
+
"""
|
|
646
|
+
Is it sensible to reparse this document?
|
|
647
|
+
"""
|
|
648
|
+
if self.docx_exists():
|
|
649
|
+
return True
|
|
650
|
+
return False
|
|
651
|
+
|
|
592
652
|
class XML:
|
|
593
653
|
"""
|
|
594
654
|
Represents the XML of a document, and should contain all methods for interacting with it.
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import importlib
|
|
1
2
|
from functools import cached_property
|
|
2
|
-
from typing import Any
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
3
4
|
|
|
5
|
+
from caselawclient.errors import DocumentNotFoundError
|
|
4
6
|
from caselawclient.models.neutral_citation_mixin import NeutralCitationMixin
|
|
5
7
|
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from caselawclient.models.press_summaries import PressSummary
|
|
10
|
+
|
|
6
11
|
from ..xml_helpers import get_xpath_match_string
|
|
7
12
|
from .documents import Document
|
|
8
13
|
|
|
@@ -32,3 +37,18 @@ class Judgment(NeutralCitationMixin, Document):
|
|
|
32
37
|
@property
|
|
33
38
|
def best_human_identifier(self) -> str:
|
|
34
39
|
return self.neutral_citation
|
|
40
|
+
|
|
41
|
+
@cached_property
|
|
42
|
+
def linked_document(self) -> Optional["PressSummary"]:
|
|
43
|
+
"""
|
|
44
|
+
Attempt to fetch a linked press summary, and return it, if it exists
|
|
45
|
+
"""
|
|
46
|
+
try:
|
|
47
|
+
uri = self.uri + "/press-summary/1"
|
|
48
|
+
PressSummary = getattr(
|
|
49
|
+
importlib.import_module("caselawclient.models.press_summaries"),
|
|
50
|
+
"PressSummary",
|
|
51
|
+
)
|
|
52
|
+
return PressSummary(uri, self.api_client) # type: ignore
|
|
53
|
+
except DocumentNotFoundError:
|
|
54
|
+
return None
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
1
4
|
from functools import cached_property
|
|
2
|
-
from typing import Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
3
6
|
|
|
7
|
+
from caselawclient.errors import DocumentNotFoundError
|
|
4
8
|
from caselawclient.models.neutral_citation_mixin import NeutralCitationMixin
|
|
5
9
|
from caselawclient.xml_helpers import get_xpath_match_string
|
|
6
10
|
|
|
7
11
|
from .documents import Document
|
|
8
12
|
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from caselawclient.models.judgments import Judgment
|
|
15
|
+
|
|
9
16
|
|
|
10
17
|
class PressSummary(NeutralCitationMixin, Document):
|
|
11
18
|
"""
|
|
@@ -31,3 +38,18 @@ class PressSummary(NeutralCitationMixin, Document):
|
|
|
31
38
|
@property
|
|
32
39
|
def best_human_identifier(self) -> str:
|
|
33
40
|
return self.neutral_citation
|
|
41
|
+
|
|
42
|
+
@cached_property
|
|
43
|
+
def linked_document(self) -> Optional["Judgment"]:
|
|
44
|
+
"""
|
|
45
|
+
Attempt to fetch a linked judgement, and return it, if it exists
|
|
46
|
+
"""
|
|
47
|
+
try:
|
|
48
|
+
uri = self.uri.removesuffix("/press-summary/1")
|
|
49
|
+
Judgment = getattr(
|
|
50
|
+
importlib.import_module("caselawclient.models.judgments"),
|
|
51
|
+
"Judgment",
|
|
52
|
+
)
|
|
53
|
+
return Judgment(uri, self.api_client) # type: ignore
|
|
54
|
+
except DocumentNotFoundError:
|
|
55
|
+
return None
|
|
@@ -78,6 +78,20 @@ def generate_signed_asset_url(key: str) -> str:
|
|
|
78
78
|
)
|
|
79
79
|
|
|
80
80
|
|
|
81
|
+
def check_docx_exists(uri: str) -> bool:
|
|
82
|
+
"""Does the docx for a document URI actually exist?"""
|
|
83
|
+
bucket = env("PRIVATE_ASSET_BUCKET", None)
|
|
84
|
+
s3_key = generate_docx_key(uri)
|
|
85
|
+
client = create_s3_client()
|
|
86
|
+
try:
|
|
87
|
+
client.head_object(Bucket=bucket, Key=s3_key)
|
|
88
|
+
return True
|
|
89
|
+
except botocore.exceptions.ClientError as e:
|
|
90
|
+
if e.response["Error"]["Code"] == "404":
|
|
91
|
+
return False
|
|
92
|
+
raise
|
|
93
|
+
|
|
94
|
+
|
|
81
95
|
def generate_docx_key(uri: str) -> str:
|
|
82
96
|
"""from a canonical caselaw URI (eat/2022/1) return the S3 key of the associated docx"""
|
|
83
97
|
return f'{uri}/{uri.replace("/", "_")}.docx'
|
|
@@ -227,7 +241,7 @@ def request_parse(
|
|
|
227
241
|
.replace("+00:00", "Z"),
|
|
228
242
|
"function": "fcl-judgment-parse-request",
|
|
229
243
|
"producer": "FCL",
|
|
230
|
-
"executionId":
|
|
244
|
+
"executionId": str(uuid.uuid4()),
|
|
231
245
|
"parentExecutionId": None,
|
|
232
246
|
},
|
|
233
247
|
"parameters": {
|
|
@@ -45,3 +45,20 @@ class SearchResponse:
|
|
|
45
45
|
"//search:response/search:result", namespaces=self.NAMESPACES
|
|
46
46
|
)
|
|
47
47
|
return [SearchResult(result, self.client) for result in results]
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def facets(self) -> dict[str, str]:
|
|
51
|
+
"""
|
|
52
|
+
Returns search facets from the SearchResponse as a dictionary
|
|
53
|
+
|
|
54
|
+
:return: A flattened dictionary of search facet values
|
|
55
|
+
"""
|
|
56
|
+
# TODO: preserve the name of the facet (e.g. "court", "year")
|
|
57
|
+
results = self.node.xpath(
|
|
58
|
+
"//search:response/search:facet/search:facet-value",
|
|
59
|
+
namespaces={"search": "http://marklogic.com/appservices/search"},
|
|
60
|
+
)
|
|
61
|
+
facets_dictionary = {
|
|
62
|
+
result.attrib["name"]: result.attrib["count"] for result in results
|
|
63
|
+
}
|
|
64
|
+
return facets_dictionary
|
|
@@ -211,6 +211,11 @@ class UserHasRoleDict(MarkLogicAPIDict):
|
|
|
211
211
|
user: str
|
|
212
212
|
|
|
213
213
|
|
|
214
|
+
# validate_document.xqy
|
|
215
|
+
class ValidateDocumentDict(MarkLogicAPIDict):
|
|
216
|
+
uri: MarkLogicDocumentURIString
|
|
217
|
+
|
|
218
|
+
|
|
214
219
|
# xslt.xqy
|
|
215
220
|
class XsltDict(MarkLogicAPIDict):
|
|
216
221
|
uri: MarkLogicDocumentURIString
|
{ds_caselaw_marklogic_api_client-22.0.2 → ds_caselaw_marklogic_api_client-23.0.1}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|