dalia_dif 0.0.17__py3-none-any.whl → 0.0.19__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.
dalia_dif/cli.py CHANGED
@@ -18,10 +18,19 @@ def main() -> None:
18
18
  @main.command()
19
19
  @click.option("--dif-version", type=click.Choice(["1.3"]), default="1.3")
20
20
  @click.option("--ignore-missing-description", is_flag=True)
21
+ @click.option("--communities-path", type=Path)
21
22
  @click.argument("location")
22
- def validate(location: str, dif_version: str, ignore_missing_description: bool) -> None:
23
+ def validate(
24
+ location: str, dif_version: str, ignore_missing_description: bool, communities_path: Path | None
25
+ ) -> None:
23
26
  """Validate a local/remote file or local folder of DIF-encoded CSVs."""
24
27
  from dalia_dif.dif13 import read_dif13
28
+ from dalia_dif.dif13.community import get_communities_dict
29
+
30
+ if communities_path is not None:
31
+ community_dict = get_communities_dict(communities_path)
32
+ else:
33
+ community_dict = {}
25
34
 
26
35
  fail = False
27
36
  p = Path(location)
@@ -36,6 +45,7 @@ def validate(location: str, dif_version: str, ignore_missing_description: bool)
36
45
  path,
37
46
  error_accumulator=errors,
38
47
  ignore_missing_description=ignore_missing_description,
48
+ custom_community_dict=community_dict,
39
49
  )
40
50
  if errors:
41
51
  fail = True
@@ -3,35 +3,79 @@
3
3
  import csv
4
4
  from collections import Counter
5
5
  from pathlib import Path
6
+ from typing import Any, TypeAlias
7
+
8
+ from pydantic import UUID4, AnyHttpUrl, BaseModel, Field
6
9
 
7
10
  HERE = Path(__file__).parent.resolve()
8
11
  COMMUNITIES_PATH = HERE / "dalia_communities.csv"
9
12
 
10
13
 
11
- def _read_mapping() -> dict[str, str]:
14
+ class Community(BaseModel):
15
+ """A data model for communities."""
16
+
17
+ uuid: UUID4
18
+ title: str
19
+ ror: str | None = None
20
+ website: AnyHttpUrl | None = None
21
+ synonyms: list[str] = Field(default_factory=list)
22
+
23
+
24
+ RENAMES = {
25
+ "ID": "uuid",
26
+ "ROR": "ror",
27
+ "Website": "website",
28
+ "Synonyms": "synonyms",
29
+ "Title": "title",
30
+ }
31
+
32
+
33
+ def _process(row: dict[str, Any]) -> Community:
34
+ row = {RENAMES[k]: v for k, v in row.items() if v}
35
+ if synonyms_raw := row.pop("synonyms", None):
36
+ row["synonyms"] = [s.strip() for s in synonyms_raw.split("|")]
37
+ return Community.model_validate(row)
38
+
39
+
40
+ def read_communities(path: Path) -> list[Community]:
41
+ """Read communities."""
42
+ with open(path, newline="") as csvfile:
43
+ return [_process(row) for row in csv.DictReader(csvfile)]
44
+
45
+
46
+ CommunityDict: TypeAlias = dict[str, str]
47
+
48
+
49
+ def get_communities_dict(path: Path) -> CommunityDict:
50
+ """Get a mapping from names/synonyms to UUID strings."""
12
51
  rv = {}
13
- with open(COMMUNITIES_PATH, newline="") as csvfile:
14
- for row in csv.DictReader(csvfile):
15
- rv[row["Title"]] = row["ID"]
16
- for synonym in row["Synonyms"].split("|"):
17
- rv[synonym] = row["ID"]
52
+ for community in read_communities(path):
53
+ rv[community.title] = str(community.uuid)
54
+ for synonym in community.synonyms:
55
+ rv[synonym] = str(community.uuid)
18
56
  return rv
19
57
 
20
58
 
