ds-caselaw-marklogic-api-client 39.2.1__py3-none-any.whl → 41.0.0__py3-none-any.whl

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.

caselawclient/Client.py CHANGED
@@ -11,6 +11,7 @@ from xml.etree.ElementTree import Element
11
11
 
12
12
  import environ
13
13
  import requests
14
+ from dateutil.parser import isoparse
14
15
  from defusedxml import ElementTree
15
16
  from defusedxml.ElementTree import ParseError, fromstring
16
17
  from ds_caselaw_utils.types import NeutralCitationString
@@ -33,6 +34,7 @@ from caselawclient.models.utilities import move
33
34
  from caselawclient.search_parameters import SearchParameters
34
35
  from caselawclient.types import DocumentIdentifierSlug, DocumentIdentifierValue, DocumentURIString
35
36
  from caselawclient.xquery_type_dicts import (
37
+ CheckContentHashUniqueByUriDict,
36
38
  MarkLogicDocumentURIString,
37
39
  MarkLogicDocumentVersionURIString,
38
40
  MarkLogicPrivilegeURIString,
@@ -727,6 +729,14 @@ class MarklogicApiClient:
727
729
  == 0
728
730
  )
729
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
+
730
740
  def eval(
731
741
  self,
732
742
  xquery_path: str,
@@ -948,12 +958,50 @@ class MarklogicApiClient:
948
958
  "value": string_value,
949
959
  "name": name,
950
960
  }
961
+ """
962
+ Set a property within MarkLogic which is specifically a boolean.
963
+
964
+ Since XML has no concept of boolean, the actual value in the database is set to `"true"` or `"false"`.
965
+ """
951
966
  return self._send_to_eval(vars, "set_boolean_property.xqy")
952
967
 
953
968
  def get_boolean_property(self, judgment_uri: DocumentURIString, name: str) -> bool:
969
+ """
970
+ Get a property from MarkLogic which is specifically a boolean.
971
+
972
+ :return: `True` if the property exists and has a value of `"true"`, otherwise `False`
973
+ """
954
974
  content = self.get_property(judgment_uri, name)
955
975
  return content == "true"
956
976
 
977
+ def set_datetime_property(
978
+ self,
979
+ judgment_uri: DocumentURIString,
980
+ name: str,
981
+ value: datetime,
982
+ ) -> requests.Response:
983
+ """Set a property within MarkLogic which is specifically a datetime."""
984
+ uri = self._format_uri_for_marklogic(judgment_uri)
985
+ vars: query_dicts.SetDatetimePropertyDict = {
986
+ "uri": uri,
987
+ "value": value.isoformat(),
988
+ "name": name,
989
+ }
990
+ return self._send_to_eval(vars, "set_datetime_property.xqy")
991
+
992
+ def get_datetime_property(self, judgment_uri: DocumentURIString, name: str) -> Optional[datetime]:
993
+ """
994
+ Get a property from MarkLogic which is specifically a datetime.
995
+
996
+ :return: A datetime with the value of the property, or `None` if it does not exist
997
+ """
998
+ content = self.get_property(judgment_uri, name)
999
+
1000
+ if content:
1001
+ return isoparse(content)
1002
+
1003
+ return None
1004
+
957
1005
  def set_published(
958
1006
  self,
959
1007
  judgment_uri: DocumentURIString,
@@ -95,6 +95,11 @@ class Document:
95
95
  True,
96
96
  "The court for this {document_noun} is not valid",
97
97
  ),
98
+ (
99
+ "has_unique_content_hash",
100
+ True,
101
+ "There is another document with identical content",
102
+ ),
98
103
  ]
