ds-caselaw-marklogic-api-client 39.2.1__py3-none-any.whl → 40.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.
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
@@ -948,12 +949,50 @@ class MarklogicApiClient:
948
949
  "value": string_value,
949
950
  "name": name,
950
951
  }
952
+ """
953
+ Set a property within MarkLogic which is specifically a boolean.
954
+
955
+ Since XML has no concept of boolean, the actual value in the database is set to `"true"` or `"false"`.
956
+ """
951
957
  return self._send_to_eval(vars, "set_boolean_property.xqy")
952
958
 
953
959
  def get_boolean_property(self, judgment_uri: DocumentURIString, name: str) -> bool:
960
+ """
961
+ Get a property from MarkLogic which is specifically a boolean.
962
+
963
+ :return: `True` if the property exists and has a value of `"true"`, otherwise `False`
964
+ """
954
965
  content = self.get_property(judgment_uri, name)
955
966
  return content == "true"
956
967
 
968
+ def set_datetime_property(
969
+ self,
970
+ judgment_uri: DocumentURIString,
971
+ name: str,
972
+ value: datetime,
973
+ ) -> requests.Response:
974
+ """Set a property within MarkLogic which is specifically a datetime."""
975
+ uri = self._format_uri_for_marklogic(judgment_uri)
976
+ vars: query_dicts.SetDatetimePropertyDict = {
977
+ "uri": uri,
978
+ "value": value.isoformat(),
979
+ "name": name,
980
+ }
981
+ return self._send_to_eval(vars, "set_datetime_property.xqy")
982
+
983
+ def get_datetime_property(self, judgment_uri: DocumentURIString, name: str) -> Optional[datetime]:
984
+ """
985
+ Get a property from MarkLogic which is specifically a datetime.
986
+
987
+ :return: A datetime with the value of the property, or `None` if it does not exist
988
+ """
989
+ content = self.get_property(judgment_uri, name)
990
+
991
+ if content:
992
+ return isoparse(content)
993
+
994
+ return None
995
+
957
996
  def set_published(
958
997
  self,
959
998
  judgment_uri: DocumentURIString,
@@ -305,6 +305,14 @@ class Document:
305
305
  # An empty list (which is falsy) therefore means the judgment can be published safely.
306
306
  return not self.validation_failure_messages
307
307
 
308
+ @cached_property
309
+ def first_published_datetime(self) -> Optional[datetime.datetime]:
310
+ return self.api_client.get_datetime_property(self.uri, "first_published_datetime")
311
+
312
+ @cached_property
313
+ def has_ever_been_published(self) -> bool:
314
+ return self.is_published or self.first_published_datetime is not None
315
+
308
316
  @cached_property
309
317
  def validation_failure_messages(self) -> list[str]:
310
318
  exception_list = []
@@ -407,6 +415,8 @@ class Document:
407
415
 
408
416
  def publish(self) -> None:
409
417
  """
418
+ Assuming that a document passes pre-publish checks, perform all necessary operations to put it into a published state.
419
+
410
420
  :raises CannotPublishUnpublishableDocument: This document has not passed the checks in `is_publishable`, and as
411
421
  such cannot be published.
412
422
  """
@@ -416,12 +426,25 @@ class Document:
416
426
  ## Make sure the document has an FCLID
417
427
  self.assign_fclid_if_missing()
418
428
 
429
+ ## Copy the document assets into the appropriate place in S3
419
430
  publish_documents(self.uri)
431
+
432
+ ## Set the fact the document is published
420
433
  self.api_client.set_published(self.uri, True)
434
+
435
+ ## If necessary, set the first published date
436
+ if not self.first_published_datetime:
437
+ self.api_client.set_datetime_property(
438
+ self.uri, "first_published_datetime", datetime.datetime.now(datetime.timezone.utc)
439
+ )
440
+
441
+ ## Announce the publication on the event bus
421
442
  announce_document_event(
422
443
  uri=self.uri,
423
444
  status="publish",
424
445
  )
446
+
447
+ ## Send the document off for enrichment, but accept if we can't for any reason
425
448
  self.enrich(accept_failures=True)
426
449
 
427
450
  def unpublish(self) -> None:
@@ -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:
@@ -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)
@@ -166,6 +166,13 @@ class SetBooleanPropertyDict(MarkLogicAPIDict):
166
166
  value: str
167
167
 
168
168
 
169
+ # set_datetime_property.xqy
170
+ class SetDatetimePropertyDict(MarkLogicAPIDict):
171
+ name: str
172
+ uri: MarkLogicDocumentURIString
173
+ value: str
174
+
175
+
169
176
  # set_metadata_citation.xqy