21
- LOOKUP_DICT_COMMUNITIES = _read_mapping()
59
+ def _read_mapping() -> dict[str, str]:
60
+ rv = {}
61
+ for community in read_communities(COMMUNITIES_PATH):
62
+ rv[community.title] = str(community.uuid)
63
+ for synonym in community.synonyms:
64
+ rv[synonym] = str(community.uuid)
65
+ return rv
66
+
22
67
 
23
- del _read_mapping
68
+ LOOKUP_DICT_COMMUNITIES: CommunityDict = get_communities_dict(COMMUNITIES_PATH)
24
69
 
25
70
  MISSING_COMMUNITIES: Counter[str] = Counter()
26
71
 
27
72
 
28
73
  def get_community_labels() -> dict[str, str]:
29
74
  """Get community labels."""
30
- with open(COMMUNITIES_PATH, newline="") as csvfile:
31
- return {
32
- row["ID"]: COMMUNITY_RELABELS.get(row["Title"], row["Title"])
33
- for row in csv.DictReader(csvfile)
34
- }
75
+ return {
76
+ str(community.uuid): COMMUNITY_RELABELS.get(community.title, community.title)
77
+ for community in read_communities(COMMUNITIES_PATH)
78
+ }
35
79
 
36
80
 
37
81
  COMMUNITY_RELABELS = {
dalia_dif/dif13/reader.py CHANGED
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import logging
6
6
  import re
7
- from collections import Counter
7
+ from collections import ChainMap, Counter
8
8
  from pathlib import Path
9
9
  from typing import TextIO
10
10
 
@@ -17,7 +17,7 @@ from pystow.utils import safe_open_dict_reader
17
17
  from rdflib import URIRef
18
18
  from tqdm import tqdm
19
19
 
20
- from .community import LOOKUP_DICT_COMMUNITIES
20
+ from .community import LOOKUP_DICT_COMMUNITIES, CommunityDict
21
21
  from .model import (
22
22
  AuthorDIF13,
23
23
  EducationalResourceDIF13,
@@ -102,6 +102,7 @@ def read_dif13(
102
102
  error_accumulator: list[str] | None = None,
103
103
  converter: curies.Converter | None = None,
104
104
  ignore_missing_description: bool = False,
105
+ custom_community_dict: CommunityDict | None = None,
105
106
  ) -> list[EducationalResourceDIF13]:
106
107
  """Parse DALIA records."""
107
108
  if isinstance(path, str) and (path.startswith("http://") or path.startswith("https://")):
@@ -139,6 +140,7 @@ def read_dif13(
139
140
  error_accumulator=error_accumulator,
140
141
  converter=converter,
141
142
  ignore_missing_description=ignore_missing_description,
143
+ custom_community_dict=custom_community_dict,
142
144
  )
143
145
  )
144
146
  is not None
@@ -164,13 +166,18 @@ def parse_dif13_row( # noqa:C901
164
166
  error_accumulator: list[str] | None = None,
165
167
  converter: curies.Converter | None = None,
166
168
  ignore_missing_description: bool = False,
169
+ custom_community_dict: CommunityDict | None = None,
167
170
  ) -> EducationalResourceDIF13 | None:
168
171
  """Convert a row in a DALIA curation file to a resource, or return none if unable."""
169
172
  if isinstance(file_name, Path):
170
173
  file_name = file_name.name
171
174
 
172
175
  supporting_communities, recommending_communities = _process_communities(
173
- file_name, idx, row, error_accumulator=error_accumulator
176
+ file_name,
177
+ idx,
178
+ row,
179
+ error_accumulator=error_accumulator,
180
+ custom_community_dict=custom_community_dict,
174
181
  )
175
182
 
176
183
  external_uris = _pop_split(row, "Link")
@@ -473,8 +480,10 @@ def _process_communities(
473
480
  row: dict[str, str],
474
481
  *,
475
482
  error_accumulator: list[str] | None = None,
483
+ custom_community_dict: CommunityDict | None = None,
476
484
  ) -> tuple[list[URIRef], list[URIRef]]:
477
485
  supporting, recommending = [], []
486
+ community_dict = ChainMap(custom_community_dict or {}, LOOKUP_DICT_COMMUNITIES)
478
487
  for community in _pop_split(row, "Community"):
479
488
  match = COMMUNITY_RELATION_RE.search(community)
480
489
  if not match:
@@ -489,7 +498,7 @@ def _process_communities(
489
498
  name = match.group("name").strip()
490
499
  relation = match.group("relation")
491
500
 
492
- community_uuid = LOOKUP_DICT_COMMUNITIES.get(name, None)
501
+ community_uuid = community_dict.get(name, None)
493
502
  if not community_uuid:
494
503
  if not MISSING_COMMUNITIES[name]:
495
504
  _log(
dalia_dif/version.py CHANGED
@@ -12,7 +12,7 @@ __all__ = [
12
12
  "get_version",
13
13
  ]
14
14
 
15
- VERSION = "0.0.17"
15
+ VERSION = "0.0.19"
16
16
 
17
17
 
18
18
  def get_git_hash() -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dalia_dif
3
- Version: 0.0.17
3
+ Version: 0.0.19
4
4
  Summary: Tools for DALIA's data model for open educational resources
5
5
  Keywords: snekpack,cookiecutter,open educational resources,educational resources,training
6
6
  Author: Charles Tapley Hoyt
@@ -39,9 +39,9 @@ Maintainer: Charles Tapley Hoyt
39
39
  Maintainer-email: Charles Tapley Hoyt <cthoyt@gmail.com>
40
40
  Requires-Python: >=3.10
41
41
  Project-URL: Bug Tracker, https://github.com/data-literacy-alliance/dalia-dif/issues
42
- Project-URL: Documentation, https://dalia-dif.readthedocs.io
43
42
  Project-URL: Homepage, https://github.com/data-literacy-alliance/dalia-dif
44
43
  Project-URL: Repository, https://github.com/data-literacy-alliance/dalia-dif.git
44
+ Project-URL: Documentation, https://dalia-dif.readthedocs.io
45
45
  Provides-Extra: export
46
46
  Provides-Extra: fti
47
47
  Description-Content-Type: text/markdown
@@ -1,9 +1,9 @@
1
1
  dalia_dif/.DS_Store,sha256=MtnD5ThzFbk9R7gZVWNniR_qnre6YMJscVWWkkQW8AM,6148
2
2
  dalia_dif/__init__.py,sha256=uyO7jo0cu-99M2a87I7XeOH6c9ZPqRH46YgTdfXLOWg,66
3
3
  dalia_dif/__main__.py,sha256=dlPNI11KSS49DY4SoTA1l8gQZr6iR9N1JJsySTjicUg,126
4
- dalia_dif/cli.py,sha256=zIKecW5aCvUrwyeW6k3ZXbb33Jl3X1d-9tZBsRpBLoU,3163
4
+ dalia_dif/cli.py,sha256=yvV0YeBSJ9cGlmcsuTaVqGw6-zokjLvoQ8xYHjPzoq8,3504
5
5
  dalia_dif/dif13/__init__.py,sha256=tMaSW0hhnuO_Mt8CM_d0cTT6j_FSTGFY99crUawWa4w,457
6
- dalia_dif/dif13/community/__init__.py,sha256=y8RnUSR1-d0oU02ZJA6z1hmDIJlUTJ66Yb51JGcp0JE,1051
6
+ dalia_dif/dif13/community/__init__.py,sha256=DvRb4_zuCKjfYJNPCZqG7iksvq0mUv9xURvIWM7Pbp8,2264
7
7
  dalia_dif/dif13/community/dalia_communities.csv,sha256=Tcpo310kOtn1zNMKu183GjqcM8XlsubGrLSvbvotJxI,6191
8
8
  dalia_dif/dif13/constants.py,sha256=NLNutj5AYok_WY1t1iE01dOCKK2eCnkezzN4TUgT-SA,6797
9
9
  dalia_dif/dif13/export/__init__.py,sha256=-HXO3x8soeYPFg5vIggJcZihGbyeVn_DO42cqWwNAuA,28
@@ -17,7 +17,7 @@ dalia_dif/dif13/model.py,sha256=GIfzAnT0Blh7Qe-wk3w_lxZld-B4VbfH2ahyaDdpuR4,6935
17
17
  dalia_dif/dif13/picklists.py,sha256=FapSFANJZ_u432RtGyOq7v8FpKfR4X9C7n3bAAXbrNI,4933
18
18
  dalia_dif/dif13/predicates.py,sha256=rrWVPMnMPvMelS4i2hOEWGhL11t-KR8yRrDArhGvYPE,1700
19
19
  dalia_dif/dif13/rdf.py,sha256=ZPdGB1hM2zNuxe6gidNwOn0LJB00Zs-mj2fHOYNm_qU,5908
20
- dalia_dif/dif13/reader.py,sha256=g7ZtDSrUBhlKNYyvB39auAdWQHndGf6pZGJa3jFpWes,17200
20
+ dalia_dif/dif13/reader.py,sha256=SinQMN_cimwihpsM3kJwom-MD8Om_WPTTi5Bo5EOKxQ,17611
21
21
  dalia_dif/dif13/utils.py,sha256=-r5ezhD7AkaJUAsUtZl1sHG_P76fz2Q_ULXgXLyDNII,814
22
22
  dalia_dif/namespace/__init__.py,sha256=kJGpIXZzeUdVhM_Pj465XlMkVqMB2Uc9aAZeFKQp5IQ,3105
23
23
  dalia_dif/namespace/bibframe_lite_relation.py,sha256=2trFP98s1wCPUfiAjHg-EK09yjWXC6ePLNJIVqgZvd8,255
@@ -31,9 +31,9 @@ dalia_dif/namespace/modalia.py,sha256=pSL-G9ib0E--Jwrbu9PvMMRjMe2FzzxoSjEv-0ank2
31
31
  dalia_dif/namespace/rec.py,sha256=c2Ce5IEhnM_BcZJUCXiMQEZ2GLFcC_76hfkKE16-zLc,241
32
32
  dalia_dif/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
33
33
  dalia_dif/utils.py,sha256=AA19Bw0vv8-ODZzDy_VR57WwndRccaQIepVS8tvodDo,761
34
- dalia_dif/version.py,sha256=aAPqI66QtdgdBvrGfuSXNCjIUCx6siw8G6_BPaSwT7w,962
35
- dalia_dif-0.0.17.dist-info/licenses/LICENSE,sha256=S-DsND478R_VQyGmtXbVYW67fRiJj3QfY8UXIJ4zvLI,1076
36
- dalia_dif-0.0.17.dist-info/WHEEL,sha256=XjEbIc5-wIORjWaafhI6vBtlxDBp7S9KiujWF1EM7Ak,79
37
- dalia_dif-0.0.17.dist-info/entry_points.txt,sha256=GmBz8JVyUD6m4v2QIxa7gm3sHIVNjTl5KTPP7L3FCGI,50
38
- dalia_dif-0.0.17.dist-info/METADATA,sha256=JwAwFe9RTi_fMDtlWApattEpFAihCPtSqcG20tF-rKg,17760
39
- dalia_dif-0.0.17.dist-info/RECORD,,
34
+ dalia_dif/version.py,sha256=JgVhjEt3ylQ4lm8iBE_45vP-IBTOL5sgAbkPUPD2Jng,962
35
+ dalia_dif-0.0.19.dist-info/licenses/LICENSE,sha256=S-DsND478R_VQyGmtXbVYW67fRiJj3QfY8UXIJ4zvLI,1076
36
+ dalia_dif-0.0.19.dist-info/WHEEL,sha256=fAguSjoiATBe7TNBkJwOjyL1Tt4wwiaQGtNtjRPNMQA,80
37
+ dalia_dif-0.0.19.dist-info/entry_points.txt,sha256=GmBz8JVyUD6m4v2QIxa7gm3sHIVNjTl5KTPP7L3FCGI,50
38
+ dalia_dif-0.0.19.dist-info/METADATA,sha256=b9rRxjsm2wZqpNKd7wP5noeSlDQ5UxfOagIj4KXY-mg,17760
39
+ dalia_dif-0.0.19.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.25
2
+ Generator: uv 0.9.28
3
3
  Root-Is-Purelib: true
4
- Tag: py3-none-any
4
+ Tag: py3-none-any