99
104
  """
100
105
  A list of tuples in the form:
@@ -305,6 +310,14 @@ class Document:
305
310
  # An empty list (which is falsy) therefore means the judgment can be published safely.
306
311
  return not self.validation_failure_messages
307
312
 
313
+ @cached_property
314
+ def first_published_datetime(self) -> Optional[datetime.datetime]:
315
+ return self.api_client.get_datetime_property(self.uri, "first_published_datetime")
316
+
317
+ @cached_property
318
+ def has_ever_been_published(self) -> bool:
319
+ return self.is_published or self.first_published_datetime is not None
320
+
308
321
  @cached_property
309
322
  def validation_failure_messages(self) -> list[str]:
310
323
  exception_list = []
@@ -317,6 +330,11 @@ class Document:
317
330
  def annotation(self) -> str:
318
331
  return self.api_client.get_version_annotation(self.uri)
319
332
 
333
+ @cached_property
334
+ def has_unique_content_hash(self) -> bool:
335
+ """Check if the content hash of this document is unique compared to all other documents in MarkLogic."""
336
+ return self.api_client.has_unique_content_hash(self.uri)
337
+
320
338
  @cached_property
321
339
  def version_created_datetime(self) -> datetime.datetime:
322
340
  return self.api_client.get_version_created_datetime(self.uri)
@@ -407,6 +425,8 @@ class Document:
407
425
 
408
426
  def publish(self) -> None:
409
427
  """
428
+ Assuming that a document passes pre-publish checks, perform all necessary operations to put it into a published state.
429
+
410
430
  :raises CannotPublishUnpublishableDocument: This document has not passed the checks in `is_publishable`, and as
411
431
  such cannot be published.
412
432
  """
@@ -416,12 +436,25 @@ class Document:
416
436
  ## Make sure the document has an FCLID
417
437
  self.assign_fclid_if_missing()
418
438
 
439
+ ## Copy the document assets into the appropriate place in S3
419
440
  publish_documents(self.uri)
441
+
442
+ ## Set the fact the document is published
420
443
  self.api_client.set_published(self.uri, True)
444
+
445
+ ## If necessary, set the first published date
446
+ if not self.first_published_datetime:
447
+ self.api_client.set_datetime_property(
448
+ self.uri, "first_published_datetime", datetime.datetime.now(datetime.timezone.utc)
449
+ )
450
+
451
+ ## Announce the publication on the event bus
421
452
  announce_document_event(
422
453
  uri=self.uri,
423
454
  status="publish",
424
455
  )
456
+
457
+ ## Send the document off for enrichment, but accept if we can't for any reason
425
458
  self.enrich(accept_failures=True)
426
459
 
427
460
  def unpublish(self) -> None:
@@ -517,14 +550,14 @@ class Document:
517
550
  """
518
551
  Is it sensible to reparse this document?
519
552
  """
520
- return self.docx_exists()
553
+ return self.docx_exists() and not self.body.has_external_data
521
554
 
522
555
  @cached_property
523
556
  def can_enrich(self) -> bool:
524
557
  """
525
558
  Is it possible to enrich this document?
