ds-caselaw-marklogic-api-client 29.0.0__py3-none-any.whl → 29.0.0a2__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 +0 -20
- caselawclient/models/documents/__init__.py +8 -23
- caselawclient/models/identifiers/__init__.py +6 -54
- caselawclient/models/identifiers/neutral_citation.py +0 -2
- caselawclient/models/identifiers/unpacker.py +0 -2
- caselawclient/models/judgments.py +13 -10
- caselawclient/models/neutral_citation_mixin.py +4 -8
- caselawclient/models/press_summaries.py +12 -9
- caselawclient/xquery_type_dicts.py +0 -6
- {ds_caselaw_marklogic_api_client-29.0.0.dist-info → ds_caselaw_marklogic_api_client-29.0.0a2.dist-info}/METADATA +2 -3
- {ds_caselaw_marklogic_api_client-29.0.0.dist-info → ds_caselaw_marklogic_api_client-29.0.0a2.dist-info}/RECORD +13 -17
- caselawclient/identifier_resolution.py +0 -43
- caselawclient/models/identifiers/fclid.py +0 -50
- caselawclient/xquery/get_next_document_sequence_number.xqy +0 -14
- caselawclient/xquery/resolve_from_identifier.xqy +0 -17
- {ds_caselaw_marklogic_api_client-29.0.0.dist-info → ds_caselaw_marklogic_api_client-29.0.0a2.dist-info}/LICENSE.md +0 -0
- {ds_caselaw_marklogic_api_client-29.0.0.dist-info → ds_caselaw_marklogic_api_client-29.0.0a2.dist-info}/WHEEL +0 -0
caselawclient/Client.py
CHANGED
|
@@ -20,7 +20,6 @@ from requests_toolbelt.multipart import decoder
|
|
|
20
20
|
|
|
21
21
|
from caselawclient import xquery_type_dicts as query_dicts
|
|
22
22
|
from caselawclient.client_helpers import VersionAnnotation
|
|
23
|
-
from caselawclient.identifier_resolution import IdentifierResolutions
|
|
24
23
|
from caselawclient.models.documents import (
|
|
25
24
|
DOCUMENT_COLLECTION_URI_JUDGMENT,
|
|
26
25
|
DOCUMENT_COLLECTION_URI_PRESS_SUMMARY,
|
|
@@ -1202,22 +1201,3 @@ class MarklogicApiClient:
|
|
|
1202
1201
|
)
|
|
1203
1202
|
|
|
1204
1203
|
return results
|
|
1205
|
-
|
|
1206
|
-
def resolve_from_identifier(self, identifier_uri: str, published_only: bool = True) -> IdentifierResolutions:
|
|
1207
|
-
"""Given a PUI/EUI url, look up the precomputed slug and return the
|
|
1208
|
-
MarkLogic document URIs which match that slug. Multiple returns should be anticipated"""
|
|
1209
|
-
vars: query_dicts.ResolveFromIdentifierDict = {
|
|
1210
|
-
"identifier_uri": DocumentURIString(identifier_uri),
|
|
1211
|
-
"published_only": int(published_only),
|
|
1212
|
-
}
|
|
1213
|
-
raw_results: list[str] = get_multipart_strings_from_marklogic_response(
|
|
1214
|
-
self._send_to_eval(
|
|
1215
|
-
vars,
|
|
1216
|
-
"resolve_from_identifier.xqy",
|
|
1217
|
-
),
|
|
1218
|
-
)
|
|
1219
|
-
return IdentifierResolutions.from_marklogic_output(raw_results)
|
|
1220
|
-
|
|
1221
|
-
def get_next_document_sequence_number(self) -> int:
|
|
1222
|
-
"""Increment the MarkLogic sequence number by one and return the value."""
|
|
1223
|
-
return int(self._eval_and_decode({}, "get_next_document_sequence_number.xqy"))
|
|
@@ -15,8 +15,6 @@ from caselawclient.errors import (
|
|
|
15
15
|
NotSupportedOnVersion,
|
|
16
16
|
OnlySupportedOnVersion,
|
|
17
17
|
)
|
|
18
|
-
from caselawclient.models.identifiers import Identifier
|
|
19
|
-
from caselawclient.models.identifiers.fclid import FindCaseLawIdentifier, FindCaseLawIdentifierSchema
|
|
20
18
|
from caselawclient.models.identifiers.unpacker import unpack_all_identifiers_from_etree
|
|
21
19
|
from caselawclient.models.utilities import VersionsDict, extract_version, render_versions
|
|
22
20
|
from caselawclient.models.utilities.aws import (
|
|
@@ -172,11 +170,13 @@ class Document:
|
|
|
172
170
|
self.identifiers = unpack_all_identifiers_from_etree(identifiers_element_as_etree)
|
|
173
171
|
|
|
174
172
|
@property
|
|
175
|
-
def best_human_identifier(self) -> Optional[
|
|
176
|
-
"""
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
173
|
+
def best_human_identifier(self) -> Optional[str]:
|
|
174
|
+
"""
|
|
175
|
+
Some identifier that is understood by legal professionals to refer to this legal event
|
|
176
|
+
that is not the name of the document.
|
|
177
|
+
Typically, this will be the neutral citation number, should it exist.
|
|
178
|
+
Should typically be overridden in subclasses.
|
|
179
|
+
"""
|
|
180
180
|
return None
|
|
181
181
|
|
|
182
182
|
@property
|
|
@@ -432,12 +432,6 @@ class Document:
|
|
|
432
432
|
if not self.is_publishable:
|
|
433
433
|
raise CannotPublishUnpublishableDocument
|
|
434
434
|
|
|
435
|
-
## If it doesn't already have one, get a new FCLID for this document and assign
|
|
436
|
-
if len(self.identifiers.of_type(FindCaseLawIdentifier)) < 1:
|
|
437
|
-
document_fclid = FindCaseLawIdentifierSchema.mint(self.api_client)
|
|
438
|
-
self.identifiers.add(document_fclid)
|
|
439
|
-
self.save_identifiers()
|
|
440
|
-
|
|
441
435
|
publish_documents(uri_for_s3(self.uri))
|
|
442
436
|
self.api_client.set_published(self.uri, True)
|
|
443
437
|
announce_document_event(
|
|
@@ -506,17 +500,13 @@ class Document:
|
|
|
506
500
|
"documentType": parser_type_noun,
|
|
507
501
|
"metadata": {
|
|
508
502
|
"name": self.body.name or None,
|
|
509
|
-
"cite": None,
|
|
503
|
+
"cite": self.best_human_identifier or None,
|
|
510
504
|
"court": self.body.court or None,
|
|
511
505
|
"date": checked_date,
|
|
512
506
|
"uri": self.uri,
|
|
513
507
|
},
|
|
514
508
|
}
|
|
515
509
|
|
|
516
|
-
## TODO: Remove this hack around the fact that NCNs are assumed to be present for all documents' metadata, but actually different document classes may have different metadata
|
|
517
|
-
if hasattr(self, "neutral_citation"):
|
|
518
|
-
parser_instructions["metadata"]["cite"] = self.neutral_citation
|
|
519
|
-
|
|
520
510
|
request_parse(
|
|
521
511
|
uri=self.uri,
|
|
522
512
|
reference=self.consignment_reference,
|
|
@@ -540,11 +530,6 @@ class Document:
|
|
|
540
530
|
"""
|
|
541
531
|
return self.docx_exists()
|
|
542
532
|
|
|
543
|
-
def save_identifiers(self) -> None:
|
|
544
|
-
"""Save the current state of this Document's identifiers to MarkLogic."""
|
|
545
|
-
self.identifiers.validate()
|
|
546
|
-
self.api_client.set_property_as_node(self.uri, "identifiers", self.identifiers.as_etree)
|
|
547
|
-
|
|
548
533
|
def __getattr__(self, name: str) -> Any:
|
|
549
534
|
warnings.warn(f"{name} no longer exists on Document, using Document.body instead", DeprecationWarning)
|
|
550
535
|
try:
|
|
@@ -32,20 +32,13 @@ class IdentifierSchema(ABC):
|
|
|
32
32
|
name: str
|
|
33
33
|
namespace: str
|
|
34
34
|
|
|
35
|
-
human_readable: bool
|
|
36
|
-
""" Should this identifier type be considered for display as a 'human readable' identifier? """
|
|
37
|
-
|
|
38
|
-
base_score_multiplier: float = 1.0
|
|
39
|
-
""" A multiplier used to adjust the relative ranking of this identifier when calculating preferred identifiers. """
|
|
40
|
-
|
|
41
35
|
def __init_subclass__(cls: type["IdentifierSchema"], **kwargs: Any) -> None:
|
|
42
36
|
"""Ensure that subclasses have the required attributes set."""
|
|
43
37
|
for required in (
|
|
44
38
|
"name",
|
|
45
39
|
"namespace",
|
|
46
|
-
"human_readable",
|
|
47
40
|
):
|
|
48
|
-
if not
|
|
41
|
+
if not getattr(cls, required, False):
|
|
49
42
|
raise NotImplementedError(f"Can't instantiate IdentifierSchema without {required} attribute.")
|
|
50
43
|
super().__init_subclass__(**kwargs)
|
|
51
44
|
|
|
@@ -108,15 +101,6 @@ class Identifier(ABC):
|
|
|
108
101
|
def url_slug(self) -> str:
|
|
109
102
|
return self.schema.compile_identifier_url_slug(self.value)
|
|
110
103
|
|
|
111
|
-
@property
|
|
112
|
-
def score(self) -> float:
|
|
113
|
-
"""Return the score of this identifier, used to calculate the preferred identifier for a document."""
|
|
114
|
-
return 1 * self.schema.base_score_multiplier
|
|
115
|
-
|
|
116
|
-
def same_as(self, other: "Identifier") -> bool:
|
|
117
|
-
"Is this the same as another identifier (in value and schema)?"
|
|
118
|
-
return self.value == other.value and self.schema == other.schema
|
|
119
|
-
|
|
120
104
|
|
|
121
105
|
class Identifiers(dict[str, Identifier]):
|
|
122
106
|
def validate(self) -> None:
|
|
@@ -125,13 +109,8 @@ class Identifiers(dict[str, Identifier]):
|
|
|
125
109
|
msg = "Key of {identifier} in Identifiers is {uuid} not {identifier.uuid}"
|
|
126
110
|
raise UUIDMismatchError(msg)
|
|
127
111
|
|
|
128
|
-
def contains(self, other_identifier: Identifier) -> bool:
|
|
129
|
-
"Do the identifier's value and namespace already exist in this group?"
|
|
130
|
-
return any(other_identifier.same_as(identifier) for identifier in self.values())
|
|
131
|
-
|
|
132
112
|
def add(self, identifier: Identifier) -> None:
|
|
133
|
-
|
|
134
|
-
self[identifier.uuid] = identifier
|
|
113
|
+
self[identifier.uuid] = identifier
|
|
135
114
|
|
|
136
115
|
def __delitem__(self, key: Union[Identifier, str]) -> None:
|
|
137
116
|
if isinstance(key, Identifier):
|
|
@@ -139,19 +118,6 @@ class Identifiers(dict[str, Identifier]):
|
|
|
139
118
|
else:
|
|
140
119
|
super().__delitem__(key)
|
|
141
120
|
|
|
142
|
-
def of_type(self, identifier_type: type[Identifier]) -> list[Identifier]:
|
|
143
|
-
"""Return a list of all identifiers of a given type."""
|
|
144
|
-
uuids = self.keys()
|
|
145
|
-
return [self[uuid] for uuid in list(uuids) if isinstance(self[uuid], identifier_type)]
|
|
146
|
-
|
|
147
|
-
def delete_type(self, deleted_identifier_type: type[Identifier]) -> None:
|
|
148
|
-
"For when we want an identifier to be the only valid identifier of that type, delete the others first"
|
|
149
|
-
uuids = self.keys()
|
|
150
|
-
for uuid in list(uuids):
|
|
151
|
-
# we could use compare to .schema instead, which would have diffferent behaviour for subclasses
|
|
152
|
-
if isinstance(self[uuid], deleted_identifier_type):
|
|
153
|
-
del self[uuid]
|
|
154
|
-
|
|
155
121
|
@property
|
|
156
122
|
def as_etree(self) -> etree._Element:
|
|
157
123
|
"""Return an etree representation of all the Document's identifiers."""
|
|
@@ -162,21 +128,7 @@ class Identifiers(dict[str, Identifier]):
|
|
|
162
128
|
|
|
163
129
|
return identifiers_root
|
|
164
130
|
|
|
165
|
-
def
|
|
166
|
-
"""
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
:return: Return a list of identifiers, sorted by their score in descending order.
|
|
170
|
-
"""
|
|
171
|
-
identifiers = self.of_type(type) if type else list(self.values())
|
|
172
|
-
return sorted(identifiers, key=lambda v: v.score, reverse=True)
|
|
173
|
-
|
|
174
|
-
def preferred(self, type: Optional[type[Identifier]] = None) -> Optional[Identifier]:
|
|
175
|
-
"""
|
|
176
|
-
:param type: Optionally, an identifier type to constrain the results to.
|
|
177
|
-
|
|
178
|
-
:return: Return the highest scoring identifier of the given type (or of any type, if none is specified). Returns `None` if no identifier is available.
|
|
179
|
-
"""
|
|
180
|
-
if len(self) == 0:
|
|
181
|
-
return None
|
|
182
|
-
return self.by_score(type)[0]
|
|
131
|
+
def save(self, document) -> None: # type: ignore[no-untyped-def, unused-ignore]
|
|
132
|
+
"""Save the current state of this Document's identifiers to MarkLogic."""
|
|
133
|
+
self.validate()
|
|
134
|
+
document.api_client.set_property_as_node(document.uri, "identifiers", self.as_etree)
|
|
@@ -3,11 +3,9 @@ from typing import Optional
|
|
|
3
3
|
from lxml import etree
|
|
4
4
|
|
|
5
5
|
from . import IDENTIFIER_UNPACKABLE_ATTRIBUTES, Identifier, Identifiers, InvalidIdentifierXMLRepresentationException
|
|
6
|
-
from .fclid import FindCaseLawIdentifier
|
|
7
6
|
from .neutral_citation import NeutralCitationNumber
|
|
8
7
|
|
|
9
8
|
IDENTIFIER_NAMESPACE_MAP: dict[str, type[Identifier]] = {
|
|
10
|
-
"fclid": FindCaseLawIdentifier,
|
|
11
9
|
"ukncn": NeutralCitationNumber,
|
|
12
10
|
}
|
|
13
11
|
|
|
@@ -25,17 +25,20 @@ class Judgment(NeutralCitationMixin, Document):
|
|
|
25
25
|
super().__init__(self.document_noun, uri, *args, **kwargs)
|
|
26
26
|
|
|
27
27
|
@cached_property
|
|
28
|
-
def neutral_citation(self) ->
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
def neutral_citation(self) -> NeutralCitationString:
|
|
29
|
+
return NeutralCitationString(
|
|
30
|
+
self.body.get_xpath_match_string(
|
|
31
|
+
"/akn:akomaNtoso/akn:*/akn:meta/akn:proprietary/uk:cite/text()",
|
|
32
|
+
{
|
|
33
|
+
"uk": "https://caselaw.nationalarchives.gov.uk/akn",
|
|
34
|
+
"akn": "http://docs.oasis-open.org/legaldocml/ns/akn/3.0",
|
|
35
|
+
},
|
|
36
|
+
)
|
|
35
37
|
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def best_human_identifier(self) -> str:
|
|
41
|
+
return self.neutral_citation
|
|
39
42
|
|
|
40
43
|
@cached_property
|
|
41
44
|
def linked_document(self) -> Optional["PressSummary"]:
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
from functools import cached_property
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any
|
|
4
4
|
|
|
5
5
|
from ds_caselaw_utils import neutral_url
|
|
6
6
|
from ds_caselaw_utils.types import NeutralCitationString
|
|
7
|
-
from typing_extensions import deprecated
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
class NeutralCitationMixin(ABC):
|
|
@@ -39,15 +38,12 @@ class NeutralCitationMixin(ABC):
|
|
|
39
38
|
|
|
40
39
|
@cached_property
|
|
41
40
|
@abstractmethod
|
|
42
|
-
|
|
43
|
-
def neutral_citation(self) -> Optional[NeutralCitationString]: ...
|
|
41
|
+
def neutral_citation(self) -> NeutralCitationString: ...
|
|
44
42
|
|
|
45
43
|
@cached_property
|
|
46
|
-
@deprecated("Legacy usage of NCNs is deprecated; you should be moving to the Identifiers framework")
|
|
47
44
|
def has_ncn(self) -> bool:
|
|
48
|
-
return self.neutral_citation
|
|
45
|
+
return bool(self.neutral_citation)
|
|
49
46
|
|
|
50
47
|
@cached_property
|
|
51
|
-
@deprecated("Legacy usage of NCNs is deprecated; you should be moving to the Identifiers framework")
|
|
52
48
|
def has_valid_ncn(self) -> bool:
|
|
53
|
-
return self.
|
|
49
|
+
return self.has_ncn and neutral_url(self.neutral_citation) is not None
|
|
@@ -27,16 +27,19 @@ class PressSummary(NeutralCitationMixin, Document):
|
|
|
27
27
|
super().__init__(self.document_noun, uri, *args, **kwargs)
|
|
28
28
|
|
|
29
29
|
@cached_property
|
|
30
|
-
def neutral_citation(self) ->
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
def neutral_citation(self) -> NeutralCitationString:
|
|
31
|
+
return NeutralCitationString(
|
|
32
|
+
self.body.get_xpath_match_string(
|
|
33
|
+
"/akn:akomaNtoso/akn:doc/akn:preface/akn:p/akn:neutralCitation/text()",
|
|
34
|
+
{
|
|
35
|
+
"akn": "http://docs.oasis-open.org/legaldocml/ns/akn/3.0",
|
|
36
|
+
},
|
|
37
|
+
)
|
|
36
38
|
)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def best_human_identifier(self) -> str:
|
|
42
|
+
return self.neutral_citation
|
|
40
43
|
|
|
41
44
|
@cached_property
|
|
42
45
|
def linked_document(self) -> Optional[Judgment]:
|
|
@@ -141,12 +141,6 @@ class ListJudgmentVersionsDict(MarkLogicAPIDict):
|
|
|
141
141
|
uri: MarkLogicDocumentURIString
|
|
142
142
|
|
|
143
143
|
|
|
144
|
-
# resolve_from_identifier.xqy
|
|
145
|
-
class ResolveFromIdentifierDict(MarkLogicAPIDict):
|
|
146
|
-
identifier_uri: DocumentURIString
|
|
147
|
-
published_only: Optional[int]
|
|
148
|
-
|
|
149
|
-
|
|
150
144
|
# set_boolean_property.xqy
|
|
151
145
|
class SetBooleanPropertyDict(MarkLogicAPIDict):
|
|
152
146
|
name: str
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ds-caselaw-marklogic-api-client
|
|
3
|
-
Version: 29.0.
|
|
3
|
+
Version: 29.0.0a2
|
|
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
|
|
@@ -11,7 +11,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Requires-Dist: boto3 (>=1.26.112,<2.0.0)
|
|
14
|
-
Requires-Dist: certifi (>=2024.
|
|
14
|
+
Requires-Dist: certifi (>=2024.8.30,<2024.9.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
17
|
Requires-Dist: ds-caselaw-utils (>=2.0.0,<3.0.0)
|
|
@@ -25,7 +25,6 @@ Requires-Dist: pytz (>=2024.1,<2025.0)
|
|
|
25
25
|
Requires-Dist: requests (>=2.28.2,<3.0.0)
|
|
26
26
|
Requires-Dist: requests-toolbelt (>=0.10.1,<1.1.0)
|
|
27
27
|
Requires-Dist: saxonche (>=12.5.0,<13.0.0)
|
|
28
|
-
Requires-Dist: sqids (>=0.5.0,<0.6.0)
|
|
29
28
|
Requires-Dist: typing-extensions (>=4.7.1,<5.0.0)
|
|
30
29
|
Description-Content-Type: text/markdown
|
|
31
30
|
|
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
caselawclient/Client.py,sha256=
|
|
1
|
+
caselawclient/Client.py,sha256=BD6XvObJHILh8C4NvLJUpkEUJ6KpxHOHKokJOrYWaKY,42818
|
|
2
2
|
caselawclient/__init__.py,sha256=DY-caubLDQWWingSdsBWgovDNXh8KcnkI6kwz08eIFk,612
|
|
3
3
|
caselawclient/client_helpers/__init__.py,sha256=fyDNKCdrTb2N0Ks23YDhmvlXKfLTHnYQCXhnZb-QQbg,3832
|
|
4
4
|
caselawclient/client_helpers/search_helpers.py,sha256=R99HyRLeYHgsw2L3DOidEqlKLLvs6Tga5rKTuWQViig,1525
|
|
5
5
|
caselawclient/content_hash.py,sha256=0cPC4OoABq0SC2wYFX9-24DodNigeOqksDxgxQH_hUA,2221
|
|
6
6
|
caselawclient/errors.py,sha256=tV0vs3wYSd331BzmfuRiZV6GAdsd91rtN65ymRaSx3s,3164
|
|
7
7
|
caselawclient/factories.py,sha256=6-xZMVmvtXA8AnyWJgJTums1EWfM6lPIhrWQu0NopJo,4472
|
|
8
|
-
caselawclient/identifier_resolution.py,sha256=IOqrZcIHoHhNOCAkNveOBcWddBNpkOB8cz1r0zFa8mQ,1829
|
|
9
8
|
caselawclient/models/__init__.py,sha256=kd23EUpvaC7aLHdgk8farqKAQEx3lf7RvNT2jEatvlg,68
|
|
10
|
-
caselawclient/models/documents/__init__.py,sha256=
|
|
9
|
+
caselawclient/models/documents/__init__.py,sha256=ZrdtHZ1M8kTODD2Zky6EdUjj8r0KQKIZ6nWtXmuZKuo,18506
|
|
11
10
|
caselawclient/models/documents/body.py,sha256=mtdjmG1WU2qSpyRLS8-PWcSoXpDa2Qz6xlcTbxZgxvA,5603
|
|
12
11
|
caselawclient/models/documents/exceptions.py,sha256=rw1xId16vBKvBImgFmFUpeFgKqU7VTNtVLIEVBPGKyk,374
|
|
13
12
|
caselawclient/models/documents/statuses.py,sha256=Cp4dTQmJOtsU41EJcxy5dV1841pGD2PNWH0VrkDEv4Q,579
|
|
14
13
|
caselawclient/models/documents/transforms/html.xsl,sha256=oSSO-IBX4qLiSWexQYmWJfGNevF09aCBx4D1NYqXxpo,38322
|
|
15
14
|
caselawclient/models/documents/xml.py,sha256=HlmPb63lLMnySSOLP4iexcAyQiLByKBZtTd25f8sY8M,1268
|
|
16
|
-
caselawclient/models/identifiers/__init__.py,sha256=
|
|
17
|
-
caselawclient/models/identifiers/
|
|
18
|
-
caselawclient/models/identifiers/
|
|
19
|
-
caselawclient/models/
|
|
20
|
-
caselawclient/models/
|
|
21
|
-
caselawclient/models/
|
|
22
|
-
caselawclient/models/press_summaries.py,sha256=bEqJxu-7eBLhwulOsDXYDl2ptIp3RkkMpOcdVvWB5ds,1836
|
|
15
|
+
caselawclient/models/identifiers/__init__.py,sha256=FSrhDXMkjgaYnOlBaTDcz9ouzL9ERxEhlqud0fdVT8A,4151
|
|
16
|
+
caselawclient/models/identifiers/neutral_citation.py,sha256=yddlfumdnkrNpoTIOf8dB1foA7hE41-zmlfa17-Ulug,1790
|
|
17
|
+
caselawclient/models/identifiers/unpacker.py,sha256=V79m4rd0FZx5TRueL1m3MbrSUWO8c0f5NoNxSP3dlFw,1757
|
|
18
|
+
caselawclient/models/judgments.py,sha256=NVOg4ZTU7Jtr33UuswL2TXCaN6_W0fKFPK4EdQ-jUhE,1915
|
|
19
|
+
caselawclient/models/neutral_citation_mixin.py,sha256=5ktKCPIDidVRwxVTzx5e242O1BxOdP--1dnatZyTbYI,1773
|
|
20
|
+
caselawclient/models/press_summaries.py,sha256=06flQ8wSLnNxoQtXO0ckmotFKszYZcub0oPcDzYbVQw,1879
|
|
23
21
|
caselawclient/models/utilities/__init__.py,sha256=u3yIhbTjFQ1JJyAm5wsMEBswWl4t6Z7UMORF5FqC2xQ,1257
|
|
24
22
|
caselawclient/models/utilities/aws.py,sha256=umfPzjtykg_-OP1ACirpXfOLN4QenqA0A8tJk3DzYRk,8211
|
|
25
23
|
caselawclient/models/utilities/dates.py,sha256=WwORxVjUHM1ZFcBF6Qtwo3Cj0sATsnSECkUZ6ls1N1Q,492
|
|
@@ -46,7 +44,6 @@ caselawclient/xquery/get_judgment.xqy,sha256=8V-sEFKmtpf2LIZD9QKVRfpblEsmDpP4BA6
|
|
|
46
44
|
caselawclient/xquery/get_judgment_checkout_status.xqy,sha256=mdY9UXLyzQdB7byEERPqentlr0YDLbXRVqH0h4UuZTQ,193
|
|
47
45
|
caselawclient/xquery/get_judgment_version.xqy,sha256=wF9k9-CBrqo8VbxxyTrD-AGzR3-3jMm25tRVCjxPLrU,292
|
|
48
46
|
caselawclient/xquery/get_last_modified.xqy,sha256=8fCm_7o_kkytCEmEeSTLWzLP7iOjuPV01IfHDgf6HaQ,172
|
|
49
|
-
caselawclient/xquery/get_next_document_sequence_number.xqy,sha256=LkGoaS7jZfaKDuZLi0apP5qHP1rpcM1HbqX3RUwquKY,450
|
|
50
47
|
caselawclient/xquery/get_pending_enrichment_for_version.xqy,sha256=8J5Pi-jMXJd_BgtpK4g6C9uR99HP57JpFv5WkoPfNuo,2016
|
|
51
48
|
caselawclient/xquery/get_pending_parse_for_version.xqy,sha256=9cjVZtHeBBjm-a7RMsn1PVJt_Ug78YFlmp5CN8VJ1jQ,1197
|
|
52
49
|
caselawclient/xquery/get_properties_for_search_results.xqy,sha256=Tlv3EKwVV_q-JyQyhjWVHIleicPDpucxP4ScuQjpgSw,625
|
|
@@ -58,7 +55,6 @@ caselawclient/xquery/get_version_annotation.xqy,sha256=pFDMGA9SxI59iUPaoAeUsq23k
|
|
|
58
55
|
caselawclient/xquery/get_version_created.xqy,sha256=bRweaXFtwMBNzL16SlOdiOxHkbqNUwpwDHLxpZYVCh0,250
|
|
59
56
|
caselawclient/xquery/insert_document.xqy,sha256=iP2xTaLGa-u6X9KfS1yJ6yPCKQUWQFYdEW1S4YcMY7w,531
|
|
60
57
|
caselawclient/xquery/list_judgment_versions.xqy,sha256=WShga8igeD21hSLfVSvCOiDMPDhNH6KGf1OW6G0SAkY,190
|
|
61
|
-
caselawclient/xquery/resolve_from_identifier.xqy,sha256=Fa-RSw9ZwD__BmT5LLJ0J0HcDstDbedkEccv45M3L4g,484
|
|
62
58
|
caselawclient/xquery/set_boolean_property.xqy,sha256=8Vg3yDWqeDynUJQHw2OF4daDIKTnp8ARol1_OCqY0Dk,355
|
|
63
59
|
caselawclient/xquery/set_metadata_citation.xqy,sha256=ImwijXowvOCiH_br_LepnKsEpys9tg4Cf3uz6MoC5-c,659
|
|
64
60
|
caselawclient/xquery/set_metadata_court.xqy,sha256=xQGR3e4pdJuDPMlzdAdzrBDSeQbEFiLVIm2z_KQI_Ds,996
|
|
@@ -76,8 +72,8 @@ caselawclient/xquery/validate_all_documents.xqy,sha256=z_0YEXmRcZ-FaJM0ouKiTjdI4
|
|
|
76
72
|
caselawclient/xquery/validate_document.xqy,sha256=PgaDcnqCRJPIVqfmWsNlXmCLNKd21qkJrvY1RtNP7eA,140
|
|
77
73
|
caselawclient/xquery/xslt.xqy,sha256=w57wNijH3dkwHkpKeAxqjlghVflQwo8cq6jS_sm-erM,199
|
|
78
74
|
caselawclient/xquery/xslt_transform.xqy,sha256=smyFFxqmtkuOzBd2l7uw6K2oAsYctudrP8omdv_XNAM,2463
|
|
79
|
-
caselawclient/xquery_type_dicts.py,sha256=
|
|
80
|
-
ds_caselaw_marklogic_api_client-29.0.
|
|
81
|
-
ds_caselaw_marklogic_api_client-29.0.
|
|
82
|
-
ds_caselaw_marklogic_api_client-29.0.
|
|
83
|
-
ds_caselaw_marklogic_api_client-29.0.
|
|
75
|
+
caselawclient/xquery_type_dicts.py,sha256=TN-4jPUsus22yBUM6_e4ZaLvYZk_qIhz2gU3Eqg0aaY,5959
|
|
76
|
+
ds_caselaw_marklogic_api_client-29.0.0a2.dist-info/LICENSE.md,sha256=fGMzyyLuQW-IAXUeDSCrRdsYW536aEWThdbpCjo6ZKg,1108
|
|
77
|
+
ds_caselaw_marklogic_api_client-29.0.0a2.dist-info/METADATA,sha256=Tlh3W1mHe_3Th1A3U_TnBhxa64njIGMH6jot3Y_O6vE,4234
|
|
78
|
+
ds_caselaw_marklogic_api_client-29.0.0a2.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
|
79
|
+
ds_caselaw_marklogic_api_client-29.0.0a2.dist-info/RECORD,,
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from typing import NamedTuple
|
|
3
|
-
|
|
4
|
-
from caselawclient.models.documents import DocumentURIString
|
|
5
|
-
from caselawclient.xquery_type_dicts import MarkLogicDocumentURIString
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class IdentifierResolutions(list["IdentifierResolution"]):
|
|
9
|
-
"""
|
|
10
|
-
A list of candidate MarkLogic documents which correspond to a Public UI uri
|
|
11
|
-
|
|
12
|
-
MarkLogic returns a list of dictionaries; IdentifierResolution handles a single dictionary
|
|
13
|
-
which corresponds to a single identifier to MarkLogic document mapping.
|
|
14
|
-
|
|
15
|
-
see `xquery/resolve_from_identifier.xqy` and `resolve_from_identifier` in `Client.py`
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
@staticmethod
|
|
19
|
-
def from_marklogic_output(table: list[str]) -> "IdentifierResolutions":
|
|
20
|
-
return IdentifierResolutions(list(IdentifierResolution.from_marklogic_output(row) for row in table))
|
|
21
|
-
|
|
22
|
-
def published(self) -> "IdentifierResolutions":
|
|
23
|
-
"Filter the list so that only published documents are returned"
|
|
24
|
-
return IdentifierResolutions(list(x for x in self if x.document_published))
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class IdentifierResolution(NamedTuple):
|
|
28
|
-
"""A single response from MarkLogic about a single identifier / document mapping"""
|
|
29
|
-
|
|
30
|
-
identifier_uuid: str
|
|
31
|
-
document_uri: MarkLogicDocumentURIString
|
|
32
|
-
identifier_slug: DocumentURIString
|
|
33
|
-
document_published: bool
|
|
34
|
-
|
|
35
|
-
@staticmethod
|
|
36
|
-
def from_marklogic_output(raw_row: str) -> "IdentifierResolution":
|
|
37
|
-
row = json.loads(raw_row)
|
|
38
|
-
return IdentifierResolution(
|
|
39
|
-
identifier_uuid=row["documents.compiled_url_slugs.identifier_uuid"],
|
|
40
|
-
document_uri=MarkLogicDocumentURIString(row["documents.compiled_url_slugs.document_uri"]),
|
|
41
|
-
identifier_slug=DocumentURIString(row["documents.compiled_url_slugs.identifier_slug"]),
|
|
42
|
-
document_published=row["documents.compiled_url_slugs.document_published"] == "true",
|
|
43
|
-
)
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
from typing import TYPE_CHECKING
|
|
3
|
-
|
|
4
|
-
from sqids import Sqids
|
|
5
|
-
|
|
6
|
-
from . import Identifier, IdentifierSchema
|
|
7
|
-
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from caselawclient.Client import MarklogicApiClient
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
VALID_FCLID_PATTERN = re.compile(r"^[bcdfghjkmnpqrstvwxyz23456789]{4,}$")
|
|
13
|
-
|
|
14
|
-
FCLID_MINIMUM_LENGTH = 8
|
|
15
|
-
FCLID_ALPHABET = "bcdfghjkmnpqrstvwxyz23456789"
|
|
16
|
-
|
|
17
|
-
sqids = Sqids(
|
|
18
|
-
min_length=FCLID_MINIMUM_LENGTH,
|
|
19
|
-
alphabet=FCLID_ALPHABET,
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class FindCaseLawIdentifierSchema(IdentifierSchema):
|
|
24
|
-
"""
|
|
25
|
-
Identifier schema describing a Find Case Law Identifier.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
name = "Find Case Law Identifier"
|
|
29
|
-
namespace = "fclid"
|
|
30
|
-
human_readable = False
|
|
31
|
-
base_score_multiplier = 0.8
|
|
32
|
-
|
|
33
|
-
@classmethod
|
|
34
|
-
def validate_identifier(cls, value: str) -> bool:
|
|
35
|
-
return bool(VALID_FCLID_PATTERN.match(value))
|
|
36
|
-
|
|
37
|
-
@classmethod
|
|
38
|
-
def compile_identifier_url_slug(cls, value: str) -> str:
|
|
39
|
-
return "tna." + value
|
|
40
|
-
|
|
41
|
-
@classmethod
|
|
42
|
-
def mint(cls, api_client: "MarklogicApiClient") -> "FindCaseLawIdentifier":
|
|
43
|
-
"""Generate a totally new Find Case Law identifier."""
|
|
44
|
-
next_sequence_number = api_client.get_next_document_sequence_number()
|
|
45
|
-
new_identifier = sqids.encode([next_sequence_number])
|
|
46
|
-
return FindCaseLawIdentifier(value=new_identifier)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class FindCaseLawIdentifier(Identifier):
|
|
50
|
-
schema = FindCaseLawIdentifierSchema
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
xquery version "1.0-ml";
|
|
2
|
-
declare option xdmp:transaction-mode "update";
|
|
3
|
-
|
|
4
|
-
let $_ := xdmp:set-transaction-mode("update")
|
|
5
|
-
let $state_doc := fn:doc("state.xml")
|
|
6
|
-
let $counter_node := $state_doc/state/document_counter
|
|
7
|
-
|
|
8
|
-
let $current_counter := $counter_node/text()
|
|
9
|
-
let $new_counter := fn:sum(($current_counter, 1))
|
|
10
|
-
|
|
11
|
-
let $_ := xdmp:node-replace($counter_node, <document_counter>{$new_counter}</document_counter>)
|
|
12
|
-
let $_ := xdmp:commit()
|
|
13
|
-
|
|
14
|
-
return $new_counter
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
xquery version "1.0-ml";
|
|
2
|
-
|
|
3
|
-
declare namespace xdmp="http://marklogic.com/xdmp";
|
|
4
|
-
declare variable $identifier_uri as xs:string external;
|
|
5
|
-
declare variable $published_only as xs:int? external := 1;
|
|
6
|
-
|
|
7
|
-
let $published_query := if ($published_only) then " AND document_published = 'true'" else ""
|
|
8
|
-
let $query := "SELECT * from compiled_url_slugs WHERE (identifier_slug = @uri)" || $published_query
|
|
9
|
-
|
|
10
|
-
return xdmp:sql(
|
|
11
|
-
$query,
|
|
12
|
-
"map",
|
|
13
|
-
map:new((
|
|
14
|
-
map:entry("uri", $identifier_uri)
|
|
15
|
-
))
|
|
16
|
-
)
|
|
17
|
-
|
|
File without changes
|
|
File without changes
|