dalia_dif 0.0.17__tar.gz → 0.0.19__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.
Files changed (39) hide show
  1. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/PKG-INFO +2 -2
  2. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/pyproject.toml +2 -2
  3. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/cli.py +11 -1
  4. dalia_dif-0.0.19/src/dalia_dif/dif13/community/__init__.py +84 -0
  5. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/reader.py +13 -4
  6. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/version.py +1 -1
  7. dalia_dif-0.0.17/src/dalia_dif/dif13/community/__init__.py +0 -40
  8. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/LICENSE +0 -0
  9. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/README.md +0 -0
  10. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/.DS_Store +0 -0
  11. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/__init__.py +0 -0
  12. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/__main__.py +0 -0
  13. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/__init__.py +0 -0
  14. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/community/dalia_communities.csv +0 -0
  15. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/constants.py +0 -0
  16. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/export/__init__.py +0 -0
  17. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/export/charts.py +0 -0
  18. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/export/fti.py +0 -0
  19. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/legacy/__init__.py +0 -0
  20. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/legacy/authors.py +0 -0
  21. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/legacy/components.py +0 -0
  22. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/legacy/learning_resource.py +0 -0
  23. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/model.py +0 -0
  24. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/picklists.py +0 -0
  25. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/predicates.py +0 -0
  26. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/rdf.py +0 -0
  27. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/dif13/utils.py +0 -0
  28. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/__init__.py +0 -0
  29. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/bibframe_lite_relation.py +0 -0
  30. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/bibo.py +0 -0
  31. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/citedcat.py +0 -0
  32. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/educor.py +0 -0
  33. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/fabio.py +0 -0
  34. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/hcrt.py +0 -0
  35. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/metadata4ing.py +0 -0
  36. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/modalia.py +0 -0
  37. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/namespace/rec.py +0 -0
  38. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/py.typed +0 -0
  39. {dalia_dif-0.0.17 → dalia_dif-0.0.19}/src/dalia_dif/utils.py +0 -0
@@ -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
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "dalia_dif"
7
- version = "0.0.17"
7
+ version = "0.0.19"
8
8
  description = "Tools for DALIA's data model for open educational resources"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -250,7 +250,7 @@ known-first-party = [
250
250
  docstring-code-format = true
251
251
 
252
252
  [tool.bumpversion]
253
- current_version = "0.0.17"
253
+ current_version = "0.0.19"
254
254
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(?:-(?P<release>[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+(?P<build>[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?"
255
255
  serialize = [
256
256
  "{major}.{minor}.{patch}-{release}+{build}",
@@ -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
@@ -0,0 +1,84 @@
1
+ """Code for curated DALIA communities."""
2
+
3
+ import csv
4
+ from collections import Counter
5
+ from pathlib import Path
6
+ from typing import Any, TypeAlias
7
+
8
+ from pydantic import UUID4, AnyHttpUrl, BaseModel, Field
9
+
10
+ HERE = Path(__file__).parent.resolve()
11
+ COMMUNITIES_PATH = HERE / "dalia_communities.csv"
12
+
13
+
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."""
51
+ rv = {}
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)
56
+ return rv
57
+
58
+
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
+
67
+
68
+ LOOKUP_DICT_COMMUNITIES: CommunityDict = get_communities_dict(COMMUNITIES_PATH)
69
+
70
+ MISSING_COMMUNITIES: Counter[str] = Counter()
71
+
72
+
73
+ def get_community_labels() -> dict[str, str]:
74
+ """Get community labels."""
75
+ return {
76
+ str(community.uuid): COMMUNITY_RELABELS.get(community.title, community.title)
77
+ for community in read_communities(COMMUNITIES_PATH)
78
+ }
79
+
80
+
81
+ COMMUNITY_RELABELS = {
82
+ "Nationale Forschungsdateninfrastruktur (NFDI)": "NFDI",
83
+ "HeFDI - Hessische Forschungsdateninfrastrukturen": "HeFDI",
84
+ }
@@ -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(
@@ -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,40 +0,0 @@
1
- """Code for curated DALIA communities."""
2
-
3
- import csv
4
- from collections import Counter
5
- from pathlib import Path
6
-
7
- HERE = Path(__file__).parent.resolve()
8
- COMMUNITIES_PATH = HERE / "dalia_communities.csv"
9
-
10
-
11
- def _read_mapping() -> dict[str, str]:
12
- 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"]
18
- return rv
19
-
20
-
21
- LOOKUP_DICT_COMMUNITIES = _read_mapping()
22
-
23
- del _read_mapping
24
-
25
- MISSING_COMMUNITIES: Counter[str] = Counter()
26
-
27
-
28
- def get_community_labels() -> dict[str, str]:
29
- """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
- }
35
-
36
-
37
- COMMUNITY_RELABELS = {
38
- "Nationale Forschungsdateninfrastruktur (NFDI)": "NFDI",
39
- "HeFDI - Hessische Forschungsdateninfrastrukturen": "HeFDI",
40
- }
File without changes
File without changes