170
177
  class SetMetadataCitationDict(MarkLogicAPIDict):
171
178
  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: 40.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=tof_riZN5c1x3_cYScfIDiGaPIYt1EuAtKOpg3qI_cg,46880
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,7 +7,7 @@ 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
10
+ caselawclient/models/documents/__init__.py,sha256=ugbklabbI1LcoN5mE6rffYDApUOtkTXBzYH3Rv2fhBE,22667
11
11
  caselawclient/models/documents/body.py,sha256=O1ZTV3KHo-YNi7Syd4oCV1CVSuRF7mcLXojwshyY4jg,6601
12
12
  caselawclient/models/documents/comparison.py,sha256=KwFZQByOcYcZKe8csjAntttACKq4BZb28n2VeV5rK54,1355
13
13
  caselawclient/models/documents/exceptions.py,sha256=te7PPQTDHjZ9EYVg5pVaiZfF00lMBFy333PHj8_mkC4,443
@@ -32,7 +32,7 @@ caselawclient/models/utilities/move.py,sha256=MXdUqkSiyqRb8YKs_66B6ICWn8EWM6DiJV
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
38
  caselawclient/types.py,sha256=5lE_0kRd7ZMUkr53Rh4ooo74Ab8JTXnMo8rNrwn_HUo,2578
@@ -68,6 +68,7 @@ caselawclient/xquery/list_judgment_versions.xqy,sha256=WShga8igeD21hSLfVSvCOiDMP
68
68
  caselawclient/xquery/resolve_from_identifier_slug.xqy,sha256=jMaOugdG1XVQIk9AR5NOth8D2RS8VEUJuBwjO9j4MFM,485
69
69
  caselawclient/xquery/resolve_from_identifier_value.xqy,sha256=7uP3DnRi67qSp0aUhW6Cv_GA8BQGw6GuvtAghjrT7Z4,493
70
70
  caselawclient/xquery/set_boolean_property.xqy,sha256=8Vg3yDWqeDynUJQHw2OF4daDIKTnp8ARol1_OCqY0Dk,355
71
+ caselawclient/xquery/set_datetime_property.xqy,sha256=61NuWft1DlpROwdkDLHJ2rcHDqKAFoD45XQ_nmdBkLY,356
71
72
  caselawclient/xquery/set_metadata_citation.xqy,sha256=ImwijXowvOCiH_br_LepnKsEpys9tg4Cf3uz6MoC5-c,659
72
73
  caselawclient/xquery/set_metadata_court.xqy,sha256=xQGR3e4pdJuDPMlzdAdzrBDSeQbEFiLVIm2z_KQI_Ds,996
73
74
  caselawclient/xquery/set_metadata_jurisdiction.xqy,sha256=7iG1uFZOme0_d1hkzLJ870ot_ioFnSwDROfA-_yGtN8,1059
@@ -84,10 +85,10 @@ caselawclient/xquery/validate_all_documents.xqy,sha256=z_0YEXmRcZ-FaJM0ouKiTjdI4
84
85
  caselawclient/xquery/validate_document.xqy,sha256=PgaDcnqCRJPIVqfmWsNlXmCLNKd21qkJrvY1RtNP7eA,140
85
86
  caselawclient/xquery/xslt.xqy,sha256=w57wNijH3dkwHkpKeAxqjlghVflQwo8cq6jS_sm-erM,199
86
87
  caselawclient/xquery/xslt_transform.xqy,sha256=cccaFiGkCcvSfDv007UriZ3I4ak2nTLP1trRZdbOoS8,2462
87
- caselawclient/xquery_type_dicts.py,sha256=zuyDGTkcN6voOXCm3APXItZ-Ey6tZ2hdZummZWzjl50,6489
88
+ caselawclient/xquery_type_dicts.py,sha256=ROwV-BpQYDOrtW6aKx5MXVi85SW5J5oGgyQT7-Ra1sA,6633
88
89
  caselawclient/xslt/modify_xml_live.xsl,sha256=gNjwBun2-UzOeeuf0wNjFtN3jXm1yrwqv_KT8r1slXw,2370
89
90
  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,,
91
+ ds_caselaw_marklogic_api_client-40.0.0.dist-info/LICENSE.md,sha256=fGMzyyLuQW-IAXUeDSCrRdsYW536aEWThdbpCjo6ZKg,1108
92
+ ds_caselaw_marklogic_api_client-40.0.0.dist-info/METADATA,sha256=Nxrgxi6sCKcfetI5h5k0PcwLkkkUQYs2e8nbtj-PUQY,4364
93
+ ds_caselaw_marklogic_api_client-40.0.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
94
+ ds_caselaw_marklogic_api_client-40.0.0.dist-info/RECORD,,