526
559
  """
527
- return self.body.has_content
560
+ return self.body.has_content and not self.body.has_external_data
528
561
 
529
562
  def validate_identifiers(self) -> SuccessFailureMessageTuple:
530
563
  return self.identifiers.perform_all_validations(document_type=type(self), api_client=self.api_client)
@@ -6,9 +6,11 @@ from typing import Optional
6
6
 
7
7
  import pytz
8
8
  from ds_caselaw_utils.types import CourtCode
9
+ from lxml import etree
9
10
  from saxonche import PySaxonProcessor
10
11
 
11
12
  from caselawclient.models.utilities.dates import parse_string_date_as_utc
13
+ from caselawclient.types import DocumentCategory
12
14
 
13
15
  from .xml import XML
14
16
 
@@ -37,6 +39,9 @@ class DocumentBody:
37
39
  def get_xpath_match_strings(self, xpath: str, namespaces: dict[str, str] = DEFAULT_NAMESPACES) -> list[str]:
38
40
  return self._xml.get_xpath_match_strings(xpath, namespaces)
39
41
 
42
+ def get_xpath_nodes(self, xpath: str, namespaces: dict[str, str] = DEFAULT_NAMESPACES) -> list[etree._Element]:
43
+ return self._xml.get_xpath_nodes(xpath, namespaces)
44
+
40
45
  @cached_property
41
46
  def name(self) -> str:
42
47
  return self.get_xpath_match_string(
@@ -51,9 +56,46 @@ class DocumentBody:
51
56
  def jurisdiction(self) -> str:
52
57
  return self.get_xpath_match_string("/akn:akomaNtoso/akn:*/akn:meta/akn:proprietary/uk:jurisdiction/text()")
53
58
 
59
+ @cached_property
60
+ def categories(self) -> list[DocumentCategory]:
61
+ xpath = "/akn:akomaNtoso/akn:*/akn:meta/akn:proprietary/uk:category"
62
+ nodes = self.get_xpath_nodes(xpath, DEFAULT_NAMESPACES)
63
+
64
+ categories: dict[str, DocumentCategory] = {}
65
+ children_map: dict[str, list[DocumentCategory]] = {}
66
+
67
+ for node in nodes:
68
+ name = node.text
69
+ if name is None or not name.strip():
70
+ continue
71
+
72
+ category = DocumentCategory(name=name)
73
+ categories[name] = category
74
+
75
+ parent = node.get("parent")
76
+
77
+ if parent:
78
+ children_map.setdefault(parent, []).append(category)
79
+
80
+ for parent, subcategories in children_map.items():
81
+ if parent in categories:
82
+ categories[parent].subcategories.extend(subcategories)
83
+
84
+ top_level_categories = [
85
+ categories[name]
86
+ for node in nodes
87
+ if node.get("parent") is None
88
+ if (name := node.text) and name in categories
89
+ ]
90
+
91
+ return top_level_categories
92
+
93
+ # NOTE: Deprecated - use categories function
54
94
  @cached_property
55
95
  def category(self) -> Optional[str]:
56
- return self.get_xpath_match_string("/akn:akomaNtoso/akn:*/akn:meta/akn:proprietary/uk:category/text()")
96
+ return self.get_xpath_match_string(
97
+ "/akn:akomaNtoso/akn:*/akn:meta/akn:proprietary/uk:category[not(@parent)][1]/text()"
98
+ )
57
99
 
58
100
  @cached_property
59
101
  def case_number(self) -> Optional[str]:
@@ -144,6 +186,13 @@ class DocumentBody:
144
186
 
145
187
  return False
146
188
 
189
+ @cached_property
190
+ def has_external_data(self) -> bool:
191
+ """Is there data which is not present within the source document:
192
+ is there a spreadsheet which has populated some fields. The current implementation
193
+ "is there a uk:party tag" is intended as a stopgap whilst we're not importing that data."""
194
+ return bool(self._xml.xml_as_tree.xpath("//uk:party", namespaces=DEFAULT_NAMESPACES))
195
+
147
196
  @cache
148
197
  def content_html(self, image_prefix: str) -> Optional[str]:
149
198
  """Convert the XML representation of the Document into HTML for rendering."""
@@ -2,7 +2,7 @@ import os
2
2
 
3
3
  from lxml import etree
4
4
 
5
- from caselawclient.xml_helpers import get_xpath_match_string, get_xpath_match_strings
5
+ from caselawclient.xml_helpers import get_xpath_match_string, get_xpath_match_strings, get_xpath_nodes
6
6
 
7
7
 
8
8
  def _xslt_path(xslt_file_name: str) -> str:
@@ -50,6 +50,9 @@ class XML:
50
50
  ) -> list[str]:
51
51
  return get_xpath_match_strings(self.xml_as_tree, xpath, namespaces)
52
52
 
53
+ def get_xpath_nodes(self, xpath: str, namespaces: dict[str, str]) -> list[etree._Element]:
54
+ return get_xpath_nodes(self.xml_as_tree, xpath, namespaces)
55
+
53
56
  def _modified(
54
57
  self,
55
58
  xslt: str,
@@ -46,7 +46,10 @@ class IdentifierSchema(ABC):
46
46
  """ Should editors be allowed to manually manipulate identifiers under this schema? """
47
47
 
48
48
  require_globally_unique: bool = True
49
- """ Must this identifier be globally unique? """
49
+ """ Must this identifier be globally unique? (appear on no other documents) """
50
+
51
+ allow_multiple: bool = False
52
+ """ May documents have more than one non-deprecated identifier of this type? """
50
53
 
51
54
  document_types: Optional[list[str]] = None
52
55
  """
@@ -43,6 +43,8 @@ class IdentifiersCollection(dict[str, Identifier]):
43
43
  """Check that only one non-deprecated identifier exists per schema where that schema does not allow multiples."""
44
44
 
45
45
  for schema, identifiers in self._list_all_identifiers_by_schema().items():
46
+ if schema.allow_multiple:
47
+ continue
46
48
  non_deprecated_identifiers = [i for i in identifiers if not i.deprecated]
47
49
  if len(non_deprecated_identifiers) > 1:
48
50
  return SuccessFailureMessageTuple(
@@ -2,6 +2,7 @@ import datetime
2
2
  import json
3
3
  import logging
4
4
  import uuid
5
+ from collections.abc import Callable
5
6
  from typing import Any, Literal, Optional, TypedDict, overload
6
7
 
7
8
  import boto3
@@ -118,11 +119,20 @@ def generate_pdf_url(uri: DocumentURIString) -> str:
118
119
 
119
120
 
120
121
  def delete_from_bucket(uri: DocumentURIString, bucket: str) -> None:
122
+ delete_some_from_bucket(uri=uri, bucket=bucket, filter=lambda x: True)
123
+
124
+
125
+ def delete_some_from_bucket(
126
+ uri: DocumentURIString, bucket: str, filter: Callable[[ObjectIdentifierTypeDef], bool]
127
+ ) -> None:
121
128
  client = create_s3_client()
122
129
  response = client.list_objects(Bucket=bucket, Prefix=uri_for_s3(uri))
123
130
 
124
131
  if response.get("Contents"):
125
- objects_to_delete: list[ObjectIdentifierTypeDef] = [{"Key": obj["Key"]} for obj in response.get("Contents", [])]
132
+ objects_to_maybe_delete: list[ObjectIdentifierTypeDef] = [
133
+ {"Key": obj["Key"]} for obj in response.get("Contents", [])
134
+ ]
135
+ objects_to_delete = [obj for obj in objects_to_maybe_delete if filter(obj)]
126
136
  client.delete_objects(
127
137
  Bucket=bucket,
128
138
  Delete={
@@ -131,6 +141,10 @@ def delete_from_bucket(uri: DocumentURIString, bucket: str) -> None:
131
141
  )
132
142
 
133
143
 
144
+ def delete_non_targz_from_bucket(uri: DocumentURIString, bucket: str) -> None:
145
+ delete_some_from_bucket(uri=uri, bucket=bucket, filter=lambda x: not x["Key"].endswith(".tar.gz"))
146
+
147
+
134
148
  def publish_documents(uri: DocumentURIString) -> None:
135
149
  """
136
150
  Copy assets from the unpublished bucket to the published one.
@@ -13,6 +13,8 @@ from lxml import etree
13
13
 
14
14
  from caselawclient.Client import MarklogicApiClient
15
15
  from caselawclient.models.identifiers.collection import IdentifiersCollection
16
+ from caselawclient.models.identifiers.neutral_citation import NeutralCitationNumber
17
+ from caselawclient.models.identifiers.press_summary_ncn import PressSummaryRelatedNCNIdentifier
16
18
  from caselawclient.models.identifiers.unpacker import unpack_all_identifiers_from_etree
17
19
  from caselawclient.types import DocumentURIString
18
20
  from caselawclient.xml_helpers import get_xpath_match_string
@@ -196,14 +198,18 @@ class SearchResult:
196
198
  return str(preferred.url_slug)
197
199
 
198
200
  @property
199
- def neutral_citation(self) -> str:
201
+ def neutral_citation(self) -> Optional[str]:
200
202
  """
201
- :return: The neutral citation of the search result, or the judgment it is a press summary of.
203
+ :return: If present, the value of preferred neutral citation of the document.
202
204
  """
203
205
 
204
- return self._get_xpath_match_string(
205
- "search:extracted/uk:cite/text()",
206
- ) or self._get_xpath_match_string("search:extracted/akn:neutralCitation/text()")
206
+ preferred_ncn = self.identifiers.preferred(type=NeutralCitationNumber)
207
+
208
+ # If the result doesn't have a preferred NCN, maybe it has a preferred press summary related NCN?
209
+ if not preferred_ncn:
210
+ preferred_ncn = self.identifiers.preferred(type=PressSummaryRelatedNCNIdentifier)
211
+
212
+ return preferred_ncn.value if preferred_ncn else None
207
213
 
208
214
  @property
209
215
  def name(self) -> str:
caselawclient/types.py CHANGED
@@ -1,6 +1,13 @@
1
+ from dataclasses import dataclass, field
1
2
  from typing import NamedTuple
2
3
 
3
4
 
5
+ @dataclass
6
+ class DocumentCategory:
7
+ name: str
8
+ subcategories: list["DocumentCategory"] = field(default_factory=list)
9
+
10
+
4
11
  class InvalidDocumentURIException(Exception):
5
12
  """The document URI is not valid."""
6
13
 
@@ -7,9 +7,25 @@ DEFAULT_NAMESPACES = {
7
7
  "akn": "http://docs.oasis-open.org/legaldocml/ns/akn/3.0",
8
8
  }
9
9
 
10
+ # _Element is the only class lxml exposes, so need to use the private class for typing
11
+ Element = etree._Element # noqa: SLF001
12
+
13
+
14
+ def get_xpath_nodes(
15
+ node: Element,
16
+ path: str,
17
+ namespaces: Optional[Dict[str, str]] = None,
18
+ ) -> list[Element]:
19
+ result = node.xpath(path, namespaces=namespaces)
20
+
21
+ if not isinstance(result, list) or not all(isinstance(x, Element) for x in result):
22
+ raise TypeError(f"Expected to return list[Element], got {type(result).__name__}")
23
+
24
+ return result
25
+
10
26
 
11
27
  def get_xpath_match_string(
12
- node: etree._Element,
28
+ node: Element,
13
29
  path: str,
14
30
  namespaces: Optional[Dict[str, str]] = None,
15
31
  fallback: str = "",
@@ -18,7 +34,7 @@ def get_xpath_match_string(
18
34
 
19
35
 
20
36
  def get_xpath_match_strings(
21
- node: etree._Element,
37
+ node: Element,
22
38
  path: str,
23
39
  namespaces: Optional[Dict[str, str]] = None,
24
40
  ) -> list[str]:
@@ -0,0 +1,9 @@
1
+ xquery version "1.0-ml";
2
+ declare namespace akn = "http://docs.oasis-open.org/legaldocml/ns/akn/3.0";
3
+ declare namespace uk = "https://caselaw.nationalarchives.gov.uk/akn";
4
+ declare variable $uri as xs:string external;
5
+
6
+ let $doc := doc($uri)
7
+ let $hash := $doc//uk:hash/text()
8
+ let $count := count(cts:search(fn:doc(), cts:element-value-query(xs:QName("uk:hash"), $hash)))
9
+ return $count = 1
@@ -0,0 +1,11 @@
1
+ xquery version "1.0-ml";
2
+
3
+ import module namespace dls = "http://marklogic.com/xdmp/dls" at "/MarkLogic/dls.xqy";
4
+
5
+ declare variable $uri as xs:string external;
6
+ declare variable $value as xs:string external;
7
+ declare variable $name as xs:string external;
8
+
9
+ let $props := ( element {$name}{xs:dateTime($value)} )
10
+
11
+ return dls:document-set-property($uri, $props)
@@ -23,6 +23,11 @@ class BreakJudgmentCheckoutDict(MarkLogicAPIDict):
23
23
  uri: MarkLogicDocumentURIString
24
24
 
25
25
 
26
+ # check_content_hash_unique_by_uri.xqy
27
+ class CheckContentHashUniqueByUriDict(MarkLogicAPIDict):
28
+ uri: MarkLogicDocumentURIString
29
+
30
+
26
31
  # checkin_judgment.xqy
27
32
  class CheckinJudgmentDict(MarkLogicAPIDict):
28
33
  uri: MarkLogicDocumentURIString
@@ -166,6 +171,13 @@ class SetBooleanPropertyDict(MarkLogicAPIDict):
166
171
  value: str
167
172
 
168
173
 
174
+ # set_datetime_property.xqy
175
+ class SetDatetimePropertyDict(MarkLogicAPIDict):
176
+ name: str
177
+ uri: MarkLogicDocumentURIString
178
+ value: str
179
+
180
+
169
181
  # set_metadata_citation.xqy
170
182
  class SetMetadataCitationDict(MarkLogicAPIDict):
171
183
  content: str
@@ -1,13 +1,11 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ds-caselaw-marklogic-api-client
3
- Version: 39.2.1
3
+ Version: 41.0.0
4
4
  Summary: An API client for interacting with the underlying data in Find Caselaw.
5
5
  Keywords: national archives,caselaw
6
6
  Author: The National Archives
7
- Requires-Python: >=3.10.0,<4.0.0
7
+ Requires-Python: >=3.12.0,<4.0.0
8
8
  Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.10
10
- Classifier: Programming Language :: Python :: 3.11
11
9
  Classifier: Programming Language :: Python :: 3.12
12
10
  Classifier: Programming Language :: Python :: 3.13
13
11
  Requires-Dist: boto3 (>=1.26.112,<2.0.0)
@@ -1,4 +1,4 @@
1
- caselawclient/Client.py,sha256=rcdgfEJ5N_Ajryf8CFHBlEWqvRB7J5IxqE1tCcudTqU,45496
1
+ caselawclient/Client.py,sha256=YyGDe0-zBIx0ggq5utwwej9ujA5UaJG8vz06pMNU4qc,47339
2
2
  caselawclient/__init__.py,sha256=QZtsOB_GR5XfFnWMJ6E9_fBany-JXFIrQmzs1mD_KVg,1225
3
3
  caselawclient/client_helpers/__init__.py,sha256=eucyUXwUqI72TPw-C5zLcHlMu4GtFY507a6lQc03lQY,5053
4
4
  caselawclient/client_helpers/search_helpers.py,sha256=R99HyRLeYHgsw2L3DOidEqlKLLvs6Tga5rKTuWQViig,1525
@@ -7,15 +7,15 @@ caselawclient/errors.py,sha256=JC16fEGq_MRJX-_KFzfINCV2Cqx8o6OWOt3C16rQd84,3142
7
7
  caselawclient/factories.py,sha256=eGj9TiZpmF3todW-08Ps7bHNMvByHqwEbgujRhvU_Yc,7382
8
8
  caselawclient/identifier_resolution.py,sha256=B5I1sD7o7YjzsXMECjbKjgiGLDda5bGhejsJ-lYpTIg,2429
9
9
  caselawclient/models/__init__.py,sha256=kd23EUpvaC7aLHdgk8farqKAQEx3lf7RvNT2jEatvlg,68
10
- caselawclient/models/documents/__init__.py,sha256=5hnKWzuj6fXCHf7jGKg_uolI_iKt6yLb9FMl_yWQ84o,21681
11
- caselawclient/models/documents/body.py,sha256=O1ZTV3KHo-YNi7Syd4oCV1CVSuRF7mcLXojwshyY4jg,6601
10
+ caselawclient/models/documents/__init__.py,sha256=DSHbaFjSZmvGlVoXYPlE3FcMhRHp1Ib52KUF9lr1g-w,23128
11
+ caselawclient/models/documents/body.py,sha256=pzk3bm9FGIWfI0Hs8dBuzk6RCiA9M4GHfgOYKpNlzyE,8455
12
12
  caselawclient/models/documents/comparison.py,sha256=KwFZQByOcYcZKe8csjAntttACKq4BZb28n2VeV5rK54,1355
13
13
  caselawclient/models/documents/exceptions.py,sha256=te7PPQTDHjZ9EYVg5pVaiZfF00lMBFy333PHj8_mkC4,443
14
14
  caselawclient/models/documents/statuses.py,sha256=Cp4dTQmJOtsU41EJcxy5dV1841pGD2PNWH0VrkDEv4Q,579
15
15
  caselawclient/models/documents/transforms/html.xsl,sha256=XyUQLFcJ7_GwthWQ6ShU0bmzrgpl7xDFU-U8VLgOvEs,38258
16
- caselawclient/models/documents/xml.py,sha256=BVra2VL_0JyImM8GC3wdouu1tApy79C-e2dHvQyrXPE,2195
17
- caselawclient/models/identifiers/__init__.py,sha256=bcXiree1FKIlJklWggvS_IKMHMppAjDbadOpxCJx3yw,7727
18
- caselawclient/models/identifiers/collection.py,sha256=kGlziJiLAqoyd6LaaZ5tsgUf2fD6Y-7fv1It9S4-Otw,7448
16
+ caselawclient/models/documents/xml.py,sha256=uGRULm_XcA9ABZmwTxxwwysPItQl1qnMd2pUVTZprgc,2376
17
+ caselawclient/models/identifiers/__init__.py,sha256=Vp5zJdJSskCuUOUwmPDiDvVlNsYmPRH350-wRx7Q8Dc,7877
18
+ caselawclient/models/identifiers/collection.py,sha256=1fw9yAuHBBMCgAfYRwgpoIPHW_vWQA-eCGDBnWI-gWI,7511
19
19
  caselawclient/models/identifiers/exceptions.py,sha256=6LVjvx-UOwqkrpxU19ydmrphKNw0rcG5GXwjTFyf8Dk,130
20
20
  caselawclient/models/identifiers/fclid.py,sha256=hj8z-VhXFrUHKOY6k_ItPvOakIvbhJ5xEbZ04E2j7t8,1521
21
21
  caselawclient/models/identifiers/neutral_citation.py,sha256=bYAeXHVm_ls0aDTeYI4uv35iZmJGSKU4-H-iLh2xED0,2912
@@ -26,18 +26,19 @@ caselawclient/models/neutral_citation_mixin.py,sha256=jAac3PPuWyPdj9N-n-U_Jfwkbg
26
26
  caselawclient/models/parser_logs.py,sha256=iOhKTAAi87XQvxz1DHjF2lrqScD19g_c8EjSf0vPdfs,364
27
27
  caselawclient/models/press_summaries.py,sha256=rtrYs_3BazUXxdA2oYmIJ6YIAiVlKeyc1aSF9uvkJJU,2196
28
28
  caselawclient/models/utilities/__init__.py,sha256=LPhyrQwLKc5tIJUO8Bysn9wCiR6Z6jMMTksjOV4JH9U,1041
29
- caselawclient/models/utilities/aws.py,sha256=_JUoJatfC1m_etT5MDwbCrOHpdqqTRqGCyzzNiW1WRA,8660
29
+ caselawclient/models/utilities/aws.py,sha256=8paywUsQrR6hx1LfKbc9U_ieKUHQU584Hw6_c7kWTdE,9201
30
30
  caselawclient/models/utilities/dates.py,sha256=WwORxVjUHM1ZFcBF6Qtwo3Cj0sATsnSECkUZ6ls1N1Q,492
31
31
  caselawclient/models/utilities/move.py,sha256=MXdUqkSiyqRb8YKs_66B6ICWn8EWM6DiJV95fuJO1Us,3610
32
32
  caselawclient/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  caselawclient/responses/__init__.py,sha256=2-5NJn_PXPTje_W4dHeHYaNRN6vXK4UcB9eLLNUAKa4,67
34
34
  caselawclient/responses/search_response.py,sha256=Z76Zj4VvM-EV_vdiehv2-Jfkr9HZD3SvCTlRrUB_cyE,1951
35
- caselawclient/responses/search_result.py,sha256=gjSpnfygw9mEgKa3_sL-6O8JkGYSyxmrPpwwMMuf-ZQ,9416
35
+ caselawclient/responses/search_result.py,sha256=glcoCeo2xO-17aV2pcpyfgl0_UjjEUqHfm2kVylXCwk,9782
36
36
  caselawclient/responses/xsl/search_match.xsl,sha256=4Sv--MrwBd7J48E9aI7jlFSXGlNi4dBqgzJ3bdMJ_ZU,1018
37
37
  caselawclient/search_parameters.py,sha256=A-9icXdyFYLDACjUaRQF8mrnaVRlFJ9XCPtu5uZ-_Lo,3484
38
- caselawclient/types.py,sha256=5lE_0kRd7ZMUkr53Rh4ooo74Ab8JTXnMo8rNrwn_HUo,2578
39
- caselawclient/xml_helpers.py,sha256=xCboRhhzezqh-VyoKBQwal5lwxv96vTMJyVFWJNN-ok,639
38
+ caselawclient/types.py,sha256=tf4EtzQyMfHk-eYvLLlRhpSV5iBIEOWxAhcCYBXnaJQ,2744
39
+ caselawclient/xml_helpers.py,sha256=31cxsDu680SFi3gR35rL7EdBZaW6r6mt4zvWHjJeX9o,1131
40
40
  caselawclient/xquery/break_judgment_checkout.xqy,sha256=rISzoBKxQKrP5ZRdCSoRqOXW8T_NDBSZRFjOXo_H3ns,220
41
+ caselawclient/xquery/check_content_hash_unique_by_uri.xqy,sha256=fqSsqm4VFW3aS_DIDn1AIF54k3hs-xvlh_Xpyp-rf-I,386
41
42
  caselawclient/xquery/checkin_judgment.xqy,sha256=QeGqO3kL-q0UrjopCVU0lCbkwbyoc5SuNLYFAIbbyMg,197
42
43
  caselawclient/xquery/checkout_judgment.xqy,sha256=aRwVo4KXoEKXfXRZ6IrVfvh0pXK-7pFxVIgEyzE5DRY,385
43
44
  caselawclient/xquery/copy_document.xqy,sha256=GwgafibZhUB4rZ7x5wmHAKi0DO1aEWNVithkguwsVGE,453
@@ -68,6 +69,7 @@ caselawclient/xquery/list_judgment_versions.xqy,sha256=WShga8igeD21hSLfVSvCOiDMP
68
69
  caselawclient/xquery/resolve_from_identifier_slug.xqy,sha256=jMaOugdG1XVQIk9AR5NOth8D2RS8VEUJuBwjO9j4MFM,485
69
70
  caselawclient/xquery/resolve_from_identifier_value.xqy,sha256=7uP3DnRi67qSp0aUhW6Cv_GA8BQGw6GuvtAghjrT7Z4,493
70
71
  caselawclient/xquery/set_boolean_property.xqy,sha256=8Vg3yDWqeDynUJQHw2OF4daDIKTnp8ARol1_OCqY0Dk,355
72
+ caselawclient/xquery/set_datetime_property.xqy,sha256=61NuWft1DlpROwdkDLHJ2rcHDqKAFoD45XQ_nmdBkLY,356
71
73
  caselawclient/xquery/set_metadata_citation.xqy,sha256=ImwijXowvOCiH_br_LepnKsEpys9tg4Cf3uz6MoC5-c,659
72
74
  caselawclient/xquery/set_metadata_court.xqy,sha256=xQGR3e4pdJuDPMlzdAdzrBDSeQbEFiLVIm2z_KQI_Ds,996
73
75
  caselawclient/xquery/set_metadata_jurisdiction.xqy,sha256=7iG1uFZOme0_d1hkzLJ870ot_ioFnSwDROfA-_yGtN8,1059
@@ -84,10 +86,10 @@ caselawclient/xquery/validate_all_documents.xqy,sha256=z_0YEXmRcZ-FaJM0ouKiTjdI4
84
86
  caselawclient/xquery/validate_document.xqy,sha256=PgaDcnqCRJPIVqfmWsNlXmCLNKd21qkJrvY1RtNP7eA,140
85
87
  caselawclient/xquery/xslt.xqy,sha256=w57wNijH3dkwHkpKeAxqjlghVflQwo8cq6jS_sm-erM,199
86
88
  caselawclient/xquery/xslt_transform.xqy,sha256=cccaFiGkCcvSfDv007UriZ3I4ak2nTLP1trRZdbOoS8,2462
87
- caselawclient/xquery_type_dicts.py,sha256=zuyDGTkcN6voOXCm3APXItZ-Ey6tZ2hdZummZWzjl50,6489
89
+ caselawclient/xquery_type_dicts.py,sha256=f4PM8yZi5RRMdL2lQ8tsLUs0aJjBa5chvd-VVj40fJY,6767
88
90
  caselawclient/xslt/modify_xml_live.xsl,sha256=gNjwBun2-UzOeeuf0wNjFtN3jXm1yrwqv_KT8r1slXw,2370
89
91
  caselawclient/xslt/sample.xsl,sha256=IG-v77stjwqiw25pguh391K-5DTKiX651WqILDZixm0,825
90
- ds_caselaw_marklogic_api_client-39.2.1.dist-info/LICENSE.md,sha256=fGMzyyLuQW-IAXUeDSCrRdsYW536aEWThdbpCjo6ZKg,1108
91
- ds_caselaw_marklogic_api_client-39.2.1.dist-info/METADATA,sha256=EiKB1ULoiBebeYY-lr9xAJ8UQUpH9K0DdvL1zZK0w0E,4466
92
- ds_caselaw_marklogic_api_client-39.2.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
93
- ds_caselaw_marklogic_api_client-39.2.1.dist-info/RECORD,,
92
+ ds_caselaw_marklogic_api_client-41.0.0.dist-info/LICENSE.md,sha256=fGMzyyLuQW-IAXUeDSCrRdsYW536aEWThdbpCjo6ZKg,1108
93
+ ds_caselaw_marklogic_api_client-41.0.0.dist-info/METADATA,sha256=56e2Zd_uMIyUmVZd1W82BSHXmjQFEICPkoKzvlHZQQ0,4364
94
+ ds_caselaw_marklogic_api_client-41.0.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
95
+ ds_caselaw_marklogic_api_client-41.0.0.dist-info/RECORD,,